linux/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
   3 */
   4
   5#define pr_fmt(fmt)     "[drm:%s:%d] " fmt, __func__, __LINE__
   6#include <linux/slab.h>
   7#include <linux/of_address.h>
   8#include <linux/platform_device.h>
   9#include "dpu_hw_mdss.h"
  10#include "dpu_hw_catalog.h"
  11#include "dpu_hw_catalog_format.h"
  12#include "dpu_kms.h"
  13
  14#define VIG_SDM845_MASK \
  15        (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_SCALER_QSEED3) | BIT(DPU_SSPP_QOS) |\
  16        BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_QOS_8LVL) |\
  17        BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT))
  18
  19#define DMA_SDM845_MASK \
  20        (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
  21        BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
  22        BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
  23
  24#define DMA_CURSOR_SDM845_MASK \
  25        (DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
  26
  27#define MIXER_SDM845_MASK \
  28        (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER))
  29
  30#define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER)
  31
  32#define PINGPONG_SDM845_SPLIT_MASK \
  33        (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
  34
  35#define DEFAULT_PIXEL_RAM_SIZE          (50 * 1024)
  36#define DEFAULT_DPU_LINE_WIDTH          2048
  37#define DEFAULT_DPU_OUTPUT_LINE_WIDTH   2560
  38
  39#define MAX_HORZ_DECIMATION     4
  40#define MAX_VERT_DECIMATION     4
  41
  42#define MAX_UPSCALE_RATIO       20
  43#define MAX_DOWNSCALE_RATIO     4
  44#define SSPP_UNITY_SCALE        1
  45
  46#define STRCAT(X, Y) (X Y)
  47
  48/*************************************************************
  49 * DPU sub blocks config
  50 *************************************************************/
  51/* DPU top level caps */
  52static const struct dpu_caps sdm845_dpu_caps = {
  53        .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
  54        .max_mixer_blendstages = 0xb,
  55        .qseed_type = DPU_SSPP_SCALER_QSEED3,
  56        .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
  57        .ubwc_version = DPU_HW_UBWC_VER_20,
  58        .has_src_split = true,
  59        .has_dim_layer = true,
  60        .has_idle_pc = true,
  61};
  62
  63static struct dpu_mdp_cfg sdm845_mdp[] = {
  64        {
  65        .name = "top_0", .id = MDP_TOP,
  66        .base = 0x0, .len = 0x45C,
  67        .features = 0,
  68        .highest_bank_bit = 0x2,
  69        .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
  70                        .reg_off = 0x2AC, .bit_off = 0},
  71        .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
  72                        .reg_off = 0x2B4, .bit_off = 0},
  73        .clk_ctrls[DPU_CLK_CTRL_VIG2] = {
  74                        .reg_off = 0x2BC, .bit_off = 0},
  75        .clk_ctrls[DPU_CLK_CTRL_VIG3] = {
  76                        .reg_off = 0x2C4, .bit_off = 0},
  77        .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
  78                        .reg_off = 0x2AC, .bit_off = 8},
  79        .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
  80                        .reg_off = 0x2B4, .bit_off = 8},
  81        .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
  82                        .reg_off = 0x2BC, .bit_off = 8},
  83        .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
  84                        .reg_off = 0x2C4, .bit_off = 8},
  85        },
  86};
  87
  88/*************************************************************
  89 * CTL sub blocks config
  90 *************************************************************/
  91static struct dpu_ctl_cfg sdm845_ctl[] = {
  92        {
  93        .name = "ctl_0", .id = CTL_0,
  94        .base = 0x1000, .len = 0xE4,
  95        .features = BIT(DPU_CTL_SPLIT_DISPLAY)
  96        },
  97        {
  98        .name = "ctl_1", .id = CTL_1,
  99        .base = 0x1200, .len = 0xE4,
 100        .features = BIT(DPU_CTL_SPLIT_DISPLAY)
 101        },
 102        {
 103        .name = "ctl_2", .id = CTL_2,
 104        .base = 0x1400, .len = 0xE4,
 105        .features = 0
 106        },
 107        {
 108        .name = "ctl_3", .id = CTL_3,
 109        .base = 0x1600, .len = 0xE4,
 110        .features = 0
 111        },
 112        {
 113        .name = "ctl_4", .id = CTL_4,
 114        .base = 0x1800, .len = 0xE4,
 115        .features = 0
 116        },
 117};
 118
 119/*************************************************************
 120 * SSPP sub blocks config
 121 *************************************************************/
 122
 123/* SSPP common configuration */
 124static const struct dpu_sspp_blks_common sdm845_sspp_common = {
 125        .maxlinewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 126        .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 127        .maxhdeciexp = MAX_HORZ_DECIMATION,
 128        .maxvdeciexp = MAX_VERT_DECIMATION,
 129};
 130
 131#define _VIG_SBLK(num, sdma_pri) \
 132        { \
 133        .common = &sdm845_sspp_common, \
 134        .maxdwnscale = MAX_DOWNSCALE_RATIO, \
 135        .maxupscale = MAX_UPSCALE_RATIO, \
 136        .smart_dma_priority = sdma_pri, \
 137        .src_blk = {.name = STRCAT("sspp_src_", num), \
 138                .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
 139        .scaler_blk = {.name = STRCAT("sspp_scaler", num), \
 140                .id = DPU_SSPP_SCALER_QSEED3, \
 141                .base = 0xa00, .len = 0xa0,}, \
 142        .csc_blk = {.name = STRCAT("sspp_csc", num), \
 143                .id = DPU_SSPP_CSC_10BIT, \
 144                .base = 0x1a00, .len = 0x100,}, \
 145        .format_list = plane_formats_yuv, \
 146        .num_formats = ARRAY_SIZE(plane_formats_yuv), \
 147        .virt_format_list = plane_formats, \
 148        .virt_num_formats = ARRAY_SIZE(plane_formats), \
 149        }
 150
 151#define _DMA_SBLK(num, sdma_pri) \
 152        { \
 153        .common = &sdm845_sspp_common, \
 154        .maxdwnscale = SSPP_UNITY_SCALE, \
 155        .maxupscale = SSPP_UNITY_SCALE, \
 156        .smart_dma_priority = sdma_pri, \
 157        .src_blk = {.name = STRCAT("sspp_src_", num), \
 158                .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
 159        .format_list = plane_formats, \
 160        .num_formats = ARRAY_SIZE(plane_formats), \
 161        .virt_format_list = plane_formats, \
 162        .virt_num_formats = ARRAY_SIZE(plane_formats), \
 163        }
 164
 165static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = _VIG_SBLK("0", 5);
 166static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 = _VIG_SBLK("1", 6);
 167static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 = _VIG_SBLK("2", 7);
 168static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 = _VIG_SBLK("3", 8);
 169
 170static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK("8", 1);
 171static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK("9", 2);
 172static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK("10", 3);
 173static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK("11", 4);
 174
 175#define SSPP_BLK(_name, _id, _base, _features, \
 176                _sblk, _xinid, _type, _clkctrl) \
 177        { \
 178        .name = _name, .id = _id, \
 179        .base = _base, .len = 0x1c8, \
 180        .features = _features, \
 181        .sblk = &_sblk, \
 182        .xin_id = _xinid, \
 183        .type = _type, \
 184        .clk_ctrl = _clkctrl \
 185        }
 186
 187static struct dpu_sspp_cfg sdm845_sspp[] = {
 188        SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK,
 189                sdm845_vig_sblk_0, 0,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
 190        SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK,
 191                sdm845_vig_sblk_1, 4,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
 192        SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK,
 193                sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
 194        SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK,
 195                sdm845_vig_sblk_3, 12,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
 196        SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
 197                sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
 198        SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK,
 199                sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
 200        SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK,
 201                sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
 202        SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK,
 203                sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
 204};
 205
 206/*************************************************************
 207 * MIXER sub blocks config
 208 *************************************************************/
 209static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
 210        .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 211        .maxblendstages = 11, /* excluding base layer */
 212        .blendstage_base = { /* offsets relative to mixer base */
 213                0x20, 0x38, 0x50, 0x68, 0x80, 0x98,
 214                0xb0, 0xc8, 0xe0, 0xf8, 0x110
 215        },
 216};
 217
 218#define LM_BLK(_name, _id, _base, _pp, _lmpair) \
 219        { \
 220        .name = _name, .id = _id, \
 221        .base = _base, .len = 0x320, \
 222        .features = MIXER_SDM845_MASK, \
 223        .sblk = &sdm845_lm_sblk, \
 224        .pingpong = _pp, \
 225        .lm_pair_mask = (1 << _lmpair) \
 226        }
 227
 228static struct dpu_lm_cfg sdm845_lm[] = {
 229        LM_BLK("lm_0", LM_0, 0x44000, PINGPONG_0, LM_1),
 230        LM_BLK("lm_1", LM_1, 0x45000, PINGPONG_1, LM_0),
 231        LM_BLK("lm_2", LM_2, 0x46000, PINGPONG_2, LM_5),
 232        LM_BLK("lm_3", LM_3, 0x0, PINGPONG_MAX, 0),
 233        LM_BLK("lm_4", LM_4, 0x0, PINGPONG_MAX, 0),
 234        LM_BLK("lm_5", LM_5, 0x49000, PINGPONG_3, LM_2),
 235};
 236
 237/*************************************************************
 238 * PINGPONG sub blocks config
 239 *************************************************************/
 240static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = {
 241        .te2 = {.id = DPU_PINGPONG_TE2, .base = 0x2000, .len = 0x0,
 242                .version = 0x1},
 243        .dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0,
 244                .len = 0x20, .version = 0x10000},
 245};
 246
 247static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = {
 248        .dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0,
 249                .len = 0x20, .version = 0x10000},
 250};
 251
 252#define PP_BLK_TE(_name, _id, _base) \
 253        {\
 254        .name = _name, .id = _id, \
 255        .base = _base, .len = 0xd4, \
 256        .features = PINGPONG_SDM845_SPLIT_MASK, \
 257        .sblk = &sdm845_pp_sblk_te \
 258        }
 259#define PP_BLK(_name, _id, _base) \
 260        {\
 261        .name = _name, .id = _id, \
 262        .base = _base, .len = 0xd4, \
 263        .features = PINGPONG_SDM845_MASK, \
 264        .sblk = &sdm845_pp_sblk \
 265        }
 266
 267static struct dpu_pingpong_cfg sdm845_pp[] = {
 268        PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000),
 269        PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800),
 270        PP_BLK("pingpong_2", PINGPONG_2, 0x71000),
 271        PP_BLK("pingpong_3", PINGPONG_3, 0x71800),
 272};
 273
 274/*************************************************************
 275 * INTF sub blocks config
 276 *************************************************************/
 277#define INTF_BLK(_name, _id, _base, _type, _ctrl_id) \
 278        {\
 279        .name = _name, .id = _id, \
 280        .base = _base, .len = 0x280, \
 281        .type = _type, \
 282        .controller_id = _ctrl_id, \
 283        .prog_fetch_lines_worst_case = 24 \
 284        }
 285
 286static struct dpu_intf_cfg sdm845_intf[] = {
 287        INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0),
 288        INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0),
 289        INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1),
 290        INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1),
 291};
 292
 293/*************************************************************
 294 * VBIF sub blocks config
 295 *************************************************************/
 296/* VBIF QOS remap */
 297static u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6};
 298static u32 sdm845_nrt_pri_lvl[] = {3, 3, 3, 3, 3, 3, 3, 3};
 299
 300static struct dpu_vbif_cfg sdm845_vbif[] = {
 301        {
 302        .name = "vbif_0", .id = VBIF_0,
 303        .base = 0, .len = 0x1040,
 304        .features = BIT(DPU_VBIF_QOS_REMAP),
 305        .xin_halt_timeout = 0x4000,
 306        .qos_rt_tbl = {
 307                .npriority_lvl = ARRAY_SIZE(sdm845_rt_pri_lvl),
 308                .priority_lvl = sdm845_rt_pri_lvl,
 309                },
 310        .qos_nrt_tbl = {
 311                .npriority_lvl = ARRAY_SIZE(sdm845_nrt_pri_lvl),
 312                .priority_lvl = sdm845_nrt_pri_lvl,
 313                },
 314        .memtype_count = 14,
 315        .memtype = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
 316        },
 317};
 318
 319static struct dpu_reg_dma_cfg sdm845_regdma = {
 320        .base = 0x0, .version = 0x1, .trigger_sel_off = 0x119c
 321};
 322
 323/*************************************************************
 324 * PERF data config
 325 *************************************************************/
 326
 327/* SSPP QOS LUTs */
 328static struct dpu_qos_lut_entry sdm845_qos_linear[] = {
 329        {.fl = 4, .lut = 0x357},
 330        {.fl = 5, .lut = 0x3357},
 331        {.fl = 6, .lut = 0x23357},
 332        {.fl = 7, .lut = 0x223357},
 333        {.fl = 8, .lut = 0x2223357},
 334        {.fl = 9, .lut = 0x22223357},
 335        {.fl = 10, .lut = 0x222223357},
 336        {.fl = 11, .lut = 0x2222223357},
 337        {.fl = 12, .lut = 0x22222223357},
 338        {.fl = 13, .lut = 0x222222223357},
 339        {.fl = 14, .lut = 0x1222222223357},
 340        {.fl = 0, .lut = 0x11222222223357}
 341};
 342
 343static struct dpu_qos_lut_entry sdm845_qos_macrotile[] = {
 344        {.fl = 10, .lut = 0x344556677},
 345        {.fl = 11, .lut = 0x3344556677},
 346        {.fl = 12, .lut = 0x23344556677},
 347        {.fl = 13, .lut = 0x223344556677},
 348        {.fl = 14, .lut = 0x1223344556677},
 349        {.fl = 0, .lut = 0x112233344556677},
 350};
 351
 352static struct dpu_qos_lut_entry sdm845_qos_nrt[] = {
 353        {.fl = 0, .lut = 0x0},
 354};
 355
 356static struct dpu_perf_cfg sdm845_perf_data = {
 357        .max_bw_low = 6800000,
 358        .max_bw_high = 6800000,
 359        .min_core_ib = 2400000,
 360        .min_llcc_ib = 800000,
 361        .min_dram_ib = 800000,
 362        .core_ib_ff = "6.0",
 363        .core_clk_ff = "1.0",
 364        .comp_ratio_rt =
 365        "NV12/5/1/1.23 AB24/5/1/1.23 XB24/5/1/1.23",
 366        .comp_ratio_nrt =
 367        "NV12/5/1/1.25 AB24/5/1/1.25 XB24/5/1/1.25",
 368        .undersized_prefill_lines = 2,
 369        .xtra_prefill_lines = 2,
 370        .dest_scale_prefill_lines = 3,
 371        .macrotile_prefill_lines = 4,
 372        .yuv_nv12_prefill_lines = 8,
 373        .linear_prefill_lines = 1,
 374        .downscaling_prefill_lines = 1,
 375        .amortizable_threshold = 25,
 376        .min_prefill_lines = 24,
 377        .danger_lut_tbl = {0xf, 0xffff, 0x0},
 378        .qos_lut_tbl = {
 379                {.nentry = ARRAY_SIZE(sdm845_qos_linear),
 380                .entries = sdm845_qos_linear
 381                },
 382                {.nentry = ARRAY_SIZE(sdm845_qos_macrotile),
 383                .entries = sdm845_qos_macrotile
 384                },
 385                {.nentry = ARRAY_SIZE(sdm845_qos_nrt),
 386                .entries = sdm845_qos_nrt
 387                },
 388        },
 389        .cdp_cfg = {
 390                {.rd_enable = 1, .wr_enable = 1},
 391                {.rd_enable = 1, .wr_enable = 0}
 392        },
 393};
 394
 395/*************************************************************
 396 * Hardware catalog init
 397 *************************************************************/
 398
 399/*
 400 * sdm845_cfg_init(): populate sdm845 dpu sub-blocks reg offsets
 401 * and instance counts.
 402 */
 403static void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
 404{
 405        *dpu_cfg = (struct dpu_mdss_cfg){
 406                .caps = &sdm845_dpu_caps,
 407                .mdp_count = ARRAY_SIZE(sdm845_mdp),
 408                .mdp = sdm845_mdp,
 409                .ctl_count = ARRAY_SIZE(sdm845_ctl),
 410                .ctl = sdm845_ctl,
 411                .sspp_count = ARRAY_SIZE(sdm845_sspp),
 412                .sspp = sdm845_sspp,
 413                .mixer_count = ARRAY_SIZE(sdm845_lm),
 414                .mixer = sdm845_lm,
 415                .pingpong_count = ARRAY_SIZE(sdm845_pp),
 416                .pingpong = sdm845_pp,
 417                .intf_count = ARRAY_SIZE(sdm845_intf),
 418                .intf = sdm845_intf,
 419                .vbif_count = ARRAY_SIZE(sdm845_vbif),
 420                .vbif = sdm845_vbif,
 421                .reg_dma_count = 1,
 422                .dma_cfg = sdm845_regdma,
 423                .perf = sdm845_perf_data,
 424        };
 425}
 426
 427static struct dpu_mdss_hw_cfg_handler cfg_handler[] = {
 428        { .hw_rev = DPU_HW_VER_400, .cfg_init = sdm845_cfg_init},
 429        { .hw_rev = DPU_HW_VER_401, .cfg_init = sdm845_cfg_init},
 430};
 431
 432void dpu_hw_catalog_deinit(struct dpu_mdss_cfg *dpu_cfg)
 433{
 434        kfree(dpu_cfg);
 435}
 436
 437struct dpu_mdss_cfg *dpu_hw_catalog_init(u32 hw_rev)
 438{
 439        int i;
 440        struct dpu_mdss_cfg *dpu_cfg;
 441
 442        dpu_cfg = kzalloc(sizeof(*dpu_cfg), GFP_KERNEL);
 443        if (!dpu_cfg)
 444                return ERR_PTR(-ENOMEM);
 445
 446        for (i = 0; i < ARRAY_SIZE(cfg_handler); i++) {
 447                if (cfg_handler[i].hw_rev == hw_rev) {
 448                        cfg_handler[i].cfg_init(dpu_cfg);
 449                        dpu_cfg->hwversion = hw_rev;
 450                        return dpu_cfg;
 451                }
 452        }
 453
 454        DPU_ERROR("unsupported chipset id:%X\n", hw_rev);
 455        dpu_hw_catalog_deinit(dpu_cfg);
 456        return ERR_PTR(-ENODEV);
 457}
 458
 459