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#include <linux/of_irq.h>
  20
  21#include "msm_drv.h"
  22#include "msm_mmu.h"
  23#include "mdp5_kms.h"
  24
  25static const char *iommu_ports[] = {
  26                "mdp_0",
  27};
  28
  29static int mdp5_hw_init(struct msm_kms *kms)
  30{
  31        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
  32        struct platform_device *pdev = mdp5_kms->pdev;
  33        unsigned long flags;
  34
  35        pm_runtime_get_sync(&pdev->dev);
  36        mdp5_enable(mdp5_kms);
  37
  38        /* Magic unknown register writes:
  39         *
  40         *    W VBIF:0x004 00000001      (mdss_mdp.c:839)
  41         *    W MDP5:0x2e0 0xe9          (mdss_mdp.c:839)
  42         *    W MDP5:0x2e4 0x55          (mdss_mdp.c:839)
  43         *    W MDP5:0x3ac 0xc0000ccc    (mdss_mdp.c:839)
  44         *    W MDP5:0x3b4 0xc0000ccc    (mdss_mdp.c:839)
  45         *    W MDP5:0x3bc 0xcccccc      (mdss_mdp.c:839)
  46         *    W MDP5:0x4a8 0xcccc0c0     (mdss_mdp.c:839)
  47         *    W MDP5:0x4b0 0xccccc0c0    (mdss_mdp.c:839)
  48         *    W MDP5:0x4b8 0xccccc000    (mdss_mdp.c:839)
  49         *
  50         * Downstream fbdev driver gets these register offsets/values
  51         * from DT.. not really sure what these registers are or if
  52         * different values for different boards/SoC's, etc.  I guess
  53         * they are the golden registers.
  54         *
  55         * Not setting these does not seem to cause any problem.  But
  56         * we may be getting lucky with the bootloader initializing
  57         * them for us.  OTOH, if we can always count on the bootloader
  58         * setting the golden registers, then perhaps we don't need to
  59         * care.
  60         */
  61
  62        spin_lock_irqsave(&mdp5_kms->resource_lock, flags);
  63        mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, 0);
  64        spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags);
  65
  66        mdp5_ctlm_hw_reset(mdp5_kms->ctlm);
  67
  68        mdp5_disable(mdp5_kms);
  69        pm_runtime_put_sync(&pdev->dev);
  70
  71        return 0;
  72}
  73
  74static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
  75{
  76        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
  77        mdp5_enable(mdp5_kms);
  78}
  79
  80static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
  81{
  82        int i;
  83        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
  84        struct drm_plane *plane;
  85        struct drm_plane_state *plane_state;
  86
  87        for_each_plane_in_state(state, plane, plane_state, i)
  88                mdp5_plane_complete_commit(plane, plane_state);
  89
  90        mdp5_disable(mdp5_kms);
  91}
  92
  93static void mdp5_wait_for_crtc_commit_done(struct msm_kms *kms,
  94                                                struct drm_crtc *crtc)
  95{
  96        mdp5_crtc_wait_for_commit_done(crtc);
  97}
  98
  99static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate,
 100                struct drm_encoder *encoder)
 101{
 102        return rate;
 103}
 104
 105static int mdp5_set_split_display(struct msm_kms *kms,
 106                struct drm_encoder *encoder,
 107                struct drm_encoder *slave_encoder,
 108                bool is_cmd_mode)
 109{
 110        if (is_cmd_mode)
 111                return mdp5_cmd_encoder_set_split_display(encoder,
 112                                                        slave_encoder);
 113        else
 114                return mdp5_encoder_set_split_display(encoder, slave_encoder);
 115}
 116
 117static void mdp5_kms_destroy(struct msm_kms *kms)
 118{
 119        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
 120        struct msm_mmu *mmu = mdp5_kms->mmu;
 121
 122        if (mmu) {
 123                mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports));
 124                mmu->funcs->destroy(mmu);
 125        }
 126}
 127
 128static const struct mdp_kms_funcs kms_funcs = {
 129        .base = {
 130                .hw_init         = mdp5_hw_init,
 131                .irq_preinstall  = mdp5_irq_preinstall,
 132                .irq_postinstall = mdp5_irq_postinstall,
 133                .irq_uninstall   = mdp5_irq_uninstall,
 134                .irq             = mdp5_irq,
 135                .enable_vblank   = mdp5_enable_vblank,
 136                .disable_vblank  = mdp5_disable_vblank,
 137                .prepare_commit  = mdp5_prepare_commit,
 138                .complete_commit = mdp5_complete_commit,
 139                .wait_for_crtc_commit_done = mdp5_wait_for_crtc_commit_done,
 140                .get_format      = mdp_get_format,
 141                .round_pixclk    = mdp5_round_pixclk,
 142                .set_split_display = mdp5_set_split_display,
 143                .destroy         = mdp5_kms_destroy,
 144        },
 145        .set_irqmask         = mdp5_set_irqmask,
 146};
 147
 148int mdp5_disable(struct mdp5_kms *mdp5_kms)
 149{
 150        DBG("");
 151
 152        clk_disable_unprepare(mdp5_kms->ahb_clk);
 153        clk_disable_unprepare(mdp5_kms->axi_clk);
 154        clk_disable_unprepare(mdp5_kms->core_clk);
 155        if (mdp5_kms->lut_clk)
 156                clk_disable_unprepare(mdp5_kms->lut_clk);
 157
 158        return 0;
 159}
 160
 161int mdp5_enable(struct mdp5_kms *mdp5_kms)
 162{
 163        DBG("");
 164
 165        clk_prepare_enable(mdp5_kms->ahb_clk);
 166        clk_prepare_enable(mdp5_kms->axi_clk);
 167        clk_prepare_enable(mdp5_kms->core_clk);
 168        if (mdp5_kms->lut_clk)
 169                clk_prepare_enable(mdp5_kms->lut_clk);
 170
 171        return 0;
 172}
 173
 174static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
 175                enum mdp5_intf_type intf_type, int intf_num,
 176                enum mdp5_intf_mode intf_mode, struct mdp5_ctl *ctl)
 177{
 178        struct drm_device *dev = mdp5_kms->dev;
 179        struct msm_drm_private *priv = dev->dev_private;
 180        struct drm_encoder *encoder;
 181        struct mdp5_interface intf = {
 182                        .num    = intf_num,
 183                        .type   = intf_type,
 184                        .mode   = intf_mode,
 185        };
 186
 187        if ((intf_type == INTF_DSI) &&
 188                (intf_mode == MDP5_INTF_DSI_MODE_COMMAND))
 189                encoder = mdp5_cmd_encoder_init(dev, &intf, ctl);
 190        else
 191                encoder = mdp5_encoder_init(dev, &intf, ctl);
 192
 193        if (IS_ERR(encoder)) {
 194                dev_err(dev->dev, "failed to construct encoder\n");
 195                return encoder;
 196        }
 197
 198        encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
 199        priv->encoders[priv->num_encoders++] = encoder;
 200
 201        return encoder;
 202}
 203
 204static int get_dsi_id_from_intf(const struct mdp5_cfg_hw *hw_cfg, int intf_num)
 205{
 206        const enum mdp5_intf_type *intfs = hw_cfg->intf.connect;
 207        const int intf_cnt = ARRAY_SIZE(hw_cfg->intf.connect);
 208        int id = 0, i;
 209
 210        for (i = 0; i < intf_cnt; i++) {
 211                if (intfs[i] == INTF_DSI) {
 212                        if (intf_num == i)
 213                                return id;
 214
 215                        id++;
 216                }
 217        }
 218
 219        return -EINVAL;
 220}
 221
 222static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
 223{
 224        struct drm_device *dev = mdp5_kms->dev;
 225        struct msm_drm_private *priv = dev->dev_private;
 226        const struct mdp5_cfg_hw *hw_cfg =
 227                                        mdp5_cfg_get_hw_config(mdp5_kms->cfg);
 228        enum mdp5_intf_type intf_type = hw_cfg->intf.connect[intf_num];
 229        struct mdp5_ctl_manager *ctlm = mdp5_kms->ctlm;
 230        struct mdp5_ctl *ctl;
 231        struct drm_encoder *encoder;
 232        int ret = 0;
 233
 234        switch (intf_type) {
 235        case INTF_DISABLED:
 236                break;
 237        case INTF_eDP:
 238                if (!priv->edp)
 239                        break;
 240
 241                ctl = mdp5_ctlm_request(ctlm, intf_num);
 242                if (!ctl) {
 243                        ret = -EINVAL;
 244                        break;
 245                }
 246
 247                encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num,
 248                                        MDP5_INTF_MODE_NONE, ctl);
 249                if (IS_ERR(encoder)) {
 250                        ret = PTR_ERR(encoder);
 251                        break;
 252                }
 253
 254                ret = msm_edp_modeset_init(priv->edp, dev, encoder);
 255                break;
 256        case INTF_HDMI:
 257                if (!priv->hdmi)
 258                        break;
 259
 260                ctl = mdp5_ctlm_request(ctlm, intf_num);
 261                if (!ctl) {
 262                        ret = -EINVAL;
 263                        break;
 264                }
 265
 266                encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num,
 267                                        MDP5_INTF_MODE_NONE, ctl);
 268                if (IS_ERR(encoder)) {
 269                        ret = PTR_ERR(encoder);
 270                        break;
 271                }
 272
 273                ret = msm_hdmi_modeset_init(priv->hdmi, dev, encoder);
 274                break;
 275        case INTF_DSI:
 276        {
 277                int dsi_id = get_dsi_id_from_intf(hw_cfg, intf_num);
 278                struct drm_encoder *dsi_encs[MSM_DSI_ENCODER_NUM];
 279                enum mdp5_intf_mode mode;
 280                int i;
 281
 282                if ((dsi_id >= ARRAY_SIZE(priv->dsi)) || (dsi_id < 0)) {
 283                        dev_err(dev->dev, "failed to find dsi from intf %d\n",
 284                                intf_num);
 285                        ret = -EINVAL;
 286                        break;
 287                }
 288
 289                if (!priv->dsi[dsi_id])
 290                        break;
 291
 292                ctl = mdp5_ctlm_request(ctlm, intf_num);
 293                if (!ctl) {
 294                        ret = -EINVAL;
 295                        break;
 296                }
 297
 298                for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) {
 299                        mode = (i == MSM_DSI_CMD_ENCODER_ID) ?
 300                                MDP5_INTF_DSI_MODE_COMMAND :
 301                                MDP5_INTF_DSI_MODE_VIDEO;
 302                        dsi_encs[i] = construct_encoder(mdp5_kms, INTF_DSI,
 303                                                        intf_num, mode, ctl);
 304                        if (IS_ERR(dsi_encs[i])) {
 305                                ret = PTR_ERR(dsi_encs[i]);
 306                                break;
 307                        }
 308                }
 309
 310                ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, dsi_encs);
 311                break;
 312        }
 313        default:
 314                dev_err(dev->dev, "unknown intf: %d\n", intf_type);
 315                ret = -EINVAL;
 316                break;
 317        }
 318
 319        return ret;
 320}
 321
 322static int modeset_init(struct mdp5_kms *mdp5_kms)
 323{
 324        static const enum mdp5_pipe crtcs[] = {
 325                        SSPP_RGB0, SSPP_RGB1, SSPP_RGB2, SSPP_RGB3,
 326        };
 327        static const enum mdp5_pipe vig_planes[] = {
 328                        SSPP_VIG0, SSPP_VIG1, SSPP_VIG2, SSPP_VIG3,
 329        };
 330        static const enum mdp5_pipe dma_planes[] = {
 331                        SSPP_DMA0, SSPP_DMA1,
 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        /* construct CRTCs and their private planes: */
 341        for (i = 0; i < hw_cfg->pipe_rgb.count; i++) {
 342                struct drm_plane *plane;
 343                struct drm_crtc *crtc;
 344
 345                plane = mdp5_plane_init(dev, crtcs[i], true,
 346                        hw_cfg->pipe_rgb.base[i], hw_cfg->pipe_rgb.caps);
 347                if (IS_ERR(plane)) {
 348                        ret = PTR_ERR(plane);
 349                        dev_err(dev->dev, "failed to construct plane for %s (%d)\n",
 350                                        pipe2name(crtcs[i]), ret);
 351                        goto fail;
 352                }
 353
 354                crtc  = mdp5_crtc_init(dev, plane, i);
 355                if (IS_ERR(crtc)) {
 356                        ret = PTR_ERR(crtc);
 357                        dev_err(dev->dev, "failed to construct crtc for %s (%d)\n",
 358                                        pipe2name(crtcs[i]), ret);
 359                        goto fail;
 360                }
 361                priv->crtcs[priv->num_crtcs++] = crtc;
 362        }
 363
 364        /* Construct video planes: */
 365        for (i = 0; i < hw_cfg->pipe_vig.count; i++) {
 366                struct drm_plane *plane;
 367
 368                plane = mdp5_plane_init(dev, vig_planes[i], false,
 369                        hw_cfg->pipe_vig.base[i], hw_cfg->pipe_vig.caps);
 370                if (IS_ERR(plane)) {
 371                        ret = PTR_ERR(plane);
 372                        dev_err(dev->dev, "failed to construct %s plane: %d\n",
 373                                        pipe2name(vig_planes[i]), ret);
 374                        goto fail;
 375                }
 376        }
 377
 378        /* DMA planes */
 379        for (i = 0; i < hw_cfg->pipe_dma.count; i++) {
 380                struct drm_plane *plane;
 381
 382                plane = mdp5_plane_init(dev, dma_planes[i], false,
 383                                hw_cfg->pipe_dma.base[i], hw_cfg->pipe_dma.caps);
 384                if (IS_ERR(plane)) {
 385                        ret = PTR_ERR(plane);
 386                        dev_err(dev->dev, "failed to construct %s plane: %d\n",
 387                                        pipe2name(dma_planes[i]), ret);
 388                        goto fail;
 389                }
 390        }
 391
 392        /* Construct encoders and modeset initialize connector devices
 393         * for each external display interface.
 394         */
 395        for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) {
 396                ret = modeset_init_intf(mdp5_kms, i);
 397                if (ret)
 398                        goto fail;
 399        }
 400
 401        return 0;
 402
 403fail:
 404        return ret;
 405}
 406
 407static void read_mdp_hw_revision(struct mdp5_kms *mdp5_kms,
 408                                 u32 *major, u32 *minor)
 409{
 410        u32 version;
 411
 412        mdp5_enable(mdp5_kms);
 413        version = mdp5_read(mdp5_kms, REG_MDP5_HW_VERSION);
 414        mdp5_disable(mdp5_kms);
 415
 416        *major = FIELD(version, MDP5_HW_VERSION_MAJOR);
 417        *minor = FIELD(version, MDP5_HW_VERSION_MINOR);
 418
 419        DBG("MDP5 version v%d.%d", *major, *minor);
 420}
 421
 422static int get_clk(struct platform_device *pdev, struct clk **clkp,
 423                const char *name, bool mandatory)
 424{
 425        struct device *dev = &pdev->dev;
 426        struct clk *clk = devm_clk_get(dev, name);
 427        if (IS_ERR(clk) && mandatory) {
 428                dev_err(dev, "failed to get %s (%ld)\n", name, PTR_ERR(clk));
 429                return PTR_ERR(clk);
 430        }
 431        if (IS_ERR(clk))
 432                DBG("skipping %s", name);
 433        else
 434                *clkp = clk;
 435
 436        return 0;
 437}
 438
 439static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc)
 440{
 441        struct drm_device *dev = crtc->dev;
 442        struct drm_encoder *encoder;
 443
 444        drm_for_each_encoder(encoder, dev)
 445                if (encoder->crtc == crtc)
 446                        return encoder;
 447
 448        return NULL;
 449}
 450
 451static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe,
 452                               unsigned int flags, int *vpos, int *hpos,
 453                               ktime_t *stime, ktime_t *etime,
 454                               const struct drm_display_mode *mode)
 455{
 456        struct msm_drm_private *priv = dev->dev_private;
 457        struct drm_crtc *crtc;
 458        struct drm_encoder *encoder;
 459        int line, vsw, vbp, vactive_start, vactive_end, vfp_end;
 460        int ret = 0;
 461
 462        crtc = priv->crtcs[pipe];
 463        if (!crtc) {
 464                DRM_ERROR("Invalid crtc %d\n", pipe);
 465                return 0;
 466        }
 467
 468        encoder = get_encoder_from_crtc(crtc);
 469        if (!encoder) {
 470                DRM_ERROR("no encoder found for crtc %d\n", pipe);
 471                return 0;
 472        }
 473
 474        ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
 475
 476        vsw = mode->crtc_vsync_end - mode->crtc_vsync_start;
 477        vbp = mode->crtc_vtotal - mode->crtc_vsync_end;
 478
 479        /*
 480         * the line counter is 1 at the start of the VSYNC pulse and VTOTAL at
 481         * the end of VFP. Translate the porch values relative to the line
 482         * counter positions.
 483         */
 484
 485        vactive_start = vsw + vbp + 1;
 486
 487        vactive_end = vactive_start + mode->crtc_vdisplay;
 488
 489        /* last scan line before VSYNC */
 490        vfp_end = mode->crtc_vtotal;
 491
 492        if (stime)
 493                *stime = ktime_get();
 494
 495        line = mdp5_encoder_get_linecount(encoder);
 496
 497        if (line < vactive_start) {
 498                line -= vactive_start;
 499                ret |= DRM_SCANOUTPOS_IN_VBLANK;
 500        } else if (line > vactive_end) {
 501                line = line - vfp_end - vactive_start;
 502                ret |= DRM_SCANOUTPOS_IN_VBLANK;
 503        } else {
 504                line -= vactive_start;
 505        }
 506
 507        *vpos = line;
 508        *hpos = 0;
 509
 510        if (etime)
 511                *etime = ktime_get();
 512
 513        return ret;
 514}
 515
 516static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
 517                                     int *max_error,
 518                                     struct timeval *vblank_time,
 519                                     unsigned flags)
 520{
 521        struct msm_drm_private *priv = dev->dev_private;
 522        struct drm_crtc *crtc;
 523
 524        if (pipe < 0 || pipe >= priv->num_crtcs) {
 525                DRM_ERROR("Invalid crtc %d\n", pipe);
 526                return -EINVAL;
 527        }
 528
 529        crtc = priv->crtcs[pipe];
 530        if (!crtc) {
 531                DRM_ERROR("Invalid crtc %d\n", pipe);
 532                return -EINVAL;
 533        }
 534
 535        return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
 536                                                     vblank_time, flags,
 537                                                     &crtc->mode);
 538}
 539
 540static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
 541{
 542        struct msm_drm_private *priv = dev->dev_private;
 543        struct drm_crtc *crtc;
 544        struct drm_encoder *encoder;
 545
 546        if (pipe < 0 || pipe >= priv->num_crtcs)
 547                return 0;
 548
 549        crtc = priv->crtcs[pipe];
 550        if (!crtc)
 551                return 0;
 552
 553        encoder = get_encoder_from_crtc(crtc);
 554        if (!encoder)
 555                return 0;
 556
 557        return mdp5_encoder_get_framecount(encoder);
 558}
 559
 560struct msm_kms *mdp5_kms_init(struct drm_device *dev)
 561{
 562        struct msm_drm_private *priv = dev->dev_private;
 563        struct platform_device *pdev;
 564        struct mdp5_kms *mdp5_kms;
 565        struct mdp5_cfg *config;
 566        struct msm_kms *kms;
 567        struct msm_mmu *mmu;
 568        int irq, i, ret;
 569
 570        /* priv->kms would have been populated by the MDP5 driver */
 571        kms = priv->kms;
 572        if (!kms)
 573                return NULL;
 574
 575        mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
 576
 577        mdp_kms_init(&mdp5_kms->base, &kms_funcs);
 578
 579        pdev = mdp5_kms->pdev;
 580
 581        irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
 582        if (irq < 0) {
 583                ret = irq;
 584                dev_err(&pdev->dev, "failed to get irq: %d\n", ret);
 585                goto fail;
 586        }
 587
 588        kms->irq = irq;
 589
 590        config = mdp5_cfg_get_config(mdp5_kms->cfg);
 591
 592        /* make sure things are off before attaching iommu (bootloader could
 593         * have left things on, in which case we'll start getting faults if
 594         * we don't disable):
 595         */
 596        mdp5_enable(mdp5_kms);
 597        for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
 598                if (mdp5_cfg_intf_is_virtual(config->hw->intf.connect[i]) ||
 599                    !config->hw->intf.base[i])
 600                        continue;
 601                mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0);
 602
 603                mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(i), 0x3);
 604        }
 605        mdp5_disable(mdp5_kms);
 606        mdelay(16);
 607
 608        if (config->platform.iommu) {
 609                mmu = msm_iommu_new(&pdev->dev, config->platform.iommu);
 610                if (IS_ERR(mmu)) {
 611                        ret = PTR_ERR(mmu);
 612                        dev_err(&pdev->dev, "failed to init iommu: %d\n", ret);
 613                        iommu_domain_free(config->platform.iommu);
 614                        goto fail;
 615                }
 616
 617                ret = mmu->funcs->attach(mmu, iommu_ports,
 618                                ARRAY_SIZE(iommu_ports));
 619                if (ret) {
 620                        dev_err(&pdev->dev, "failed to attach iommu: %d\n",
 621                                ret);
 622                        mmu->funcs->destroy(mmu);
 623                        goto fail;
 624                }
 625        } else {
 626                dev_info(&pdev->dev,
 627                         "no iommu, fallback to phys contig buffers for scanout\n");
 628                mmu = NULL;
 629        }
 630        mdp5_kms->mmu = mmu;
 631
 632        mdp5_kms->id = msm_register_mmu(dev, mmu);
 633        if (mdp5_kms->id < 0) {
 634                ret = mdp5_kms->id;
 635                dev_err(&pdev->dev, "failed to register mdp5 iommu: %d\n", ret);
 636                goto fail;
 637        }
 638
 639        ret = modeset_init(mdp5_kms);
 640        if (ret) {
 641                dev_err(&pdev->dev, "modeset_init failed: %d\n", ret);
 642                goto fail;
 643        }
 644
 645        dev->mode_config.min_width = 0;
 646        dev->mode_config.min_height = 0;
 647        dev->mode_config.max_width = config->hw->lm.max_width;
 648        dev->mode_config.max_height = config->hw->lm.max_height;
 649
 650        dev->driver->get_vblank_timestamp = mdp5_get_vblank_timestamp;
 651        dev->driver->get_scanout_position = mdp5_get_scanoutpos;
 652        dev->driver->get_vblank_counter = mdp5_get_vblank_counter;
 653        dev->max_vblank_count = 0xffffffff;
 654        dev->vblank_disable_immediate = true;
 655
 656        return kms;
 657fail:
 658        if (kms)
 659                mdp5_kms_destroy(kms);
 660        return ERR_PTR(ret);
 661}
 662
 663static void mdp5_destroy(struct platform_device *pdev)
 664{
 665        struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
 666
 667        if (mdp5_kms->ctlm)
 668                mdp5_ctlm_destroy(mdp5_kms->ctlm);
 669        if (mdp5_kms->smp)
 670                mdp5_smp_destroy(mdp5_kms->smp);
 671        if (mdp5_kms->cfg)
 672                mdp5_cfg_destroy(mdp5_kms->cfg);
 673
 674        if (mdp5_kms->rpm_enabled)
 675                pm_runtime_disable(&pdev->dev);
 676}
 677
 678static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
 679{
 680        struct msm_drm_private *priv = dev->dev_private;
 681        struct mdp5_kms *mdp5_kms;
 682        struct mdp5_cfg *config;
 683        u32 major, minor;
 684        int ret;
 685
 686        mdp5_kms = devm_kzalloc(&pdev->dev, sizeof(*mdp5_kms), GFP_KERNEL);
 687        if (!mdp5_kms) {
 688                ret = -ENOMEM;
 689                goto fail;
 690        }
 691
 692        platform_set_drvdata(pdev, mdp5_kms);
 693
 694        spin_lock_init(&mdp5_kms->resource_lock);
 695
 696        mdp5_kms->dev = dev;
 697        mdp5_kms->pdev = pdev;
 698
 699        mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5");
 700        if (IS_ERR(mdp5_kms->mmio)) {
 701                ret = PTR_ERR(mdp5_kms->mmio);
 702                goto fail;
 703        }
 704
 705        /* mandatory clocks: */
 706        ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus_clk", true);
 707        if (ret)
 708                goto fail;
 709        ret = get_clk(pdev, &mdp5_kms->ahb_clk, "iface_clk", true);
 710        if (ret)
 711                goto fail;
 712        ret = get_clk(pdev, &mdp5_kms->core_clk, "core_clk", true);
 713        if (ret)
 714                goto fail;
 715        ret = get_clk(pdev, &mdp5_kms->vsync_clk, "vsync_clk", true);
 716        if (ret)
 717                goto fail;
 718
 719        /* optional clocks: */
 720        get_clk(pdev, &mdp5_kms->lut_clk, "lut_clk", false);
 721
 722        /* we need to set a default rate before enabling.  Set a safe
 723         * rate first, then figure out hw revision, and then set a
 724         * more optimal rate:
 725         */
 726        clk_set_rate(mdp5_kms->core_clk, 200000000);
 727
 728        pm_runtime_enable(&pdev->dev);
 729        mdp5_kms->rpm_enabled = true;
 730
 731        read_mdp_hw_revision(mdp5_kms, &major, &minor);
 732
 733        mdp5_kms->cfg = mdp5_cfg_init(mdp5_kms, major, minor);
 734        if (IS_ERR(mdp5_kms->cfg)) {
 735                ret = PTR_ERR(mdp5_kms->cfg);
 736                mdp5_kms->cfg = NULL;
 737                goto fail;
 738        }
 739
 740        config = mdp5_cfg_get_config(mdp5_kms->cfg);
 741        mdp5_kms->caps = config->hw->mdp.caps;
 742
 743        /* TODO: compute core clock rate at runtime */
 744        clk_set_rate(mdp5_kms->core_clk, config->hw->max_clk);
 745
 746        /*
 747         * Some chipsets have a Shared Memory Pool (SMP), while others
 748         * have dedicated latency buffering per source pipe instead;
 749         * this section initializes the SMP:
 750         */
 751        if (mdp5_kms->caps & MDP_CAP_SMP) {
 752                mdp5_kms->smp = mdp5_smp_init(mdp5_kms->dev, &config->hw->smp);
 753                if (IS_ERR(mdp5_kms->smp)) {
 754                        ret = PTR_ERR(mdp5_kms->smp);
 755                        mdp5_kms->smp = NULL;
 756                        goto fail;
 757                }
 758        }
 759
 760        mdp5_kms->ctlm = mdp5_ctlm_init(dev, mdp5_kms->mmio, mdp5_kms->cfg);
 761        if (IS_ERR(mdp5_kms->ctlm)) {
 762                ret = PTR_ERR(mdp5_kms->ctlm);
 763                mdp5_kms->ctlm = NULL;
 764                goto fail;
 765        }
 766
 767        /* set uninit-ed kms */
 768        priv->kms = &mdp5_kms->base.base;
 769
 770        return 0;
 771fail:
 772        mdp5_destroy(pdev);
 773        return ret;
 774}
 775
 776static int mdp5_bind(struct device *dev, struct device *master, void *data)
 777{
 778        struct drm_device *ddev = dev_get_drvdata(master);
 779        struct platform_device *pdev = to_platform_device(dev);
 780
 781        DBG("");
 782
 783        return mdp5_init(pdev, ddev);
 784}
 785
 786static void mdp5_unbind(struct device *dev, struct device *master,
 787                        void *data)
 788{
 789        struct platform_device *pdev = to_platform_device(dev);
 790
 791        mdp5_destroy(pdev);
 792}
 793
 794static const struct component_ops mdp5_ops = {
 795        .bind   = mdp5_bind,
 796        .unbind = mdp5_unbind,
 797};
 798
 799static int mdp5_dev_probe(struct platform_device *pdev)
 800{
 801        DBG("");
 802        return component_add(&pdev->dev, &mdp5_ops);
 803}
 804
 805static int mdp5_dev_remove(struct platform_device *pdev)
 806{
 807        DBG("");
 808        component_del(&pdev->dev, &mdp5_ops);
 809        return 0;
 810}
 811
 812static const struct of_device_id mdp5_dt_match[] = {
 813        { .compatible = "qcom,mdp5", },
 814        /* to support downstream DT files */
 815        { .compatible = "qcom,mdss_mdp", },
 816        {}
 817};
 818MODULE_DEVICE_TABLE(of, mdp5_dt_match);
 819
 820static struct platform_driver mdp5_driver = {
 821        .probe = mdp5_dev_probe,
 822        .remove = mdp5_dev_remove,
 823        .driver = {
 824                .name = "msm_mdp",
 825                .of_match_table = mdp5_dt_match,
 826        },
 827};
 828
 829void __init msm_mdp_register(void)
 830{
 831        DBG("");
 832        platform_driver_register(&mdp5_driver);
 833}
 834
 835void __exit msm_mdp_unregister(void)
 836{
 837        DBG("");
 838        platform_driver_unregister(&mdp5_driver);
 839}
 840