aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c90
1 files changed, 47 insertions, 43 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 1ed65dd5befe..b3edc6d2bf16 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -28,8 +28,8 @@
28#include "tilcdc_regs.h" 28#include "tilcdc_regs.h"
29 29
30#define TILCDC_VBLANK_SAFETY_THRESHOLD_US 1000 30#define TILCDC_VBLANK_SAFETY_THRESHOLD_US 1000
31#define TILCDC_REV1_PALETTE_SIZE 32 31#define TILCDC_PALETTE_SIZE 32
32#define TILCDC_REV1_PALETTE_FIRST_ENTRY 0x4000 32#define TILCDC_PALETTE_FIRST_ENTRY 0x4000
33 33
34struct tilcdc_crtc { 34struct tilcdc_crtc {
35 struct drm_crtc base; 35 struct drm_crtc base;
@@ -62,7 +62,7 @@ struct tilcdc_crtc {
62 struct work_struct recover_work; 62 struct work_struct recover_work;
63 63
64 dma_addr_t palette_dma_handle; 64 dma_addr_t palette_dma_handle;
65 void *palette_base; 65 u16 *palette_base;
66 struct completion palette_loaded; 66 struct completion palette_loaded;
67}; 67};
68#define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) 68#define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)
@@ -114,23 +114,17 @@ static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
114} 114}
115 115
116/* 116/*
117 * The driver currently only supports the RGB565 format for revision 1. For 117 * The driver currently only supports only true color formats. For
118 * 16 bits-per-pixel the palette block is bypassed, but the first 32 bytes of 118 * true color the palette block is bypassed, but a 32 byte palette
119 * the framebuffer are still considered palette. The first 16-bit entry must 119 * should still be loaded. The first 16-bit entry must be 0x4000 while
120 * be 0x4000 while all other entries must be zeroed. 120 * all other entries must be zeroed.
121 */ 121 */
122static void tilcdc_crtc_load_palette(struct drm_crtc *crtc) 122static void tilcdc_crtc_load_palette(struct drm_crtc *crtc)
123{ 123{
124 u32 dma_fb_base, dma_fb_ceiling, raster_ctl; 124 u32 dma_fb_base, dma_fb_ceiling, raster_ctl;
125 struct tilcdc_crtc *tilcdc_crtc; 125 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
126 struct drm_device *dev; 126 struct drm_device *dev = crtc->dev;
127 u16 *first_entry; 127 struct tilcdc_drm_private *priv = dev->dev_private;
128
129 dev = crtc->dev;
130 tilcdc_crtc = to_tilcdc_crtc(crtc);
131 first_entry = tilcdc_crtc->palette_base;
132
133 *first_entry = TILCDC_REV1_PALETTE_FIRST_ENTRY;
134 128
135 dma_fb_base = tilcdc_read(dev, LCDC_DMA_FB_BASE_ADDR_0_REG); 129 dma_fb_base = tilcdc_read(dev, LCDC_DMA_FB_BASE_ADDR_0_REG);
136 dma_fb_ceiling = tilcdc_read(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG); 130 dma_fb_ceiling = tilcdc_read(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG);
@@ -140,23 +134,34 @@ static void tilcdc_crtc_load_palette(struct drm_crtc *crtc)
140 tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, 134 tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG,
141 tilcdc_crtc->palette_dma_handle); 135 tilcdc_crtc->palette_dma_handle);
142 tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, 136 tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG,
143 (u32)tilcdc_crtc->palette_dma_handle 137 (u32) tilcdc_crtc->palette_dma_handle +
144 + TILCDC_REV1_PALETTE_SIZE - 1); 138 TILCDC_PALETTE_SIZE - 1);
145 139
146 /* Load it. */ 140 /* Set dma load mode for palette loading only. */
147 tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, 141 tilcdc_write_mask(dev, LCDC_RASTER_CTRL_REG,
148 LCDC_PALETTE_LOAD_MODE(DATA_ONLY)); 142 LCDC_PALETTE_LOAD_MODE(PALETTE_ONLY),
149 tilcdc_set(dev, LCDC_RASTER_CTRL_REG, 143 LCDC_PALETTE_LOAD_MODE_MASK);
150 LCDC_PALETTE_LOAD_MODE(PALETTE_ONLY)); 144
145 /* Enable DMA Palette Loaded Interrupt */
146 if (priv->rev == 1)
147 tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA);
148 else
149 tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG, LCDC_V2_PL_INT_ENA);
151 150
152 /* Enable the LCDC and wait for palette to be loaded. */ 151 /* Enable LCDC DMA and wait for palette to be loaded. */
153 tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA); 152 tilcdc_clear_irqstatus(dev, 0xffffffff);
154 tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); 153 tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
155 154
156 wait_for_completion(&tilcdc_crtc->palette_loaded); 155 wait_for_completion(&tilcdc_crtc->palette_loaded);
157 156
158 /* Restore the registers. */ 157 /* Disable LCDC DMA and DMA Palette Loaded Interrupt. */
159 tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); 158 tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
159 if (priv->rev == 1)
160 tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA);
161 else
162 tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG, LCDC_V2_PL_INT_ENA);
163
164 /* Restore the registers. */
160 tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, dma_fb_base); 165 tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, dma_fb_base);
161 tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, dma_fb_ceiling); 166 tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, dma_fb_ceiling);
162 tilcdc_write(dev, LCDC_RASTER_CTRL_REG, raster_ctl); 167 tilcdc_write(dev, LCDC_RASTER_CTRL_REG, raster_ctl);
@@ -218,7 +223,6 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
218{ 223{
219 struct drm_device *dev = crtc->dev; 224 struct drm_device *dev = crtc->dev;
220 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 225 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
221 struct tilcdc_drm_private *priv = dev->dev_private;
222 226
223 WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); 227 WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
224 mutex_lock(&tilcdc_crtc->enable_lock); 228 mutex_lock(&tilcdc_crtc->enable_lock);
@@ -231,7 +235,7 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
231 235
232 reset(crtc); 236 reset(crtc);
233 237
234 if (priv->rev == 1 && !completion_done(&tilcdc_crtc->palette_loaded)) 238 if (!completion_done(&tilcdc_crtc->palette_loaded))
235 tilcdc_crtc_load_palette(crtc); 239 tilcdc_crtc_load_palette(crtc);
236 240
237 tilcdc_crtc_enable_irqs(dev); 241 tilcdc_crtc_enable_irqs(dev);
@@ -281,8 +285,7 @@ static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown)
281 * LCDC will not retain the palette when reset. Make sure it gets 285 * LCDC will not retain the palette when reset. Make sure it gets
282 * reloaded on tilcdc_crtc_enable(). 286 * reloaded on tilcdc_crtc_enable().
283 */ 287 */
284 if (priv->rev == 1) 288 reinit_completion(&tilcdc_crtc->palette_loaded);
285 reinit_completion(&tilcdc_crtc->palette_loaded);
286 289
287 drm_crtc_vblank_off(crtc); 290 drm_crtc_vblank_off(crtc);
288 291
@@ -917,12 +920,14 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
917 dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underflow", 920 dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underflow",
918 __func__, stat); 921 __func__, stat);
919 922
920 if (priv->rev == 1) { 923 if (stat & LCDC_PL_LOAD_DONE) {
921 if (stat & LCDC_PL_LOAD_DONE) { 924 complete(&tilcdc_crtc->palette_loaded);
922 complete(&tilcdc_crtc->palette_loaded); 925 if (priv->rev == 1)
923 tilcdc_clear(dev, 926 tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
924 LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA); 927 LCDC_V1_PL_INT_ENA);
925 } 928 else
929 tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
930 LCDC_V2_PL_INT_ENA);
926 } 931 }
927 932
928 if (stat & LCDC_SYNC_LOST) { 933 if (stat & LCDC_SYNC_LOST) {
@@ -972,15 +977,14 @@ int tilcdc_crtc_create(struct drm_device *dev)
972 return -ENOMEM; 977 return -ENOMEM;
973 } 978 }
974 979
975 if (priv->rev == 1) { 980 init_completion(&tilcdc_crtc->palette_loaded);
976 init_completion(&tilcdc_crtc->palette_loaded); 981 tilcdc_crtc->palette_base = dmam_alloc_coherent(dev->dev,
977 tilcdc_crtc->palette_base = dmam_alloc_coherent(dev->dev, 982 TILCDC_PALETTE_SIZE,
978 TILCDC_REV1_PALETTE_SIZE,
979 &tilcdc_crtc->palette_dma_handle, 983 &tilcdc_crtc->palette_dma_handle,
980 GFP_KERNEL | __GFP_ZERO); 984 GFP_KERNEL | __GFP_ZERO);
981 if (!tilcdc_crtc->palette_base) 985 if (!tilcdc_crtc->palette_base)
982 return -ENOMEM; 986 return -ENOMEM;
983 } 987 *tilcdc_crtc->palette_base = TILCDC_PALETTE_FIRST_ENTRY;
984 988
985 crtc = &tilcdc_crtc->base; 989 crtc = &tilcdc_crtc->base;
986 990