Commit 1bdb542d authored by Paul Cercueil's avatar Paul Cercueil

drm/ingenic: Simplify code by using hwdescs array

Instead of having one 'hwdesc' variable for the plane #0, one for the
plane #1 and one for the palette, use a 'hwdesc[3]' array, where the
DMA hardware descriptors are indexed by the plane's number.

v2: dma_hwdesc_addr() extended to support palette hwdesc. The palette
    hwdesc is now hwdesc[3] to simplify things. Add
    ingenic_drm_configure_hwdesc*() functions to factorize code.
Signed-off-by: default avatarPaul Cercueil <paul@crapouillou.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20211026181240.213806-2-paul@crapouillou.netTested-by: default avatarNikolaus Schaller <hns@goldelico.com>
Reviewed-by: default avatarChristophe Branchereau <cbranchereau@gmail.com>
parent 67505311
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
#define HWDESC_PALETTE 2
struct ingenic_dma_hwdesc { struct ingenic_dma_hwdesc {
u32 next; u32 next;
u32 addr; u32 addr;
...@@ -49,9 +51,7 @@ struct ingenic_dma_hwdesc { ...@@ -49,9 +51,7 @@ struct ingenic_dma_hwdesc {
} __aligned(16); } __aligned(16);
struct ingenic_dma_hwdescs { struct ingenic_dma_hwdescs {
struct ingenic_dma_hwdesc hwdesc_f0; struct ingenic_dma_hwdesc hwdesc[3];
struct ingenic_dma_hwdesc hwdesc_f1;
struct ingenic_dma_hwdesc hwdesc_pal;
u16 palette[256] __aligned(16); u16 palette[256] __aligned(16);
}; };
...@@ -141,6 +141,14 @@ static inline struct ingenic_drm *drm_nb_get_priv(struct notifier_block *nb) ...@@ -141,6 +141,14 @@ static inline struct ingenic_drm *drm_nb_get_priv(struct notifier_block *nb)
return container_of(nb, struct ingenic_drm, clock_nb); return container_of(nb, struct ingenic_drm, clock_nb);
} }
static inline dma_addr_t dma_hwdesc_addr(const struct ingenic_drm *priv,
unsigned int idx)
{
u32 offset = offsetof(struct ingenic_dma_hwdescs, hwdesc[idx]);
return priv->dma_hwdescs_phys + offset;
}
static int ingenic_drm_update_pixclk(struct notifier_block *nb, static int ingenic_drm_update_pixclk(struct notifier_block *nb,
unsigned long action, unsigned long action,
void *data) void *data)
...@@ -558,9 +566,9 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, ...@@ -558,9 +566,9 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane,
struct ingenic_drm *priv = drm_device_get_priv(plane->dev); struct ingenic_drm *priv = drm_device_get_priv(plane->dev);
struct drm_plane_state *newstate = drm_atomic_get_new_plane_state(state, plane); struct drm_plane_state *newstate = drm_atomic_get_new_plane_state(state, plane);
struct drm_plane_state *oldstate = drm_atomic_get_old_plane_state(state, plane); struct drm_plane_state *oldstate = drm_atomic_get_old_plane_state(state, plane);
unsigned int width, height, cpp, next_id, plane_id;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *crtc_state;
struct ingenic_dma_hwdesc *hwdesc; struct ingenic_dma_hwdesc *hwdesc;
unsigned int width, height, cpp, offset;
dma_addr_t addr; dma_addr_t addr;
u32 fourcc; u32 fourcc;
...@@ -569,16 +577,14 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, ...@@ -569,16 +577,14 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane,
drm_fb_cma_sync_non_coherent(&priv->drm, oldstate, newstate); drm_fb_cma_sync_non_coherent(&priv->drm, oldstate, newstate);
crtc_state = newstate->crtc->state; crtc_state = newstate->crtc->state;
plane_id = !!(priv->soc_info->has_osd && plane != &priv->f0);
addr = drm_fb_cma_get_gem_addr(newstate->fb, newstate, 0); addr = drm_fb_cma_get_gem_addr(newstate->fb, newstate, 0);
width = newstate->src_w >> 16; width = newstate->src_w >> 16;
height = newstate->src_h >> 16; height = newstate->src_h >> 16;
cpp = newstate->fb->format->cpp[0]; cpp = newstate->fb->format->cpp[0];
if (!priv->soc_info->has_osd || plane == &priv->f0) hwdesc = &priv->dma_hwdescs->hwdesc[plane_id];
hwdesc = &priv->dma_hwdescs->hwdesc_f0;
else
hwdesc = &priv->dma_hwdescs->hwdesc_f1;
hwdesc->addr = addr; hwdesc->addr = addr;
hwdesc->cmd = JZ_LCD_CMD_EOF_IRQ | (width * height * cpp / 4); hwdesc->cmd = JZ_LCD_CMD_EOF_IRQ | (width * height * cpp / 4);
...@@ -588,12 +594,8 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, ...@@ -588,12 +594,8 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane,
ingenic_drm_plane_config(priv->dev, plane, fourcc); ingenic_drm_plane_config(priv->dev, plane, fourcc);
if (fourcc == DRM_FORMAT_C8) next_id = fourcc == DRM_FORMAT_C8 ? HWDESC_PALETTE : 0;
offset = offsetof(struct ingenic_dma_hwdescs, hwdesc_pal); priv->dma_hwdescs->hwdesc[0].next = dma_hwdesc_addr(priv, next_id);
else
offset = offsetof(struct ingenic_dma_hwdescs, hwdesc_f0);
priv->dma_hwdescs->hwdesc_f0.next = priv->dma_hwdescs_phys + offset;
crtc_state->color_mgmt_changed = fourcc == DRM_FORMAT_C8; crtc_state->color_mgmt_changed = fourcc == DRM_FORMAT_C8;
} }
...@@ -846,6 +848,35 @@ static void __maybe_unused ingenic_drm_release_rmem(void *d) ...@@ -846,6 +848,35 @@ static void __maybe_unused ingenic_drm_release_rmem(void *d)
of_reserved_mem_device_release(d); of_reserved_mem_device_release(d);
} }
static void ingenic_drm_configure_hwdesc(struct ingenic_drm *priv,
unsigned int hwdesc,
unsigned int next_hwdesc, u32 id)
{
struct ingenic_dma_hwdesc *desc = &priv->dma_hwdescs->hwdesc[hwdesc];
desc->next = dma_hwdesc_addr(priv, next_hwdesc);
desc->id = id;
}
static void ingenic_drm_configure_hwdesc_palette(struct ingenic_drm *priv)
{
struct ingenic_dma_hwdesc *desc;
ingenic_drm_configure_hwdesc(priv, HWDESC_PALETTE, 0, 0xc0);
desc = &priv->dma_hwdescs->hwdesc[HWDESC_PALETTE];
desc->addr = priv->dma_hwdescs_phys
+ offsetof(struct ingenic_dma_hwdescs, palette);
desc->cmd = JZ_LCD_CMD_ENABLE_PAL
| (sizeof(priv->dma_hwdescs->palette) / 4);
}
static void ingenic_drm_configure_hwdesc_plane(struct ingenic_drm *priv,
unsigned int plane)
{
ingenic_drm_configure_hwdesc(priv, plane, plane, 0xf0 | plane);
}
static int ingenic_drm_bind(struct device *dev, bool has_components) static int ingenic_drm_bind(struct device *dev, bool has_components)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
...@@ -942,27 +973,14 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) ...@@ -942,27 +973,14 @@ static int ingenic_drm_bind(struct device *dev, bool has_components)
if (!priv->dma_hwdescs) if (!priv->dma_hwdescs)
return -ENOMEM; return -ENOMEM;
/* Configure DMA hwdesc for foreground0 plane */ /* Configure DMA hwdesc for foreground0 plane */
dma_hwdesc_phys_f0 = priv->dma_hwdescs_phys ingenic_drm_configure_hwdesc_plane(priv, 0);
+ offsetof(struct ingenic_dma_hwdescs, hwdesc_f0);
priv->dma_hwdescs->hwdesc_f0.next = dma_hwdesc_phys_f0;
priv->dma_hwdescs->hwdesc_f0.id = 0xf0;
/* Configure DMA hwdesc for foreground1 plane */ /* Configure DMA hwdesc for foreground1 plane */
dma_hwdesc_phys_f1 = priv->dma_hwdescs_phys ingenic_drm_configure_hwdesc_plane(priv, 1);
+ offsetof(struct ingenic_dma_hwdescs, hwdesc_f1);
priv->dma_hwdescs->hwdesc_f1.next = dma_hwdesc_phys_f1;
priv->dma_hwdescs->hwdesc_f1.id = 0xf1;
/* Configure DMA hwdesc for palette */ /* Configure DMA hwdesc for palette */
priv->dma_hwdescs->hwdesc_pal.next = priv->dma_hwdescs_phys ingenic_drm_configure_hwdesc_palette(priv);
+ offsetof(struct ingenic_dma_hwdescs, hwdesc_f0);
priv->dma_hwdescs->hwdesc_pal.id = 0xc0;
priv->dma_hwdescs->hwdesc_pal.addr = priv->dma_hwdescs_phys
+ offsetof(struct ingenic_dma_hwdescs, palette);
priv->dma_hwdescs->hwdesc_pal.cmd = JZ_LCD_CMD_ENABLE_PAL
| (sizeof(priv->dma_hwdescs->palette) / 4);
primary = priv->soc_info->has_osd ? &priv->f1 : &priv->f0; primary = priv->soc_info->has_osd ? &priv->f1 : &priv->f0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment