linux/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
   3 * Copyright (C) 2013 Red Hat
   4 * Author: Rob Clark <robdclark@gmail.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms of the GNU General Public License version 2 as published by
   8 * the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 *
  15 * You should have received a copy of the GNU General Public License along with
  16 * this program.  If not, see <http://www.gnu.org/licenses/>.
  17 */
  18
  19
  20#include "msm_drv.h"
  21#include "msm_mmu.h"
  22#include "mdp5_kms.h"
  23
  24static const char *iommu_ports[] = {
  25                "mdp_0",
  26};
  27
  28static int mdp5_hw_init(struct msm_kms *kms)
  29{
  30        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
  31        struct drm_device *dev = mdp5_kms->dev;
  32        unsigned long flags;
  33
  34        pm_runtime_get_sync(dev->dev);
  35
  36        /* Magic unknown register writes:
  37         *
  38         *    W VBIF:0x004 00000001      (mdss_mdp.c:839)
  39         *    W MDP5:0x2e0 0xe9          (mdss_mdp.c:839)
  40         *    W MDP5:0x2e4 0x55          (mdss_mdp.c:839)
  41         *    W MDP5:0x3ac 0xc0000ccc    (mdss_mdp.c:839)
  42         *    W MDP5:0x3b4 0xc0000ccc    (mdss_mdp.c:839)
  43         *    W MDP5:0x3bc 0xcccccc      (mdss_mdp.c:839)
  44         *    W MDP5:0x4a8 0xcccc0c0     (mdss_mdp.c:839)
  45         *    W MDP5:0x4b0 0xccccc0c0    (mdss_mdp.c:839)
  46         *    W MDP5:0x4b8 0xccccc000    (mdss_mdp.c:839)
  47         *
  48         * Downstream fbdev driver gets these register offsets/values
  49         * from DT.. not really sure what these registers are or if
  50         * different values for different boards/SoC's, etc.  I guess
  51         * they are the golden registers.
  52         *
  53         * Not setting these does not seem to cause any problem.  But
  54         * we may be getting lucky with the bootloader initializing
  55         * them for us.  OTOH, if we can always count on the bootloader
  56         * setting the golden registers, then perhaps we don't need to
  57         * care.
  58         */
  59
  60        spin_lock_irqsave(&mdp5_kms->resource_lock, flags);
  61        mdp5_write(mdp5_kms, REG_MDP5_MDP_DISP_INTF_SEL(0), 0);
  62        spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags);
  63
  64        mdp5_ctlm_hw_reset(mdp5_kms->ctlm);
  65
  66        pm_runtime_put_sync(dev->dev);
  67
  68        return 0;
  69}
  70
  71static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
  72{
  73        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
  74        mdp5_enable(mdp5_kms);
  75}
  76
  77static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
  78{
  79        int i;
  80        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
  81        int nplanes = mdp5_kms->dev->mode_config.num_total_plane;
  82
  83        for (i = 0; i < nplanes; i++) {
  84                struct drm_plane *plane = state->planes[i];
  85                struct drm_plane_state *plane_state = state->plane_states[i];
  86
  87                if (!plane)
  88                        continue;
  89
  90                mdp5_plane_complete_commit(plane, plane_state);
  91        }
  92
  93        mdp5_disable(mdp5_kms);
  94}
  95
  96static void mdp5_wait_for_crtc_commit_done(struct msm_kms *kms,
  97                                                struct drm_crtc *crtc)
  98{
  99        mdp5_crtc_wait_for_commit_done(crtc);
 100}
 101
 102static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate,
 103                struct drm_encoder *encoder)
 104{
 105        return rate;
 106}
 107
 108static int mdp5_set_split_display(struct msm_kms *kms,
 109                struct drm_encoder *encoder,
 110                struct drm_encoder *slave_encoder,
 111                bool is_cmd_mode)
 112{
 113        if (is_cmd_mode)
 114                return mdp5_cmd_encoder_set_split_display(encoder,
 115                                                        slave_encoder);
 116        else
 117                return mdp5_encoder_set_split_display(encoder, slave_encoder);
 118}
 119
 120static void mdp5_preclose(struct msm_kms *kms, struct drm_file *file)
 121{
 122        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
 123        struct msm_drm_private *priv = mdp5_kms->dev->dev_private;
 124        unsigned i;
 125
 126        for (i = 0; i < priv->num_crtcs; i++)
 127                mdp5_crtc_cancel_pending_flip(priv->crtcs[i], file);
 128}
 129
 130static void mdp5_destroy(struct msm_kms *kms)
 131{
 132        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
 133        struct msm_mmu *mmu = mdp5_kms->mmu;
 134
 135        mdp5_irq_domain_fini(mdp5_kms);
 136
 137        if (mmu) {
 138                mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports));
 139                mmu->funcs->destroy(mmu);
 140        }
 141
 142        if (mdp5_kms->ctlm)
 143                mdp5_ctlm_destroy(mdp5_kms->ctlm);
 144        if (mdp5_kms->smp)
 145                mdp5_smp_destroy(mdp5_kms->smp);
 146        if (mdp5_kms->cfg)
 147                mdp5_cfg_destroy(mdp5_kms->cfg);
 148
 149        kfree(mdp5_kms);
 150}
 151
 152static const struct mdp_kms_funcs kms_funcs = {
 153        .base = {
 154                .hw_init         = mdp5_hw_init,
 155                .irq_preinstall  = mdp5_irq_preinstall,
 156                .irq_postinstall = mdp5_irq_postinstall,
 157                .irq_uninstall   = mdp5_irq_uninstall,
 158                .irq             = mdp5_irq,
 159                .enable_vblank   = mdp5_enable_vblank,
 160                .disable_vblank  = mdp5_disable_vblank,
 161                .prepare_commit  = mdp5_prepare_commit,
 162                .complete_commit = mdp5_complete_commit,
 163                .wait_for_crtc_commit_done = mdp5_wait_for_crtc_commit_done,
 164                .get_format      = mdp_get_format,
 165                .round_pixclk    = mdp5_round_pixclk,
 166                .set_split_display = mdp5_set_split_display,
 167                .preclose        = mdp5_preclose,
 168                .destroy         = mdp5_destroy,
 169        },
 170        .set_irqmask         = mdp5_set_irqmask,
 171};
 172
 173int mdp5_disable(struct mdp5_kms *mdp5_kms)
 174{
 175        DBG("");
 176
 177        clk_disable_unprepare(mdp5_kms->ahb_clk);
 178        clk_disable_unprepare(mdp5_kms->axi_clk);
 179        clk_disable_unprepare(mdp5_kms->core_clk);
 180        clk_disable_unprepare(mdp5_kms->lut_clk);
 181
 182        return 0;
 183}
 184
 185int mdp5_enable(struct mdp5_kms *mdp5_kms)
 186{
 187        DBG("");
 188
 189        clk_prepare_enable(mdp5_kms->ahb_clk);
 190        clk_prepare_enable(mdp5_kms->axi_clk);
 191        clk_prepare_enable(mdp5_kms->core_clk);
 192        clk_prepare_enable(mdp5_kms->lut_clk);
 193
 194        return 0;
 195}
 196
 197static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
 198                enum mdp5_intf_type intf_type, int intf_num,
 199                enum mdp5_intf_mode intf_mode)
 200{
 201        struct drm_device *dev = mdp5_kms->dev;
 202        struct msm_drm_private *priv = dev->dev_private;
 203        struct drm_encoder *encoder;
 204        struct mdp5_interface intf = {
 205                        .num    = intf_num,
 206                        .type   = intf_type,
 207                        .mode   = intf_mode,
 208        };
 209
 210        if ((intf_type == INTF_DSI) &&
 211                (intf_mode == MDP5_INTF_DSI_MODE_COMMAND))
 212                encoder = mdp5_cmd_encoder_init(dev, &intf);
 213        else
 214                encoder = mdp5_encoder_init(dev, &intf);
 215
 216        if (IS_ERR(encoder)) {
 217                dev_err(dev->dev, "failed to construct encoder\n");
 218                return encoder;
 219        }
 220
 221        encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
 222        priv->encoders[priv->num_encoders++] = encoder;
 223
 224        return encoder;
 225}
 226
 227static int get_dsi_id_from_intf(const struct mdp5_cfg_hw *hw_cfg, int intf_num)
 228{
 229        const enum mdp5_intf_type *intfs = hw_cfg->intf.connect;
 230        const int intf_cnt = ARRAY_SIZE(hw_cfg->intf.connect);
 231        int id = 0, i;
 232
 233        for (i = 0; i < intf_cnt; i++) {
 234                if (intfs[i] == INTF_DSI) {
 235                        if (intf_num == i)
 236                                return id;
 237
 238                        id++;
 239                }
 240        }
 241
 242        return -EINVAL;
 243}
 244
 245static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
 246{
 247        struct drm_device *dev = mdp5_kms->dev;
 248        struct msm_drm_private *priv = dev->dev_private;
 249        const struct mdp5_cfg_hw *hw_cfg =
 250                                        mdp5_cfg_get_hw_config(mdp5_kms->cfg);
 251        enum mdp5_intf_type intf_type = hw_cfg->intf.connect[intf_num];
 252        struct drm_encoder *encoder;
 253        int ret = 0;
 254
 255        switch (intf_type) {
 256        case INTF_DISABLED:
 257                break;
 258        case INTF_eDP:
 259                if (!priv->edp)
 260                        break;
 261
 262                encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num,
 263                                        MDP5_INTF_MODE_NONE);
 264                if (IS_ERR(encoder)) {
 265                        ret = PTR_ERR(encoder);
 266                        break;
 267                }
 268
 269                ret = msm_edp_modeset_init(priv->edp, dev, encoder);
 270                break;
 271        case INTF_HDMI:
 272                if (!priv->hdmi)
 273                        break;
 274
 275                encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num,
 276                                        MDP5_INTF_MODE_NONE);
 277                if (IS_ERR(encoder)) {
 278                        ret = PTR_ERR(encoder);
 279                        break;
 280                }
 281
 282                ret = hdmi_modeset_init(priv->hdmi, dev, encoder);
 283                break;
 284        case INTF_DSI:
 285        {
 286                int dsi_id = get_dsi_id_from_intf(hw_cfg, intf_num);
 287                struct drm_encoder *dsi_encs[MSM_DSI_ENCODER_NUM];
 288                enum mdp5_intf_mode mode;
 289                int i;
 290
 291                if ((dsi_id >= ARRAY_SIZE(priv->dsi)) || (dsi_id < 0)) {
 292                        dev_err(dev->dev, "failed to find dsi from intf %d\n",
 293                                intf_num);
 294                        ret = -EINVAL;
 295                        break;
 296                }
 297
 298                if (!priv->dsi[dsi_id])
 299                        break;
 300
 301                for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) {
 302                        mode = (i == MSM_DSI_CMD_ENCODER_ID) ?
 303                                MDP5_INTF_DSI_MODE_COMMAND :
 304                                MDP5_INTF_DSI_MODE_VIDEO;
 305                        dsi_encs[i] = construct_encoder(mdp5_kms, INTF_DSI,
 306                                                        intf_num, mode);
 307                        if (IS_ERR(dsi_encs)) {
 308                                ret = PTR_ERR(dsi_encs);
 309                                break;
 310                        }
 311                }
 312
 313                ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, dsi_encs);
 314                break;
 315        }
 316        default:
 317                dev_err(dev->dev, "unknown intf: %d\n", intf_type);
 318                ret = -EINVAL;
 319                break;
 320        }
 321
 322        return ret;
 323}
 324
 325static int modeset_init(struct mdp5_kms *mdp5_kms)
 326{
 327        static const enum mdp5_pipe crtcs[] = {
 328                        SSPP_RGB0, SSPP_RGB1, SSPP_RGB2, SSPP_RGB3,
 329        };
 330        static const enum mdp5_pipe pub_planes[] = {
 331                        SSPP_VIG0, SSPP_VIG1, SSPP_VIG2, SSPP_VIG3,
 332        };
 333        struct drm_device *dev = mdp5_kms->dev;
 334        struct msm_drm_private *priv = dev->dev_private;
 335        const struct mdp5_cfg_hw *hw_cfg;
 336        int i, ret;
 337
 338        hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
 339
 340        /* register our interrupt-controller for hdmi/eDP/dsi/etc
 341         * to use for irqs routed through mdp:
 342         */
 343        ret = mdp5_irq_domain_init(mdp5_kms);
 344        if (ret)
 345                goto fail;
 346
 347        /* construct CRTCs and their private planes: */
 348        for (i = 0; i < hw_cfg->pipe_rgb.count; i++) {
 349                struct drm_plane *plane;
 350                struct drm_crtc *crtc;
 351
 352                plane = mdp5_plane_init(dev, crtcs[i], true,
 353                                hw_cfg->pipe_rgb.base[i]);
 354                if (IS_ERR(plane)) {
 355                        ret = PTR_ERR(plane);
 356                        dev_err(dev->dev, "failed to construct plane for %s (%d)\n",
 357                                        pipe2name(crtcs[i]), ret);
 358                        goto fail;
 359                }
 360
 361                crtc  = mdp5_crtc_init(dev, plane, i);
 362                if (IS_ERR(crtc)) {
 363                        ret = PTR_ERR(crtc);
 364                        dev_err(dev->dev, "failed to construct crtc for %s (%d)\n",
 365                                        pipe2name(crtcs[i]), ret);
 366                        goto fail;
 367                }
 368                priv->crtcs[priv->num_crtcs++] = crtc;
 369        }
 370
 371        /* Construct public planes: */
 372        for (i = 0; i < hw_cfg->pipe_vig.count; i++) {
 373                struct drm_plane *plane;
 374
 375                plane = mdp5_plane_init(dev, pub_planes[i], false,
 376                                hw_cfg->pipe_vig.base[i]);
 377                if (IS_ERR(plane)) {
 378                        ret = PTR_ERR(plane);
 379                        dev_err(dev->dev, "failed to construct %s plane: %d\n",
 380                                        pipe2name(pub_planes[i]), ret);
 381                        goto fail;
 382                }
 383        }
 384
 385        /* Construct encoders and modeset initialize connector devices
 386         * for each external display interface.
 387         */
 388        for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) {
 389                ret = modeset_init_intf(mdp5_kms, i);
 390                if (ret)
 391                        goto fail;
 392        }
 393
 394        return 0;
 395
 396fail:
 397        return ret;
 398}
 399
 400static void read_hw_revision(struct mdp5_kms *mdp5_kms,
 401                uint32_t *major, uint32_t *minor)
 402{
 403        uint32_t version;
 404
 405        mdp5_enable(mdp5_kms);
 406        version = mdp5_read(mdp5_kms, REG_MDSS_HW_VERSION);
 407        mdp5_disable(mdp5_kms);
 408
 409        *major = FIELD(version, MDSS_HW_VERSION_MAJOR);
 410        *minor = FIELD(version, MDSS_HW_VERSION_MINOR);
 411
 412        DBG("MDP5 version v%d.%d", *major, *minor);
 413}
 414
 415static int get_clk(struct platform_device *pdev, struct clk **clkp,
 416                const char *name)
 417{
 418        struct device *dev = &pdev->dev;
 419        struct clk *clk = devm_clk_get(dev, name);
 420        if (IS_ERR(clk)) {
 421                dev_err(dev, "failed to get %s (%ld)\n", name, PTR_ERR(clk));
 422                return PTR_ERR(clk);
 423        }
 424        *clkp = clk;
 425        return 0;
 426}
 427
 428struct msm_kms *mdp5_kms_init(struct drm_device *dev)
 429{
 430        struct platform_device *pdev = dev->platformdev;
 431        struct mdp5_cfg *config;
 432        struct mdp5_kms *mdp5_kms;
 433        struct msm_kms *kms = NULL;
 434        struct msm_mmu *mmu;
 435        uint32_t major, minor;
 436        int i, ret;
 437
 438        mdp5_kms = kzalloc(sizeof(*mdp5_kms), GFP_KERNEL);
 439        if (!mdp5_kms) {
 440                dev_err(dev->dev, "failed to allocate kms\n");
 441                ret = -ENOMEM;
 442                goto fail;
 443        }
 444
 445        spin_lock_init(&mdp5_kms->resource_lock);
 446
 447        mdp_kms_init(&mdp5_kms->base, &kms_funcs);
 448
 449        kms = &mdp5_kms->base.base;
 450
 451        mdp5_kms->dev = dev;
 452
 453        /* mdp5_kms->mmio actually represents the MDSS base address */
 454        mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5");
 455        if (IS_ERR(mdp5_kms->mmio)) {
 456                ret = PTR_ERR(mdp5_kms->mmio);
 457                goto fail;
 458        }
 459
 460        mdp5_kms->vbif = msm_ioremap(pdev, "vbif_phys", "VBIF");
 461        if (IS_ERR(mdp5_kms->vbif)) {
 462                ret = PTR_ERR(mdp5_kms->vbif);
 463                goto fail;
 464        }
 465
 466        mdp5_kms->vdd = devm_regulator_get(&pdev->dev, "vdd");
 467        if (IS_ERR(mdp5_kms->vdd)) {
 468                ret = PTR_ERR(mdp5_kms->vdd);
 469                goto fail;
 470        }
 471
 472        ret = regulator_enable(mdp5_kms->vdd);
 473        if (ret) {
 474                dev_err(dev->dev, "failed to enable regulator vdd: %d\n", ret);
 475                goto fail;
 476        }
 477
 478        ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus_clk");
 479        if (ret)
 480                goto fail;
 481        ret = get_clk(pdev, &mdp5_kms->ahb_clk, "iface_clk");
 482        if (ret)
 483                goto fail;
 484        ret = get_clk(pdev, &mdp5_kms->src_clk, "core_clk_src");
 485        if (ret)
 486                goto fail;
 487        ret = get_clk(pdev, &mdp5_kms->core_clk, "core_clk");
 488        if (ret)
 489                goto fail;
 490        ret = get_clk(pdev, &mdp5_kms->lut_clk, "lut_clk");
 491        if (ret)
 492                goto fail;
 493        ret = get_clk(pdev, &mdp5_kms->vsync_clk, "vsync_clk");
 494        if (ret)
 495                goto fail;
 496
 497        /* we need to set a default rate before enabling.  Set a safe
 498         * rate first, then figure out hw revision, and then set a
 499         * more optimal rate:
 500         */
 501        clk_set_rate(mdp5_kms->src_clk, 200000000);
 502
 503        read_hw_revision(mdp5_kms, &major, &minor);
 504
 505        mdp5_kms->cfg = mdp5_cfg_init(mdp5_kms, major, minor);
 506        if (IS_ERR(mdp5_kms->cfg)) {
 507                ret = PTR_ERR(mdp5_kms->cfg);
 508                mdp5_kms->cfg = NULL;
 509                goto fail;
 510        }
 511
 512        config = mdp5_cfg_get_config(mdp5_kms->cfg);
 513
 514        /* TODO: compute core clock rate at runtime */
 515        clk_set_rate(mdp5_kms->src_clk, config->hw->max_clk);
 516
 517        mdp5_kms->smp = mdp5_smp_init(mdp5_kms->dev, &config->hw->smp);
 518        if (IS_ERR(mdp5_kms->smp)) {
 519                ret = PTR_ERR(mdp5_kms->smp);
 520                mdp5_kms->smp = NULL;
 521                goto fail;
 522        }
 523
 524        mdp5_kms->ctlm = mdp5_ctlm_init(dev, mdp5_kms->mmio, config->hw);
 525        if (IS_ERR(mdp5_kms->ctlm)) {
 526                ret = PTR_ERR(mdp5_kms->ctlm);
 527                mdp5_kms->ctlm = NULL;
 528                goto fail;
 529        }
 530
 531        /* make sure things are off before attaching iommu (bootloader could
 532         * have left things on, in which case we'll start getting faults if
 533         * we don't disable):
 534         */
 535        mdp5_enable(mdp5_kms);
 536        for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
 537                if (mdp5_cfg_intf_is_virtual(config->hw->intf.connect[i]) ||
 538                                !config->hw->intf.base[i])
 539                        continue;
 540                mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0);
 541        }
 542        mdp5_disable(mdp5_kms);
 543        mdelay(16);
 544
 545        if (config->platform.iommu) {
 546                mmu = msm_iommu_new(&pdev->dev, config->platform.iommu);
 547                if (IS_ERR(mmu)) {
 548                        ret = PTR_ERR(mmu);
 549                        dev_err(dev->dev, "failed to init iommu: %d\n", ret);
 550                        goto fail;
 551                }
 552
 553                ret = mmu->funcs->attach(mmu, iommu_ports,
 554                                ARRAY_SIZE(iommu_ports));
 555                if (ret) {
 556                        dev_err(dev->dev, "failed to attach iommu: %d\n", ret);
 557                        mmu->funcs->destroy(mmu);
 558                        goto fail;
 559                }
 560        } else {
 561                dev_info(dev->dev, "no iommu, fallback to phys "
 562                                "contig buffers for scanout\n");
 563                mmu = NULL;
 564        }
 565        mdp5_kms->mmu = mmu;
 566
 567        mdp5_kms->id = msm_register_mmu(dev, mmu);
 568        if (mdp5_kms->id < 0) {
 569                ret = mdp5_kms->id;
 570                dev_err(dev->dev, "failed to register mdp5 iommu: %d\n", ret);
 571                goto fail;
 572        }
 573
 574        ret = modeset_init(mdp5_kms);
 575        if (ret) {
 576                dev_err(dev->dev, "modeset_init failed: %d\n", ret);
 577                goto fail;
 578        }
 579
 580        return kms;
 581
 582fail:
 583        if (kms)
 584                mdp5_destroy(kms);
 585        return ERR_PTR(ret);
 586}
 587