Skip to content

Commit 7ebdb0d

Browse files
committed
Merge tag 'exynos-drm-next-for-v4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next
Summary: - Provide NV12MT pixel format support of Mixer driver in generic way. - Refactor Exynos KMS drivers . Refactoring to panel detection way . Refactoring to setting up possible_crtcs . Refactoring to video and command mode support - Some cleanups * tag 'exynos-drm-next-for-v4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: drm/exynos: simplify set_pixfmt() in DECON and FIMD drivers drm/exynos: consistent use of cpp drm/exynos: mixer: remove src offset from mixer_graph_buffer() drm/exynos: mixer: simplify mixer_graph_buffer() drm/exynos: mixer: simplify vp_video_buffer() drm/exynos: mixer: enable NV12MT support for the video plane drm/exynos: mixer: fix chroma comment in vp_video_buffer() arm64: dts: exynos: remove i80-if-timings nodes dt-bindings: exynos5433-decon: remove i80-if-timings property drm/exynos/decon5433: use mode info stored in CRTC to detect i80 mode drm/exynos: add mode_valid callback to exynos_drm drm/exynos/decon5433: refactor irq requesting code drm/exynos/mic: use mode info stored in CRTC to detect i80 mode drm/exynos/dsi: propagate info about command mode from panel drm/exynos/dsi: refactor panel detection logic drm/exynos: use helper to set possible crtcs drm/exynos/decon5433: use readl_poll_timeout helpers
2 parents 095e2d0 + 5b7b1b7 commit 7ebdb0d

18 files changed

+299
-327
lines changed

Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,6 @@ Required properties:
2525
size-cells must 1 and 0, respectively.
2626
- port: contains an endpoint node which is connected to the endpoint in the mic
2727
node. The reg value muset be 0.
28-
- i80-if-timings: specify whether the panel which is connected to decon uses
29-
i80 lcd interface or mipi video interface. This node contains
30-
no timing information as that of fimd does. Because there is
31-
no register in decon to specify i80 interface timing value,
32-
it is not needed, but make it remain to use same kind of node
33-
in fimd and exynos7 decon.
3428

3529
Example:
3630
SoC specific DT entry:
@@ -59,9 +53,3 @@ decon: decon@13800000 {
5953
};
6054
};
6155
};
62-
63-
Board specific DT entry:
64-
&decon {
65-
i80-if-timings {
66-
};
67-
};

arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,6 @@
280280

281281
&decon {
282282
status = "okay";
283-
284-
i80-if-timings {
285-
};
286283
};
287284

