Skip to content

Commit 8201f1e

Browse files
committed
Merge branch 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-fixes
Just several fixups, - fix page fault and vblank timeout issues due to delayed vblank handling. - fix panel driver probing to fail without te-gpios property. - fix potential security hole by using "%pK" format. - fix wrong if statement condition. And one cleanup which removes Exynos4415 SoC support which is not supported anymore. * 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: drm/exynos/dsi: make te-gpios optional drm/exynos: Print kernel pointers in a restricted form drm/exynos/decon5433: fix software trigger mask drm/exynos/fimd: signal frame done interrupt at front porch drm/exynos/decon5433: signal frame done interrupt at front porch drm/exynos/decon5433: fix vblank event handling drm/exynos: move crtc event handling to drivers callbacks drm/exynos: Remove support for Exynos4415 (SoC not supported anymore) drm/exynos/decon5433: & vs | typo
2 parents d08997c + 22e098d commit 8201f1e

File tree

16 files changed

+142
-69
lines changed

16 files changed

+142
-69
lines changed

Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ Required properties:
44
- compatible: value should be one of the following
55
"samsung,exynos3250-mipi-dsi" /* for Exynos3250/3472 SoCs */
66
"samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */
7-
"samsung,exynos4415-mipi-dsi" /* for Exynos4415 SoC */
87
"samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */
98
"samsung,exynos5422-mipi-dsi" /* for Exynos5422/5800 SoCs */
109
"samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */

Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ Required properties:
1111
"samsung,s5pv210-fimd"; /* for S5PV210 SoC */
1212
"samsung,exynos3250-fimd"; /* for Exynos3250/3472 SoCs */
1313
"samsung,exynos4210-fimd"; /* for Exynos4 SoCs */
14-
"samsung,exynos4415-fimd"; /* for Exynos4415 SoC */
1514
"samsung,exynos5250-fimd"; /* for Exynos5250 SoCs */
1615
"samsung,exynos5420-fimd"; /* for Exynos5420/5422/5800 SoCs */
1716

drivers/gpu/drm/exynos/exynos5433_drm_decon.c

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ struct decon_context {
6868
unsigned long flags;
6969
unsigned long out_type;
7070
int first_win;
71+
spinlock_t vblank_lock;
72+
u32 frame_id;
7173
};
7274

7375
static const uint32_t decon_formats[] = {
@@ -103,7 +105,7 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
103105
if (ctx->out_type & IFTYPE_I80)
104106
val |= VIDINTCON0_FRAMEDONE;
105107
else
106-
val |= VIDINTCON0_INTFRMEN;
108+
val |= VIDINTCON0_INTFRMEN | VIDINTCON0_FRAMESEL_FP;
107109

108110
writel(val, ctx->addr + DECON_VIDINTCON0);
109111
}
@@ -122,14 +124,56 @@ static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
122124
writel(0, ctx->addr + DECON_VIDINTCON0);
123125
}
124126

