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        if (mdp5_kms->lut_clk)
 181                clk_disable_unprepare(mdp5_kms->lut_clk);
 182
 183        return 0;
 184}
 185
 186int mdp5_enable(struct mdp5_kms *mdp5_kms)
 187{
 188        DBG("");
 189
 190        clk_prepare_enable(mdp5_kms->ahb_clk);
 191        clk_prepare_enable(mdp5_kms->axi_clk);
 192        clk_prepare_enable(mdp5_kms->core_clk);
 193        if (mdp5_kms->lut_clk)
 194                clk_prepare_enable(mdp5_kms->lut_clk);
 195
 196        return 0;
 197}
 198
 199static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
 200                enum mdp5_intf_type intf_type, int intf_num,
 201                enum mdp5_intf_mode intf_mode, struct mdp5_ctl *ctl)
 202{
 203        struct drm_device *dev = mdp5_kms->dev;
 204        struct msm_drm_private *priv = dev->dev_private;
 205        struct drm_encoder *encoder;
 206        struct mdp5_interface intf = {
 207                        .num    = intf_num,
 208                        .type   = intf_type,
 209                        .mode   = intf_mode,
 210        };
 211
 212        if ((intf_type == INTF_DSI) &&
 213                (intf_mode == MDP5_INTF_DSI_MODE_COMMAND))
 214                encoder = mdp5_cmd_encoder_init(dev, &intf, ctl);
 215        else
 216                encoder = mdp5_encoder_init(dev, &intf, ctl);
 217
 218        if (IS_ERR(encoder)) {
 219                dev_err(dev->dev, "failed to construct encoder\n");
 220                return encoder;
 221        }
 222
 223        encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
 224        priv->encoders[priv->num_encoders++] = encoder;
 225
 226        return encoder;
 227}
 228
 229static int get_dsi_id_from_intf(const struct mdp5_cfg_hw *hw_cfg, int intf_num)
 230{
 231        const enum mdp5_intf_type *intfs = hw_cfg->intf.connect;
 232        const int intf_cnt = ARRAY_SIZE(hw_cfg->intf.connect);
 233        int id = 0, i;
 234
 235        for (i = 0; i < intf_cnt; i++) {
 236                if (intfs[i] == INTF_DSI) {
 237                        if (intf_num == i)
 238                                return id;
 239
 240                        id++;
 241                }
 242        }
 243
 244        return -EINVAL;
 245}
 246
 247static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
 248{
 249        struct drm_device *dev = mdp5_kms->dev;
 250        struct msm_drm_private *priv = dev->dev_private;
 251        const struct mdp5_cfg_hw *hw_cfg =
 252                                        mdp5_cfg_get_hw_config(mdp5_kms->cfg);
 253        enum mdp5_intf_type intf_type = hw_cfg->intf.connect[intf_num];
 254        struct mdp5_ctl_manager *ctlm = mdp5_kms->ctlm;
 255        struct mdp5_ctl *ctl;
 256        struct drm_encoder *encoder;
 257        int ret = 0;
 258
 259        switch (intf_type) {
 260        case INTF_DISABLED:
 261                break;
 262        case INTF_eDP:
 263                if (!priv->edp)
 264                        break;
 265
 266                ctl = mdp5_ctlm_request(ctlm, intf_num);
 267                if (!ctl) {
 268                        ret = -EINVAL;
 269                        break;
 270                }
 271
 272                encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num,
 273                                        MDP5_INTF_MODE_NONE, ctl);
 274                if (IS_ERR(encoder)) {
 275                        ret = PTR_ERR(encoder);
 276                        break;
 277                }
 278
 279                ret = msm_edp_modeset_init(priv->edp, dev, encoder);
 280                break;
 281        case INTF_HDMI:
 282                if (!priv->hdmi)
 283                        break;
 284
 285                ctl = mdp5_ctlm_request(ctlm, intf_num);
 286                if (!ctl) {
 287                        ret = -EINVAL;
 288                        break;
 289                }
 290
 291                encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num,
 292                                        MDP5_INTF_MODE_NONE, ctl);
 293                if (IS_ERR(encoder)) {
 294                        ret = PTR_ERR(encoder);
 295                        break;
 296                }
 297
 298                ret = hdmi_modeset_init(priv->hdmi, dev, encoder);
 299                break;
 300        case INTF_DSI:
 301        {
 302                int dsi_id = get_dsi_id_from_intf(hw_cfg, intf_num);
 303                struct drm_encoder *dsi_encs[MSM_DSI_ENCODER_NUM];
 304                enum mdp5_intf_mode mode;
 305                int i;
 306
 307                if ((dsi_id >= ARRAY_SIZE(priv->dsi)) || (dsi_id < 0)) {
 308                        dev_err(dev->dev, "failed to find dsi from intf %d\n",
 309                                intf_num);
 310                        ret = -EINVAL;
 311                        break;
 312                }
 313
 314                if (!priv->dsi[dsi_id])
 315                        break;
 316
 317                ctl = mdp5_ctlm_request(ctlm, intf_num);
 318                if (!ctl) {
 319                        ret = -EINVAL;
 320                        break;
 321                }
 322
 323                for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) {
 324                        mode = (i == MSM_DSI_CMD_ENCODER_ID) ?
 325                                MDP5_INTF_DSI_MODE_COMMAND :
 326                                MDP5_INTF_DSI_MODE_VIDEO;
 327                        dsi_encs[i] = construct_encoder(mdp5_kms, INTF_DSI,
 328                                                        intf_num, mode, ctl);
 329                        if (IS_ERR(dsi_encs[i])) {
 330                                ret = PTR_ERR(dsi_encs[i]);
 331                                break;
 332                        }
 333                }
 334
 335                ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, dsi_encs);
 336                break;
 337        }
 338        default:
 339                dev_err(dev->dev, "unknown intf: %d\n", intf_type);
 340                ret = -EINVAL;
 341                break;
 342        }
 343
 344        return ret;
 345}
 346
 347static int modeset_init(struct mdp5_kms *mdp5_kms)
 348{
 349        static const enum mdp5_pipe crtcs[] = {
 350                        SSPP_RGB0, SSPP_RGB1, SSPP_RGB2, SSPP_RGB3,
 351        };
 352        static const enum mdp5_pipe vig_planes[] = {
 353                        SSPP_VIG0, SSPP_VIG1, SSPP_VIG2, SSPP_VIG3,
 354        };
 355        static const enum mdp5_pipe dma_planes[] = {
 356                        SSPP_DMA0, SSPP_DMA1,
 357        };
 358        struct drm_device *dev = mdp5_kms->dev;
 359        struct msm_drm_private *priv = dev->dev_private;
 360        const struct mdp5_cfg_hw *hw_cfg;
 361        int i, ret;
 362
 363        hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
 364
 365        /* register our interrupt-controller for hdmi/eDP/dsi/etc
 366         * to use for irqs routed through mdp:
 367         */
 368        ret = mdp5_irq_domain_init(mdp5_kms);
 369        if (ret)
 370                goto fail;
 371
 372        /* construct CRTCs and their private planes: */
 373        for (i = 0; i < hw_cfg->pipe_rgb.count; i++) {
 374                struct drm_plane *plane;
 375                struct drm_crtc *crtc;
 376
 377                plane = mdp5_plane_init(dev, crtcs[i], true,
 378                        hw_cfg->pipe_rgb.base[i], hw_cfg->pipe_rgb.caps);
 379                if (IS_ERR(plane)) {
 380                        ret = PTR_ERR(plane);
 381                        dev_err(dev->dev, "failed to construct plane for %s (%d)\n",
 382                                        pipe2name(crtcs[i]), ret);
 383                        goto fail;
 384                }
 385
 386                crtc  = mdp5_crtc_init(dev, plane, i);
 387                if (IS_ERR(crtc)) {
 388                        ret = PTR_ERR(crtc);
 389                        dev_err(dev->dev, "failed to construct crtc for %s (%d)\n",
 390                                        pipe2name(crtcs[i]), ret);
 391                        goto fail;
 392                }
 393                priv->crtcs[priv->num_crtcs++] = crtc;
 394        }
 395
 396        /* Construct video planes: */
 397        for (i = 0; i < hw_cfg->pipe_vig.count; i++) {
 398                struct drm_plane *plane;
 399
 400                plane = mdp5_plane_init(dev, vig_planes[i], false,
 401                        hw_cfg->pipe_vig.base[i], hw_cfg->pipe_vig.caps);
 402                if (IS_ERR(plane)) {
 403                        ret = PTR_ERR(plane);
 404                        dev_err(dev->dev, "failed to construct %s plane: %d\n",
 405                                        pipe2name(vig_planes[i]), ret);
 406                        goto fail;
 407                }
 408        }
 409
 410        /* DMA planes */
 411        for (i = 0; i < hw_cfg->pipe_dma.count; i++) {
 412                struct drm_plane *plane;
 413
 414                plane = mdp5_plane_init(dev, dma_planes[i], false,
 415                                hw_cfg->pipe_dma.base[i], hw_cfg->pipe_dma.caps);
 416                if (IS_ERR(plane)) {
 417                        ret = PTR_ERR(plane);
 418                        dev_err(dev->dev, "failed to construct %s plane: %d\n",
 419                                        pipe2name(dma_planes[i]), ret);
 420                        goto fail;
 421                }
 422        }
 423
 424        /* Construct encoders and modeset initialize connector devices
 425         * for each external display interface.
 426         */
 427        for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) {
 428                ret = modeset_init_intf(mdp5_kms, i);
 429                if (ret)
 430                        goto fail;
 431        }
 432
 433        return 0;
 434
 435fail:
 436        return ret;
 437}
 438
 439static void read_hw_revision(struct mdp5_kms *mdp5_kms,
 440                uint32_t *major, uint32_t *minor)
 441{
 442        uint32_t version;
 443
 444        mdp5_enable(mdp5_kms);
 445        version = mdp5_read(mdp5_kms, REG_MDSS_HW_VERSION);
 446        mdp5_disable(mdp5_kms);
 447
 448        *major = FIELD(version, MDSS_HW_VERSION_MAJOR);
 449        *minor = FIELD(version, MDSS_HW_VERSION_MINOR);
 450
 451        DBG("MDP5 version v%d.%d", *major, *minor);
 452}
 453
 454static int get_clk(struct platform_device *pdev, struct clk **clkp,
 455                const char *name)
 456{
 457        struct device *dev = &pdev->dev;
 458        struct clk *clk = devm_clk_get(dev, name);
 459        if (IS_ERR(clk)) {
 460                dev_err(dev, "failed to get %s (%ld)\n", name, PTR_ERR(clk));
 461                return PTR_ERR(clk);
 462        }
 463        *clkp = clk;
 464        return 0;
 465}
 466
 467struct msm_kms *mdp5_kms_init(struct drm_device *dev)
 468{
 469        struct platform_device *pdev = dev->platformdev;
 470        struct mdp5_cfg *config;
 471        struct mdp5_kms *mdp5_kms;
 472        struct msm_kms *kms = NULL;
 473        struct msm_mmu *mmu;
 474        uint32_t major, minor;
 475        int i, ret;
 476
 477        mdp5_kms = kzalloc(sizeof(*mdp5_kms), GFP_KERNEL);
 478        if (!mdp5_kms) {
 479                dev_err(dev->dev, "failed to allocate kms\n");
 480                ret = -ENOMEM;
 481                goto fail;
 482        }
 483
 484        spin_lock_init(&mdp5_kms->resource_lock);
 485
 486        mdp_kms_init(&mdp5_kms->base, &kms_funcs);
 487
 488        kms = &mdp5_kms->base.base;
 489
 490        mdp5_kms->dev = dev;
 491
 492        /* mdp5_kms->mmio actually represents the MDSS base address */
 493        mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5");
 494        if (IS_ERR(mdp5_kms->mmio)) {
 495                ret = PTR_ERR(mdp5_kms->mmio);
 496                goto fail;
 497        }
 498
 499        mdp5_kms->vbif = msm_ioremap(pdev, "vbif_phys", "VBIF");
 500        if (IS_ERR(mdp5_kms->vbif)) {
 501                ret = PTR_ERR(mdp5_kms->vbif);
 502                goto fail;
 503        }
 504
 505        mdp5_kms->vdd = devm_regulator_get(&pdev->dev, "vdd");
 506        if (IS_ERR(mdp5_kms->vdd)) {
 507                ret = PTR_ERR(mdp5_kms->vdd);
 508                goto fail;
 509        }
 510
 511        ret = regulator_enable(mdp5_kms->vdd);
 512        if (ret) {
 513                dev_err(dev->dev, "failed to enable regulator vdd: %d\n", ret);
 514                goto fail;
 515        }
 516
 517        ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus_clk");
 518        if (ret)
 519                goto fail;
 520        ret = get_clk(pdev, &mdp5_kms->ahb_clk, "iface_clk");
 521        if (ret)
 522                goto fail;
 523        ret = get_clk(pdev, &mdp5_kms->src_clk, "core_clk_src");
 524        if (ret)
 525                goto fail;
 526        ret = get_clk(pdev, &mdp5_kms->core_clk, "core_clk");
 527        if (ret)
 528                goto fail;
 529        ret = get_clk(pdev, &mdp5_kms->lut_clk, "lut_clk");
 530        if (ret)
 531                DBG("failed to get (optional) lut_clk clock");
 532        ret = get_clk(pdev, &mdp5_kms->vsync_clk, "vsync_clk");
 533        if (ret)
 534                goto fail;
 535
 536        /* we need to set a default rate before enabling.  Set a safe
 537         * rate first, then figure out hw revision, and then set a
 538         * more optimal rate:
 539         */
 540        clk_set_rate(mdp5_kms->src_clk, 200000000);
 541
 542        read_hw_revision(mdp5_kms, &major, &minor);
 543
 544        mdp5_kms->cfg = mdp5_cfg_init(mdp5_kms, major, minor);
 545        if (IS_ERR(mdp5_kms->cfg)) {
 546                ret = PTR_ERR(mdp5_kms->cfg);
 547                mdp5_kms->cfg = NULL;
 548                goto fail;
 549        }
 550
 551        config = mdp5_cfg_get_config(mdp5_kms->cfg);
 552
 553        /* TODO: compute core clock rate at runtime */
 554        clk_set_rate(mdp5_kms->src_clk, config->hw->max_clk);
 555
 556        mdp5_kms->smp = mdp5_smp_init(mdp5_kms->dev, &config->hw->smp);
 557        if (IS_ERR(mdp5_kms->smp)) {
 558                ret = PTR_ERR(mdp5_kms->smp);
 559                mdp5_kms->smp = NULL;
 560                goto fail;
 561        }
 562
 563        mdp5_kms->ctlm = mdp5_ctlm_init(dev, mdp5_kms->mmio, mdp5_kms->cfg);
 564        if (IS_ERR(mdp5_kms->ctlm)) {
 565                ret = PTR_ERR(mdp5_kms->ctlm);
 566                mdp5_kms->ctlm = NULL;
 567                goto fail;
 568        }
 569
 570        /* make sure things are off before attaching iommu (bootloader could
 571         * have left things on, in which case we'll start getting faults if
 572         * we don't disable):
 573         */
 574        mdp5_enable(mdp5_kms);
 575        for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
 576                if (mdp5_cfg_intf_is_virtual(config->hw->intf.connect[i]) ||
 577                                !config->hw->intf.base[i])
 578                        continue;
 579                mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0);
 580        }
 581        mdp5_disable(mdp5_kms);
 582        mdelay(16);
 583
 584        if (config->platform.iommu) {
 585                mmu = msm_iommu_new(&pdev->dev, config->platform.iommu);
 586                if (IS_ERR(mmu)) {
 587                        ret = PTR_ERR(mmu);
 588                        dev_err(dev->dev, "failed to init iommu: %d\n", ret);
 589                        goto fail;
 590                }
 591
 592                ret = mmu->funcs->attach(mmu, iommu_ports,
 593                                ARRAY_SIZE(iommu_ports));
 594                if (ret) {
 595                        dev_err(dev->dev, "failed to attach iommu: %d\n", ret);
 596                        mmu->funcs->destroy(mmu);
 597                        goto fail;
 598                }
 599        } else {
 600                dev_info(dev->dev, "no iommu, fallback to phys "
 601                                "contig buffers for scanout\n");
 602                mmu = NULL;
 603        }
 604        mdp5_kms->mmu = mmu;
 605
 606        mdp5_kms->id = msm_register_mmu(dev, mmu);
 607        if (mdp5_kms->id < 0) {
 608                ret = mdp5_kms->id;
 609                dev_err(dev->dev, "failed to register mdp5 iommu: %d\n", ret);
 610                goto fail;
 611        }
 612
 613        ret = modeset_init(mdp5_kms);
 614        if (ret) {
 615                dev_err(dev->dev, "modeset_init failed: %d\n", ret);
 616                goto fail;
 617        }
 618
 619        dev->mode_config.min_width = 0;
 620        dev->mode_config.min_height = 0;
 621        dev->mode_config.max_width = config->hw->lm.max_width;
 622        dev->mode_config.max_height = config->hw->lm.max_height;
 623
 624        return kms;
 625
 626fail:
 627        if (kms)
 628                mdp5_destroy(kms);
 629        return ERR_PTR(ret);
 630}
 631