diff options
-rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 90 |
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 | ||
34 | struct tilcdc_crtc { | 34 | struct 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 | */ |
122 | static void tilcdc_crtc_load_palette(struct drm_crtc *crtc) | 122 | static 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 | ||