127+
/* return number of starts/ends of frame transmissions since reset */
128+
static u32 decon_get_frame_count(struct decon_context *ctx, bool end)
129+
{
130+
u32 frm, pfrm, status, cnt = 2;
131+
132+
/* To get consistent result repeat read until frame id is stable.
133+
* Usually the loop will be executed once, in rare cases when the loop
134+
* is executed at frame change time 2nd pass will be needed.
135+
*/
136+
frm = readl(ctx->addr + DECON_CRFMID);
137+
do {
138+
status = readl(ctx->addr + DECON_VIDCON1);
139+
pfrm = frm;
140+
frm = readl(ctx->addr + DECON_CRFMID);
141+
} while (frm != pfrm && --cnt);
142+
143+
/* CRFMID is incremented on BPORCH in case of I80 and on VSYNC in case
144+
* of RGB, it should be taken into account.
145+
*/
146+
if (!frm)
147+
return 0;
148+
149+
switch (status & (VIDCON1_VSTATUS_MASK | VIDCON1_I80_ACTIVE)) {
150+
case VIDCON1_VSTATUS_VS:
151+
if (!(ctx->out_type & IFTYPE_I80))
152+
--frm;
153+
break;
154+
case VIDCON1_VSTATUS_BP:
155+
--frm;
156+
break;
157+
case VIDCON1_I80_ACTIVE:
158+
case VIDCON1_VSTATUS_AC:
159+
if (end)
160+
--frm;
161+
break;
162+
default:
163+
break;
164+
}
165+
166+
return frm;
167+
}
168+
125169
static void decon_setup_trigger(struct decon_context *ctx)
126170
{
127171
if (!(ctx->out_type & (IFTYPE_I80 | I80_HW_TRG)))
128172
return;
129173

130174
if (!(ctx->out_type & I80_HW_TRG)) {
131-
writel(TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN
132-
| TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN,
175+
writel(TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
176+
TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN,
133177
ctx->addr + DECON_TRIGCON);
134178
return;
135179
}
@@ -365,11 +409,14 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
365409
static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
366410
{
367411
struct decon_context *ctx = crtc->ctx;
412+
unsigned long flags;
368413
int i;
369414

370415
if (test_bit(BIT_SUSPENDED, &ctx->flags))
371416
return;
372417

418+
spin_lock_irqsave(&ctx->vblank_lock, flags);
419+
373420
for (i = ctx->first_win; i < WINDOWS_NR; i++)
374421
decon_shadow_protect_win(ctx, i, false);
375422

@@ -378,11 +425,18 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
378425

379426
if (ctx->out_type & IFTYPE_I80)
380427
set_bit(BIT_WIN_UPDATED, &ctx->flags);
428+
429+
ctx->frame_id = decon_get_frame_count(ctx, true);
430+
431+
exynos_crtc_handle_event(crtc);
432+
433+
spin_unlock_irqrestore(&ctx->vblank_lock, flags);
381434
}
382435

383436
static void decon_swreset(struct decon_context *ctx)
384437
{
385438
unsigned int tries;
439+
unsigned long flags;
386440

387441
writel(0, ctx->addr + DECON_VIDCON0);
388442
for (tries = 2000; tries; --tries) {
@@ -400,6 +454,10 @@ static void decon_swreset(struct decon_context *ctx)
400454

401455
WARN(tries == 0, "failed to software reset DECON\n");
402456

457+
spin_lock_irqsave(&ctx->vblank_lock, flags);
458+
ctx->frame_id = 0;
459+
spin_unlock_irqrestore(&ctx->vblank_lock, flags);
460+
403461
if (!(ctx->out_type & IFTYPE_HDMI))
404462
return;
405463

@@ -578,6 +636,24 @@ static const struct component_ops decon_component_ops = {
578636
.unbind = decon_unbind,
579637
};
580638

639+
static void decon_handle_vblank(struct decon_context *ctx)
640+
{
641+
u32 frm;
642+
643+
spin_lock(&ctx->vblank_lock);
644+
645+
frm = decon_get_frame_count(ctx, true);
646+
647+
if (frm != ctx->frame_id) {
648+
/* handle only if incremented, take care of wrap-around */
649+
if ((s32)(frm - ctx->frame_id) > 0)
650+
drm_crtc_handle_vblank(&ctx->crtc->base);
651+
ctx->frame_id = frm;
652+
}
653+
654+
spin_unlock(&ctx->vblank_lock);
655+
}
656+
581657
static irqreturn_t decon_irq_handler(int irq, void *dev_id)
582658
{
583659
struct decon_context *ctx = dev_id;
@@ -598,7 +674,7 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
598674
(VIDOUT_INTERLACE_EN_F | VIDOUT_INTERLACE_FIELD_F))
599675
return IRQ_HANDLED;
600676
}
601-
drm_crtc_handle_vblank(&ctx->crtc->base);
677+
decon_handle_vblank(ctx);
602678
}
603679

604680
out:
@@ -671,14 +747,15 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
671747
__set_bit(BIT_SUSPENDED, &ctx->flags);
672748
ctx->dev = dev;
673749
ctx->out_type = (unsigned long)of_device_get_match_data(dev);
750+
spin_lock_init(&ctx->vblank_lock);
674751

675752
if (ctx->out_type & IFTYPE_HDMI) {
676753
ctx->first_win = 1;
677754
} else if (of_get_child_by_name(dev->of_node, "i80-if-timings")) {
678755
ctx->out_type |= IFTYPE_I80;
679756
}
680757

681-
if (ctx->out_type | I80_HW_TRG) {
758+
if (ctx->out_type & I80_HW_TRG) {
682759
ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
683760
"samsung,disp-sysreg");
684761
if (IS_ERR(ctx->sysreg)) {

drivers/gpu/drm/exynos/exynos7_drm_decon.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
526526

527527
for (i = 0; i < WINDOWS_NR; i++)
528528
decon_shadow_protect_win(ctx, i, false);
529+
exynos_crtc_handle_event(crtc);
529530
}
530531

531532
static void decon_init(struct decon_context *ctx)

drivers/gpu/drm/exynos/exynos_drm_crtc.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,28 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
8585
struct drm_crtc_state *old_crtc_state)
8686
{
8787
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
88-
struct drm_pending_vblank_event *event;
89-
unsigned long flags;
9088

9189
if (exynos_crtc->ops->atomic_flush)
9290
exynos_crtc->ops->atomic_flush(exynos_crtc);
91+
}
92+
93+
static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
94+
.enable = exynos_drm_crtc_enable,
95+
.disable = exynos_drm_crtc_disable,
96+
.mode_set_nofb = exynos_drm_crtc_mode_set_nofb,
97+
.atomic_check = exynos_crtc_atomic_check,
98+
.atomic_begin = exynos_crtc_atomic_begin,
99+
.atomic_flush = exynos_crtc_atomic_flush,
100+
};
101+
102+
void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc)
103+
{
104+
struct drm_crtc *crtc = &exynos_crtc->base;
105+
struct drm_pending_vblank_event *event = crtc->state->event;
106+
unsigned long flags;
93107

94-
event = crtc->state->event;
95108
if (event) {
96109
crtc->state->event = NULL;
97-
98110
spin_lock_irqsave(&crtc->dev->event_lock, flags);
99111
if (drm_crtc_vblank_get(crtc) == 0)
100112
drm_crtc_arm_vblank_event(crtc, event);
@@ -105,15 +117,6 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
105117

106118
}
107119

108-
static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
109-
.enable = exynos_drm_crtc_enable,
110-
.disable = exynos_drm_crtc_disable,
111-
.mode_set_nofb = exynos_drm_crtc_mode_set_nofb,
112-
.atomic_check = exynos_crtc_atomic_check,
113-
.atomic_begin = exynos_crtc_atomic_begin,
114-
.atomic_flush = exynos_crtc_atomic_flush,
115-
};
116-
117120
static void exynos_drm_crtc_destroy(struct drm_crtc *crtc)
118121
{
119122
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);

