diff options
author | YoungJun Cho <yj44.cho@samsung.com> | 2013-03-13 03:44:37 -0400 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2013-03-20 06:09:10 -0400 |
commit | 7ad018140cc9c0e3388243e524f8410e5f174658 (patch) | |
tree | 31060a50f00cc52cb0115beff1797a7a4d8f3cae /drivers/gpu | |
parent | 5efc1d1b53ba60a89ce8269880ed02eddecd1add (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.c | 20 |
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 */ |