1
2
3
4
5
6#include <drm/drm_atomic.h>
7#include <drm/drm_atomic_helper.h>
8#include <drm/drm_crtc.h>
9#include <drm/drm_crtc_helper.h>
10#include <drm/drm_fb_cma_helper.h>
11#include <drm/drm_fb_helper.h>
12#include <drm/drm_fourcc.h>
13#include <drm/drm_gem_cma_helper.h>
14#include <drm/drm_managed.h>
15#include <drm/drm_plane_helper.h>
16
17#include "kmb_drv.h"
18#include "kmb_plane.h"
19#include "kmb_regs.h"
20
21const u32 layer_irqs[] = {
22 LCD_INT_VL0,
23 LCD_INT_VL1,
24 LCD_INT_GL0,
25 LCD_INT_GL1
26};
27
28
29static const u32 csc_coef_lcd[] = {
30 1024, 0, 1436,
31 1024, -352, -731,
32 1024, 1814, 0,
33 -179, 125, -226
34};
35
36
37static const u32 kmb_formats_g[] = {
38 DRM_FORMAT_RGB332,
39 DRM_FORMAT_XRGB4444, DRM_FORMAT_XBGR4444,
40 DRM_FORMAT_ARGB4444, DRM_FORMAT_ABGR4444,
41 DRM_FORMAT_XRGB1555, DRM_FORMAT_XBGR1555,
42 DRM_FORMAT_ARGB1555, DRM_FORMAT_ABGR1555,
43 DRM_FORMAT_RGB565, DRM_FORMAT_BGR565,
44 DRM_FORMAT_RGB888, DRM_FORMAT_BGR888,
45 DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888,
46 DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888,
47};
48
49
50static const u32 kmb_formats_v[] = {
51
52 DRM_FORMAT_RGB332,
53 DRM_FORMAT_XRGB4444, DRM_FORMAT_XBGR4444,
54 DRM_FORMAT_ARGB4444, DRM_FORMAT_ABGR4444,
55 DRM_FORMAT_XRGB1555, DRM_FORMAT_XBGR1555,
56 DRM_FORMAT_ARGB1555, DRM_FORMAT_ABGR1555,
57 DRM_FORMAT_RGB565, DRM_FORMAT_BGR565,
58 DRM_FORMAT_RGB888, DRM_FORMAT_BGR888,
59 DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888,
60 DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888,
61
62 DRM_FORMAT_YUV420, DRM_FORMAT_YVU420,
63 DRM_FORMAT_YUV422, DRM_FORMAT_YVU422,
64 DRM_FORMAT_YUV444, DRM_FORMAT_YVU444,
65 DRM_FORMAT_NV12, DRM_FORMAT_NV21,
66};
67
68static unsigned int check_pixel_format(struct drm_plane *plane, u32 format)
69{
70 int i;
71
72 for (i = 0; i < plane->format_count; i++) {
73 if (plane->format_types[i] == format)
74 return 0;
75 }
76 return -EINVAL;
77}
78
79static int kmb_plane_atomic_check(struct drm_plane *plane,
80 struct drm_atomic_state *state)
81{
82 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
83 plane);
84 struct drm_framebuffer *fb;
85 int ret;
86 struct drm_crtc_state *crtc_state;
87 bool can_position;
88
89 fb = new_plane_state->fb;
90 if (!fb || !new_plane_state->crtc)
91 return 0;
92
93 ret = check_pixel_format(plane, fb->format->format);
94 if (ret)
95 return ret;
96
97 if (new_plane_state->crtc_w > KMB_MAX_WIDTH || new_plane_state->crtc_h > KMB_MAX_HEIGHT)
98 return -EINVAL;
99 if (new_plane_state->crtc_w < KMB_MIN_WIDTH || new_plane_state->crtc_h < KMB_MIN_HEIGHT)
100 return -EINVAL;
101 can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
102 crtc_state =
103 drm_atomic_get_existing_crtc_state(state,
104 new_plane_state->crtc);
105 return drm_atomic_helper_check_plane_state(new_plane_state,
106 crtc_state,
107 DRM_PLANE_HELPER_NO_SCALING,
108 DRM_PLANE_HELPER_NO_SCALING,
109 can_position, true);
110}
111
112static void kmb_plane_atomic_disable(struct drm_plane *plane,
113 struct drm_atomic_state *state)
114{
115 struct kmb_plane *kmb_plane = to_kmb_plane(plane);
116 int plane_id = kmb_plane->id;
117 struct kmb_drm_private *kmb;
118
119 kmb = to_kmb(plane->dev);
120
121 if (WARN_ON(plane_id >= KMB_MAX_PLANES))
122 return;
123
124 switch (plane_id) {
125 case LAYER_0:
126 kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL1_ENABLE;
127 break;
128 case LAYER_1:
129 kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL2_ENABLE;
130 break;
131 case LAYER_2:
132 kmb->plane_status[plane_id].ctrl = LCD_CTRL_GL1_ENABLE;
133 break;
134 case LAYER_3:
135 kmb->plane_status[plane_id].ctrl = LCD_CTRL_GL2_ENABLE;
136 break;
137 }
138
139 kmb->plane_status[plane_id].disable = true;
140}
141
142static unsigned int get_pixel_format(u32 format)
143{
144 unsigned int val = 0;
145
146 switch (format) {
147
148 case DRM_FORMAT_YUV444:
149 val = LCD_LAYER_FORMAT_YCBCR444PLAN | LCD_LAYER_PLANAR_STORAGE;
150 break;
151 case DRM_FORMAT_YVU444:
152 val = LCD_LAYER_FORMAT_YCBCR444PLAN | LCD_LAYER_PLANAR_STORAGE
153 | LCD_LAYER_CRCB_ORDER;
154 break;
155 case DRM_FORMAT_YUV422:
156 val = LCD_LAYER_FORMAT_YCBCR422PLAN | LCD_LAYER_PLANAR_STORAGE;
157 break;
158 case DRM_FORMAT_YVU422:
159 val = LCD_LAYER_FORMAT_YCBCR422PLAN | LCD_LAYER_PLANAR_STORAGE
160 | LCD_LAYER_CRCB_ORDER;
161 break;
162 case DRM_FORMAT_YUV420:
163 val = LCD_LAYER_FORMAT_YCBCR420PLAN | LCD_LAYER_PLANAR_STORAGE;
164 break;
165 case DRM_FORMAT_YVU420:
166 val = LCD_LAYER_FORMAT_YCBCR420PLAN | LCD_LAYER_PLANAR_STORAGE
167 | LCD_LAYER_CRCB_ORDER;
168 break;
169 case DRM_FORMAT_NV12:
170 val = LCD_LAYER_FORMAT_NV12 | LCD_LAYER_PLANAR_STORAGE;
171 break;
172 case DRM_FORMAT_NV21:
173 val = LCD_LAYER_FORMAT_NV12 | LCD_LAYER_PLANAR_STORAGE
174 | LCD_LAYER_CRCB_ORDER;
175 break;
176
177
178 case DRM_FORMAT_RGB332:
179 val = LCD_LAYER_FORMAT_RGB332 | LCD_LAYER_BGR_ORDER;
180 break;
181 case DRM_FORMAT_XBGR4444:
182 val = LCD_LAYER_FORMAT_RGBX4444;
183 break;
184 case DRM_FORMAT_ARGB4444:
185 val = LCD_LAYER_FORMAT_RGBA4444 | LCD_LAYER_BGR_ORDER;
186 break;
187 case DRM_FORMAT_ABGR4444:
188 val = LCD_LAYER_FORMAT_RGBA4444;
189 break;
190 case DRM_FORMAT_XRGB1555:
191 val = LCD_LAYER_FORMAT_XRGB1555 | LCD_LAYER_BGR_ORDER;
192 break;
193 case DRM_FORMAT_XBGR1555:
194 val = LCD_LAYER_FORMAT_XRGB1555;
195 break;
196 case DRM_FORMAT_ARGB1555:
197 val = LCD_LAYER_FORMAT_RGBA1555 | LCD_LAYER_BGR_ORDER;
198 break;
199 case DRM_FORMAT_ABGR1555:
200 val = LCD_LAYER_FORMAT_RGBA1555;
201 break;
202 case DRM_FORMAT_RGB565:
203 val = LCD_LAYER_FORMAT_RGB565 | LCD_LAYER_BGR_ORDER;
204 break;
205 case DRM_FORMAT_BGR565:
206 val = LCD_LAYER_FORMAT_RGB565;
207 break;
208 case DRM_FORMAT_RGB888:
209 val = LCD_LAYER_FORMAT_RGB888 | LCD_LAYER_BGR_ORDER;
210 break;
211 case DRM_FORMAT_BGR888:
212 val = LCD_LAYER_FORMAT_RGB888;
213 break;
214 case DRM_FORMAT_XRGB8888:
215 val = LCD_LAYER_FORMAT_RGBX8888 | LCD_LAYER_BGR_ORDER;
216 break;
217 case DRM_FORMAT_XBGR8888:
218 val = LCD_LAYER_FORMAT_RGBX8888;
219 break;
220 case DRM_FORMAT_ARGB8888:
221 val = LCD_LAYER_FORMAT_RGBA8888 | LCD_LAYER_BGR_ORDER;
222 break;
223 case DRM_FORMAT_ABGR8888:
224 val = LCD_LAYER_FORMAT_RGBA8888;
225 break;
226 }
227 DRM_INFO_ONCE("%s : %d format=0x%x val=0x%x\n",
228 __func__, __LINE__, format, val);
229 return val;
230}
231
232static unsigned int get_bits_per_pixel(const struct drm_format_info *format)
233{
234 u32 bpp = 0;
235 unsigned int val = 0;
236
237 if (format->num_planes > 1) {
238 val = LCD_LAYER_8BPP;
239 return val;
240 }
241
242 bpp += 8 * format->cpp[0];
243
244 switch (bpp) {
245 case 8:
246 val = LCD_LAYER_8BPP;
247 break;
248 case 16:
249 val = LCD_LAYER_16BPP;
250 break;
251 case 24:
252 val = LCD_LAYER_24BPP;
253 break;
254 case 32:
255 val = LCD_LAYER_32BPP;
256 break;
257 }
258
259 DRM_DEBUG("bpp=%d val=0x%x\n", bpp, val);
260 return val;
261}
262
263static void config_csc(struct kmb_drm_private *kmb, int plane_id)
264{
265
266 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF11(plane_id), csc_coef_lcd[0]);
267 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF12(plane_id), csc_coef_lcd[1]);
268 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF13(plane_id), csc_coef_lcd[2]);
269 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF21(plane_id), csc_coef_lcd[3]);
270 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF22(plane_id), csc_coef_lcd[4]);
271 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF23(plane_id), csc_coef_lcd[5]);
272 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF31(plane_id), csc_coef_lcd[6]);
273 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF32(plane_id), csc_coef_lcd[7]);
274 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF33(plane_id), csc_coef_lcd[8]);
275 kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF1(plane_id), csc_coef_lcd[9]);
276 kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF2(plane_id), csc_coef_lcd[10]);
277 kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF3(plane_id), csc_coef_lcd[11]);
278}
279
280static void kmb_plane_atomic_update(struct drm_plane *plane,
281 struct drm_atomic_state *state)
282{
283 struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state,
284 plane);
285 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
286 plane);
287 struct drm_framebuffer *fb;
288 struct kmb_drm_private *kmb;
289 unsigned int width;
290 unsigned int height;
291 unsigned int dma_len;
292 struct kmb_plane *kmb_plane;
293 unsigned int dma_cfg;
294 unsigned int ctrl = 0, val = 0, out_format = 0;
295 unsigned int src_w, src_h, crtc_x, crtc_y;
296 unsigned char plane_id;
297 int num_planes;
298 static dma_addr_t addr[MAX_SUB_PLANES];
299
300 if (!plane || !new_plane_state || !old_plane_state)
301 return;
302
303 fb = new_plane_state->fb;
304 if (!fb)
305 return;
306 num_planes = fb->format->num_planes;
307 kmb_plane = to_kmb_plane(plane);
308 plane_id = kmb_plane->id;
309
310 kmb = to_kmb(plane->dev);
311
312 spin_lock_irq(&kmb->irq_lock);
313 if (kmb->kmb_under_flow || kmb->kmb_flush_done) {
314 spin_unlock_irq(&kmb->irq_lock);
315 drm_dbg(&kmb->drm, "plane_update:underflow!!!! returning");
316 return;
317 }
318 spin_unlock_irq(&kmb->irq_lock);
319
320 src_w = (new_plane_state->src_w >> 16);
321 src_h = new_plane_state->src_h >> 16;
322 crtc_x = new_plane_state->crtc_x;
323 crtc_y = new_plane_state->crtc_y;
324
325 drm_dbg(&kmb->drm,
326 "src_w=%d src_h=%d, fb->format->format=0x%x fb->flags=0x%x\n",
327 src_w, src_h, fb->format->format, fb->flags);
328
329 width = fb->width;
330 height = fb->height;
331 dma_len = (width * height * fb->format->cpp[0]);
332 drm_dbg(&kmb->drm, "dma_len=%d ", dma_len);
333 kmb_write_lcd(kmb, LCD_LAYERn_DMA_LEN(plane_id), dma_len);
334 kmb_write_lcd(kmb, LCD_LAYERn_DMA_LEN_SHADOW(plane_id), dma_len);
335 kmb_write_lcd(kmb, LCD_LAYERn_DMA_LINE_VSTRIDE(plane_id),
336 fb->pitches[0]);
337 kmb_write_lcd(kmb, LCD_LAYERn_DMA_LINE_WIDTH(plane_id),
338 (width * fb->format->cpp[0]));
339
340 addr[Y_PLANE] = drm_fb_cma_get_gem_addr(fb, new_plane_state, 0);
341 kmb_write_lcd(kmb, LCD_LAYERn_DMA_START_ADDR(plane_id),
342 addr[Y_PLANE] + fb->offsets[0]);
343 val = get_pixel_format(fb->format->format);
344 val |= get_bits_per_pixel(fb->format);
345
346 if (num_planes > 1) {
347 kmb_write_lcd(kmb, LCD_LAYERn_DMA_CB_LINE_VSTRIDE(plane_id),
348 width * fb->format->cpp[0]);
349 kmb_write_lcd(kmb, LCD_LAYERn_DMA_CB_LINE_WIDTH(plane_id),
350 (width * fb->format->cpp[0]));
351
352 addr[U_PLANE] = drm_fb_cma_get_gem_addr(fb, new_plane_state,
353 U_PLANE);
354
355 if (num_planes == 3 && (val & LCD_LAYER_CRCB_ORDER))
356 kmb_write_lcd(kmb,
357 LCD_LAYERn_DMA_START_CR_ADR(plane_id),
358 addr[U_PLANE]);
359 else
360 kmb_write_lcd(kmb,
361 LCD_LAYERn_DMA_START_CB_ADR(plane_id),
362 addr[U_PLANE]);
363
364 if (num_planes == 3) {
365 kmb_write_lcd(kmb,
366 LCD_LAYERn_DMA_CR_LINE_VSTRIDE(plane_id),
367 ((width) * fb->format->cpp[0]));
368
369 kmb_write_lcd(kmb,
370 LCD_LAYERn_DMA_CR_LINE_WIDTH(plane_id),
371 ((width) * fb->format->cpp[0]));
372
373 addr[V_PLANE] = drm_fb_cma_get_gem_addr(fb,
374 new_plane_state,
375 V_PLANE);
376
377
378 if (val & LCD_LAYER_CRCB_ORDER)
379 kmb_write_lcd(kmb,
380 LCD_LAYERn_DMA_START_CB_ADR(plane_id),
381 addr[V_PLANE]);
382 else
383 kmb_write_lcd(kmb,
384 LCD_LAYERn_DMA_START_CR_ADR(plane_id),
385 addr[V_PLANE]);
386 }
387 }
388
389 kmb_write_lcd(kmb, LCD_LAYERn_WIDTH(plane_id), src_w - 1);
390 kmb_write_lcd(kmb, LCD_LAYERn_HEIGHT(plane_id), src_h - 1);
391 kmb_write_lcd(kmb, LCD_LAYERn_COL_START(plane_id), crtc_x);
392 kmb_write_lcd(kmb, LCD_LAYERn_ROW_START(plane_id), crtc_y);
393
394 val |= LCD_LAYER_FIFO_100;
395
396 if (val & LCD_LAYER_PLANAR_STORAGE) {
397 val |= LCD_LAYER_CSC_EN;
398
399
400 config_csc(kmb, plane_id);
401 }
402
403 kmb_write_lcd(kmb, LCD_LAYERn_CFG(plane_id), val);
404
405 switch (plane_id) {
406 case LAYER_0:
407 ctrl = LCD_CTRL_VL1_ENABLE;
408 break;
409 case LAYER_1:
410 ctrl = LCD_CTRL_VL2_ENABLE;
411 break;
412 case LAYER_2:
413 ctrl = LCD_CTRL_GL1_ENABLE;
414 break;
415 case LAYER_3:
416 ctrl = LCD_CTRL_GL2_ENABLE;
417 break;
418 }
419
420 ctrl |= LCD_CTRL_PROGRESSIVE | LCD_CTRL_TIM_GEN_ENABLE
421 | LCD_CTRL_CONTINUOUS | LCD_CTRL_OUTPUT_ENABLED;
422
423
424
425
426 ctrl |= LCD_CTRL_VHSYNC_IDLE_LVL;
427
428 kmb_set_bitmask_lcd(kmb, LCD_CONTROL, ctrl);
429
430
431
432
433 out_format |= LCD_OUTF_FORMAT_RGB888;
434
435
436
437 out_format |= LCD_OUTF_MIPI_RGB_MODE;
438 kmb_write_lcd(kmb, LCD_OUT_FORMAT_CFG, out_format);
439
440 dma_cfg = LCD_DMA_LAYER_ENABLE | LCD_DMA_LAYER_VSTRIDE_EN |
441 LCD_DMA_LAYER_CONT_UPDATE | LCD_DMA_LAYER_AXI_BURST_16;
442
443
444 kmb_write_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id), dma_cfg);
445 drm_dbg(&kmb->drm, "dma_cfg=0x%x LCD_DMA_CFG=0x%x\n", dma_cfg,
446 kmb_read_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id)));
447
448 kmb_set_bitmask_lcd(kmb, LCD_INT_CLEAR, LCD_INT_EOF |
449 LCD_INT_DMA_ERR);
450 kmb_set_bitmask_lcd(kmb, LCD_INT_ENABLE, LCD_INT_EOF |
451 LCD_INT_DMA_ERR);
452}
453
454static const struct drm_plane_helper_funcs kmb_plane_helper_funcs = {
455 .atomic_check = kmb_plane_atomic_check,
456 .atomic_update = kmb_plane_atomic_update,
457 .atomic_disable = kmb_plane_atomic_disable
458};
459
460void kmb_plane_destroy(struct drm_plane *plane)
461{
462 struct kmb_plane *kmb_plane = to_kmb_plane(plane);
463
464 drm_plane_cleanup(plane);
465 kfree(kmb_plane);
466}
467
468static const struct drm_plane_funcs kmb_plane_funcs = {
469 .update_plane = drm_atomic_helper_update_plane,
470 .disable_plane = drm_atomic_helper_disable_plane,
471 .destroy = kmb_plane_destroy,
472 .reset = drm_atomic_helper_plane_reset,
473 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
474 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
475};
476
477struct kmb_plane *kmb_plane_init(struct drm_device *drm)
478{
479 struct kmb_drm_private *kmb = to_kmb(drm);
480 struct kmb_plane *plane = NULL;
481 struct kmb_plane *primary = NULL;
482 int i = 0;
483 int ret = 0;
484 enum drm_plane_type plane_type;
485 const u32 *plane_formats;
486 int num_plane_formats;
487
488 for (i = 0; i < KMB_MAX_PLANES; i++) {
489 plane = drmm_kzalloc(drm, sizeof(*plane), GFP_KERNEL);
490
491 if (!plane) {
492 drm_err(drm, "Failed to allocate plane\n");
493 return ERR_PTR(-ENOMEM);
494 }
495
496 plane_type = (i == 0) ? DRM_PLANE_TYPE_PRIMARY :
497 DRM_PLANE_TYPE_OVERLAY;
498 if (i < 2) {
499 plane_formats = kmb_formats_v;
500 num_plane_formats = ARRAY_SIZE(kmb_formats_v);
501 } else {
502 plane_formats = kmb_formats_g;
503 num_plane_formats = ARRAY_SIZE(kmb_formats_g);
504 }
505
506 ret = drm_universal_plane_init(drm, &plane->base_plane,
507 POSSIBLE_CRTCS, &kmb_plane_funcs,
508 plane_formats, num_plane_formats,
509 NULL, plane_type, "plane %d", i);
510 if (ret < 0) {
511 drm_err(drm, "drm_universal_plane_init failed (ret=%d)",
512 ret);
513 goto cleanup;
514 }
515 drm_dbg(drm, "%s : %d i=%d type=%d",
516 __func__, __LINE__,
517 i, plane_type);
518 drm_plane_helper_add(&plane->base_plane,
519 &kmb_plane_helper_funcs);
520 if (plane_type == DRM_PLANE_TYPE_PRIMARY) {
521 primary = plane;
522 kmb->plane = plane;
523 }
524 drm_dbg(drm, "%s : %d primary=%p\n", __func__, __LINE__,
525 &primary->base_plane);
526 plane->id = i;
527 }
528
529 return primary;
530cleanup:
531 drmm_kfree(drm, plane);
532 return ERR_PTR(ret);
533}
534