From cbd2b690a434766559eed943947f3ec533ccde9c Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:25 +0100 Subject: drm/sun4i: Rename DE2 RGB format macros Current RGB formats macros are actually not specific to UI planes. Rename it to something more universal and introduce shift macro. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-3-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index cb193c5f1686..b9c48c60131f 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -71,15 +71,15 @@ static int sun8i_mixer_drm_format_to_layer(struct drm_plane *plane, { switch (format) { case DRM_FORMAT_ARGB8888: - *mode = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_ARGB8888; + *mode = SUN8I_MIXER_FBFMT_ARGB8888; break; case DRM_FORMAT_XRGB8888: - *mode = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_XRGB8888; + *mode = SUN8I_MIXER_FBFMT_XRGB8888; break; case DRM_FORMAT_RGB888: - *mode = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_RGB888; + *mode = SUN8I_MIXER_FBFMT_RGB888; break; default: @@ -173,6 +173,7 @@ int sun8i_mixer_update_layer_formats(struct sun8i_mixer *mixer, return ret; } + val <<= SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET; regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_CHAN_UI_LAYER_ATTR(chan, layer), SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val); -- cgit v1.2.3 From 2a08e37eb603e12838377b02c3105fe0f27e2c71 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:26 +0100 Subject: drm/sun4i: Remove setting alpha mode in DE2 driver Current code sets alpha mode to global alpha mode and global alpha value to 0xff which is totaly opaque. That is not needed for two reasons: - only one plane is active and thus it can be blended only with background, which is black, - it will hinder proper blending when more than one plane is supported Default mode (0) considers pixel alpha value or 0xff if pixel has no alpha information. Global alpha value is ignored in this case. Because of that, just remove the code. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-4-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index b9c48c60131f..d3dee6131209 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -54,16 +54,6 @@ void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_CHAN_UI_LAYER_ATTR(chan, layer), SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val); - - /* Set the alpha configuration */ - regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR(chan, layer), - SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_MASK, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_DEF); - regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR(chan, layer), - SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MASK, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_DEF); } static int sun8i_mixer_drm_format_to_layer(struct drm_plane *plane, -- cgit v1.2.3 From 66bda1a68ba162c91817f755323c377e19e63913 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:27 +0100 Subject: drm/sun4i: Fix debug message in DE2 Debug message would print "Enabling" even when disabling plane. Fix it. Fixes: 9d75b8c0b999 (drm/sun4i: add support for Allwinner DE2 mixers) Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-5-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index d3dee6131209..b947ee2e4fe4 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -44,7 +44,8 @@ void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, /* Currently the first UI channel is used */ int chan = mixer->cfg->vi_num; - DRM_DEBUG_DRIVER("Enabling layer %d in channel %d\n", layer, chan); + DRM_DEBUG_DRIVER("%sabling layer %d in channel %d\n", + enable ? "En" : "Dis", layer, chan); if (enable) val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN; -- cgit v1.2.3 From 7f11f1da5cfd870ddd0a2fedbd2d8c6ace04c113 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:28 +0100 Subject: drm/sun4i: Remove setting default values in DE2 driver Premultiply and color key control registers are already set to zero by initialization code few lines above. Furthermore, it seems that colorkeying doesn't really work. It's not used in BSP driver and experiments with it all failed. Just remove the code. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-6-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index b947ee2e4fe4..f4a7fa0ba7ad 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -320,14 +320,10 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, /* Initialize blender */ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_FCOLOR_CTL, SUN8I_MIXER_BLEND_FCOLOR_CTL_DEF); - regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PREMULTIPLY, - SUN8I_MIXER_BLEND_PREMULTIPLY_DEF); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR, SUN8I_MIXER_BLEND_BKCOLOR_DEF); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_MODE(0), SUN8I_MIXER_BLEND_MODE_DEF); - regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_CK_CTL, - SUN8I_MIXER_BLEND_CK_CTL_DEF); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(0), -- cgit v1.2.3 From 2f4cffe4e23c2eb638b03f853c830ab669063410 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:29 +0100 Subject: drm/sun4i: Explain color macro in DE2 driver Color attribute have same format troughout the whole driver. Rename macro, add comment with simple explanation and remove redundant definitions. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-7-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index f4a7fa0ba7ad..5144e6d0ac56 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -317,17 +317,19 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL, SUN8I_MIXER_GLOBAL_CTL_RT_EN); + /* Set background color to black */ + regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR, + SUN8I_MIXER_BLEND_COLOR_BLACK); + /* Initialize blender */ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_FCOLOR_CTL, SUN8I_MIXER_BLEND_FCOLOR_CTL_DEF); - regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR, - SUN8I_MIXER_BLEND_BKCOLOR_DEF); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_MODE(0), SUN8I_MIXER_BLEND_MODE_DEF); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(0), - SUN8I_MIXER_BLEND_ATTR_FCOLOR_DEF); + SUN8I_MIXER_BLEND_COLOR_BLACK); /* Select the first UI channel */ DRM_DEBUG_DRIVER("Selecting channel %d (first UI channel)\n", -- cgit v1.2.3 From 7a744a7572716dd6756cf0b5ac55af0f45827846 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:30 +0100 Subject: drm/sun4i: Set blending mode for all channels (DE2) BSP driver always sets blend mode for all channels, no matter if they are really used or not. Do the same here. The exact meaning of the value is not exactly known, but BSP driver mentions "SRC OVER" and by digging through code some more info can be found. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-8-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 5144e6d0ac56..23659ce1cf27 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -239,6 +239,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, struct sun8i_mixer *mixer; struct resource *res; void __iomem *regs; + int plane_cnt; int i, ret; /* @@ -324,8 +325,6 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, /* Initialize blender */ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_FCOLOR_CTL, SUN8I_MIXER_BLEND_FCOLOR_CTL_DEF); - regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_MODE(0), - SUN8I_MIXER_BLEND_MODE_DEF); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(0), @@ -337,6 +336,11 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ROUTE, mixer->cfg->vi_num); + plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num; + for (i = 0; i < plane_cnt; i++) + regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_MODE(i), + SUN8I_MIXER_BLEND_MODE_DEF); + return 0; err_disable_bus_clk: -- cgit v1.2.3 From bb940be791ebf704f1736e2f5ffd8301df5f145e Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:31 +0100 Subject: drm/sun4i: Rename some macros in DE2 driver Now that some knowledge of DE2 is gained, rename or add some macros to make code more readable. Max channel macro is removed, since it is not used and it is not clear if it has right value. Structures in BSP driver shows possibility of 5 channels maximum although there is no SoC with such configuration. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-9-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 23659ce1cf27..c7d4ccd605e0 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -323,8 +323,9 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, SUN8I_MIXER_BLEND_COLOR_BLACK); /* Initialize blender */ - regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_FCOLOR_CTL, - SUN8I_MIXER_BLEND_FCOLOR_CTL_DEF); + regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL, + SUN8I_MIXER_BLEND_PIPE_CTL_EN(0) | + SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0)); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(0), -- cgit v1.2.3 From 26264ceeb55617fe9ddee84d9dd98645f5f62d34 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:32 +0100 Subject: drm/sun4i: Rework enabling plane in DE2 driver If we want to support multiple planes in the future, code which enables pipe has to be moved to appropriate place and it must depend on channel id instead of being hardcoded. Side effect of that rework is definition of default Z position. For now, put first channel at the bottom, second above it and so on. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-10-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index c7d4ccd605e0..015943c0ed5a 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -55,6 +55,15 @@ void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_CHAN_UI_LAYER_ATTR(chan, layer), SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val); + + if (enable) + val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(chan); + else + val = 0; + + regmap_update_bits(mixer->engine.regs, + SUN8I_MIXER_BLEND_PIPE_CTL, + SUN8I_MIXER_BLEND_PIPE_CTL_EN(chan), val); } static int sun8i_mixer_drm_format_to_layer(struct drm_plane *plane, @@ -98,7 +107,7 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, state->crtc_h)); DRM_DEBUG_DRIVER("Updating blender size\n"); regmap_write(mixer->engine.regs, - SUN8I_MIXER_BLEND_ATTR_INSIZE(0), + SUN8I_MIXER_BLEND_ATTR_INSIZE(chan), SUN8I_MIXER_SIZE(state->crtc_w, state->crtc_h)); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_OUTSIZE, @@ -322,20 +331,17 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR, SUN8I_MIXER_BLEND_COLOR_BLACK); - /* Initialize blender */ + /* + * Set fill color of bottom plane to black. Generally not needed + * except when VI plane is at bottom (zpos = 0) and enabled. + */ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL, - SUN8I_MIXER_BLEND_PIPE_CTL_EN(0) | SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0)); - - regmap_write(mixer->engine.regs, - SUN8I_MIXER_BLEND_ATTR_FCOLOR(0), + regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(0), SUN8I_MIXER_BLEND_COLOR_BLACK); - /* Select the first UI channel */ - DRM_DEBUG_DRIVER("Selecting channel %d (first UI channel)\n", - mixer->cfg->vi_num); - regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ROUTE, - mixer->cfg->vi_num); + /* Fixed zpos for now */ + regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ROUTE, 0x43210); plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num; for (i = 0; i < plane_cnt; i++) -- cgit v1.2.3 From f356fe8e0fb630b4b00c6207d5af53a5d1fab660 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:33 +0100 Subject: drm/sun4i: Start using layer id in DE2 driver Till now, plane selection was hardcoded to first overlay in first UI channel and layer parameter is unused. Rename and add parameters to layer functions so they would represent HW more accurately and start using then. It turns out that overlays don't fit well in current DRM design, because they can't be blended together or scaled independetly when they are set to same channel. Because of that, always use only first overlay in each channel. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-11-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 50 ++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 29 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 015943c0ed5a..2bf7ba1e5ba7 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -37,15 +37,13 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine) SUN8I_MIXER_GLOBAL_DBUFF_ENABLE); } -void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, - int layer, bool enable) +void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, int channel, + int overlay, bool enable) { u32 val; - /* Currently the first UI channel is used */ - int chan = mixer->cfg->vi_num; - DRM_DEBUG_DRIVER("%sabling layer %d in channel %d\n", - enable ? "En" : "Dis", layer, chan); + DRM_DEBUG_DRIVER("%sabling channel %d overlay %d\n", + enable ? "En" : "Dis", channel, overlay); if (enable) val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN; @@ -53,17 +51,17 @@ void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, val = 0; regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR(chan, layer), + SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay), SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val); if (enable) - val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(chan); + val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(channel); else val = 0; regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL, - SUN8I_MIXER_BLEND_PIPE_CTL_EN(chan), val); + SUN8I_MIXER_BLEND_PIPE_CTL_EN(channel), val); } static int sun8i_mixer_drm_format_to_layer(struct drm_plane *plane, @@ -89,15 +87,13 @@ static int sun8i_mixer_drm_format_to_layer(struct drm_plane *plane, return 0; } -int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, - int layer, struct drm_plane *plane) +int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel, + int overlay, struct drm_plane *plane) { struct drm_plane_state *state = plane->state; struct drm_framebuffer *fb = state->fb; - /* Currently the first UI channel is used */ - int chan = mixer->cfg->vi_num; - DRM_DEBUG_DRIVER("Updating layer %d\n", layer); + DRM_DEBUG_DRIVER("Updating channel %d overlay %d\n", channel, overlay); if (plane->type == DRM_PLANE_TYPE_PRIMARY) { DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n", @@ -107,7 +103,7 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, state->crtc_h)); DRM_DEBUG_DRIVER("Updating blender size\n"); regmap_write(mixer->engine.regs, - SUN8I_MIXER_BLEND_ATTR_INSIZE(chan), + SUN8I_MIXER_BLEND_ATTR_INSIZE(channel), SUN8I_MIXER_SIZE(state->crtc_w, state->crtc_h)); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_OUTSIZE, @@ -115,7 +111,7 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, state->crtc_h)); DRM_DEBUG_DRIVER("Updating channel size\n"); regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_OVL_SIZE(chan), + SUN8I_MIXER_CHAN_UI_OVL_SIZE(channel), SUN8I_MIXER_SIZE(state->crtc_w, state->crtc_h)); } @@ -123,35 +119,33 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, /* Set the line width */ DRM_DEBUG_DRIVER("Layer line width: %d bytes\n", fb->pitches[0]); regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_PITCH(chan, layer), + SUN8I_MIXER_CHAN_UI_LAYER_PITCH(channel, overlay), fb->pitches[0]); /* Set height and width */ DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n", state->crtc_w, state->crtc_h); regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_SIZE(chan, layer), + SUN8I_MIXER_CHAN_UI_LAYER_SIZE(channel, overlay), SUN8I_MIXER_SIZE(state->crtc_w, state->crtc_h)); /* Set base coordinates */ DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n", state->crtc_x, state->crtc_y); regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_COORD(chan, layer), + SUN8I_MIXER_BLEND_ATTR_COORD(channel), SUN8I_MIXER_COORD(state->crtc_x, state->crtc_y)); return 0; } -int sun8i_mixer_update_layer_formats(struct sun8i_mixer *mixer, - int layer, struct drm_plane *plane) +int sun8i_mixer_update_layer_formats(struct sun8i_mixer *mixer, int channel, + int overlay, struct drm_plane *plane) { struct drm_plane_state *state = plane->state; struct drm_framebuffer *fb = state->fb; bool interlaced = false; u32 val; - /* Currently the first UI channel is used */ - int chan = mixer->cfg->vi_num; int ret; if (plane->state->crtc) @@ -175,21 +169,19 @@ int sun8i_mixer_update_layer_formats(struct sun8i_mixer *mixer, val <<= SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET; regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR(chan, layer), + SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay), SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val); return 0; } -int sun8i_mixer_update_layer_buffer(struct sun8i_mixer *mixer, - int layer, struct drm_plane *plane) +int sun8i_mixer_update_layer_buffer(struct sun8i_mixer *mixer, int channel, + int overlay, struct drm_plane *plane) { struct drm_plane_state *state = plane->state; struct drm_framebuffer *fb = state->fb; struct drm_gem_cma_object *gem; dma_addr_t paddr; - /* Currently the first UI channel is used */ - int chan = mixer->cfg->vi_num; int bpp; /* Get the physical address of the buffer in memory */ @@ -221,7 +213,7 @@ int sun8i_mixer_update_layer_buffer(struct sun8i_mixer *mixer, DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr); regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(chan, layer), + SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(channel, overlay), lower_32_bits(paddr)); return 0; -- cgit v1.2.3 From 90212fffa4fceba708208908bd690edda7b3e60a Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:35 +0100 Subject: drm/sun4i: Use values calculated by atomic check Now that we have properly clipped coordinates in plane state structure, use them. This also fixes bug where source x and y were adjusted for negative value, but width and height weren't. It wasn't discovered because primary plane usually doesn't have negative coordinates. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-13-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 52 ++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 30 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 2bf7ba1e5ba7..37fcc5ed18c5 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -92,28 +92,34 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel, { struct drm_plane_state *state = plane->state; struct drm_framebuffer *fb = state->fb; + u32 width, height, size; DRM_DEBUG_DRIVER("Updating channel %d overlay %d\n", channel, overlay); + /* + * Same source and destination width and height are guaranteed + * by atomic check function. + */ + width = drm_rect_width(&state->dst); + height = drm_rect_height(&state->dst); + size = SUN8I_MIXER_SIZE(width, height); + if (plane->type == DRM_PLANE_TYPE_PRIMARY) { DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n", - state->crtc_w, state->crtc_h); - regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_SIZE, - SUN8I_MIXER_SIZE(state->crtc_w, - state->crtc_h)); + width, height); + regmap_write(mixer->engine.regs, + SUN8I_MIXER_GLOBAL_SIZE, + size); DRM_DEBUG_DRIVER("Updating blender size\n"); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_INSIZE(channel), - SUN8I_MIXER_SIZE(state->crtc_w, - state->crtc_h)); + size); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_OUTSIZE, - SUN8I_MIXER_SIZE(state->crtc_w, - state->crtc_h)); + size); DRM_DEBUG_DRIVER("Updating channel size\n"); regmap_write(mixer->engine.regs, SUN8I_MIXER_CHAN_UI_OVL_SIZE(channel), - SUN8I_MIXER_SIZE(state->crtc_w, - state->crtc_h)); + size); } /* Set the line width */ @@ -123,18 +129,17 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel, fb->pitches[0]); /* Set height and width */ - DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n", - state->crtc_w, state->crtc_h); + DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n", width, height); regmap_write(mixer->engine.regs, SUN8I_MIXER_CHAN_UI_LAYER_SIZE(channel, overlay), - SUN8I_MIXER_SIZE(state->crtc_w, state->crtc_h)); + size); /* Set base coordinates */ DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n", - state->crtc_x, state->crtc_y); + state->dst.x1, state->dst.y1); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_COORD(channel), - SUN8I_MIXER_COORD(state->crtc_x, state->crtc_y)); + SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1)); return 0; } @@ -194,21 +199,8 @@ int sun8i_mixer_update_layer_buffer(struct sun8i_mixer *mixer, int channel, paddr = gem->paddr + fb->offsets[0]; /* Fixup framebuffer address for src coordinates */ - paddr += (state->src_x >> 16) * bpp; - paddr += (state->src_y >> 16) * fb->pitches[0]; - - /* - * The hardware cannot correctly deal with negative crtc - * coordinates, the display is cropped to the requested size, - * but the display content is not moved. - * Manually move the display content by fixup the framebuffer - * address when crtc_x or crtc_y is negative, like what we - * have did for src_x and src_y. - */ - if (state->crtc_x < 0) - paddr += -state->crtc_x * bpp; - if (state->crtc_y < 0) - paddr += -state->crtc_y * fb->pitches[0]; + paddr += (state->src.x1 >> 16) * bpp; + paddr += (state->src.y1 >> 16) * fb->pitches[0]; DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr); -- cgit v1.2.3 From c53e6fd47d6efd65cafa4c5859e30af80e01f634 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:36 +0100 Subject: drm/sun4i: Move line width setting in DE2 Line width is a property of a framebuffer and it belongs to sun8i_mixer_update_layer_buffer(). This will became even more obvious when support for multi-plane formats will be added. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-14-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 37fcc5ed18c5..9635c30651d6 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -91,7 +91,6 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel, int overlay, struct drm_plane *plane) { struct drm_plane_state *state = plane->state; - struct drm_framebuffer *fb = state->fb; u32 width, height, size; DRM_DEBUG_DRIVER("Updating channel %d overlay %d\n", channel, overlay); @@ -122,12 +121,6 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel, size); } - /* Set the line width */ - DRM_DEBUG_DRIVER("Layer line width: %d bytes\n", fb->pitches[0]); - regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_PITCH(channel, overlay), - fb->pitches[0]); - /* Set height and width */ DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n", width, height); regmap_write(mixer->engine.regs, @@ -202,6 +195,12 @@ int sun8i_mixer_update_layer_buffer(struct sun8i_mixer *mixer, int channel, paddr += (state->src.x1 >> 16) * bpp; paddr += (state->src.y1 >> 16) * fb->pitches[0]; + /* Set the line width */ + DRM_DEBUG_DRIVER("Layer line width: %d bytes\n", fb->pitches[0]); + regmap_write(mixer->engine.regs, + SUN8I_MIXER_CHAN_UI_LAYER_PITCH(channel, overlay), + fb->pitches[0]); + DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr); regmap_write(mixer->engine.regs, -- cgit v1.2.3 From 58e21823edc5f3a3eb96c5e3d5b042f91fd46598 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:37 +0100 Subject: drm/sun4i: Move channel size related code in DE2 Channel size should be set every time plane is changed, not only when primary plane changes. Current code works only because only one (primary) plane is supported at the moment. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-15-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 9635c30651d6..00c0cc6440e2 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -109,16 +109,8 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel, regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_SIZE, size); - DRM_DEBUG_DRIVER("Updating blender size\n"); - regmap_write(mixer->engine.regs, - SUN8I_MIXER_BLEND_ATTR_INSIZE(channel), - size); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_OUTSIZE, size); - DRM_DEBUG_DRIVER("Updating channel size\n"); - regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_OVL_SIZE(channel), - size); } /* Set height and width */ @@ -126,6 +118,9 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel, regmap_write(mixer->engine.regs, SUN8I_MIXER_CHAN_UI_LAYER_SIZE(channel, overlay), size); + regmap_write(mixer->engine.regs, + SUN8I_MIXER_CHAN_UI_OVL_SIZE(channel), + size); /* Set base coordinates */ DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n", @@ -133,6 +128,9 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel, regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_COORD(channel), SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1)); + regmap_write(mixer->engine.regs, + SUN8I_MIXER_BLEND_ATTR_INSIZE(channel), + size); return 0; } -- cgit v1.2.3 From 165d24df78b8aae0fc59557fdd73f4c3deb240ea Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:38 +0100 Subject: drm/sun4i: Move interlace related code in DE2 There is no point having code which sets interlace mode of mixer in channel related function. Interlace mode will only change when CRTC state will change, so let's move it to the block which is executed only when primary plane state is changed. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-16-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 00c0cc6440e2..f35a08dc260b 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -104,6 +104,9 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel, size = SUN8I_MIXER_SIZE(width, height); if (plane->type == DRM_PLANE_TYPE_PRIMARY) { + bool interlaced = false; + u32 val; + DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n", width, height); regmap_write(mixer->engine.regs, @@ -111,6 +114,23 @@ int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel, size); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_OUTSIZE, size); + + if (state->crtc) + interlaced = state->crtc->state->adjusted_mode.flags + & DRM_MODE_FLAG_INTERLACE; + + if (interlaced) + val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED; + else + val = 0; + + regmap_update_bits(mixer->engine.regs, + SUN8I_MIXER_BLEND_OUTCTL, + SUN8I_MIXER_BLEND_OUTCTL_INTERLACED, + val); + + DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n", + interlaced ? "on" : "off"); } /* Set height and width */ @@ -140,22 +160,9 @@ int sun8i_mixer_update_layer_formats(struct sun8i_mixer *mixer, int channel, { struct drm_plane_state *state = plane->state; struct drm_framebuffer *fb = state->fb; - bool interlaced = false; u32 val; int ret; - if (plane->state->crtc) - interlaced = plane->state->crtc->state->adjusted_mode.flags - & DRM_MODE_FLAG_INTERLACE; - - regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_OUTCTL, - SUN8I_MIXER_BLEND_OUTCTL_INTERLACED, - interlaced ? - SUN8I_MIXER_BLEND_OUTCTL_INTERLACED : 0); - - DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n", - interlaced ? "on" : "off"); - ret = sun8i_mixer_drm_format_to_layer(plane, fb->format->format, &val); if (ret) { -- cgit v1.2.3 From fba4955e9c4f2312314a902341c169f4bcbff735 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:40 +0100 Subject: drm/sun4i: Add support for all HW supported DE2 RGB formats Currently only a few RGB formats are supported by the DE2 driver. Add support for all formats supported by the HW. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-18-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 134 ++++++++++++++++++++++++++++-------- 1 file changed, 104 insertions(+), 30 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index f35a08dc260b..d49eed97b452 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -29,6 +29,105 @@ #include "sun8i_layer.h" #include "sunxi_engine.h" +struct de2_fmt_info { + u32 drm_fmt; + u32 de2_fmt; +}; + +static const struct de2_fmt_info de2_formats[] = { + { + .drm_fmt = DRM_FORMAT_ARGB8888, + .de2_fmt = SUN8I_MIXER_FBFMT_ARGB8888, + }, + { + .drm_fmt = DRM_FORMAT_ABGR8888, + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR8888, + }, + { + .drm_fmt = DRM_FORMAT_RGBA8888, + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA8888, + }, + { + .drm_fmt = DRM_FORMAT_BGRA8888, + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA8888, + }, + { + .drm_fmt = DRM_FORMAT_XRGB8888, + .de2_fmt = SUN8I_MIXER_FBFMT_XRGB8888, + }, + { + .drm_fmt = DRM_FORMAT_XBGR8888, + .de2_fmt = SUN8I_MIXER_FBFMT_XBGR8888, + }, + { + .drm_fmt = DRM_FORMAT_RGBX8888, + .de2_fmt = SUN8I_MIXER_FBFMT_RGBX8888, + }, + { + .drm_fmt = DRM_FORMAT_BGRX8888, + .de2_fmt = SUN8I_MIXER_FBFMT_BGRX8888, + }, + { + .drm_fmt = DRM_FORMAT_RGB888, + .de2_fmt = SUN8I_MIXER_FBFMT_RGB888, + }, + { + .drm_fmt = DRM_FORMAT_BGR888, + .de2_fmt = SUN8I_MIXER_FBFMT_BGR888, + }, + { + .drm_fmt = DRM_FORMAT_RGB565, + .de2_fmt = SUN8I_MIXER_FBFMT_RGB565, + }, + { + .drm_fmt = DRM_FORMAT_BGR565, + .de2_fmt = SUN8I_MIXER_FBFMT_BGR565, + }, + { + .drm_fmt = DRM_FORMAT_ARGB4444, + .de2_fmt = SUN8I_MIXER_FBFMT_ARGB4444, + }, + { + .drm_fmt = DRM_FORMAT_ABGR4444, + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR4444, + }, + { + .drm_fmt = DRM_FORMAT_RGBA4444, + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA4444, + }, + { + .drm_fmt = DRM_FORMAT_BGRA4444, + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA4444, + }, + { + .drm_fmt = DRM_FORMAT_ARGB1555, + .de2_fmt = SUN8I_MIXER_FBFMT_ARGB1555, + }, + { + .drm_fmt = DRM_FORMAT_ABGR1555, + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR1555, + }, + { + .drm_fmt = DRM_FORMAT_RGBA5551, + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA5551, + }, + { + .drm_fmt = DRM_FORMAT_BGRA5551, + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA5551, + }, +}; + +static const struct de2_fmt_info *sun8i_mixer_format_info(u32 format) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(de2_formats); ++i) + if (de2_formats[i].drm_fmt == format) + return &de2_formats[i]; + + return NULL; +} + static void sun8i_mixer_commit(struct sunxi_engine *engine) { DRM_DEBUG_DRIVER("Committing changes\n"); @@ -64,29 +163,6 @@ void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, int channel, SUN8I_MIXER_BLEND_PIPE_CTL_EN(channel), val); } -static int sun8i_mixer_drm_format_to_layer(struct drm_plane *plane, - u32 format, u32 *mode) -{ - switch (format) { - case DRM_FORMAT_ARGB8888: - *mode = SUN8I_MIXER_FBFMT_ARGB8888; - break; - - case DRM_FORMAT_XRGB8888: - *mode = SUN8I_MIXER_FBFMT_XRGB8888; - break; - - case DRM_FORMAT_RGB888: - *mode = SUN8I_MIXER_FBFMT_RGB888; - break; - - default: - return -EINVAL; - } - - return 0; -} - int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel, int overlay, struct drm_plane *plane) { @@ -159,18 +235,16 @@ int sun8i_mixer_update_layer_formats(struct sun8i_mixer *mixer, int channel, int overlay, struct drm_plane *plane) { struct drm_plane_state *state = plane->state; - struct drm_framebuffer *fb = state->fb; + const struct de2_fmt_info *fmt_info; u32 val; - int ret; - ret = sun8i_mixer_drm_format_to_layer(plane, fb->format->format, - &val); - if (ret) { + fmt_info = sun8i_mixer_format_info(state->fb->format->format); + if (!fmt_info) { DRM_DEBUG_DRIVER("Invalid format\n"); - return ret; + return -EINVAL; } - val <<= SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET; + val = fmt_info->de2_fmt << SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET; regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay), SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val); -- cgit v1.2.3 From 5bb5f5dafa1ad3ac5ebb85e74a07193fda7aec4e Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:41 +0100 Subject: drm/sun4i: Reorganize UI layer code in DE2 Till now, DE2 driver supported only UI planes. Before we add support for VI planes, lets split out UI layer specific code from common parts. This commit does the following: - renames sun8i_layer.c to sun8i_ui_layer.c - moves UI channel specific code to sun8i_ui_layer.c - moves common code from sun8i_layer.c to sun8i_mixer.c - renames function and structure names so it is apparent where they belong to No functional change is made. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-19-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 174 +++++------------------------------- 1 file changed, 22 insertions(+), 152 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index d49eed97b452..1de98ad9f6c1 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -26,14 +26,9 @@ #include "sun4i_drv.h" #include "sun8i_mixer.h" -#include "sun8i_layer.h" +#include "sun8i_ui_layer.h" #include "sunxi_engine.h" -struct de2_fmt_info { - u32 drm_fmt; - u32 de2_fmt; -}; - static const struct de2_fmt_info de2_formats[] = { { .drm_fmt = DRM_FORMAT_ARGB8888, @@ -117,7 +112,7 @@ static const struct de2_fmt_info de2_formats[] = { }, }; -static const struct de2_fmt_info *sun8i_mixer_format_info(u32 format) +const struct de2_fmt_info *sun8i_mixer_format_info(u32 format) { unsigned int i; @@ -136,157 +131,32 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine) SUN8I_MIXER_GLOBAL_DBUFF_ENABLE); } -void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, int channel, - int overlay, bool enable) -{ - u32 val; - - DRM_DEBUG_DRIVER("%sabling channel %d overlay %d\n", - enable ? "En" : "Dis", channel, overlay); - - if (enable) - val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN; - else - val = 0; - - regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay), - SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val); - - if (enable) - val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(channel); - else - val = 0; - - regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_BLEND_PIPE_CTL, - SUN8I_MIXER_BLEND_PIPE_CTL_EN(channel), val); -} - -int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel, - int overlay, struct drm_plane *plane) -{ - struct drm_plane_state *state = plane->state; - u32 width, height, size; - - DRM_DEBUG_DRIVER("Updating channel %d overlay %d\n", channel, overlay); - - /* - * Same source and destination width and height are guaranteed - * by atomic check function. - */ - width = drm_rect_width(&state->dst); - height = drm_rect_height(&state->dst); - size = SUN8I_MIXER_SIZE(width, height); - - if (plane->type == DRM_PLANE_TYPE_PRIMARY) { - bool interlaced = false; - u32 val; - - DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n", - width, height); - regmap_write(mixer->engine.regs, - SUN8I_MIXER_GLOBAL_SIZE, - size); - regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_OUTSIZE, - size); - - if (state->crtc) - interlaced = state->crtc->state->adjusted_mode.flags - & DRM_MODE_FLAG_INTERLACE; - - if (interlaced) - val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED; - else - val = 0; - - regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_BLEND_OUTCTL, - SUN8I_MIXER_BLEND_OUTCTL_INTERLACED, - val); - - DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n", - interlaced ? "on" : "off"); - } - - /* Set height and width */ - DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n", width, height); - regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_SIZE(channel, overlay), - size); - regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_OVL_SIZE(channel), - size); - - /* Set base coordinates */ - DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n", - state->dst.x1, state->dst.y1); - regmap_write(mixer->engine.regs, - SUN8I_MIXER_BLEND_ATTR_COORD(channel), - SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1)); - regmap_write(mixer->engine.regs, - SUN8I_MIXER_BLEND_ATTR_INSIZE(channel), - size); - - return 0; -} - -int sun8i_mixer_update_layer_formats(struct sun8i_mixer *mixer, int channel, - int overlay, struct drm_plane *plane) +static struct drm_plane **sun8i_layers_init(struct drm_device *drm, + struct sunxi_engine *engine) { - struct drm_plane_state *state = plane->state; - const struct de2_fmt_info *fmt_info; - u32 val; + struct drm_plane **planes; + struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine); + int i; - fmt_info = sun8i_mixer_format_info(state->fb->format->format); - if (!fmt_info) { - DRM_DEBUG_DRIVER("Invalid format\n"); - return -EINVAL; - } + planes = devm_kcalloc(drm->dev, mixer->cfg->ui_num + 1, + sizeof(*planes), GFP_KERNEL); + if (!planes) + return ERR_PTR(-ENOMEM); - val = fmt_info->de2_fmt << SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET; - regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay), - SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val); + for (i = 0; i < mixer->cfg->ui_num; i++) { + struct sun8i_ui_layer *layer; - return 0; -} + layer = sun8i_ui_layer_init_one(drm, mixer, i); + if (IS_ERR(layer)) { + dev_err(drm->dev, "Couldn't initialize %s plane\n", + i ? "overlay" : "primary"); + return ERR_CAST(layer); + }; -int sun8i_mixer_update_layer_buffer(struct sun8i_mixer *mixer, int channel, - int overlay, struct drm_plane *plane) -{ - struct drm_plane_state *state = plane->state; - struct drm_framebuffer *fb = state->fb; - struct drm_gem_cma_object *gem; - dma_addr_t paddr; - int bpp; + planes[i] = &layer->plane; + }; - /* Get the physical address of the buffer in memory */ - gem = drm_fb_cma_get_gem_obj(fb, 0); - - DRM_DEBUG_DRIVER("Using GEM @ %pad\n", &gem->paddr); - - /* Compute the start of the displayed memory */ - bpp = fb->format->cpp[0]; - paddr = gem->paddr + fb->offsets[0]; - - /* Fixup framebuffer address for src coordinates */ - paddr += (state->src.x1 >> 16) * bpp; - paddr += (state->src.y1 >> 16) * fb->pitches[0]; - - /* Set the line width */ - DRM_DEBUG_DRIVER("Layer line width: %d bytes\n", fb->pitches[0]); - regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_PITCH(channel, overlay), - fb->pitches[0]); - - DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr); - - regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(channel, overlay), - lower_32_bits(paddr)); - - return 0; + return planes; } static const struct sunxi_engine_ops sun8i_engine_ops = { -- cgit v1.2.3 From 7480ba4d75714b4f5b080aa5a53e352b303d2663 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:42 +0100 Subject: drm/sun4i: Add support for DE2 VI planes This commit adds basic support for VI planes. They are meant for video overlay and because of that they support YUV formats too. However, using YUV format is not straightforward, so only RGB formats are supported for now. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-20-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 1de98ad9f6c1..888620b1d3f1 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -27,6 +27,7 @@ #include "sun4i_drv.h" #include "sun8i_mixer.h" #include "sun8i_ui_layer.h" +#include "sun8i_vi_layer.h" #include "sunxi_engine.h" static const struct de2_fmt_info de2_formats[] = { @@ -138,11 +139,25 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm, struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine); int i; - planes = devm_kcalloc(drm->dev, mixer->cfg->ui_num + 1, + planes = devm_kcalloc(drm->dev, + mixer->cfg->vi_num + mixer->cfg->ui_num + 1, sizeof(*planes), GFP_KERNEL); if (!planes) return ERR_PTR(-ENOMEM); + for (i = 0; i < mixer->cfg->vi_num; i++) { + struct sun8i_vi_layer *layer; + + layer = sun8i_vi_layer_init_one(drm, mixer, i); + if (IS_ERR(layer)) { + dev_err(drm->dev, + "Couldn't initialize overlay plane\n"); + return ERR_CAST(layer); + }; + + planes[i] = &layer->plane; + }; + for (i = 0; i < mixer->cfg->ui_num; i++) { struct sun8i_ui_layer *layer; @@ -153,7 +168,7 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm, return ERR_CAST(layer); }; - planes[i] = &layer->plane; + planes[mixer->cfg->vi_num + i] = &layer->plane; }; return planes; -- cgit v1.2.3 From 5b1f8367f3ea1a74414a4dce3ccb2e76fdd84385 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:43 +0100 Subject: drm/sun4i: Add scaler configuration to DE2 mixers No all SoCs support scaling on all channels. For example, V3s support scaling only on VI channels. Because of that, add additional configuration bitmask which tells which channel support scaler. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-21-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 888620b1d3f1..e3296a060352 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -336,6 +336,7 @@ static int sun8i_mixer_remove(struct platform_device *pdev) static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = { .vi_num = 2, .ui_num = 1, + .scaler_mask = 0x3, }; static const struct of_device_id sun8i_mixer_of_table[] = { -- cgit v1.2.3 From bd3bcb9112894bc0fa29ad4b0c4b534932efeab0 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:45 +0100 Subject: drm/sun4i: Add CCSC property to DE2 configuration Base addresses of channel output CSC (CCSC) depends whether mixer in question is first or second and if it is second, if supports VEP or not. This new property will tell which set of base addresses to take. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-23-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index e3296a060352..7f88cf5f97eb 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -337,6 +337,7 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = { .vi_num = 2, .ui_num = 1, .scaler_mask = 0x3, + .ccsc = 0, }; static const struct of_device_id sun8i_mixer_of_table[] = { -- cgit v1.2.3 From 60a3dcf96aa8d9d7205294737df426e7b3e87473 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 1 Dec 2017 07:05:47 +0100 Subject: drm/sun4i: Add DE2 definitions for YUV formats This commit expands translation of DRM YUV format to HW specific information. It doesn't do any functional changes. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-25-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 136 ++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 7f88cf5f97eb..29ceeb016d72 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -34,82 +34,218 @@ static const struct de2_fmt_info de2_formats[] = { { .drm_fmt = DRM_FORMAT_ARGB8888, .de2_fmt = SUN8I_MIXER_FBFMT_ARGB8888, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_ABGR8888, .de2_fmt = SUN8I_MIXER_FBFMT_ABGR8888, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_RGBA8888, .de2_fmt = SUN8I_MIXER_FBFMT_RGBA8888, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_BGRA8888, .de2_fmt = SUN8I_MIXER_FBFMT_BGRA8888, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_XRGB8888, .de2_fmt = SUN8I_MIXER_FBFMT_XRGB8888, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_XBGR8888, .de2_fmt = SUN8I_MIXER_FBFMT_XBGR8888, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_RGBX8888, .de2_fmt = SUN8I_MIXER_FBFMT_RGBX8888, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_BGRX8888, .de2_fmt = SUN8I_MIXER_FBFMT_BGRX8888, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_RGB888, .de2_fmt = SUN8I_MIXER_FBFMT_RGB888, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_BGR888, .de2_fmt = SUN8I_MIXER_FBFMT_BGR888, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_RGB565, .de2_fmt = SUN8I_MIXER_FBFMT_RGB565, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_BGR565, .de2_fmt = SUN8I_MIXER_FBFMT_BGR565, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_ARGB4444, .de2_fmt = SUN8I_MIXER_FBFMT_ARGB4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_ABGR4444, .de2_fmt = SUN8I_MIXER_FBFMT_ABGR4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_RGBA4444, .de2_fmt = SUN8I_MIXER_FBFMT_RGBA4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_BGRA4444, .de2_fmt = SUN8I_MIXER_FBFMT_BGRA4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_ARGB1555, .de2_fmt = SUN8I_MIXER_FBFMT_ARGB1555, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_ABGR1555, .de2_fmt = SUN8I_MIXER_FBFMT_ABGR1555, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_RGBA5551, .de2_fmt = SUN8I_MIXER_FBFMT_RGBA5551, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, }, { .drm_fmt = DRM_FORMAT_BGRA5551, .de2_fmt = SUN8I_MIXER_FBFMT_BGRA5551, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { + .drm_fmt = DRM_FORMAT_UYVY, + .de2_fmt = SUN8I_MIXER_FBFMT_UYVY, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_VYUY, + .de2_fmt = SUN8I_MIXER_FBFMT_VYUY, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_YUYV, + .de2_fmt = SUN8I_MIXER_FBFMT_YUYV, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_YVYU, + .de2_fmt = SUN8I_MIXER_FBFMT_YVYU, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_NV16, + .de2_fmt = SUN8I_MIXER_FBFMT_NV16, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_NV61, + .de2_fmt = SUN8I_MIXER_FBFMT_NV61, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_NV12, + .de2_fmt = SUN8I_MIXER_FBFMT_NV12, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_NV21, + .de2_fmt = SUN8I_MIXER_FBFMT_NV21, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_YUV444, + .de2_fmt = SUN8I_MIXER_FBFMT_RGB888, + .rgb = true, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_YUV422, + .de2_fmt = SUN8I_MIXER_FBFMT_YUV422, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_YUV420, + .de2_fmt = SUN8I_MIXER_FBFMT_YUV420, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_YUV411, + .de2_fmt = SUN8I_MIXER_FBFMT_YUV411, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_YVU444, + .de2_fmt = SUN8I_MIXER_FBFMT_RGB888, + .rgb = true, + .csc = SUN8I_CSC_MODE_YVU2RGB, + }, + { + .drm_fmt = DRM_FORMAT_YVU422, + .de2_fmt = SUN8I_MIXER_FBFMT_YUV422, + .rgb = false, + .csc = SUN8I_CSC_MODE_YVU2RGB, + }, + { + .drm_fmt = DRM_FORMAT_YVU420, + .de2_fmt = SUN8I_MIXER_FBFMT_YUV420, + .rgb = false, + .csc = SUN8I_CSC_MODE_YVU2RGB, + }, + { + .drm_fmt = DRM_FORMAT_YVU411, + .de2_fmt = SUN8I_MIXER_FBFMT_YUV411, + .rgb = false, + .csc = SUN8I_CSC_MODE_YVU2RGB, }, }; -- cgit v1.2.3