diff options
Diffstat (limited to 'drivers/gpu/drm/mediatek/mtk_disp_rdma.c')
-rw-r--r-- | drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index 585943c81e1f..b0a5cffe345a 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c | |||
@@ -31,14 +31,31 @@ | |||
31 | #define RDMA_REG_UPDATE_INT BIT(0) | 31 | #define RDMA_REG_UPDATE_INT BIT(0) |
32 | #define DISP_REG_RDMA_GLOBAL_CON 0x0010 | 32 | #define DISP_REG_RDMA_GLOBAL_CON 0x0010 |
33 | #define RDMA_ENGINE_EN BIT(0) | 33 | #define RDMA_ENGINE_EN BIT(0) |
34 | #define RDMA_MODE_MEMORY BIT(1) | ||
34 | #define DISP_REG_RDMA_SIZE_CON_0 0x0014 | 35 | #define DISP_REG_RDMA_SIZE_CON_0 0x0014 |
36 | #define RDMA_MATRIX_ENABLE BIT(17) | ||
37 | #define RDMA_MATRIX_INT_MTX_SEL GENMASK(23, 20) | ||
38 | #define RDMA_MATRIX_INT_MTX_BT601_to_RGB (6 << 20) | ||
35 | #define DISP_REG_RDMA_SIZE_CON_1 0x0018 | 39 | #define DISP_REG_RDMA_SIZE_CON_1 0x0018 |
36 | #define DISP_REG_RDMA_TARGET_LINE 0x001c | 40 | #define DISP_REG_RDMA_TARGET_LINE 0x001c |
41 | #define DISP_RDMA_MEM_CON 0x0024 | ||
42 | #define MEM_MODE_INPUT_FORMAT_RGB565 (0x000 << 4) | ||
43 | #define MEM_MODE_INPUT_FORMAT_RGB888 (0x001 << 4) | ||
44 | #define MEM_MODE_INPUT_FORMAT_RGBA8888 (0x002 << 4) | ||
45 | #define MEM_MODE_INPUT_FORMAT_ARGB8888 (0x003 << 4) | ||
46 | #define MEM_MODE_INPUT_FORMAT_UYVY (0x004 << 4) | ||
47 | #define MEM_MODE_INPUT_FORMAT_YUYV (0x005 << 4) | ||
48 | #define MEM_MODE_INPUT_SWAP BIT(8) | ||
49 | #define DISP_RDMA_MEM_SRC_PITCH 0x002c | ||
50 | #define DISP_RDMA_MEM_GMC_SETTING_0 0x0030 | ||
37 | #define DISP_REG_RDMA_FIFO_CON 0x0040 | 51 | #define DISP_REG_RDMA_FIFO_CON 0x0040 |
38 | #define RDMA_FIFO_UNDERFLOW_EN BIT(31) | 52 | #define RDMA_FIFO_UNDERFLOW_EN BIT(31) |
39 | #define RDMA_FIFO_PSEUDO_SIZE(bytes) (((bytes) / 16) << 16) | 53 | #define RDMA_FIFO_PSEUDO_SIZE(bytes) (((bytes) / 16) << 16) |
40 | #define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes) ((bytes) / 16) | 54 | #define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes) ((bytes) / 16) |
41 | #define RDMA_FIFO_SIZE(rdma) ((rdma)->data->fifo_size) | 55 | #define RDMA_FIFO_SIZE(rdma) ((rdma)->data->fifo_size) |
56 | #define DISP_RDMA_MEM_START_ADDR 0x0f00 | ||
57 | |||
58 | #define RDMA_MEM_GMC 0x40402020 | ||
42 | 59 | ||
43 | struct mtk_disp_rdma_data { | 60 | struct mtk_disp_rdma_data { |
44 | unsigned int fifo_size; | 61 | unsigned int fifo_size; |
@@ -138,12 +155,87 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width, | |||
138 | writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON); | 155 | writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON); |
139 | } | 156 | } |
140 | 157 | ||
158 | static unsigned int rdma_fmt_convert(struct mtk_disp_rdma *rdma, | ||
159 | unsigned int fmt) | ||
160 | { | ||
161 | /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX" | ||
162 | * is defined in mediatek HW data sheet. | ||
163 | * The alphabet order in XXX is no relation to data | ||
164 | * arrangement in memory. | ||
165 | */ | ||
166 | switch (fmt) { | ||
167 | default: | ||
168 | case DRM_FORMAT_RGB565: | ||
169 | return MEM_MODE_INPUT_FORMAT_RGB565; | ||
170 | case DRM_FORMAT_BGR565: | ||
171 | return MEM_MODE_INPUT_FORMAT_RGB565 | MEM_MODE_INPUT_SWAP; | ||
172 | case DRM_FORMAT_RGB888: | ||
173 | return MEM_MODE_INPUT_FORMAT_RGB888; | ||
174 | case DRM_FORMAT_BGR888: | ||
175 | return MEM_MODE_INPUT_FORMAT_RGB888 | MEM_MODE_INPUT_SWAP; | ||
176 | case DRM_FORMAT_RGBX8888: | ||
177 | case DRM_FORMAT_RGBA8888: | ||
178 | return MEM_MODE_INPUT_FORMAT_ARGB8888; | ||
179 | case DRM_FORMAT_BGRX8888: | ||
180 | case DRM_FORMAT_BGRA8888: | ||
181 | return MEM_MODE_INPUT_FORMAT_ARGB8888 | MEM_MODE_INPUT_SWAP; | ||
182 | case DRM_FORMAT_XRGB8888: | ||
183 | case DRM_FORMAT_ARGB8888: | ||
184 | return MEM_MODE_INPUT_FORMAT_RGBA8888; | ||
185 | case DRM_FORMAT_XBGR8888: | ||
186 | case DRM_FORMAT_ABGR8888: | ||
187 | return MEM_MODE_INPUT_FORMAT_RGBA8888 | MEM_MODE_INPUT_SWAP; | ||
188 | case DRM_FORMAT_UYVY: | ||
189 | return MEM_MODE_INPUT_FORMAT_UYVY; | ||
190 | case DRM_FORMAT_YUYV: | ||
191 | return MEM_MODE_INPUT_FORMAT_YUYV; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | static unsigned int mtk_rdma_layer_nr(struct mtk_ddp_comp *comp) | ||
196 | { | ||
197 | return 1; | ||
198 | } | ||
199 | |||
200 | static void mtk_rdma_layer_config(struct mtk_ddp_comp *comp, unsigned int idx, | ||
201 | struct mtk_plane_state *state) | ||
202 | { | ||
203 | struct mtk_disp_rdma *rdma = comp_to_rdma(comp); | ||
204 | struct mtk_plane_pending_state *pending = &state->pending; | ||
205 | unsigned int addr = pending->addr; | ||
206 | unsigned int pitch = pending->pitch & 0xffff; | ||
207 | unsigned int fmt = pending->format; | ||
208 | unsigned int con; | ||
209 | |||
210 | con = rdma_fmt_convert(rdma, fmt); | ||
211 | writel_relaxed(con, comp->regs + DISP_RDMA_MEM_CON); | ||
212 | |||
213 | if (fmt == DRM_FORMAT_UYVY || fmt == DRM_FORMAT_YUYV) { | ||
214 | rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, | ||
215 | RDMA_MATRIX_ENABLE, RDMA_MATRIX_ENABLE); | ||
216 | rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, | ||
217 | RDMA_MATRIX_INT_MTX_SEL, | ||
218 | RDMA_MATRIX_INT_MTX_BT601_to_RGB); | ||
219 | } else { | ||
220 | rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, | ||
221 | RDMA_MATRIX_ENABLE, 0); | ||
222 | } | ||
223 | |||
224 | writel_relaxed(addr, comp->regs + DISP_RDMA_MEM_START_ADDR); | ||
225 | writel_relaxed(pitch, comp->regs + DISP_RDMA_MEM_SRC_PITCH); | ||
226 | writel(RDMA_MEM_GMC, comp->regs + DISP_RDMA_MEM_GMC_SETTING_0); | ||
227 | rdma_update_bits(comp, DISP_REG_RDMA_GLOBAL_CON, | ||
228 | RDMA_MODE_MEMORY, RDMA_MODE_MEMORY); | ||
229 | } | ||
230 | |||
141 | static const struct mtk_ddp_comp_funcs mtk_disp_rdma_funcs = { | 231 | static const struct mtk_ddp_comp_funcs mtk_disp_rdma_funcs = { |
142 | .config = mtk_rdma_config, | 232 | .config = mtk_rdma_config, |
143 | .start = mtk_rdma_start, | 233 | .start = mtk_rdma_start, |
144 | .stop = mtk_rdma_stop, | 234 | .stop = mtk_rdma_stop, |
145 | .enable_vblank = mtk_rdma_enable_vblank, | 235 | .enable_vblank = mtk_rdma_enable_vblank, |
146 | .disable_vblank = mtk_rdma_disable_vblank, | 236 | .disable_vblank = mtk_rdma_disable_vblank, |
237 | .layer_nr = mtk_rdma_layer_nr, | ||
238 | .layer_config = mtk_rdma_layer_config, | ||
147 | }; | 239 | }; |
148 | 240 | ||
149 | static int mtk_disp_rdma_bind(struct device *dev, struct device *master, | 241 | static int mtk_disp_rdma_bind(struct device *dev, struct device *master, |