aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorYoungJun Cho <yj44.cho@samsung.com>2013-03-13 03:44:37 -0400
committerInki Dae <inki.dae@samsung.com>2013-03-20 06:09:10 -0400
commit7ad018140cc9c0e3388243e524f8410e5f174658 (patch)
tree31060a50f00cc52cb0115beff1797a7a4d8f3cae /drivers/gpu
parent5efc1d1b53ba60a89ce8269880ed02eddecd1add (diff)
drm/exynos: Fix G2D core malfunctioning issue
This patch fixes G2D core malfunctioning issue once g2d dma is started. Without 'DMA_HOLD_CMD_REG' register setting, there is only one interrupt after the execution to all command lists have been completed. And that induces watchdog. So this patch sets 'LIST_HOLD' command to the register so that command execution interrupt can be occured whenever each command list execution is finished. Changelog v2: - Consider for interrupt setup to each command list and all command lists And correct typo. Signed-off-by: YoungJun Cho <yj44.cho@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_g2d.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 095520fdf5eb..1ff11443f552 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -82,7 +82,7 @@
82#define G2D_DMA_LIST_DONE_COUNT_OFFSET 17 82#define G2D_DMA_LIST_DONE_COUNT_OFFSET 17
83 83
84/* G2D_DMA_HOLD_CMD */ 84/* G2D_DMA_HOLD_CMD */
85#define G2D_USET_HOLD (1 << 2) 85#define G2D_USER_HOLD (1 << 2)
86#define G2D_LIST_HOLD (1 << 1) 86#define G2D_LIST_HOLD (1 << 1)
87#define G2D_BITBLT_HOLD (1 << 0) 87#define G2D_BITBLT_HOLD (1 << 0)
88 88
@@ -592,10 +592,6 @@ static void g2d_dma_start(struct g2d_data *g2d,
592 pm_runtime_get_sync(g2d->dev); 592 pm_runtime_get_sync(g2d->dev);
593 clk_enable(g2d->gate_clk); 593 clk_enable(g2d->gate_clk);
594 594
595 /* interrupt enable */
596 writel_relaxed(G2D_INTEN_ACF | G2D_INTEN_UCF | G2D_INTEN_GCF,
597 g2d->regs + G2D_INTEN);
598
599 writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR); 595 writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR);
600 writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND); 596 writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND);
601} 597}
@@ -863,9 +859,23 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
863 cmdlist->data[cmdlist->last++] = G2D_SRC_BASE_ADDR; 859 cmdlist->data[cmdlist->last++] = G2D_SRC_BASE_ADDR;
864 cmdlist->data[cmdlist->last++] = 0; 860 cmdlist->data[cmdlist->last++] = 0;
865 861
862 /*
863 * 'LIST_HOLD' command should be set to the DMA_HOLD_CMD_REG
864 * and GCF bit should be set to INTEN register if user wants
865 * G2D interrupt event once current command list execution is
866 * finished.
867 * Otherwise only ACF bit should be set to INTEN register so
868 * that one interrupt is occured after all command lists
869 * have been completed.
870 */
866 if (node->event) { 871 if (node->event) {
872 cmdlist->data[cmdlist->last++] = G2D_INTEN;
873 cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF | G2D_INTEN_GCF;
867 cmdlist->data[cmdlist->last++] = G2D_DMA_HOLD_CMD; 874 cmdlist->data[cmdlist->last++] = G2D_DMA_HOLD_CMD;
868 cmdlist->data[cmdlist->last++] = G2D_LIST_HOLD; 875 cmdlist->data[cmdlist->last++] = G2D_LIST_HOLD;
876 } else {
877 cmdlist->data[cmdlist->last++] = G2D_INTEN;
878 cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF;
869 } 879 }
870 880
871 /* Check size of cmdlist: last 2 is about G2D_BITBLT_START */ 881 /* Check size of cmdlist: last 2 is about G2D_BITBLT_START */