drivers/gpu/drm/exynos/exynos_drm_crtc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,6 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
4040
*/
4141
void exynos_drm_crtc_te_handler(struct drm_crtc *crtc);
4242

43+
void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc);
44+
4345
#endif

drivers/gpu/drm/exynos/exynos_drm_dsi.c

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
#define DSIM_SYNC_INFORM (1 << 27)
8787
#define DSIM_EOT_DISABLE (1 << 28)
8888
#define DSIM_MFLUSH_VS (1 << 29)
89-
/* This flag is valid only for exynos3250/3472/4415/5260/5430 */
89+
/* This flag is valid only for exynos3250/3472/5260/5430 */
9090
#define DSIM_CLKLANE_STOP (1 << 30)
9191

9292
/* DSIM_ESCMODE */
@@ -473,17 +473,6 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
473473
.reg_values = reg_values,
474474
};
475475

476-
static const struct exynos_dsi_driver_data exynos4415_dsi_driver_data = {
477-
.reg_ofs = exynos_reg_ofs,
478-
.plltmr_reg = 0x58,
479-
.has_clklane_stop = 1,
480-
.num_clks = 2,
481-
.max_freq = 1000,
482-
.wait_for_reset = 1,
483-
.num_bits_resol = 11,
484-
.reg_values = reg_values,
485-
};
486-
487476
static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
488477
.reg_ofs = exynos_reg_ofs,
489478
.plltmr_reg = 0x58,
@@ -521,8 +510,6 @@ static const struct of_device_id exynos_dsi_of_match[] = {
521510
.data = &exynos3_dsi_driver_data },
522511
{ .compatible = "samsung,exynos4210-mipi-dsi",
523512
.data = &exynos4_dsi_driver_data },
524-
{ .compatible = "samsung,exynos4415-mipi-dsi",
525-
.data = &exynos4415_dsi_driver_data },
526513
{ .compatible = "samsung,exynos5410-mipi-dsi",
527514
.data = &exynos5_dsi_driver_data },
528515
{ .compatible = "samsung,exynos5422-mipi-dsi",
@@ -979,7 +966,7 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
979966
bool first = !xfer->tx_done;
980967
u32 reg;
981968

982-
dev_dbg(dev, "< xfer %p: tx len %u, done %u, rx len %u, done %u\n",
969+
dev_dbg(dev, "< xfer %pK: tx len %u, done %u, rx len %u, done %u\n",
983970
xfer, length, xfer->tx_done, xfer->rx_len, xfer->rx_done);
984971

985972
if (length > DSI_TX_FIFO_SIZE)
@@ -1177,7 +1164,7 @@ static bool exynos_dsi_transfer_finish(struct exynos_dsi *dsi)
11771164
spin_unlock_irqrestore(&dsi->transfer_lock, flags);
11781165

11791166
dev_dbg(dsi->dev,
1180-
"> xfer %p, tx_len %zu, tx_done %u, rx_len %u, rx_done %u\n",
1167+
"> xfer %pK, tx_len %zu, tx_done %u, rx_len %u, rx_done %u\n",
11811168
xfer, xfer->packet.payload_length, xfer->tx_done, xfer->rx_len,
11821169
xfer->rx_done);
11831170

@@ -1348,9 +1335,12 @@ static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi)
13481335
int te_gpio_irq;
13491336

13501337
dsi->te_gpio = of_get_named_gpio(dsi->panel_node, "te-gpios", 0);
1338+
if (dsi->te_gpio == -ENOENT)
1339+
return 0;
1340+
13511341
if (!gpio_is_valid(dsi->te_gpio)) {
1352-
dev_err(dsi->dev, "no te-gpios specified\n");
13531342
ret = dsi->te_gpio;
1343+
dev_err(dsi->dev, "cannot get te-gpios, %d\n", ret);
13541344
goto out;
13551345
}
13561346

drivers/gpu/drm/exynos/exynos_drm_fimc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1695,7 +1695,7 @@ static int fimc_probe(struct platform_device *pdev)
16951695
goto err_put_clk;
16961696
}
16971697

