summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/ingenic/ingenic-drm-drv.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
index d34e76f5f57d..e8d47549ff2e 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
@@ -45,7 +45,12 @@ struct ingenic_dma_hwdesc {
u32 addr;
u32 id;
u32 cmd;
-} __packed;
+} __aligned(16);
+
+struct ingenic_dma_hwdescs {
+ struct ingenic_dma_hwdesc hwdesc_f0;
+ struct ingenic_dma_hwdesc hwdesc_f1;
+};
struct jz_soc_info {
bool needs_dev_clk;
@@ -68,8 +73,8 @@ struct ingenic_drm {
struct clk *lcd_clk, *pix_clk;
const struct jz_soc_info *soc_info;
- struct ingenic_dma_hwdesc *dma_hwdesc_f0, *dma_hwdesc_f1;
- dma_addr_t dma_hwdesc_phys_f0, dma_hwdesc_phys_f1;
+ struct ingenic_dma_hwdescs *dma_hwdescs;
+ dma_addr_t dma_hwdescs_phys;
bool panel_is_sharp;
bool no_vblank;
@@ -546,9 +551,9 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane,
cpp = state->fb->format->cpp[0];
if (priv->soc_info->has_osd && plane->type == DRM_PLANE_TYPE_OVERLAY)
- hwdesc = priv->dma_hwdesc_f0;
+ hwdesc = &priv->dma_hwdescs->hwdesc_f0;
else
- hwdesc = priv->dma_hwdesc_f1;
+ hwdesc = &priv->dma_hwdescs->hwdesc_f1;
hwdesc->addr = addr;
hwdesc->cmd = JZ_LCD_CMD_EOF_IRQ | (width * height * cpp / 4);
@@ -856,6 +861,7 @@ static int ingenic_drm_bind(struct device *dev, bool has_components)
void __iomem *base;
long parent_rate;
unsigned int i, clone_mask = 0;
+ dma_addr_t dma_hwdesc_phys_f0, dma_hwdesc_phys_f1;
int ret, irq;
soc_info = of_device_get_match_data(dev);
@@ -930,26 +936,25 @@ static int ingenic_drm_bind(struct device *dev, bool has_components)
return PTR_ERR(priv->pix_clk);
}
- priv->dma_hwdesc_f1 = dmam_alloc_coherent(dev, sizeof(*priv->dma_hwdesc_f1),
- &priv->dma_hwdesc_phys_f1,
- GFP_KERNEL);
- if (!priv->dma_hwdesc_f1)
+ priv->dma_hwdescs = dmam_alloc_coherent(dev,
+ sizeof(*priv->dma_hwdescs),
+ &priv->dma_hwdescs_phys,
+ GFP_KERNEL);
+ if (!priv->dma_hwdescs)
return -ENOMEM;
- priv->dma_hwdesc_f1->next = priv->dma_hwdesc_phys_f1;
- priv->dma_hwdesc_f1->id = 0xf1;
- if (priv->soc_info->has_osd) {
- priv->dma_hwdesc_f0 = dmam_alloc_coherent(dev,
- sizeof(*priv->dma_hwdesc_f0),
- &priv->dma_hwdesc_phys_f0,
- GFP_KERNEL);
- if (!priv->dma_hwdesc_f0)
- return -ENOMEM;
+ /* Configure DMA hwdesc for foreground0 plane */
+ dma_hwdesc_phys_f0 = priv->dma_hwdescs_phys
+ + offsetof(struct ingenic_dma_hwdescs, hwdesc_f0);
+ priv->dma_hwdescs->hwdesc_f0.next = dma_hwdesc_phys_f0;
+ priv->dma_hwdescs->hwdesc_f0.id = 0xf0;
- priv->dma_hwdesc_f0->next = priv->dma_hwdesc_phys_f0;
- priv->dma_hwdesc_f0->id = 0xf0;
- }
+ /* Configure DMA hwdesc for foreground1 plane */
+ dma_hwdesc_phys_f1 = priv->dma_hwdescs_phys
+ + offsetof(struct ingenic_dma_hwdescs, hwdesc_f1);
+ priv->dma_hwdescs->hwdesc_f1.next = dma_hwdesc_phys_f1;
+ priv->dma_hwdescs->hwdesc_f1.id = 0xf1;
if (soc_info->has_osd)
priv->ipu_plane = drm_plane_from_index(drm, 0);
@@ -1101,8 +1106,8 @@ static int ingenic_drm_bind(struct device *dev, bool has_components)
}
/* Set address of our DMA descriptor chain */
- regmap_write(priv->map, JZ_REG_LCD_DA0, priv->dma_hwdesc_phys_f0);
- regmap_write(priv->map, JZ_REG_LCD_DA1, priv->dma_hwdesc_phys_f1);
+ regmap_write(priv->map, JZ_REG_LCD_DA0, dma_hwdesc_phys_f0);
+ regmap_write(priv->map, JZ_REG_LCD_DA1, dma_hwdesc_phys_f1);
/* Enable OSD if available */
if (soc_info->has_osd)