linux/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
   4 * Author: James.Qian.Wang <james.qian.wang@arm.com>
   5 *
   6 */
   7
   8#include <drm/drm_print.h>
   9#include "d71_dev.h"
  10#include "malidp_io.h"
  11
  12static u64 get_lpu_event(struct d71_pipeline *d71_pipeline)
  13{
  14        u32 __iomem *reg = d71_pipeline->lpu_addr;
  15        u32 status, raw_status;
  16        u64 evts = 0ULL;
  17
  18        raw_status = malidp_read32(reg, BLK_IRQ_RAW_STATUS);
  19        if (raw_status & LPU_IRQ_IBSY)
  20                evts |= KOMEDA_EVENT_IBSY;
  21        if (raw_status & LPU_IRQ_EOW)
  22                evts |= KOMEDA_EVENT_EOW;
  23        if (raw_status & LPU_IRQ_OVR)
  24                evts |= KOMEDA_EVENT_OVR;
  25
  26        if (raw_status & (LPU_IRQ_ERR | LPU_IRQ_IBSY | LPU_IRQ_OVR)) {
  27                u32 restore = 0, tbu_status;
  28                /* Check error of LPU status */
  29                status = malidp_read32(reg, BLK_STATUS);
  30                if (status & LPU_STATUS_AXIE) {
  31                        restore |= LPU_STATUS_AXIE;
  32                        evts |= KOMEDA_ERR_AXIE;
  33                }
  34                if (status & LPU_STATUS_ACE0) {
  35                        restore |= LPU_STATUS_ACE0;
  36                        evts |= KOMEDA_ERR_ACE0;
  37                }
  38                if (status & LPU_STATUS_ACE1) {
  39                        restore |= LPU_STATUS_ACE1;
  40                        evts |= KOMEDA_ERR_ACE1;
  41                }
  42                if (status & LPU_STATUS_ACE2) {
  43                        restore |= LPU_STATUS_ACE2;
  44                        evts |= KOMEDA_ERR_ACE2;
  45                }
  46                if (status & LPU_STATUS_ACE3) {
  47                        restore |= LPU_STATUS_ACE3;
  48                        evts |= KOMEDA_ERR_ACE3;
  49                }
  50                if (status & LPU_STATUS_FEMPTY) {
  51                        restore |= LPU_STATUS_FEMPTY;
  52                        evts |= KOMEDA_EVENT_EMPTY;
  53                }
  54                if (status & LPU_STATUS_FFULL) {
  55                        restore |= LPU_STATUS_FFULL;
  56                        evts |= KOMEDA_EVENT_FULL;
  57                }
  58
  59                if (restore != 0)
  60                        malidp_write32_mask(reg, BLK_STATUS, restore, 0);
  61
  62                restore = 0;
  63                /* Check errors of TBU status */
  64                tbu_status = malidp_read32(reg, LPU_TBU_STATUS);
  65                if (tbu_status & LPU_TBU_STATUS_TCF) {
  66                        restore |= LPU_TBU_STATUS_TCF;
  67                        evts |= KOMEDA_ERR_TCF;
  68                }
  69                if (tbu_status & LPU_TBU_STATUS_TTNG) {
  70                        restore |= LPU_TBU_STATUS_TTNG;
  71                        evts |= KOMEDA_ERR_TTNG;
  72                }
  73                if (tbu_status & LPU_TBU_STATUS_TITR) {
  74                        restore |= LPU_TBU_STATUS_TITR;
  75                        evts |= KOMEDA_ERR_TITR;
  76                }
  77                if (tbu_status & LPU_TBU_STATUS_TEMR) {
  78                        restore |= LPU_TBU_STATUS_TEMR;
  79                        evts |= KOMEDA_ERR_TEMR;
  80                }
  81                if (tbu_status & LPU_TBU_STATUS_TTF) {
  82                        restore |= LPU_TBU_STATUS_TTF;
  83                        evts |= KOMEDA_ERR_TTF;
  84                }
  85                if (restore != 0)
  86                        malidp_write32_mask(reg, LPU_TBU_STATUS, restore, 0);
  87        }
  88
  89        malidp_write32(reg, BLK_IRQ_CLEAR, raw_status);
  90        return evts;
  91}
  92
  93static u64 get_cu_event(struct d71_pipeline *d71_pipeline)
  94{
  95        u32 __iomem *reg = d71_pipeline->cu_addr;
  96        u32 status, raw_status;
  97        u64 evts = 0ULL;
  98
  99        raw_status = malidp_read32(reg, BLK_IRQ_RAW_STATUS);
 100        if (raw_status & CU_IRQ_OVR)
 101                evts |= KOMEDA_EVENT_OVR;
 102
 103        if (raw_status & (CU_IRQ_ERR | CU_IRQ_OVR)) {
 104                status = malidp_read32(reg, BLK_STATUS) & 0x7FFFFFFF;
 105                if (status & CU_STATUS_CPE)
 106                        evts |= KOMEDA_ERR_CPE;
 107                if (status & CU_STATUS_ZME)
 108                        evts |= KOMEDA_ERR_ZME;
 109                if (status & CU_STATUS_CFGE)
 110                        evts |= KOMEDA_ERR_CFGE;
 111                if (status)
 112                        malidp_write32_mask(reg, BLK_STATUS, status, 0);
 113        }
 114
 115        malidp_write32(reg, BLK_IRQ_CLEAR, raw_status);
 116
 117        return evts;
 118}
 119
 120static u64 get_dou_event(struct d71_pipeline *d71_pipeline)
 121{
 122        u32 __iomem *reg = d71_pipeline->dou_addr;
 123        u32 status, raw_status;
 124        u64 evts = 0ULL;
 125
 126        raw_status = malidp_read32(reg, BLK_IRQ_RAW_STATUS);
 127        if (raw_status & DOU_IRQ_PL0)
 128                evts |= KOMEDA_EVENT_VSYNC;
 129        if (raw_status & DOU_IRQ_UND)
 130                evts |= KOMEDA_EVENT_URUN;
 131
 132        if (raw_status & (DOU_IRQ_ERR | DOU_IRQ_UND)) {
 133                u32 restore  = 0;
 134
 135                status = malidp_read32(reg, BLK_STATUS);
 136                if (status & DOU_STATUS_DRIFTTO) {
 137                        restore |= DOU_STATUS_DRIFTTO;
 138                        evts |= KOMEDA_ERR_DRIFTTO;
 139                }
 140                if (status & DOU_STATUS_FRAMETO) {
 141                        restore |= DOU_STATUS_FRAMETO;
 142                        evts |= KOMEDA_ERR_FRAMETO;
 143                }
 144                if (status & DOU_STATUS_TETO) {
 145                        restore |= DOU_STATUS_TETO;
 146                        evts |= KOMEDA_ERR_TETO;
 147                }
 148                if (status & DOU_STATUS_CSCE) {
 149                        restore |= DOU_STATUS_CSCE;
 150                        evts |= KOMEDA_ERR_CSCE;
 151                }
 152
 153                if (restore != 0)
 154                        malidp_write32_mask(reg, BLK_STATUS, restore, 0);
 155        }
 156
 157        malidp_write32(reg, BLK_IRQ_CLEAR, raw_status);
 158        return evts;
 159}
 160
 161static u64 get_pipeline_event(struct d71_pipeline *d71_pipeline, u32 gcu_status)
 162{
 163        u32 evts = 0ULL;
 164
 165        if (gcu_status & (GLB_IRQ_STATUS_LPU0 | GLB_IRQ_STATUS_LPU1))
 166                evts |= get_lpu_event(d71_pipeline);
 167
 168        if (gcu_status & (GLB_IRQ_STATUS_CU0 | GLB_IRQ_STATUS_CU1))
 169                evts |= get_cu_event(d71_pipeline);
 170
 171        if (gcu_status & (GLB_IRQ_STATUS_DOU0 | GLB_IRQ_STATUS_DOU1))
 172                evts |= get_dou_event(d71_pipeline);
 173
 174        return evts;
 175}
 176
 177static irqreturn_t
 178d71_irq_handler(struct komeda_dev *mdev, struct komeda_events *evts)
 179{
 180        struct d71_dev *d71 = mdev->chip_data;
 181        u32 status, gcu_status, raw_status;
 182
 183        gcu_status = malidp_read32(d71->gcu_addr, GLB_IRQ_STATUS);
 184
 185        if (gcu_status & GLB_IRQ_STATUS_GCU) {
 186                raw_status = malidp_read32(d71->gcu_addr, BLK_IRQ_RAW_STATUS);
 187                if (raw_status & GCU_IRQ_CVAL0)
 188                        evts->pipes[0] |= KOMEDA_EVENT_FLIP;
 189                if (raw_status & GCU_IRQ_CVAL1)
 190                        evts->pipes[1] |= KOMEDA_EVENT_FLIP;
 191                if (raw_status & GCU_IRQ_ERR) {
 192                        status = malidp_read32(d71->gcu_addr, BLK_STATUS);
 193                        if (status & GCU_STATUS_MERR) {
 194                                evts->global |= KOMEDA_ERR_MERR;
 195                                malidp_write32_mask(d71->gcu_addr, BLK_STATUS,
 196                                                    GCU_STATUS_MERR, 0);
 197                        }
 198                }
 199
 200                malidp_write32(d71->gcu_addr, BLK_IRQ_CLEAR, raw_status);
 201        }
 202
 203        if (gcu_status & GLB_IRQ_STATUS_PIPE0)
 204                evts->pipes[0] |= get_pipeline_event(d71->pipes[0], gcu_status);
 205
 206        if (gcu_status & GLB_IRQ_STATUS_PIPE1)
 207                evts->pipes[1] |= get_pipeline_event(d71->pipes[1], gcu_status);
 208
 209        return IRQ_RETVAL(gcu_status);
 210}
 211
 212#define ENABLED_GCU_IRQS        (GCU_IRQ_CVAL0 | GCU_IRQ_CVAL1 | \
 213                                 GCU_IRQ_MODE | GCU_IRQ_ERR)
 214#define ENABLED_LPU_IRQS        (LPU_IRQ_IBSY | LPU_IRQ_ERR | LPU_IRQ_EOW)
 215#define ENABLED_CU_IRQS         (CU_IRQ_OVR | CU_IRQ_ERR)
 216#define ENABLED_DOU_IRQS        (DOU_IRQ_UND | DOU_IRQ_ERR)
 217
 218static int d71_enable_irq(struct komeda_dev *mdev)
 219{
 220        struct d71_dev *d71 = mdev->chip_data;
 221        struct d71_pipeline *pipe;
 222        u32 i;
 223
 224        malidp_write32_mask(d71->gcu_addr, BLK_IRQ_MASK,
 225                            ENABLED_GCU_IRQS, ENABLED_GCU_IRQS);
 226        for (i = 0; i < d71->num_pipelines; i++) {
 227                pipe = d71->pipes[i];
 228                malidp_write32_mask(pipe->cu_addr,  BLK_IRQ_MASK,
 229                                    ENABLED_CU_IRQS, ENABLED_CU_IRQS);
 230                malidp_write32_mask(pipe->lpu_addr, BLK_IRQ_MASK,
 231                                    ENABLED_LPU_IRQS, ENABLED_LPU_IRQS);
 232                malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK,
 233                                    ENABLED_DOU_IRQS, ENABLED_DOU_IRQS);
 234        }
 235        return 0;
 236}
 237
 238static int d71_disable_irq(struct komeda_dev *mdev)
 239{
 240        struct d71_dev *d71 = mdev->chip_data;
 241        struct d71_pipeline *pipe;
 242        u32 i;
 243
 244        malidp_write32_mask(d71->gcu_addr, BLK_IRQ_MASK, ENABLED_GCU_IRQS, 0);
 245        for (i = 0; i < d71->num_pipelines; i++) {
 246                pipe = d71->pipes[i];
 247                malidp_write32_mask(pipe->cu_addr,  BLK_IRQ_MASK,
 248                                    ENABLED_CU_IRQS, 0);
 249                malidp_write32_mask(pipe->lpu_addr, BLK_IRQ_MASK,
 250                                    ENABLED_LPU_IRQS, 0);
 251                malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK,
 252                                    ENABLED_DOU_IRQS, 0);
 253        }
 254        return 0;
 255}
 256
 257static void d71_on_off_vblank(struct komeda_dev *mdev, int master_pipe, bool on)
 258{
 259        struct d71_dev *d71 = mdev->chip_data;
 260        struct d71_pipeline *pipe = d71->pipes[master_pipe];
 261
 262        malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK,
 263                            DOU_IRQ_PL0, on ? DOU_IRQ_PL0 : 0);
 264}
 265
 266static int to_d71_opmode(int core_mode)
 267{
 268        switch (core_mode) {
 269        case KOMEDA_MODE_DISP0:
 270                return DO0_ACTIVE_MODE;
 271        case KOMEDA_MODE_DISP1:
 272                return DO1_ACTIVE_MODE;
 273        case KOMEDA_MODE_DUAL_DISP:
 274                return DO01_ACTIVE_MODE;
 275        case KOMEDA_MODE_INACTIVE:
 276                return INACTIVE_MODE;
 277        default:
 278                WARN(1, "Unknown operation mode");
 279                return INACTIVE_MODE;
 280        }
 281}
 282
 283static int d71_change_opmode(struct komeda_dev *mdev, int new_mode)
 284{
 285        struct d71_dev *d71 = mdev->chip_data;
 286        u32 opmode = to_d71_opmode(new_mode);
 287        int ret;
 288
 289        malidp_write32_mask(d71->gcu_addr, BLK_CONTROL, 0x7, opmode);
 290
 291        ret = dp_wait_cond(((malidp_read32(d71->gcu_addr, BLK_CONTROL) & 0x7) == opmode),
 292                           100, 1000, 10000);
 293
 294        return ret;
 295}
 296
 297static void d71_flush(struct komeda_dev *mdev,
 298                      int master_pipe, u32 active_pipes)
 299{
 300        struct d71_dev *d71 = mdev->chip_data;
 301        u32 reg_offset = (master_pipe == 0) ?
 302                         GCU_CONFIG_VALID0 : GCU_CONFIG_VALID1;
 303
 304        malidp_write32(d71->gcu_addr, reg_offset, GCU_CONFIG_CVAL);
 305}
 306
 307static int d71_reset(struct d71_dev *d71)
 308{
 309        u32 __iomem *gcu = d71->gcu_addr;
 310        int ret;
 311
 312        malidp_write32_mask(gcu, BLK_CONTROL,
 313                            GCU_CONTROL_SRST, GCU_CONTROL_SRST);
 314
 315        ret = dp_wait_cond(!(malidp_read32(gcu, BLK_CONTROL) & GCU_CONTROL_SRST),
 316                           100, 1000, 10000);
 317
 318        return ret;
 319}
 320
 321void d71_read_block_header(u32 __iomem *reg, struct block_header *blk)
 322{
 323        int i;
 324
 325        blk->block_info = malidp_read32(reg, BLK_BLOCK_INFO);
 326        if (BLOCK_INFO_BLK_TYPE(blk->block_info) == D71_BLK_TYPE_RESERVED)
 327                return;
 328
 329        blk->pipeline_info = malidp_read32(reg, BLK_PIPELINE_INFO);
 330
 331        /* get valid input and output ids */
 332        for (i = 0; i < PIPELINE_INFO_N_VALID_INPUTS(blk->pipeline_info); i++)
 333                blk->input_ids[i] = malidp_read32(reg + i, BLK_VALID_INPUT_ID0);
 334        for (i = 0; i < PIPELINE_INFO_N_OUTPUTS(blk->pipeline_info); i++)
 335                blk->output_ids[i] = malidp_read32(reg + i, BLK_OUTPUT_ID0);
 336}
 337
 338static void d71_cleanup(struct komeda_dev *mdev)
 339{
 340        struct d71_dev *d71 = mdev->chip_data;
 341
 342        if (!d71)
 343                return;
 344
 345        devm_kfree(mdev->dev, d71);
 346        mdev->chip_data = NULL;
 347}
 348
 349static int d71_enum_resources(struct komeda_dev *mdev)
 350{
 351        struct d71_dev *d71;
 352        struct komeda_pipeline *pipe;
 353        struct block_header blk;
 354        u32 __iomem *blk_base;
 355        u32 i, value, offset;
 356        int err;
 357
 358        d71 = devm_kzalloc(mdev->dev, sizeof(*d71), GFP_KERNEL);
 359        if (!d71)
 360                return -ENOMEM;
 361
 362        mdev->chip_data = d71;
 363        d71->mdev = mdev;
 364        d71->gcu_addr = mdev->reg_base;
 365        d71->periph_addr = mdev->reg_base + (D71_BLOCK_OFFSET_PERIPH >> 2);
 366
 367        err = d71_reset(d71);
 368        if (err) {
 369                DRM_ERROR("Fail to reset d71 device.\n");
 370                goto err_cleanup;
 371        }
 372
 373        /* probe GCU */
 374        value = malidp_read32(d71->gcu_addr, GLB_CORE_INFO);
 375        d71->num_blocks = value & 0xFF;
 376        d71->num_pipelines = (value >> 8) & 0x7;
 377
 378        if (d71->num_pipelines > D71_MAX_PIPELINE) {
 379                DRM_ERROR("d71 supports %d pipelines, but got: %d.\n",
 380                          D71_MAX_PIPELINE, d71->num_pipelines);
 381                err = -EINVAL;
 382                goto err_cleanup;
 383        }
 384
 385        /* Only the legacy HW has the periph block, the newer merges the periph
 386         * into GCU
 387         */
 388        value = malidp_read32(d71->periph_addr, BLK_BLOCK_INFO);
 389        if (BLOCK_INFO_BLK_TYPE(value) != D71_BLK_TYPE_PERIPH)
 390                d71->periph_addr = NULL;
 391
 392        if (d71->periph_addr) {
 393                /* probe PERIPHERAL in legacy HW */
 394                value = malidp_read32(d71->periph_addr, PERIPH_CONFIGURATION_ID);
 395
 396                d71->max_line_size      = value & PERIPH_MAX_LINE_SIZE ? 4096 : 2048;
 397                d71->max_vsize          = 4096;
 398                d71->num_rich_layers    = value & PERIPH_NUM_RICH_LAYERS ? 2 : 1;
 399                d71->supports_dual_link = !!(value & PERIPH_SPLIT_EN);
 400                d71->integrates_tbu     = !!(value & PERIPH_TBU_EN);
 401        } else {
 402                value = malidp_read32(d71->gcu_addr, GCU_CONFIGURATION_ID0);
 403                d71->max_line_size      = GCU_MAX_LINE_SIZE(value);
 404                d71->max_vsize          = GCU_MAX_NUM_LINES(value);
 405
 406                value = malidp_read32(d71->gcu_addr, GCU_CONFIGURATION_ID1);
 407                d71->num_rich_layers    = GCU_NUM_RICH_LAYERS(value);
 408                d71->supports_dual_link = GCU_DISPLAY_SPLIT_EN(value);
 409                d71->integrates_tbu     = GCU_DISPLAY_TBU_EN(value);
 410        }
 411
 412        for (i = 0; i < d71->num_pipelines; i++) {
 413                pipe = komeda_pipeline_add(mdev, sizeof(struct d71_pipeline),
 414                                           &d71_pipeline_funcs);
 415                if (IS_ERR(pipe)) {
 416                        err = PTR_ERR(pipe);
 417                        goto err_cleanup;
 418                }
 419
 420                /* D71 HW doesn't update shadow registers when display output
 421                 * is turning off, so when we disable all pipeline components
 422                 * together with display output disable by one flush or one
 423                 * operation, the disable operation updated registers will not
 424                 * be flush to or valid in HW, which may leads problem.
 425                 * To workaround this problem, introduce a two phase disable.
 426                 * Phase1: Disabling components with display is on to make sure
 427                 *         the disable can be flushed to HW.
 428                 * Phase2: Only turn-off display output.
 429                 */
 430                value = KOMEDA_PIPELINE_IMPROCS |
 431                        BIT(KOMEDA_COMPONENT_TIMING_CTRLR);
 432
 433                pipe->standalone_disabled_comps = value;
 434
 435                d71->pipes[i] = to_d71_pipeline(pipe);
 436        }
 437
 438        /* loop the register blks and probe.
 439         * NOTE: d71->num_blocks includes reserved blocks.
 440         * d71->num_blocks = GCU + valid blocks + reserved blocks
 441         */
 442        i = 1; /* exclude GCU */
 443        offset = D71_BLOCK_SIZE; /* skip GCU */
 444        while (i < d71->num_blocks) {
 445                blk_base = mdev->reg_base + (offset >> 2);
 446
 447                d71_read_block_header(blk_base, &blk);
 448                if (BLOCK_INFO_BLK_TYPE(blk.block_info) != D71_BLK_TYPE_RESERVED) {
 449                        err = d71_probe_block(d71, &blk, blk_base);
 450                        if (err)
 451                                goto err_cleanup;
 452                }
 453
 454                i++;
 455                offset += D71_BLOCK_SIZE;
 456        }
 457
 458        DRM_DEBUG("total %d (out of %d) blocks are found.\n",
 459                  i, d71->num_blocks);
 460
 461        return 0;
 462
 463err_cleanup:
 464        d71_cleanup(mdev);
 465        return err;
 466}
 467
 468#define __HW_ID(__group, __format) \
 469        ((((__group) & 0x7) << 3) | ((__format) & 0x7))
 470
 471#define RICH            KOMEDA_FMT_RICH_LAYER
 472#define SIMPLE          KOMEDA_FMT_SIMPLE_LAYER
 473#define RICH_SIMPLE     (KOMEDA_FMT_RICH_LAYER | KOMEDA_FMT_SIMPLE_LAYER)
 474#define RICH_WB         (KOMEDA_FMT_RICH_LAYER | KOMEDA_FMT_WB_LAYER)
 475#define RICH_SIMPLE_WB  (RICH_SIMPLE | KOMEDA_FMT_WB_LAYER)
 476
 477#define Rot_0           DRM_MODE_ROTATE_0
 478#define Flip_H_V        (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y | Rot_0)
 479#define Rot_ALL_H_V     (DRM_MODE_ROTATE_MASK | Flip_H_V)
 480
 481#define LYT_NM          BIT(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16)
 482#define LYT_WB          BIT(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8)
 483#define LYT_NM_WB       (LYT_NM | LYT_WB)
 484
 485#define AFB_TH          AFBC(_TILED | _SPARSE)
 486#define AFB_TH_SC_YTR   AFBC(_TILED | _SC | _SPARSE | _YTR)
 487#define AFB_TH_SC_YTR_BS AFBC(_TILED | _SC | _SPARSE | _YTR | _SPLIT)
 488
 489static struct komeda_format_caps d71_format_caps_table[] = {
 490        /*   HW_ID    |        fourcc         |   layer_types |   rots    | afbc_layouts | afbc_features */
 491        /* ABGR_2101010*/
 492        {__HW_ID(0, 0), DRM_FORMAT_ARGB2101010, RICH_SIMPLE_WB, Flip_H_V,               0, 0},
 493        {__HW_ID(0, 1), DRM_FORMAT_ABGR2101010, RICH_SIMPLE_WB, Flip_H_V,               0, 0},
 494        {__HW_ID(0, 1), DRM_FORMAT_ABGR2101010, RICH_SIMPLE,    Rot_ALL_H_V,    LYT_NM_WB, AFB_TH_SC_YTR_BS}, /* afbc */
 495        {__HW_ID(0, 2), DRM_FORMAT_RGBA1010102, RICH_SIMPLE_WB, Flip_H_V,               0, 0},
 496        {__HW_ID(0, 3), DRM_FORMAT_BGRA1010102, RICH_SIMPLE_WB, Flip_H_V,               0, 0},
 497        /* ABGR_8888*/
 498        {__HW_ID(1, 0), DRM_FORMAT_ARGB8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
 499        {__HW_ID(1, 1), DRM_FORMAT_ABGR8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
 500        {__HW_ID(1, 1), DRM_FORMAT_ABGR8888,    RICH_SIMPLE,    Rot_ALL_H_V,    LYT_NM_WB, AFB_TH_SC_YTR_BS}, /* afbc */
 501        {__HW_ID(1, 2), DRM_FORMAT_RGBA8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
 502        {__HW_ID(1, 3), DRM_FORMAT_BGRA8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
 503        /* XBGB_8888 */
 504        {__HW_ID(2, 0), DRM_FORMAT_XRGB8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
 505        {__HW_ID(2, 1), DRM_FORMAT_XBGR8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
 506        {__HW_ID(2, 2), DRM_FORMAT_RGBX8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
 507        {__HW_ID(2, 3), DRM_FORMAT_BGRX8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
 508        /* BGR_888 */ /* none-afbc RGB888 doesn't support rotation and flip */
 509        {__HW_ID(3, 0), DRM_FORMAT_RGB888,      RICH_SIMPLE_WB, Rot_0,                  0, 0},
 510        {__HW_ID(3, 1), DRM_FORMAT_BGR888,      RICH_SIMPLE_WB, Rot_0,                  0, 0},
 511        {__HW_ID(3, 1), DRM_FORMAT_BGR888,      RICH_SIMPLE,    Rot_ALL_H_V,    LYT_NM_WB, AFB_TH_SC_YTR_BS}, /* afbc */
 512        /* BGR 16bpp */
 513        {__HW_ID(4, 0), DRM_FORMAT_RGBA5551,    RICH_SIMPLE,    Flip_H_V,               0, 0},
 514        {__HW_ID(4, 1), DRM_FORMAT_ABGR1555,    RICH_SIMPLE,    Flip_H_V,               0, 0},
 515        {__HW_ID(4, 1), DRM_FORMAT_ABGR1555,    RICH_SIMPLE,    Rot_ALL_H_V,    LYT_NM_WB, AFB_TH_SC_YTR}, /* afbc */
 516        {__HW_ID(4, 2), DRM_FORMAT_RGB565,      RICH_SIMPLE,    Flip_H_V,               0, 0},
 517        {__HW_ID(4, 3), DRM_FORMAT_BGR565,      RICH_SIMPLE,    Flip_H_V,               0, 0},
 518        {__HW_ID(4, 3), DRM_FORMAT_BGR565,      RICH_SIMPLE,    Rot_ALL_H_V,    LYT_NM_WB, AFB_TH_SC_YTR}, /* afbc */
 519        {__HW_ID(4, 4), DRM_FORMAT_R8,          SIMPLE,         Rot_0,                  0, 0},
 520        /* YUV 444/422/420 8bit  */
 521        {__HW_ID(5, 1), DRM_FORMAT_YUYV,        RICH,           Rot_ALL_H_V,    LYT_NM, AFB_TH}, /* afbc */
 522        {__HW_ID(5, 2), DRM_FORMAT_YUYV,        RICH,           Flip_H_V,               0, 0},
 523        {__HW_ID(5, 3), DRM_FORMAT_UYVY,        RICH,           Flip_H_V,               0, 0},
 524        {__HW_ID(5, 6), DRM_FORMAT_NV12,        RICH,           Flip_H_V,               0, 0},
 525        {__HW_ID(5, 6), DRM_FORMAT_YUV420_8BIT, RICH,           Rot_ALL_H_V,    LYT_NM, AFB_TH}, /* afbc */
 526        {__HW_ID(5, 7), DRM_FORMAT_YUV420,      RICH,           Flip_H_V,               0, 0},
 527        /* YUV 10bit*/
 528        {__HW_ID(6, 6), DRM_FORMAT_X0L2,        RICH,           Flip_H_V,               0, 0},
 529        {__HW_ID(6, 7), DRM_FORMAT_P010,        RICH,           Flip_H_V,               0, 0},
 530        {__HW_ID(6, 7), DRM_FORMAT_YUV420_10BIT, RICH,          Rot_ALL_H_V,    LYT_NM, AFB_TH},
 531};
 532
 533static bool d71_format_mod_supported(const struct komeda_format_caps *caps,
 534                                     u32 layer_type, u64 modifier, u32 rot)
 535{
 536        uint64_t layout = modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK;
 537
 538        if ((layout == AFBC_FORMAT_MOD_BLOCK_SIZE_32x8) &&
 539            drm_rotation_90_or_270(rot)) {
 540                DRM_DEBUG_ATOMIC("D71 doesn't support ROT90 for WB-AFBC.\n");
 541                return false;
 542        }
 543
 544        return true;
 545}
 546
 547static void d71_init_fmt_tbl(struct komeda_dev *mdev)
 548{
 549        struct komeda_format_caps_table *table = &mdev->fmt_tbl;
 550
 551        table->format_caps = d71_format_caps_table;
 552        table->format_mod_supported = d71_format_mod_supported;
 553        table->n_formats = ARRAY_SIZE(d71_format_caps_table);
 554}
 555
 556static int d71_connect_iommu(struct komeda_dev *mdev)
 557{
 558        struct d71_dev *d71 = mdev->chip_data;
 559        u32 __iomem *reg = d71->gcu_addr;
 560        u32 check_bits = (d71->num_pipelines == 2) ?
 561                         GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
 562        int i, ret;
 563
 564        if (!d71->integrates_tbu)
 565                return -1;
 566
 567        malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_CONNECT_MODE);
 568
 569        ret = dp_wait_cond(has_bits(check_bits, malidp_read32(reg, BLK_STATUS)),
 570                        100, 1000, 1000);
 571        if (ret < 0) {
 572                DRM_ERROR("timed out connecting to TCU!\n");
 573                malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
 574                return ret;
 575        }
 576
 577        for (i = 0; i < d71->num_pipelines; i++)
 578                malidp_write32_mask(d71->pipes[i]->lpu_addr, LPU_TBU_CONTROL,
 579                                    LPU_TBU_CTRL_TLBPEN, LPU_TBU_CTRL_TLBPEN);
 580        return 0;
 581}
 582
 583static int d71_disconnect_iommu(struct komeda_dev *mdev)
 584{
 585        struct d71_dev *d71 = mdev->chip_data;
 586        u32 __iomem *reg = d71->gcu_addr;
 587        u32 check_bits = (d71->num_pipelines == 2) ?
 588                         GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
 589        int ret;
 590
 591        malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_DISCONNECT_MODE);
 592
 593        ret = dp_wait_cond(((malidp_read32(reg, BLK_STATUS) & check_bits) == 0),
 594                        100, 1000, 1000);
 595        if (ret < 0) {
 596                DRM_ERROR("timed out disconnecting from TCU!\n");
 597                malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
 598        }
 599
 600        return ret;
 601}
 602
 603static const struct komeda_dev_funcs d71_chip_funcs = {
 604        .init_format_table      = d71_init_fmt_tbl,
 605        .enum_resources         = d71_enum_resources,
 606        .cleanup                = d71_cleanup,
 607        .irq_handler            = d71_irq_handler,
 608        .enable_irq             = d71_enable_irq,
 609        .disable_irq            = d71_disable_irq,
 610        .on_off_vblank          = d71_on_off_vblank,
 611        .change_opmode          = d71_change_opmode,
 612        .flush                  = d71_flush,
 613        .connect_iommu          = d71_connect_iommu,
 614        .disconnect_iommu       = d71_disconnect_iommu,
 615        .dump_register          = d71_dump,
 616};
 617
 618const struct komeda_dev_funcs *
 619d71_identify(u32 __iomem *reg_base, struct komeda_chip_info *chip)
 620{
 621        const struct komeda_dev_funcs *funcs;
 622        u32 product_id;
 623
 624        chip->core_id = malidp_read32(reg_base, GLB_CORE_ID);
 625
 626        product_id = MALIDP_CORE_ID_PRODUCT_ID(chip->core_id);
 627
 628        switch (product_id) {
 629        case MALIDP_D71_PRODUCT_ID:
 630        case MALIDP_D32_PRODUCT_ID:
 631                funcs = &d71_chip_funcs;
 632                break;
 633        default:
 634                DRM_ERROR("Unsupported product: 0x%x\n", product_id);
 635                return NULL;
 636        }
 637
 638        chip->arch_id   = malidp_read32(reg_base, GLB_ARCH_ID);
 639        chip->core_info = malidp_read32(reg_base, GLB_CORE_INFO);
 640        chip->bus_width = D71_BUS_WIDTH_16_BYTES;
 641
 642        return funcs;
 643}
 644