1698-
DRM_DEBUG_KMS("id[%d]ippdrv[%p]\n", ctx->id, ippdrv);
1698+
DRM_DEBUG_KMS("id[%d]ippdrv[%pK]\n", ctx->id, ippdrv);
16991699

17001700
spin_lock_init(&ctx->lock);
17011701
platform_set_drvdata(pdev, ctx);

drivers/gpu/drm/exynos/exynos_drm_fimd.c

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@
7171
#define TRIGCON 0x1A4
7272
#define TRGMODE_ENABLE (1 << 0)
7373
#define SWTRGCMD_ENABLE (1 << 1)
74-
/* Exynos3250, 3472, 4415, 5260 5410, 5420 and 5422 only supported. */
74+
/* Exynos3250, 3472, 5260 5410, 5420 and 5422 only supported. */
7575
#define HWTRGEN_ENABLE (1 << 3)
7676
#define HWTRGMASK_ENABLE (1 << 4)
77-
/* Exynos3250, 3472, 4415, 5260, 5420 and 5422 only supported. */
77+
/* Exynos3250, 3472, 5260, 5420 and 5422 only supported. */
7878
#define HWTRIGEN_PER_ENABLE (1 << 31)
7979

8080
/* display mode change control register except exynos4 */
@@ -138,18 +138,6 @@ static struct fimd_driver_data exynos4_fimd_driver_data = {
138138
.has_vtsel = 1,
139139
};
140140

141-
static struct fimd_driver_data exynos4415_fimd_driver_data = {
142-
.timing_base = 0x20000,
143-
.lcdblk_offset = 0x210,
144-
.lcdblk_vt_shift = 10,
145-
.lcdblk_bypass_shift = 1,
146-
.trg_type = I80_HW_TRG,
147-
.has_shadowcon = 1,
148-
.has_vidoutcon = 1,
149-
.has_vtsel = 1,
150-
.has_trigger_per_te = 1,
151-
};
152-
153141
static struct fimd_driver_data exynos5_fimd_driver_data = {
154142
.timing_base = 0x20000,
155143
.lcdblk_offset = 0x214,
@@ -210,8 +198,6 @@ static const struct of_device_id fimd_driver_dt_match[] = {
210198
.data = &exynos3_fimd_driver_data },
211199
{ .compatible = "samsung,exynos4210-fimd",
212200
.data = &exynos4_fimd_driver_data },
213-
{ .compatible = "samsung,exynos4415-fimd",
214-
.data = &exynos4415_fimd_driver_data },
215201
{ .compatible = "samsung,exynos5250-fimd",
216202
.data = &exynos5_fimd_driver_data },
217203
{ .compatible = "samsung,exynos5420-fimd",
@@ -257,7 +243,7 @@ static int fimd_enable_vblank(struct exynos_drm_crtc *crtc)
257243
val |= VIDINTCON0_INT_FRAME;
258244

259245
val &= ~VIDINTCON0_FRAMESEL0_MASK;
260-
val |= VIDINTCON0_FRAMESEL0_VSYNC;
246+
val |= VIDINTCON0_FRAMESEL0_FRONTPORCH;
261247
val &= ~VIDINTCON0_FRAMESEL1_MASK;
262248
val |= VIDINTCON0_FRAMESEL1_NONE;
263249
}
@@ -723,6 +709,8 @@ static void fimd_atomic_flush(struct exynos_drm_crtc *crtc)
723709

724710
for (i = 0; i < WINDOWS_NR; i++)
725711
fimd_shadow_protect_win(ctx, i, false);
712+
713+
exynos_crtc_handle_event(crtc);
726714
}
727715

728716
static void fimd_update_plane(struct exynos_drm_crtc *crtc,

drivers/gpu/drm/exynos/exynos_drm_gem.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev,
218218
return ERR_PTR(ret);
219219
}
220220

221-
DRM_DEBUG_KMS("created file object = %p\n", obj->filp);
221+
DRM_DEBUG_KMS("created file object = %pK\n", obj->filp);
222222

223223
return exynos_gem;
224224
}

0 commit comments

Comments
 (0)