linux/drivers/gpu/drm/kmb/kmb_plane.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright © 2018-2020 Intel Corporation
   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/* Conversion (yuv->rgb) matrix from myriadx */
  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/* Graphics layer (layers 2 & 3) formats, only packed formats  are supported */
  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/* Video layer ( 0 & 1) formats, packed and planar formats are supported */
  50static const u32 kmb_formats_v[] = {
  51        /* packed formats */
  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        /*planar formats */
  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        struct kmb_drm_private *kmb;
  71        struct kmb_plane *kmb_plane = to_kmb_plane(plane);
  72        int i;
  73        int plane_id = kmb_plane->id;
  74        struct disp_cfg init_disp_cfg;
  75
  76        kmb = to_kmb(plane->dev);
  77        init_disp_cfg = kmb->init_disp_cfg[plane_id];
  78        /* Due to HW limitations, changing pixel format after initial
  79         * plane configuration is not supported.
  80         */
  81        if (init_disp_cfg.format && init_disp_cfg.format != format) {
  82                drm_dbg(&kmb->drm, "Cannot change format after initial plane configuration");
  83                return -EINVAL;
  84        }
  85        for (i = 0; i < plane->format_count; i++) {
  86                if (plane->format_types[i] == format)
  87                        return 0;
  88        }
  89        return -EINVAL;
  90}
  91
  92static int kmb_plane_atomic_check(struct drm_plane *plane,
  93                                  struct drm_atomic_state *state)
  94{
  95        struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
  96                                                                                 plane);
  97        struct kmb_drm_private *kmb;
  98        struct kmb_plane *kmb_plane = to_kmb_plane(plane);
  99        int plane_id = kmb_plane->id;
 100        struct disp_cfg init_disp_cfg;
 101        struct drm_framebuffer *fb;
 102        int ret;
 103        struct drm_crtc_state *crtc_state;
 104        bool can_position;
 105
 106        kmb = to_kmb(plane->dev);
 107        init_disp_cfg = kmb->init_disp_cfg[plane_id];
 108        fb = new_plane_state->fb;
 109        if (!fb || !new_plane_state->crtc)
 110                return 0;
 111
 112        ret = check_pixel_format(plane, fb->format->format);
 113        if (ret)
 114                return ret;
 115
 116        if (new_plane_state->crtc_w > KMB_FB_MAX_WIDTH ||
 117            new_plane_state->crtc_h > KMB_FB_MAX_HEIGHT ||
 118            new_plane_state->crtc_w < KMB_FB_MIN_WIDTH ||
 119            new_plane_state->crtc_h < KMB_FB_MIN_HEIGHT)
 120                return -EINVAL;
 121
 122        /* Due to HW limitations, changing plane height or width after
 123         * initial plane configuration is not supported.
 124         */
 125        if ((init_disp_cfg.width && init_disp_cfg.height) &&
 126            (init_disp_cfg.width != fb->width ||
 127            init_disp_cfg.height != fb->height)) {
 128                drm_dbg(&kmb->drm, "Cannot change plane height or width after initial configuration");
 129                return -EINVAL;
 130        }
 131        can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
 132        crtc_state =
 133                drm_atomic_get_existing_crtc_state(state,
 134                                                   new_plane_state->crtc);
 135        return drm_atomic_helper_check_plane_state(new_plane_state,
 136                                                   crtc_state,
 137                                                   DRM_PLANE_HELPER_NO_SCALING,
 138                                                   DRM_PLANE_HELPER_NO_SCALING,
 139                                                   can_position, true);
 140}
 141
 142static void kmb_plane_atomic_disable(struct drm_plane *plane,
 143                                     struct drm_atomic_state *state)
 144{
 145        struct kmb_plane *kmb_plane = to_kmb_plane(plane);
 146        int plane_id = kmb_plane->id;
 147        struct kmb_drm_private *kmb;
 148
 149        kmb = to_kmb(plane->dev);
 150
 151        if (WARN_ON(plane_id >= KMB_MAX_PLANES))
 152                return;
 153
 154        switch (plane_id) {
 155        case LAYER_0:
 156                kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL1_ENABLE;
 157                break;
 158        case LAYER_1:
 159                kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL2_ENABLE;
 160                break;
 161        case LAYER_2:
 162                kmb->plane_status[plane_id].ctrl = LCD_CTRL_GL1_ENABLE;
 163                break;
 164        case LAYER_3:
 165                kmb->plane_status[plane_id].ctrl = LCD_CTRL_GL2_ENABLE;
 166                break;
 167        }
 168
 169        kmb->plane_status[plane_id].disable = true;
 170}
 171
 172static unsigned int get_pixel_format(u32 format)
 173{
 174        unsigned int val = 0;
 175
 176        switch (format) {
 177                /* planar formats */
 178        case DRM_FORMAT_YUV444:
 179                val = LCD_LAYER_FORMAT_YCBCR444PLAN | LCD_LAYER_PLANAR_STORAGE;
 180                break;
 181        case DRM_FORMAT_YVU444:
 182                val = LCD_LAYER_FORMAT_YCBCR444PLAN | LCD_LAYER_PLANAR_STORAGE
 183                    | LCD_LAYER_CRCB_ORDER;
 184                break;
 185        case DRM_FORMAT_YUV422:
 186                val = LCD_LAYER_FORMAT_YCBCR422PLAN | LCD_LAYER_PLANAR_STORAGE;
 187                break;
 188        case DRM_FORMAT_YVU422:
 189                val = LCD_LAYER_FORMAT_YCBCR422PLAN | LCD_LAYER_PLANAR_STORAGE
 190                    | LCD_LAYER_CRCB_ORDER;
 191                break;
 192        case DRM_FORMAT_YUV420:
 193                val = LCD_LAYER_FORMAT_YCBCR420PLAN | LCD_LAYER_PLANAR_STORAGE;
 194                break;
 195        case DRM_FORMAT_YVU420:
 196                val = LCD_LAYER_FORMAT_YCBCR420PLAN | LCD_LAYER_PLANAR_STORAGE
 197                    | LCD_LAYER_CRCB_ORDER;
 198                break;
 199        case DRM_FORMAT_NV12:
 200                val = LCD_LAYER_FORMAT_NV12 | LCD_LAYER_PLANAR_STORAGE;
 201                break;
 202        case DRM_FORMAT_NV21:
 203                val = LCD_LAYER_FORMAT_NV12 | LCD_LAYER_PLANAR_STORAGE
 204                    | LCD_LAYER_CRCB_ORDER;
 205                break;
 206                /* packed formats */
 207                /* looks hw requires B & G to be swapped when RGB */
 208        case DRM_FORMAT_RGB332:
 209                val = LCD_LAYER_FORMAT_RGB332 | LCD_LAYER_BGR_ORDER;
 210                break;
 211        case DRM_FORMAT_XBGR4444:
 212                val = LCD_LAYER_FORMAT_RGBX4444;
 213                break;
 214        case DRM_FORMAT_ARGB4444:
 215                val = LCD_LAYER_FORMAT_RGBA4444 | LCD_LAYER_BGR_ORDER;
 216                break;
 217        case DRM_FORMAT_ABGR4444:
 218                val = LCD_LAYER_FORMAT_RGBA4444;
 219                break;
 220        case DRM_FORMAT_XRGB1555:
 221                val = LCD_LAYER_FORMAT_XRGB1555 | LCD_LAYER_BGR_ORDER;
 222                break;
 223        case DRM_FORMAT_XBGR1555:
 224                val = LCD_LAYER_FORMAT_XRGB1555;
 225                break;
 226        case DRM_FORMAT_ARGB1555:
 227                val = LCD_LAYER_FORMAT_RGBA1555 | LCD_LAYER_BGR_ORDER;
 228                break;
 229        case DRM_FORMAT_ABGR1555:
 230                val = LCD_LAYER_FORMAT_RGBA1555;
 231                break;
 232        case DRM_FORMAT_RGB565:
 233                val = LCD_LAYER_FORMAT_RGB565 | LCD_LAYER_BGR_ORDER;
 234                break;
 235        case DRM_FORMAT_BGR565:
 236                val = LCD_LAYER_FORMAT_RGB565;
 237                break;
 238        case DRM_FORMAT_RGB888:
 239                val = LCD_LAYER_FORMAT_RGB888 | LCD_LAYER_BGR_ORDER;
 240                break;
 241        case DRM_FORMAT_BGR888:
 242                val = LCD_LAYER_FORMAT_RGB888;
 243                break;
 244        case DRM_FORMAT_XRGB8888:
 245                val = LCD_LAYER_FORMAT_RGBX8888 | LCD_LAYER_BGR_ORDER;
 246                break;
 247        case DRM_FORMAT_XBGR8888:
 248                val = LCD_LAYER_FORMAT_RGBX8888;
 249                break;
 250        case DRM_FORMAT_ARGB8888:
 251                val = LCD_LAYER_FORMAT_RGBA8888 | LCD_LAYER_BGR_ORDER;
 252                break;
 253        case DRM_FORMAT_ABGR8888:
 254                val = LCD_LAYER_FORMAT_RGBA8888;
 255                break;
 256        }
 257        DRM_INFO_ONCE("%s : %d format=0x%x val=0x%x\n",
 258                      __func__, __LINE__, format, val);
 259        return val;
 260}
 261
 262static unsigned int get_bits_per_pixel(const struct drm_format_info *format)
 263{
 264        u32 bpp = 0;
 265        unsigned int val = 0;
 266
 267        if (format->num_planes > 1) {
 268                val = LCD_LAYER_8BPP;
 269                return val;
 270        }
 271
 272        bpp += 8 * format->cpp[0];
 273
 274        switch (bpp) {
 275        case 8:
 276                val = LCD_LAYER_8BPP;
 277                break;
 278        case 16:
 279                val = LCD_LAYER_16BPP;
 280                break;
 281        case 24:
 282                val = LCD_LAYER_24BPP;
 283                break;
 284        case 32:
 285                val = LCD_LAYER_32BPP;
 286                break;
 287        }
 288
 289        DRM_DEBUG("bpp=%d val=0x%x\n", bpp, val);
 290        return val;
 291}
 292
 293static void config_csc(struct kmb_drm_private *kmb, int plane_id)
 294{
 295        /* YUV to RGB conversion using the fixed matrix csc_coef_lcd */
 296        kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF11(plane_id), csc_coef_lcd[0]);
 297        kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF12(plane_id), csc_coef_lcd[1]);
 298        kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF13(plane_id), csc_coef_lcd[2]);
 299        kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF21(plane_id), csc_coef_lcd[3]);
 300        kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF22(plane_id), csc_coef_lcd[4]);
 301        kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF23(plane_id), csc_coef_lcd[5]);
 302        kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF31(plane_id), csc_coef_lcd[6]);
 303        kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF32(plane_id), csc_coef_lcd[7]);
 304        kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF33(plane_id), csc_coef_lcd[8]);
 305        kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF1(plane_id), csc_coef_lcd[9]);
 306        kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF2(plane_id), csc_coef_lcd[10]);
 307        kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF3(plane_id), csc_coef_lcd[11]);
 308}
 309
 310static void kmb_plane_set_alpha(struct kmb_drm_private *kmb,
 311                                const struct drm_plane_state *state,
 312                                unsigned char plane_id,
 313                                unsigned int *val)
 314{
 315        u16 plane_alpha = state->alpha;
 316        u16 pixel_blend_mode = state->pixel_blend_mode;
 317        int has_alpha = state->fb->format->has_alpha;
 318
 319        if (plane_alpha != DRM_BLEND_ALPHA_OPAQUE)
 320                *val |= LCD_LAYER_ALPHA_STATIC;
 321
 322        if (has_alpha) {
 323                switch (pixel_blend_mode) {
 324                case DRM_MODE_BLEND_PIXEL_NONE:
 325                        break;
 326                case DRM_MODE_BLEND_PREMULTI:
 327                        *val |= LCD_LAYER_ALPHA_EMBED | LCD_LAYER_ALPHA_PREMULT;
 328                        break;
 329                case DRM_MODE_BLEND_COVERAGE:
 330                        *val |= LCD_LAYER_ALPHA_EMBED;
 331                        break;
 332                default:
 333                        DRM_DEBUG("Missing pixel blend mode case (%s == %ld)\n",
 334                                  __stringify(pixel_blend_mode),
 335                                  (long)pixel_blend_mode);
 336                        break;
 337                }
 338        }
 339
 340        if (plane_alpha == DRM_BLEND_ALPHA_OPAQUE && !has_alpha) {
 341                *val &= LCD_LAYER_ALPHA_DISABLED;
 342                return;
 343        }
 344
 345        kmb_write_lcd(kmb, LCD_LAYERn_ALPHA(plane_id), plane_alpha);
 346}
 347
 348static void kmb_plane_atomic_update(struct drm_plane *plane,
 349                                    struct drm_atomic_state *state)
 350{
 351        struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state,
 352                                                                                 plane);
 353        struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
 354                                                                                 plane);
 355        struct drm_framebuffer *fb;
 356        struct kmb_drm_private *kmb;
 357        unsigned int width;
 358        unsigned int height;
 359        unsigned int dma_len;
 360        struct kmb_plane *kmb_plane;
 361        unsigned int dma_cfg;
 362        unsigned int ctrl = 0, val = 0, out_format = 0;
 363        unsigned int src_w, src_h, crtc_x, crtc_y;
 364        unsigned char plane_id;
 365        int num_planes;
 366        static dma_addr_t addr[MAX_SUB_PLANES];
 367        struct disp_cfg *init_disp_cfg;
 368
 369        if (!plane || !new_plane_state || !old_plane_state)
 370                return;
 371
 372        fb = new_plane_state->fb;
 373        if (!fb)
 374                return;
 375
 376        num_planes = fb->format->num_planes;
 377        kmb_plane = to_kmb_plane(plane);
 378
 379        kmb = to_kmb(plane->dev);
 380        plane_id = kmb_plane->id;
 381
 382        spin_lock_irq(&kmb->irq_lock);
 383        if (kmb->kmb_under_flow || kmb->kmb_flush_done) {
 384                spin_unlock_irq(&kmb->irq_lock);
 385                drm_dbg(&kmb->drm, "plane_update:underflow!!!! returning");
 386                return;
 387        }
 388        spin_unlock_irq(&kmb->irq_lock);
 389
 390        init_disp_cfg = &kmb->init_disp_cfg[plane_id];
 391        src_w = new_plane_state->src_w >> 16;
 392        src_h = new_plane_state->src_h >> 16;
 393        crtc_x = new_plane_state->crtc_x;
 394        crtc_y = new_plane_state->crtc_y;
 395
 396        drm_dbg(&kmb->drm,
 397                "src_w=%d src_h=%d, fb->format->format=0x%x fb->flags=0x%x\n",
 398                  src_w, src_h, fb->format->format, fb->flags);
 399
 400        width = fb->width;
 401        height = fb->height;
 402        dma_len = (width * height * fb->format->cpp[0]);
 403        drm_dbg(&kmb->drm, "dma_len=%d ", dma_len);
 404        kmb_write_lcd(kmb, LCD_LAYERn_DMA_LEN(plane_id), dma_len);
 405        kmb_write_lcd(kmb, LCD_LAYERn_DMA_LEN_SHADOW(plane_id), dma_len);
 406        kmb_write_lcd(kmb, LCD_LAYERn_DMA_LINE_VSTRIDE(plane_id),
 407                      fb->pitches[0]);
 408        kmb_write_lcd(kmb, LCD_LAYERn_DMA_LINE_WIDTH(plane_id),
 409                      (width * fb->format->cpp[0]));
 410
 411        addr[Y_PLANE] = drm_fb_cma_get_gem_addr(fb, new_plane_state, 0);
 412        kmb_write_lcd(kmb, LCD_LAYERn_DMA_START_ADDR(plane_id),
 413                      addr[Y_PLANE] + fb->offsets[0]);
 414        val = get_pixel_format(fb->format->format);
 415        val |= get_bits_per_pixel(fb->format);
 416        /* Program Cb/Cr for planar formats */
 417        if (num_planes > 1) {
 418                kmb_write_lcd(kmb, LCD_LAYERn_DMA_CB_LINE_VSTRIDE(plane_id),
 419                              width * fb->format->cpp[0]);
 420                kmb_write_lcd(kmb, LCD_LAYERn_DMA_CB_LINE_WIDTH(plane_id),
 421                              (width * fb->format->cpp[0]));
 422
 423                addr[U_PLANE] = drm_fb_cma_get_gem_addr(fb, new_plane_state,
 424                                                        U_PLANE);
 425                /* check if Cb/Cr is swapped*/
 426                if (num_planes == 3 && (val & LCD_LAYER_CRCB_ORDER))
 427                        kmb_write_lcd(kmb,
 428                                      LCD_LAYERn_DMA_START_CR_ADR(plane_id),
 429                                        addr[U_PLANE]);
 430                else
 431                        kmb_write_lcd(kmb,
 432                                      LCD_LAYERn_DMA_START_CB_ADR(plane_id),
 433                                        addr[U_PLANE]);
 434
 435                if (num_planes == 3) {
 436                        kmb_write_lcd(kmb,
 437                                      LCD_LAYERn_DMA_CR_LINE_VSTRIDE(plane_id),
 438                                      ((width) * fb->format->cpp[0]));
 439
 440                        kmb_write_lcd(kmb,
 441                                      LCD_LAYERn_DMA_CR_LINE_WIDTH(plane_id),
 442                                      ((width) * fb->format->cpp[0]));
 443
 444                        addr[V_PLANE] = drm_fb_cma_get_gem_addr(fb,
 445                                                                new_plane_state,
 446                                                                V_PLANE);
 447
 448                        /* check if Cb/Cr is swapped*/
 449                        if (val & LCD_LAYER_CRCB_ORDER)
 450                                kmb_write_lcd(kmb,
 451                                              LCD_LAYERn_DMA_START_CB_ADR(plane_id),
 452                                              addr[V_PLANE]);
 453                        else
 454                                kmb_write_lcd(kmb,
 455                                              LCD_LAYERn_DMA_START_CR_ADR(plane_id),
 456                                              addr[V_PLANE]);
 457                }
 458        }
 459
 460        kmb_write_lcd(kmb, LCD_LAYERn_WIDTH(plane_id), src_w - 1);
 461        kmb_write_lcd(kmb, LCD_LAYERn_HEIGHT(plane_id), src_h - 1);
 462        kmb_write_lcd(kmb, LCD_LAYERn_COL_START(plane_id), crtc_x);
 463        kmb_write_lcd(kmb, LCD_LAYERn_ROW_START(plane_id), crtc_y);
 464
 465        val |= LCD_LAYER_FIFO_100;
 466
 467        if (val & LCD_LAYER_PLANAR_STORAGE) {
 468                val |= LCD_LAYER_CSC_EN;
 469
 470                /* Enable CSC if input is planar and output is RGB */
 471                config_csc(kmb, plane_id);
 472        }
 473
 474        kmb_plane_set_alpha(kmb, plane->state, plane_id, &val);
 475
 476        kmb_write_lcd(kmb, LCD_LAYERn_CFG(plane_id), val);
 477
 478        /* Configure LCD_CONTROL */
 479        ctrl = kmb_read_lcd(kmb, LCD_CONTROL);
 480
 481        /* Set layer blending config */
 482        ctrl &= ~LCD_CTRL_ALPHA_ALL;
 483        ctrl |= LCD_CTRL_ALPHA_BOTTOM_VL1 |
 484                LCD_CTRL_ALPHA_BLEND_VL2;
 485
 486        ctrl &= ~LCD_CTRL_ALPHA_BLEND_BKGND_DISABLE;
 487
 488        switch (plane_id) {
 489        case LAYER_0:
 490                ctrl |= LCD_CTRL_VL1_ENABLE;
 491                break;
 492        case LAYER_1:
 493                ctrl |= LCD_CTRL_VL2_ENABLE;
 494                break;
 495        case LAYER_2:
 496                ctrl |= LCD_CTRL_GL1_ENABLE;
 497                break;
 498        case LAYER_3:
 499                ctrl |= LCD_CTRL_GL2_ENABLE;
 500                break;
 501        }
 502
 503        ctrl |= LCD_CTRL_PROGRESSIVE | LCD_CTRL_TIM_GEN_ENABLE
 504            | LCD_CTRL_CONTINUOUS | LCD_CTRL_OUTPUT_ENABLED;
 505
 506        /* LCD is connected to MIPI on kmb
 507         * Therefore this bit is required for DSI Tx
 508         */
 509        ctrl |= LCD_CTRL_VHSYNC_IDLE_LVL;
 510
 511        kmb_write_lcd(kmb, LCD_CONTROL, ctrl);
 512
 513        /* Enable pipeline AXI read transactions for the DMA
 514         * after setting graphics layers. This must be done
 515         * in a separate write cycle.
 516         */
 517        kmb_set_bitmask_lcd(kmb, LCD_CONTROL, LCD_CTRL_PIPELINE_DMA);
 518
 519        /* FIXME no doc on how to set output format, these values are taken
 520         * from the Myriadx tests
 521         */
 522        out_format |= LCD_OUTF_FORMAT_RGB888;
 523
 524        /* Leave RGB order,conversion mode and clip mode to default */
 525        /* do not interleave RGB channels for mipi Tx compatibility */
 526        out_format |= LCD_OUTF_MIPI_RGB_MODE;
 527        kmb_write_lcd(kmb, LCD_OUT_FORMAT_CFG, out_format);
 528
 529        dma_cfg = LCD_DMA_LAYER_ENABLE | LCD_DMA_LAYER_VSTRIDE_EN |
 530            LCD_DMA_LAYER_CONT_UPDATE | LCD_DMA_LAYER_AXI_BURST_16;
 531
 532        /* Enable DMA */
 533        kmb_write_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id), dma_cfg);
 534
 535        /* Save initial display config */
 536        if (!init_disp_cfg->width ||
 537            !init_disp_cfg->height ||
 538            !init_disp_cfg->format) {
 539                init_disp_cfg->width = width;
 540                init_disp_cfg->height = height;
 541                init_disp_cfg->format = fb->format->format;
 542        }
 543
 544        drm_dbg(&kmb->drm, "dma_cfg=0x%x LCD_DMA_CFG=0x%x\n", dma_cfg,
 545                kmb_read_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id)));
 546
 547        kmb_set_bitmask_lcd(kmb, LCD_INT_CLEAR, LCD_INT_EOF |
 548                        LCD_INT_DMA_ERR);
 549        kmb_set_bitmask_lcd(kmb, LCD_INT_ENABLE, LCD_INT_EOF |
 550                        LCD_INT_DMA_ERR);
 551}
 552
 553static const struct drm_plane_helper_funcs kmb_plane_helper_funcs = {
 554        .atomic_check = kmb_plane_atomic_check,
 555        .atomic_update = kmb_plane_atomic_update,
 556        .atomic_disable = kmb_plane_atomic_disable
 557};
 558
 559void kmb_plane_destroy(struct drm_plane *plane)
 560{
 561        struct kmb_plane *kmb_plane = to_kmb_plane(plane);
 562
 563        drm_plane_cleanup(plane);
 564        kfree(kmb_plane);
 565}
 566
 567static const struct drm_plane_funcs kmb_plane_funcs = {
 568        .update_plane = drm_atomic_helper_update_plane,
 569        .disable_plane = drm_atomic_helper_disable_plane,
 570        .destroy = kmb_plane_destroy,
 571        .reset = drm_atomic_helper_plane_reset,
 572        .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 573        .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 574};
 575
 576struct kmb_plane *kmb_plane_init(struct drm_device *drm)
 577{
 578        struct kmb_drm_private *kmb = to_kmb(drm);
 579        struct kmb_plane *plane = NULL;
 580        struct kmb_plane *primary = NULL;
 581        int i = 0;
 582        int ret = 0;
 583        enum drm_plane_type plane_type;
 584        const u32 *plane_formats;
 585        int num_plane_formats;
 586        unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
 587                                  BIT(DRM_MODE_BLEND_PREMULTI)   |
 588                                  BIT(DRM_MODE_BLEND_COVERAGE);
 589
 590        for (i = 0; i < KMB_MAX_PLANES; i++) {
 591                plane = drmm_kzalloc(drm, sizeof(*plane), GFP_KERNEL);
 592
 593                if (!plane) {
 594                        drm_err(drm, "Failed to allocate plane\n");
 595                        return ERR_PTR(-ENOMEM);
 596                }
 597
 598                plane_type = (i == 0) ? DRM_PLANE_TYPE_PRIMARY :
 599                    DRM_PLANE_TYPE_OVERLAY;
 600                if (i < 2) {
 601                        plane_formats = kmb_formats_v;
 602                        num_plane_formats = ARRAY_SIZE(kmb_formats_v);
 603                } else {
 604                        plane_formats = kmb_formats_g;
 605                        num_plane_formats = ARRAY_SIZE(kmb_formats_g);
 606                }
 607
 608                ret = drm_universal_plane_init(drm, &plane->base_plane,
 609                                               POSSIBLE_CRTCS, &kmb_plane_funcs,
 610                                               plane_formats, num_plane_formats,
 611                                               NULL, plane_type, "plane %d", i);
 612                if (ret < 0) {
 613                        drm_err(drm, "drm_universal_plane_init failed (ret=%d)",
 614                                ret);
 615                        goto cleanup;
 616                }
 617                drm_dbg(drm, "%s : %d i=%d type=%d",
 618                        __func__, __LINE__,
 619                          i, plane_type);
 620                drm_plane_create_alpha_property(&plane->base_plane);
 621
 622                drm_plane_create_blend_mode_property(&plane->base_plane,
 623                                                     blend_caps);
 624
 625                drm_plane_create_zpos_immutable_property(&plane->base_plane, i);
 626
 627                drm_plane_helper_add(&plane->base_plane,
 628                                     &kmb_plane_helper_funcs);
 629
 630                if (plane_type == DRM_PLANE_TYPE_PRIMARY) {
 631                        primary = plane;
 632                        kmb->plane = plane;
 633                }
 634                drm_dbg(drm, "%s : %d primary=%p\n", __func__, __LINE__,
 635                        &primary->base_plane);
 636                plane->id = i;
 637        }
 638
 639        /* Disable pipeline AXI read transactions for the DMA
 640         * prior to setting graphics layers
 641         */
 642        kmb_clr_bitmask_lcd(kmb, LCD_CONTROL, LCD_CTRL_PIPELINE_DMA);
 643
 644        return primary;
 645cleanup:
 646        drmm_kfree(drm, plane);
 647        return ERR_PTR(ret);
 648}
 649