linux/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 and
   6 * only version 2 as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 */
  13
  14#include "mdp5_kms.h"
  15#include "mdp5_cfg.h"
  16
  17struct mdp5_cfg_handler {
  18        int revision;
  19        struct mdp5_cfg config;
  20};
  21
  22/* mdp5_cfg must be exposed (used in mdp5.xml.h) */
  23const struct mdp5_cfg_hw *mdp5_cfg = NULL;
  24
  25const struct mdp5_cfg_hw msm8x74v1_config = {
  26        .name = "msm8x74v1",
  27        .mdp = {
  28                .count = 1,
  29                .caps = MDP_CAP_SMP |
  30                        0,
  31        },
  32        .smp = {
  33                .mmb_count = 22,
  34                .mmb_size = 4096,
  35                .clients = {
  36                        [SSPP_VIG0] =  1, [SSPP_VIG1] =  4, [SSPP_VIG2] =  7,
  37                        [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
  38                        [SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
  39                },
  40        },
  41        .ctl = {
  42                .count = 5,
  43                .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
  44                .flush_hw_mask = 0x0003ffff,
  45        },
  46        .pipe_vig = {
  47                .count = 3,
  48                .base = { 0x01100, 0x01500, 0x01900 },
  49                .caps = MDP_PIPE_CAP_HFLIP |
  50                        MDP_PIPE_CAP_VFLIP |
  51                        MDP_PIPE_CAP_SCALE |
  52                        MDP_PIPE_CAP_CSC   |
  53                        0,
  54        },
  55        .pipe_rgb = {
  56                .count = 3,
  57                .base = { 0x01d00, 0x02100, 0x02500 },
  58                .caps = MDP_PIPE_CAP_HFLIP |
  59                        MDP_PIPE_CAP_VFLIP |
  60                        MDP_PIPE_CAP_SCALE |
  61                        0,
  62        },
  63        .pipe_dma = {
  64                .count = 2,
  65                .base = { 0x02900, 0x02d00 },
  66                .caps = MDP_PIPE_CAP_HFLIP |
  67                        MDP_PIPE_CAP_VFLIP |
  68                        0,
  69        },
  70        .lm = {
  71                .count = 5,
  72                .base = { 0x03100, 0x03500, 0x03900, 0x03d00, 0x04100 },
  73                .nb_stages = 5,
  74        },
  75        .dspp = {
  76                .count = 3,
  77                .base = { 0x04500, 0x04900, 0x04d00 },
  78        },
  79        .pp = {
  80                .count = 3,
  81                .base = { 0x21a00, 0x21b00, 0x21c00 },
  82        },
  83        .intf = {
  84                .base = { 0x21000, 0x21200, 0x21400, 0x21600 },
  85                .connect = {
  86                        [0] = INTF_eDP,
  87                        [1] = INTF_DSI,
  88                        [2] = INTF_DSI,
  89                        [3] = INTF_HDMI,
  90                },
  91        },
  92        .max_clk = 200000000,
  93};
  94
  95const struct mdp5_cfg_hw msm8x74v2_config = {
  96        .name = "msm8x74",
  97        .mdp = {
  98                .count = 1,
  99                .caps = MDP_CAP_SMP |
 100                        0,
 101        },
 102        .smp = {
 103                .mmb_count = 22,
 104                .mmb_size = 4096,
 105                .clients = {
 106                        [SSPP_VIG0] =  1, [SSPP_VIG1] =  4, [SSPP_VIG2] =  7,
 107                        [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
 108                        [SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
 109                },
 110        },
 111        .ctl = {
 112                .count = 5,
 113                .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
 114                .flush_hw_mask = 0x0003ffff,
 115        },
 116        .pipe_vig = {
 117                .count = 3,
 118                .base = { 0x01100, 0x01500, 0x01900 },
 119                .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
 120                                MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
 121                                MDP_PIPE_CAP_DECIMATION,
 122        },
 123        .pipe_rgb = {
 124                .count = 3,
 125                .base = { 0x01d00, 0x02100, 0x02500 },
 126                .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
 127                                MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
 128        },
 129        .pipe_dma = {
 130                .count = 2,
 131                .base = { 0x02900, 0x02d00 },
 132                .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
 133        },
 134        .lm = {
 135                .count = 5,
 136                .base = { 0x03100, 0x03500, 0x03900, 0x03d00, 0x04100 },
 137                .nb_stages = 5,
 138                .max_width = 2048,
 139                .max_height = 0xFFFF,
 140        },
 141        .dspp = {
 142                .count = 3,
 143                .base = { 0x04500, 0x04900, 0x04d00 },
 144        },
 145        .ad = {
 146                .count = 2,
 147                .base = { 0x13000, 0x13200 },
 148        },
 149        .pp = {
 150                .count = 3,
 151                .base = { 0x12c00, 0x12d00, 0x12e00 },
 152        },
 153        .intf = {
 154                .base = { 0x12400, 0x12600, 0x12800, 0x12a00 },
 155                .connect = {
 156                        [0] = INTF_eDP,
 157                        [1] = INTF_DSI,
 158                        [2] = INTF_DSI,
 159                        [3] = INTF_HDMI,
 160                },
 161        },
 162        .max_clk = 200000000,
 163};
 164
 165const struct mdp5_cfg_hw apq8084_config = {
 166        .name = "apq8084",
 167        .mdp = {
 168                .count = 1,
 169                .caps = MDP_CAP_SMP |
 170                        0,
 171        },
 172        .smp = {
 173                .mmb_count = 44,
 174                .mmb_size = 8192,
 175                .clients = {
 176                        [SSPP_VIG0] =  1, [SSPP_VIG1] =  4,
 177                        [SSPP_VIG2] =  7, [SSPP_VIG3] = 19,
 178                        [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
 179                        [SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
 180                        [SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
 181                },
 182                .reserved_state[0] = GENMASK(7, 0),     /* first 8 MMBs */
 183                .reserved = {
 184                        /* Two SMP blocks are statically tied to RGB pipes: */
 185                        [16] = 2, [17] = 2, [18] = 2, [22] = 2,
 186                },
 187        },
 188        .ctl = {
 189                .count = 5,
 190                .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
 191                .flush_hw_mask = 0x003fffff,
 192        },
 193        .pipe_vig = {
 194                .count = 4,
 195                .base = { 0x01100, 0x01500, 0x01900, 0x01d00 },
 196                .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
 197                                MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
 198                                MDP_PIPE_CAP_DECIMATION,
 199        },
 200        .pipe_rgb = {
 201                .count = 4,
 202                .base = { 0x02100, 0x02500, 0x02900, 0x02d00 },
 203                .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
 204                                MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
 205        },
 206        .pipe_dma = {
 207                .count = 2,
 208                .base = { 0x03100, 0x03500 },
 209                .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
 210        },
 211        .lm = {
 212                .count = 6,
 213                .base = { 0x03900, 0x03d00, 0x04100, 0x04500, 0x04900, 0x04d00 },
 214                .nb_stages = 5,
 215                .max_width = 2048,
 216                .max_height = 0xFFFF,
 217        },
 218        .dspp = {
 219                .count = 4,
 220                .base = { 0x05100, 0x05500, 0x05900, 0x05d00 },
 221
 222        },
 223        .ad = {
 224                .count = 3,
 225                .base = { 0x13400, 0x13600, 0x13800 },
 226        },
 227        .pp = {
 228                .count = 4,
 229                .base = { 0x12e00, 0x12f00, 0x13000, 0x13100 },
 230        },
 231        .intf = {
 232                .base = { 0x12400, 0x12600, 0x12800, 0x12a00, 0x12c00 },
 233                .connect = {
 234                        [0] = INTF_eDP,
 235                        [1] = INTF_DSI,
 236                        [2] = INTF_DSI,
 237                        [3] = INTF_HDMI,
 238                },
 239        },
 240        .max_clk = 320000000,
 241};
 242
 243const struct mdp5_cfg_hw msm8x16_config = {
 244        .name = "msm8x16",
 245        .mdp = {
 246                .count = 1,
 247                .base = { 0x0 },
 248                .caps = MDP_CAP_SMP |
 249                        0,
 250        },
 251        .smp = {
 252                .mmb_count = 8,
 253                .mmb_size = 8192,
 254                .clients = {
 255                        [SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
 256                        [SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
 257                },
 258        },
 259        .ctl = {
 260                .count = 5,
 261                .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
 262                .flush_hw_mask = 0x4003ffff,
 263        },
 264        .pipe_vig = {
 265                .count = 1,
 266                .base = { 0x04000 },
 267                .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
 268                                MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
 269                                MDP_PIPE_CAP_DECIMATION,
 270        },
 271        .pipe_rgb = {
 272                .count = 2,
 273                .base = { 0x14000, 0x16000 },
 274                .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
 275                                MDP_PIPE_CAP_DECIMATION,
 276        },
 277        .pipe_dma = {
 278                .count = 1,
 279                .base = { 0x24000 },
 280                .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
 281        },
 282        .lm = {
 283                .count = 2, /* LM0 and LM3 */
 284                .base = { 0x44000, 0x47000 },
 285                .nb_stages = 8,
 286                .max_width = 2048,
 287                .max_height = 0xFFFF,
 288        },
 289        .dspp = {
 290                .count = 1,
 291                .base = { 0x54000 },
 292
 293        },
 294        .intf = {
 295                .base = { 0x00000, 0x6a800 },
 296                .connect = {
 297                        [0] = INTF_DISABLED,
 298                        [1] = INTF_DSI,
 299                },
 300        },
 301        .max_clk = 320000000,
 302};
 303
 304const struct mdp5_cfg_hw msm8x94_config = {
 305        .name = "msm8x94",
 306        .mdp = {
 307                .count = 1,
 308                .caps = MDP_CAP_SMP |
 309                        0,
 310        },
 311        .smp = {
 312                .mmb_count = 44,
 313                .mmb_size = 8192,
 314                .clients = {
 315                        [SSPP_VIG0] =  1, [SSPP_VIG1] =  4,
 316                        [SSPP_VIG2] =  7, [SSPP_VIG3] = 19,
 317                        [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
 318                        [SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
 319                        [SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
 320                },
 321                .reserved_state[0] = GENMASK(23, 0),    /* first 24 MMBs */
 322                .reserved = {
 323                         [1] = 1,  [4] = 1,  [7] = 1, [19] = 1,
 324                        [16] = 5, [17] = 5, [18] = 5, [22] = 5,
 325                },
 326        },
 327        .ctl = {
 328                .count = 5,
 329                .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
 330                .flush_hw_mask = 0xf0ffffff,
 331        },
 332        .pipe_vig = {
 333                .count = 4,
 334                .base = { 0x04000, 0x06000, 0x08000, 0x0a000 },
 335                .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
 336                                MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
 337                                MDP_PIPE_CAP_DECIMATION,
 338        },
 339        .pipe_rgb = {
 340                .count = 4,
 341                .base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
 342                .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
 343                                MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
 344        },
 345        .pipe_dma = {
 346                .count = 2,
 347                .base = { 0x24000, 0x26000 },
 348                .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
 349        },
 350        .lm = {
 351                .count = 6,
 352                .base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
 353                .nb_stages = 8,
 354                .max_width = 2048,
 355                .max_height = 0xFFFF,
 356        },
 357        .dspp = {
 358                .count = 4,
 359                .base = { 0x54000, 0x56000, 0x58000, 0x5a000 },
 360
 361        },
 362        .ad = {
 363                .count = 3,
 364                .base = { 0x78000, 0x78800, 0x79000 },
 365        },
 366        .pp = {
 367                .count = 4,
 368                .base = { 0x70000, 0x70800, 0x71000, 0x71800 },
 369        },
 370        .intf = {
 371                .base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800, 0x6c000 },
 372                .connect = {
 373                        [0] = INTF_DISABLED,
 374                        [1] = INTF_DSI,
 375                        [2] = INTF_DSI,
 376                        [3] = INTF_HDMI,
 377                },
 378        },
 379        .max_clk = 400000000,
 380};
 381
 382const struct mdp5_cfg_hw msm8x96_config = {
 383        .name = "msm8x96",
 384        .mdp = {
 385                .count = 1,
 386                .caps = MDP_CAP_DSC |
 387                        MDP_CAP_CDM |
 388                        0,
 389        },
 390        .ctl = {
 391                .count = 5,
 392                .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
 393                .flush_hw_mask = 0xf4ffffff,
 394        },
 395        .pipe_vig = {
 396                .count = 4,
 397                .base = { 0x04000, 0x06000, 0x08000, 0x0a000 },
 398                .caps = MDP_PIPE_CAP_HFLIP      |
 399                        MDP_PIPE_CAP_VFLIP      |
 400                        MDP_PIPE_CAP_SCALE      |
 401                        MDP_PIPE_CAP_CSC        |
 402                        MDP_PIPE_CAP_DECIMATION |
 403                        MDP_PIPE_CAP_SW_PIX_EXT |
 404                        0,
 405        },
 406        .pipe_rgb = {
 407                .count = 4,
 408                .base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
 409                .caps = MDP_PIPE_CAP_HFLIP      |
 410                        MDP_PIPE_CAP_VFLIP      |
 411                        MDP_PIPE_CAP_SCALE      |
 412                        MDP_PIPE_CAP_DECIMATION |
 413                        MDP_PIPE_CAP_SW_PIX_EXT |
 414                        0,
 415        },
 416        .pipe_dma = {
 417                .count = 2,
 418                .base = { 0x24000, 0x26000 },
 419                .caps = MDP_PIPE_CAP_HFLIP      |
 420                        MDP_PIPE_CAP_VFLIP      |
 421                        MDP_PIPE_CAP_SW_PIX_EXT |
 422                        0,
 423        },
 424        .lm = {
 425                .count = 6,
 426                .base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
 427                .nb_stages = 8,
 428                .max_width = 2560,
 429                .max_height = 0xFFFF,
 430        },
 431        .dspp = {
 432                .count = 2,
 433                .base = { 0x54000, 0x56000 },
 434        },
 435        .ad = {
 436                .count = 3,
 437                .base = { 0x78000, 0x78800, 0x79000 },
 438        },
 439        .pp = {
 440                .count = 4,
 441                .base = { 0x70000, 0x70800, 0x71000, 0x71800 },
 442        },
 443        .cdm = {
 444                .count = 1,
 445                .base = { 0x79200 },
 446        },
 447        .dsc = {
 448                .count = 2,
 449                .base = { 0x80000, 0x80400 },
 450        },
 451        .intf = {
 452                .base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800, 0x6c000 },
 453                .connect = {
 454                        [0] = INTF_DISABLED,
 455                        [1] = INTF_DSI,
 456                        [2] = INTF_DSI,
 457                        [3] = INTF_HDMI,
 458                },
 459        },
 460        .max_clk = 412500000,
 461};
 462
 463static const struct mdp5_cfg_handler cfg_handlers[] = {
 464        { .revision = 0, .config = { .hw = &msm8x74v1_config } },
 465        { .revision = 2, .config = { .hw = &msm8x74v2_config } },
 466        { .revision = 3, .config = { .hw = &apq8084_config } },
 467        { .revision = 6, .config = { .hw = &msm8x16_config } },
 468        { .revision = 9, .config = { .hw = &msm8x94_config } },
 469        { .revision = 7, .config = { .hw = &msm8x96_config } },
 470};
 471
 472static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev);
 473
 474const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_handler)
 475{
 476        return cfg_handler->config.hw;
 477}
 478
 479struct mdp5_cfg *mdp5_cfg_get_config(struct mdp5_cfg_handler *cfg_handler)
 480{
 481        return &cfg_handler->config;
 482}
 483
 484int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_handler)
 485{
 486        return cfg_handler->revision;
 487}
 488
 489void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_handler)
 490{
 491        kfree(cfg_handler);
 492}
 493
 494struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms,
 495                uint32_t major, uint32_t minor)
 496{
 497        struct drm_device *dev = mdp5_kms->dev;
 498        struct platform_device *pdev = dev->platformdev;
 499        struct mdp5_cfg_handler *cfg_handler;
 500        struct mdp5_cfg_platform *pconfig;
 501        int i, ret = 0;
 502
 503        cfg_handler = kzalloc(sizeof(*cfg_handler), GFP_KERNEL);
 504        if (unlikely(!cfg_handler)) {
 505                ret = -ENOMEM;
 506                goto fail;
 507        }
 508
 509        if (major != 1) {
 510                dev_err(dev->dev, "unexpected MDP major version: v%d.%d\n",
 511                                major, minor);
 512                ret = -ENXIO;
 513                goto fail;
 514        }
 515
 516        /* only after mdp5_cfg global pointer's init can we access the hw */
 517        for (i = 0; i < ARRAY_SIZE(cfg_handlers); i++) {
 518                if (cfg_handlers[i].revision != minor)
 519                        continue;
 520                mdp5_cfg = cfg_handlers[i].config.hw;
 521
 522                break;
 523        }
 524        if (unlikely(!mdp5_cfg)) {
 525                dev_err(dev->dev, "unexpected MDP minor revision: v%d.%d\n",
 526                                major, minor);
 527                ret = -ENXIO;
 528                goto fail;
 529        }
 530
 531        cfg_handler->revision = minor;
 532        cfg_handler->config.hw = mdp5_cfg;
 533
 534        pconfig = mdp5_get_config(pdev);
 535        memcpy(&cfg_handler->config.platform, pconfig, sizeof(*pconfig));
 536
 537        DBG("MDP5: %s hw config selected", mdp5_cfg->name);
 538
 539        return cfg_handler;
 540
 541fail:
 542        if (cfg_handler)
 543                mdp5_cfg_destroy(cfg_handler);
 544
 545        return NULL;
 546}
 547
 548static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev)
 549{
 550        static struct mdp5_cfg_platform config = {};
 551
 552        config.iommu = iommu_domain_alloc(&platform_bus_type);
 553
 554        return &config;
 555}
 556