aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/sun4i/sun8i_mixer.c
diff options
context:
space:
mode:
authorJernej Skrabec <jernej.skrabec@siol.net>2017-12-01 07:05:41 +0100
committerMaxime Ripard <maxime.ripard@free-electrons.com>2017-12-05 13:22:43 +0100
commit5bb5f5dafa1ad3ac5ebb85e74a07193fda7aec4e (patch)
tree476dd39038ad4793a0121a7fa4f1b789d9d38b90 /drivers/gpu/drm/sun4i/sun8i_mixer.c
parentdrm/sun4i: Add support for all HW supported DE2 RGB formats (diff)
downloadlinux-dev-5bb5f5dafa1ad3ac5ebb85e74a07193fda7aec4e.tar.xz
linux-dev-5bb5f5dafa1ad3ac5ebb85e74a07193fda7aec4e.zip
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 <jernej.skrabec@siol.net> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-19-jernej.skrabec@siol.net
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun8i_mixer.c')
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_mixer.c174
1 files changed, 22 insertions, 152 deletions
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 = {