linux/drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
   4 * Copyright (C) 2013 Red Hat
   5 * Author: Rob Clark <robdclark@gmail.com>
   6 */
   7
   8#include <drm/drm_crtc.h>
   9#include <drm/drm_probe_helper.h>
  10
  11#include "mdp5_kms.h"
  12
  13static struct mdp5_kms *get_kms(struct drm_encoder *encoder)
  14{
  15        struct msm_drm_private *priv = encoder->dev->dev_private;
  16        return to_mdp5_kms(to_mdp_kms(priv->kms));
  17}
  18
  19#ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING
  20#include <mach/board.h>
  21#include <mach/msm_bus.h>
  22#include <mach/msm_bus_board.h>
  23#define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val)            \
  24        {                                               \
  25                .src = MSM_BUS_MASTER_MDP_PORT0,        \
  26                .dst = MSM_BUS_SLAVE_EBI_CH0,           \
  27                .ab = (ab_val),                         \
  28                .ib = (ib_val),                         \
  29        }
  30
  31static struct msm_bus_vectors mdp_bus_vectors[] = {
  32        MDP_BUS_VECTOR_ENTRY(0, 0),
  33        MDP_BUS_VECTOR_ENTRY(2000000000, 2000000000),
  34};
  35static struct msm_bus_paths mdp_bus_usecases[] = { {
  36                .num_paths = 1,
  37                .vectors = &mdp_bus_vectors[0],
  38}, {
  39                .num_paths = 1,
  40                .vectors = &mdp_bus_vectors[1],
  41} };
  42static struct msm_bus_scale_pdata mdp_bus_scale_table = {
  43        .usecase = mdp_bus_usecases,
  44        .num_usecases = ARRAY_SIZE(mdp_bus_usecases),
  45        .name = "mdss_mdp",
  46};
  47
  48static void bs_init(struct mdp5_encoder *mdp5_encoder)
  49{
  50        mdp5_encoder->bsc = msm_bus_scale_register_client(
  51                        &mdp_bus_scale_table);
  52        DBG("bus scale client: %08x", mdp5_encoder->bsc);
  53}
  54
  55static void bs_fini(struct mdp5_encoder *mdp5_encoder)
  56{
  57        if (mdp5_encoder->bsc) {
  58                msm_bus_scale_unregister_client(mdp5_encoder->bsc);
  59                mdp5_encoder->bsc = 0;
  60        }
  61}
  62
  63static void bs_set(struct mdp5_encoder *mdp5_encoder, int idx)
  64{
  65        if (mdp5_encoder->bsc) {
  66                DBG("set bus scaling: %d", idx);
  67                /* HACK: scaling down, and then immediately back up
  68                 * seems to leave things broken (underflow).. so
  69                 * never disable:
  70                 */
  71                idx = 1;
  72                msm_bus_scale_client_update_request(mdp5_encoder->bsc, idx);
  73        }
  74}
  75#else
  76static void bs_init(struct mdp5_encoder *mdp5_encoder) {}
  77static void bs_fini(struct mdp5_encoder *mdp5_encoder) {}
  78static void bs_set(struct mdp5_encoder *mdp5_encoder, int idx) {}
  79#endif
  80
  81static void mdp5_encoder_destroy(struct drm_encoder *encoder)
  82{
  83        struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
  84        bs_fini(mdp5_encoder);
  85        drm_encoder_cleanup(encoder);
  86        kfree(mdp5_encoder);
  87}
  88
  89static const struct drm_encoder_funcs mdp5_encoder_funcs = {
  90        .destroy = mdp5_encoder_destroy,
  91};
  92
  93static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder,
  94                                      struct drm_display_mode *mode,
  95                                      struct drm_display_mode *adjusted_mode)
  96{
  97        struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
  98        struct mdp5_kms *mdp5_kms = get_kms(encoder);
  99        struct drm_device *dev = encoder->dev;
 100        struct drm_connector *connector;
 101        int intf = mdp5_encoder->intf->num;
 102        uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol;
 103        uint32_t display_v_start, display_v_end;
 104        uint32_t hsync_start_x, hsync_end_x;
 105        uint32_t format = 0x2100;
 106        unsigned long flags;
 107
 108        mode = adjusted_mode;
 109
 110        DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
 111
 112        ctrl_pol = 0;
 113
 114        /* DSI controller cannot handle active-low sync signals. */
 115        if (mdp5_encoder->intf->type != INTF_DSI) {
 116                if (mode->flags & DRM_MODE_FLAG_NHSYNC)
 117                        ctrl_pol |= MDP5_INTF_POLARITY_CTL_HSYNC_LOW;
 118                if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 119                        ctrl_pol |= MDP5_INTF_POLARITY_CTL_VSYNC_LOW;
 120        }
 121        /* probably need to get DATA_EN polarity from panel.. */
 122
 123        dtv_hsync_skew = 0;  /* get this from panel? */
 124
 125        /* Get color format from panel, default is 8bpc */
 126        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 127                if (connector->encoder == encoder) {
 128                        switch (connector->display_info.bpc) {
 129                        case 4:
 130                                format |= 0;
 131                                break;
 132                        case 5:
 133                                format |= 0x15;
 134                                break;
 135                        case 6:
 136                                format |= 0x2A;
 137                                break;
 138                        case 8:
 139                        default:
 140                                format |= 0x3F;
 141                                break;
 142                        }
 143                        break;
 144                }
 145        }
 146
 147        hsync_start_x = (mode->htotal - mode->hsync_start);
 148        hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1;
 149
 150        vsync_period = mode->vtotal * mode->htotal;
 151        vsync_len = (mode->vsync_end - mode->vsync_start) * mode->htotal;
 152        display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + dtv_hsync_skew;
 153        display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + dtv_hsync_skew - 1;
 154
 155        /*
 156         * For edp only:
 157         * DISPLAY_V_START = (VBP * HCYCLE) + HBP
 158         * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP
 159         */
 160        if (mdp5_encoder->intf->type == INTF_eDP) {
 161                display_v_start += mode->htotal - mode->hsync_start;
 162                display_v_end -= mode->hsync_start - mode->hdisplay;
 163        }
 164
 165        spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
 166
 167        mdp5_write(mdp5_kms, REG_MDP5_INTF_HSYNC_CTL(intf),
 168                        MDP5_INTF_HSYNC_CTL_PULSEW(mode->hsync_end - mode->hsync_start) |
 169                        MDP5_INTF_HSYNC_CTL_PERIOD(mode->htotal));
 170        mdp5_write(mdp5_kms, REG_MDP5_INTF_VSYNC_PERIOD_F0(intf), vsync_period);
 171        mdp5_write(mdp5_kms, REG_MDP5_INTF_VSYNC_LEN_F0(intf), vsync_len);
 172        mdp5_write(mdp5_kms, REG_MDP5_INTF_DISPLAY_HCTL(intf),
 173                        MDP5_INTF_DISPLAY_HCTL_START(hsync_start_x) |
 174                        MDP5_INTF_DISPLAY_HCTL_END(hsync_end_x));
 175        mdp5_write(mdp5_kms, REG_MDP5_INTF_DISPLAY_VSTART_F0(intf), display_v_start);
 176        mdp5_write(mdp5_kms, REG_MDP5_INTF_DISPLAY_VEND_F0(intf), display_v_end);
 177        mdp5_write(mdp5_kms, REG_MDP5_INTF_BORDER_COLOR(intf), 0);
 178        mdp5_write(mdp5_kms, REG_MDP5_INTF_UNDERFLOW_COLOR(intf), 0xff);
 179        mdp5_write(mdp5_kms, REG_MDP5_INTF_HSYNC_SKEW(intf), dtv_hsync_skew);
 180        mdp5_write(mdp5_kms, REG_MDP5_INTF_POLARITY_CTL(intf), ctrl_pol);
 181        mdp5_write(mdp5_kms, REG_MDP5_INTF_ACTIVE_HCTL(intf),
 182                        MDP5_INTF_ACTIVE_HCTL_START(0) |
 183                        MDP5_INTF_ACTIVE_HCTL_END(0));
 184        mdp5_write(mdp5_kms, REG_MDP5_INTF_ACTIVE_VSTART_F0(intf), 0);
 185        mdp5_write(mdp5_kms, REG_MDP5_INTF_ACTIVE_VEND_F0(intf), 0);
 186        mdp5_write(mdp5_kms, REG_MDP5_INTF_PANEL_FORMAT(intf), format);
 187        mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(intf), 0x3);  /* frame+line? */
 188
 189        spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
 190
 191        mdp5_crtc_set_pipeline(encoder->crtc);
 192}
 193
 194static void mdp5_vid_encoder_disable(struct drm_encoder *encoder)
 195{
 196        struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 197        struct mdp5_kms *mdp5_kms = get_kms(encoder);
 198        struct mdp5_ctl *ctl = mdp5_encoder->ctl;
 199        struct mdp5_pipeline *pipeline = mdp5_crtc_get_pipeline(encoder->crtc);
 200        struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc);
 201        struct mdp5_interface *intf = mdp5_encoder->intf;
 202        int intfn = mdp5_encoder->intf->num;
 203        unsigned long flags;
 204
 205        if (WARN_ON(!mdp5_encoder->enabled))
 206                return;
 207
 208        mdp5_ctl_set_encoder_state(ctl, pipeline, false);
 209
 210        spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
 211        mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 0);
 212        spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
 213        mdp5_ctl_commit(ctl, pipeline, mdp_ctl_flush_mask_encoder(intf), true);
 214
 215        /*
 216         * Wait for a vsync so we know the ENABLE=0 latched before
 217         * the (connector) source of the vsync's gets disabled,
 218         * otherwise we end up in a funny state if we re-enable
 219         * before the disable latches, which results that some of
 220         * the settings changes for the new modeset (like new
 221         * scanout buffer) don't latch properly..
 222         */
 223        mdp_irq_wait(&mdp5_kms->base, intf2vblank(mixer, intf));
 224
 225        bs_set(mdp5_encoder, 0);
 226
 227        mdp5_encoder->enabled = false;
 228}
 229
 230static void mdp5_vid_encoder_enable(struct drm_encoder *encoder)
 231{
 232        struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 233        struct mdp5_kms *mdp5_kms = get_kms(encoder);
 234        struct mdp5_ctl *ctl = mdp5_encoder->ctl;
 235        struct mdp5_interface *intf = mdp5_encoder->intf;
 236        struct mdp5_pipeline *pipeline = mdp5_crtc_get_pipeline(encoder->crtc);
 237        int intfn = intf->num;
 238        unsigned long flags;
 239
 240        if (WARN_ON(mdp5_encoder->enabled))
 241                return;
 242
 243        bs_set(mdp5_encoder, 1);
 244        spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
 245        mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 1);
 246        spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
 247        mdp5_ctl_commit(ctl, pipeline, mdp_ctl_flush_mask_encoder(intf), true);
 248
 249        mdp5_ctl_set_encoder_state(ctl, pipeline, true);
 250
 251        mdp5_encoder->enabled = true;
 252}
 253
 254static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
 255                                  struct drm_display_mode *mode,
 256                                  struct drm_display_mode *adjusted_mode)
 257{
 258        struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 259        struct mdp5_interface *intf = mdp5_encoder->intf;
 260
 261        if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
 262                mdp5_cmd_encoder_mode_set(encoder, mode, adjusted_mode);
 263        else
 264                mdp5_vid_encoder_mode_set(encoder, mode, adjusted_mode);
 265}
 266
 267static void mdp5_encoder_disable(struct drm_encoder *encoder)
 268{
 269        struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 270        struct mdp5_interface *intf = mdp5_encoder->intf;
 271
 272        if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
 273                mdp5_cmd_encoder_disable(encoder);
 274        else
 275                mdp5_vid_encoder_disable(encoder);
 276}
 277
 278static void mdp5_encoder_enable(struct drm_encoder *encoder)
 279{
 280        struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 281        struct mdp5_interface *intf = mdp5_encoder->intf;
 282        /* this isn't right I think */
 283        struct drm_crtc_state *cstate = encoder->crtc->state;
 284
 285        mdp5_encoder_mode_set(encoder, &cstate->mode, &cstate->adjusted_mode);
 286
 287        if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
 288                mdp5_cmd_encoder_enable(encoder);
 289        else
 290                mdp5_vid_encoder_enable(encoder);
 291}
 292
 293static int mdp5_encoder_atomic_check(struct drm_encoder *encoder,
 294                                     struct drm_crtc_state *crtc_state,
 295                                     struct drm_connector_state *conn_state)
 296{
 297        struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 298        struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc_state);
 299        struct mdp5_interface *intf = mdp5_encoder->intf;
 300        struct mdp5_ctl *ctl = mdp5_encoder->ctl;
 301
 302        mdp5_cstate->ctl = ctl;
 303        mdp5_cstate->pipeline.intf = intf;
 304
 305        /*
 306         * This is a bit awkward, but we want to flush the CTL and hit the
 307         * START bit at most once for an atomic update.  In the non-full-
 308         * modeset case, this is done from crtc->atomic_flush(), but that
 309         * is too early in the case of full modeset, in which case we
 310         * defer to encoder->enable().  But we need to *know* whether
 311         * encoder->enable() will be called to do this:
 312         */
 313        if (drm_atomic_crtc_needs_modeset(crtc_state))
 314                mdp5_cstate->defer_start = true;
 315
 316        return 0;
 317}
 318
 319static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = {
 320        .disable = mdp5_encoder_disable,
 321        .enable = mdp5_encoder_enable,
 322        .atomic_check = mdp5_encoder_atomic_check,
 323};
 324
 325int mdp5_encoder_get_linecount(struct drm_encoder *encoder)
 326{
 327        struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 328        struct mdp5_kms *mdp5_kms = get_kms(encoder);
 329        int intf = mdp5_encoder->intf->num;
 330
 331        return mdp5_read(mdp5_kms, REG_MDP5_INTF_LINE_COUNT(intf));
 332}
 333
 334u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder)
 335{
 336        struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 337        struct mdp5_kms *mdp5_kms = get_kms(encoder);
 338        int intf = mdp5_encoder->intf->num;
 339
 340        return mdp5_read(mdp5_kms, REG_MDP5_INTF_FRAME_COUNT(intf));
 341}
 342
 343int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
 344                                       struct drm_encoder *slave_encoder)
 345{
 346        struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 347        struct mdp5_encoder *mdp5_slave_enc = to_mdp5_encoder(slave_encoder);
 348        struct mdp5_kms *mdp5_kms;
 349        struct device *dev;
 350        int intf_num;
 351        u32 data = 0;
 352
 353        if (!encoder || !slave_encoder)
 354                return -EINVAL;
 355
 356        mdp5_kms = get_kms(encoder);
 357        intf_num = mdp5_encoder->intf->num;
 358
 359        /* Switch slave encoder's TimingGen Sync mode,
 360         * to use the master's enable signal for the slave encoder.
 361         */
 362        if (intf_num == 1)
 363                data |= MDP5_SPLIT_DPL_LOWER_INTF2_TG_SYNC;
 364        else if (intf_num == 2)
 365                data |= MDP5_SPLIT_DPL_LOWER_INTF1_TG_SYNC;
 366        else
 367                return -EINVAL;
 368
 369        dev = &mdp5_kms->pdev->dev;
 370        /* Make sure clocks are on when connectors calling this function. */
 371        pm_runtime_get_sync(dev);
 372
 373        /* Dumb Panel, Sync mode */
 374        mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_UPPER, 0);
 375        mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_LOWER, data);
 376        mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_EN, 1);
 377
 378        mdp5_ctl_pair(mdp5_encoder->ctl, mdp5_slave_enc->ctl, true);
 379
 380        pm_runtime_put_sync(dev);
 381
 382        return 0;
 383}
 384
 385void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode)
 386{
 387        struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 388        struct mdp5_interface *intf = mdp5_encoder->intf;
 389
 390        /* TODO: Expand this to set writeback modes too */
 391        if (cmd_mode) {
 392                WARN_ON(intf->type != INTF_DSI);
 393                intf->mode = MDP5_INTF_DSI_MODE_COMMAND;
 394        } else {
 395                if (intf->type == INTF_DSI)
 396                        intf->mode = MDP5_INTF_DSI_MODE_VIDEO;
 397                else
 398                        intf->mode = MDP5_INTF_MODE_NONE;
 399        }
 400}
 401
 402/* initialize encoder */
 403struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
 404                                      struct mdp5_interface *intf,
 405                                      struct mdp5_ctl *ctl)
 406{
 407        struct drm_encoder *encoder = NULL;
 408        struct mdp5_encoder *mdp5_encoder;
 409        int enc_type = (intf->type == INTF_DSI) ?
 410                DRM_MODE_ENCODER_DSI : DRM_MODE_ENCODER_TMDS;
 411        int ret;
 412
 413        mdp5_encoder = kzalloc(sizeof(*mdp5_encoder), GFP_KERNEL);
 414        if (!mdp5_encoder) {
 415                ret = -ENOMEM;
 416                goto fail;
 417        }
 418
 419        encoder = &mdp5_encoder->base;
 420        mdp5_encoder->ctl = ctl;
 421        mdp5_encoder->intf = intf;
 422
 423        spin_lock_init(&mdp5_encoder->intf_lock);
 424
 425        drm_encoder_init(dev, encoder, &mdp5_encoder_funcs, enc_type, NULL);
 426
 427        drm_encoder_helper_add(encoder, &mdp5_encoder_helper_funcs);
 428
 429        bs_init(mdp5_encoder);
 430
 431        return encoder;
 432
 433fail:
 434        if (encoder)
 435                mdp5_encoder_destroy(encoder);
 436
 437        return ERR_PTR(ret);
 438}
 439