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        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                /* planar formats */
 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                /* packed formats */
 177                /* looks hw requires B & G to be swapped when RGB */
 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        /* YUV to RGB conversion using the fixed matrix csc_coef_lcd */
 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        /* Program Cb/Cr for planar formats */
 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                /* check if Cb/Cr is swapped*/
 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                        /* check if Cb/Cr is swapped*/
 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                /* Enable CSC if input is planar and output is RGB */
 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        /* LCD is connected to MIPI on kmb
 424         * Therefore this bit is required for DSI Tx
 425         */
 426        ctrl |= LCD_CTRL_VHSYNC_IDLE_LVL;
 427
 428        kmb_set_bitmask_lcd(kmb, LCD_CONTROL, ctrl);
 429
 430        /* FIXME no doc on how to set output format,these values are
 431         * taken from the Myriadx tests
 432         */
 433        out_format |= LCD_OUTF_FORMAT_RGB888;
 434
 435        /* Leave RGB order,conversion mode and clip mode to default */
 436        /* do not interleave RGB channels for mipi Tx compatibility */
 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        /* Enable DMA */
 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