288285
&decon_tv {
@@ -1116,9 +1113,6 @@
11161113

11171114
&mic {
11181115
status = "okay";
1119-
1120-
i80-if-timings {
1121-
};
11221116
};
11231117

11241118
&pmu_system_controller {

drivers/gpu/drm/exynos/exynos5433_drm_decon.c

Lines changed: 67 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/platform_device.h>
1414
#include <linux/clk.h>
1515
#include <linux/component.h>
16+
#include <linux/iopoll.h>
1617
#include <linux/mfd/syscon.h>
1718
#include <linux/of_device.h>
1819
#include <linux/of_gpio.h>
@@ -33,9 +34,8 @@
3334
#define WINDOWS_NR 3
3435
#define MIN_FB_WIDTH_FOR_16WORD_BURST 128
3536

36-
#define IFTYPE_I80 (1 << 0)
37-
#define I80_HW_TRG (1 << 1)
38-
#define IFTYPE_HDMI (1 << 2)
37+
#define I80_HW_TRG (1 << 0)
38+
#define IFTYPE_HDMI (1 << 1)
3939

4040
static const char * const decon_clks_name[] = {
4141
"pclk",
@@ -57,6 +57,8 @@ struct decon_context {
5757
struct regmap *sysreg;
5858
struct clk *clks[ARRAY_SIZE(decon_clks_name)];
5959
unsigned int irq;
60+
unsigned int irq_vsync;
61+
unsigned int irq_lcd_sys;
6062
unsigned int te_irq;
6163
unsigned long out_type;
6264
int first_win;
@@ -90,7 +92,7 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
9092
u32 val;
9193

9294
val = VIDINTCON0_INTEN;
93-
if (ctx->out_type & IFTYPE_I80)
95+
if (crtc->i80_mode)
9496
val |= VIDINTCON0_FRAMEDONE;
9597
else
9698
val |= VIDINTCON0_INTFRMEN | VIDINTCON0_FRAMESEL_FP;
@@ -139,7 +141,7 @@ static u32 decon_get_frame_count(struct decon_context *ctx, bool end)
139141

140142
switch (status & (VIDCON1_VSTATUS_MASK | VIDCON1_I80_ACTIVE)) {
141143
case VIDCON1_VSTATUS_VS:
142-
if (!(ctx->out_type & IFTYPE_I80))
144+
if (!(ctx->crtc->i80_mode))
143145
--frm;
144146
break;
145147
case VIDCON1_VSTATUS_BP:
@@ -166,7 +168,7 @@ static u32 decon_get_vblank_counter(struct exynos_drm_crtc *crtc)
166168

167169
static void decon_setup_trigger(struct decon_context *ctx)
168170
{
169-
if (!(ctx->out_type & (IFTYPE_I80 | I80_HW_TRG)))
171+
if (!ctx->crtc->i80_mode && !(ctx->out_type & I80_HW_TRG))
170172
return;
171173

172174
if (!(ctx->out_type & I80_HW_TRG)) {
@@ -206,7 +208,7 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
206208
val = VIDOUT_LCD_ON;
207209
if (interlaced)
208210
val |= VIDOUT_INTERLACE_EN_F;
209-
if (ctx->out_type & IFTYPE_I80) {
211+
if (crtc->i80_mode) {
210212
val |= VIDOUT_COMMAND_IF;
211213
} else {
212214
val |= VIDOUT_RGB_IF;
@@ -222,7 +224,7 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
222224
VIDTCON2_HOZVAL(m->hdisplay - 1);
223225
writel(val, ctx->addr + DECON_VIDTCON2);
224226

225-
if (!(ctx->out_type & IFTYPE_I80)) {
227+
if (!crtc->i80_mode) {
226228
int vbp = m->crtc_vtotal - m->crtc_vsync_end;
227229
int vfp = m->crtc_vsync_start - m->crtc_vdisplay;
228230

@@ -277,16 +279,14 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
277279
val |= WINCONx_BURSTLEN_16WORD;
278280
break;
279281
case DRM_FORMAT_ARGB8888:
282+
default:
280283
val |= WINCONx_BPPMODE_32BPP_A8888;
281284
val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F;
282285
val |= WINCONx_BURSTLEN_16WORD;
283286
break;
284-
default:
285-
DRM_ERROR("Proper pixel format is not set\n");
286-
return;
287287
}
288288

289-
DRM_DEBUG_KMS("bpp = %u\n", fb->format->cpp[0] * 8);
289+
DRM_DEBUG_KMS("cpp = %u\n", fb->format->cpp[0]);
290290

291291
/*
292292
* In case of exynos, setting dma-burst to 16Word causes permanent
@@ -329,7 +329,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
329329
struct decon_context *ctx = crtc->ctx;
330330
struct drm_framebuffer *fb = state->base.fb;
331331
unsigned int win = plane->index;
332-
unsigned int bpp = fb->format->cpp[0];
332+
unsigned int cpp = fb->format->cpp[0];
333333
unsigned int pitch = fb->pitches[0];
334334
dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0);
335335
u32 val;
@@ -365,11 +365,11 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
365365
writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
366366

367367
if (!(ctx->out_type & IFTYPE_HDMI))
368-
val = BIT_VAL(pitch - state->crtc.w * bpp, 27, 14)
369-
| BIT_VAL(state->crtc.w * bpp, 13, 0);
368+
val = BIT_VAL(pitch - state->crtc.w * cpp, 27, 14)
369+
| BIT_VAL(state->crtc.w * cpp, 13, 0);
370370
else
371-
val = BIT_VAL(pitch - state->crtc.w * bpp, 29, 15)
372-
| BIT_VAL(state->crtc.w * bpp, 14, 0);
371+
val = BIT_VAL(pitch - state->crtc.w * cpp, 29, 15)
372+
| BIT_VAL(state->crtc.w * cpp, 14, 0);
373373
writel(val, ctx->addr + DECON_VIDW0xADD2(win));
374374

375375
decon_win_set_pixfmt(ctx, win, fb);
@@ -407,24 +407,19 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
407407

408408
static void decon_swreset(struct decon_context *ctx)
409409
{
410-
unsigned int tries;
411410
unsigned long flags;
411+
u32 val;
412+
int ret;
412413

413414
writel(0, ctx->addr + DECON_VIDCON0);
414-
for (tries = 2000; tries; --tries) {
415-
if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_STOP_STATUS)
416-
break;
417-
udelay(10);
418-
}
415+
readl_poll_timeout(ctx->addr + DECON_VIDCON0, val,
416+
~val & VIDCON0_STOP_STATUS, 12, 20000);
419417

420418
writel(VIDCON0_SWRESET, ctx->addr + DECON_VIDCON0);
421-
for (tries = 2000; tries; --tries) {
422-
if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_SWRESET)
423-
break;
424-
udelay(10);
425-
}
419+
ret = readl_poll_timeout(ctx->addr + DECON_VIDCON0, val,
420+
~val & VIDCON0_SWRESET, 12, 20000);
426421

427-
WARN(tries == 0, "failed to software reset DECON\n");
422+
WARN(ret < 0, "failed to software reset DECON\n");
428423

429424
spin_lock_irqsave(&ctx->vblank_lock, flags);
430425
ctx->frame_id = 0;
@@ -515,6 +510,22 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc)
515510
clk_disable_unprepare(ctx->clks[i]);
516511
}
517512

513+
static enum drm_mode_status decon_mode_valid(struct exynos_drm_crtc *crtc,
514+
const struct drm_display_mode *mode)
515+
{
516+
struct decon_context *ctx = crtc->ctx;
517+
518+
ctx->irq = crtc->i80_mode ? ctx->irq_lcd_sys : ctx->irq_vsync;
519+
520+
if (ctx->irq)
521+
return MODE_OK;
522+
523+
dev_info(ctx->dev, "Sink requires %s mode, but appropriate interrupt is not provided.\n",
524+
crtc->i80_mode ? "command" : "video");
525+
526+
return MODE_BAD;
527+
}
528+
518529
static const struct exynos_drm_crtc_ops decon_crtc_ops = {
519530
.enable = decon_enable,
520531
.disable = decon_disable,
@@ -524,6 +535,7 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
524535
.atomic_begin = decon_atomic_begin,
525536
.update_plane = decon_update_plane,
526537
.disable_plane = decon_disable_plane,
538+
.mode_valid = decon_mode_valid,
527539
.atomic_flush = decon_atomic_flush,
528540
};
529541

@@ -674,19 +686,22 @@ static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
674686
MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match);
675687

676688
static int decon_conf_irq(struct decon_context *ctx, const char *name,
677-
irq_handler_t handler, unsigned long int flags, bool required)
689+
irq_handler_t handler, unsigned long int flags)
678690
{
679691
struct platform_device *pdev = to_platform_device(ctx->dev);
680692
int ret, irq = platform_get_irq_byname(pdev, name);
681693

682694
if (irq < 0) {
683-
if (irq == -EPROBE_DEFER)
695+
switch (irq) {
696+
case -EPROBE_DEFER:
684697
return irq;
685-
if (required)
686-
dev_err(ctx->dev, "cannot get %s IRQ\n", name);
687-
else
688-
irq = 0;
689-
return irq;
698+
case -ENODATA:
699+
case -ENXIO:
700+
return 0;
701+
default:
702+
dev_err(ctx->dev, "IRQ %s get failed, %d\n", name, irq);
703+
return irq;
704+
}
690705
}
691706
irq_set_status_flags(irq, IRQ_NOAUTOEN);
692707
ret = devm_request_irq(ctx->dev, irq, handler, flags, "drm_decon", ctx);
@@ -714,11 +729,8 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
714729
ctx->out_type = (unsigned long)of_device_get_match_data(dev);
715730
spin_lock_init(&ctx->vblank_lock);
716731

717-
if (ctx->out_type & IFTYPE_HDMI) {
732+
if (ctx->out_type & IFTYPE_HDMI)
718733
ctx->first_win = 1;
719-
} else if (of_get_child_by_name(dev->of_node, "i80-if-timings")) {
720-
ctx->out_type |= IFTYPE_I80;
721-
}
722734

723735
for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
724736
struct clk *clk;
@@ -742,25 +754,23 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
742754
return PTR_ERR(ctx->addr);
743755
}
744756

745-
if (ctx->out_type & IFTYPE_I80) {
746-
ret = decon_conf_irq(ctx, "lcd_sys", decon_irq_handler, 0, true);
747-
if (ret < 0)
748-
return ret;
749-
ctx->irq = ret;
757+
ret = decon_conf_irq(ctx, "vsync", decon_irq_handler, 0);
758+
if (ret < 0)
759+
return ret;
760+
ctx->irq_vsync = ret;
750761

751-
ret = decon_conf_irq(ctx, "te", decon_te_irq_handler,
752-
IRQF_TRIGGER_RISING, false);
753-
if (ret < 0)
754-
return ret;
755-
if (ret) {
756-
ctx->te_irq = ret;
757-
ctx->out_type &= ~I80_HW_TRG;
758-
}
759-
} else {
760-
ret = decon_conf_irq(ctx, "vsync", decon_irq_handler, 0, true);
761-
if (ret < 0)
762+
ret = decon_conf_irq(ctx, "lcd_sys", decon_irq_handler, 0);
763+
if (ret < 0)
764+
return ret;
765+
ctx->irq_lcd_sys = ret;
766+
767+
ret = decon_conf_irq(ctx, "te", decon_te_irq_handler,
768+
IRQF_TRIGGER_RISING);
769+
if (ret < 0)
762770
return ret;
763-
ctx->irq = ret;
771+
if (ret) {
772+
ctx->te_irq = ret;
773+
ctx->out_type &= ~I80_HW_TRG;
764774
}
765775

766776
if (ctx->out_type & I80_HW_TRG) {

drivers/gpu/drm/exynos/exynos7_drm_decon.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -309,19 +309,14 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
309309
val |= WINCONx_BURSTLEN_16WORD;
310310
break;
311311
case DRM_FORMAT_BGRA8888:
312+
default:
312313
val |= WINCONx_BPPMODE_32BPP_BGRA | WINCONx_BLD_PIX |
313314
WINCONx_ALPHA_SEL;
314315
val |= WINCONx_BURSTLEN_16WORD;
315316
break;
316-
default:
317-
DRM_DEBUG_KMS("invalid pixel size so using unpacked 24bpp.\n");
318-
319-
val |= WINCONx_BPPMODE_24BPP_xRGB;
320-
val |= WINCONx_BURSTLEN_16WORD;
321-
break;
322317
}
323318

324-
DRM_DEBUG_KMS("bpp = %d\n", fb->format->cpp[0] * 8);
319+
DRM_DEBUG_KMS("cpp = %d\n", fb->format->cpp[0]);
325320

326321
/*
327322
* In case of exynos, setting dma-burst to 16Word causes permanent
@@ -398,7 +393,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
398393
unsigned int last_x;
399394
unsigned int last_y;
400395
unsigned int win = plane->index;
401-
unsigned int bpp = fb->format->cpp[0];
396+
unsigned int cpp = fb->format->cpp[0];
402397
unsigned int pitch = fb->pitches[0];
403398

404399
if (ctx->suspended)
@@ -418,7 +413,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
418413
val = (unsigned long)exynos_drm_fb_dma_addr(fb, 0);
419414
writel(val, ctx->regs + VIDW_BUF_START(win));
420415

421-
padding = (pitch / bpp) - fb->width;
416+
padding = (pitch / cpp) - fb->width;
422417

423418
/* buffer size */
424419
writel(fb->width + padding, ctx->regs + VIDW_WHOLE_X(win));

drivers/gpu/drm/exynos/exynos_dp.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
155155
struct exynos_dp_device *dp = dev_get_drvdata(dev);
156156
struct drm_encoder *encoder = &dp->encoder;
157157
struct drm_device *drm_dev = data;
158-
int pipe, ret;
158+
int ret;
159159

160160
/*
161161
* Just like the probe function said, we don't need the
@@ -179,20 +179,15 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
179179
return ret;
180180
}
181181

182-
pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
183-
EXYNOS_DISPLAY_TYPE_LCD);
184-
if (pipe < 0)
185-
return pipe;
186-
187-
encoder->possible_crtcs = 1 << pipe;
188-
189-
DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
190-
191182
drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs,
192183
DRM_MODE_ENCODER_TMDS, NULL);
193184

194185
drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs);
195186

187+
ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_LCD);
188+
if (ret < 0)
189+
return ret;
190+
196191
dp->plat_data.encoder = encoder;
197192

198193
return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data);

drivers/gpu/drm/exynos/exynos_drm_core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*/
1414

1515
#include <drm/drmP.h>
16+
1617
#include "exynos_drm_drv.h"
1718
#include "exynos_drm_crtc.h"
1819

0 commit comments

Comments
 (0)