linux/drivers/gpu/drm/tegra/dc.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2012 Avionic Design GmbH
   3 * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 */
   9
  10#include <linux/clk.h>
  11#include <linux/debugfs.h>
  12#include <linux/module.h>
  13#include <linux/of.h>
  14#include <linux/platform_device.h>
  15
  16#include <mach/clk.h>
  17
  18#include "drm.h"
  19#include "dc.h"
  20
  21struct tegra_dc_window {
  22        fixed20_12 x;
  23        fixed20_12 y;
  24        fixed20_12 w;
  25        fixed20_12 h;
  26        unsigned int outx;
  27        unsigned int outy;
  28        unsigned int outw;
  29        unsigned int outh;
  30        unsigned int stride;
  31        unsigned int fmt;
  32};
  33
  34static const struct drm_crtc_funcs tegra_crtc_funcs = {
  35        .set_config = drm_crtc_helper_set_config,
  36        .destroy = drm_crtc_cleanup,
  37};
  38
  39static void tegra_crtc_dpms(struct drm_crtc *crtc, int mode)
  40{
  41}
  42
  43static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc,
  44                                  const struct drm_display_mode *mode,
  45                                  struct drm_display_mode *adjusted)
  46{
  47        return true;
  48}
  49
  50static inline u32 compute_dda_inc(fixed20_12 inf, unsigned int out, bool v,
  51                                  unsigned int bpp)
  52{
  53        fixed20_12 outf = dfixed_init(out);
  54        u32 dda_inc;
  55        int max;
  56
  57        if (v)
  58                max = 15;
  59        else {
  60                switch (bpp) {
  61                case 2:
  62                        max = 8;
  63                        break;
  64
  65                default:
  66                        WARN_ON_ONCE(1);
  67                        /* fallthrough */
  68                case 4:
  69                        max = 4;
  70                        break;
  71                }
  72        }
  73
  74        outf.full = max_t(u32, outf.full - dfixed_const(1), dfixed_const(1));
  75        inf.full -= dfixed_const(1);
  76
  77        dda_inc = dfixed_div(inf, outf);
  78        dda_inc = min_t(u32, dda_inc, dfixed_const(max));
  79
  80        return dda_inc;
  81}
  82
  83static inline u32 compute_initial_dda(fixed20_12 in)
  84{
  85        return dfixed_frac(in);
  86}
  87
  88static int tegra_dc_set_timings(struct tegra_dc *dc,
  89                                struct drm_display_mode *mode)
  90{
  91        /* TODO: For HDMI compliance, h & v ref_to_sync should be set to 1 */
  92        unsigned int h_ref_to_sync = 0;
  93        unsigned int v_ref_to_sync = 0;
  94        unsigned long value;
  95
  96        tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS);
  97
  98        value = (v_ref_to_sync << 16) | h_ref_to_sync;
  99        tegra_dc_writel(dc, value, DC_DISP_REF_TO_SYNC);
 100
 101        value = ((mode->vsync_end - mode->vsync_start) << 16) |
 102                ((mode->hsync_end - mode->hsync_start) <<  0);
 103        tegra_dc_writel(dc, value, DC_DISP_SYNC_WIDTH);
 104
 105        value = ((mode->vtotal - mode->vsync_end) << 16) |
 106                ((mode->htotal - mode->hsync_end) <<  0);
 107        tegra_dc_writel(dc, value, DC_DISP_BACK_PORCH);
 108
 109        value = ((mode->vsync_start - mode->vdisplay) << 16) |
 110                ((mode->hsync_start - mode->hdisplay) <<  0);
 111        tegra_dc_writel(dc, value, DC_DISP_FRONT_PORCH);
 112
 113        value = (mode->vdisplay << 16) | mode->hdisplay;
 114        tegra_dc_writel(dc, value, DC_DISP_ACTIVE);
 115
 116        return 0;
 117}
 118
 119static int tegra_crtc_setup_clk(struct drm_crtc *crtc,
 120                                struct drm_display_mode *mode,
 121                                unsigned long *div)
 122{
 123        unsigned long pclk = mode->clock * 1000, rate;
 124        struct tegra_dc *dc = to_tegra_dc(crtc);
 125        struct tegra_output *output = NULL;
 126        struct drm_encoder *encoder;
 127        long err;
 128
 129        list_for_each_entry(encoder, &crtc->dev->mode_config.encoder_list, head)
 130                if (encoder->crtc == crtc) {
 131                        output = encoder_to_output(encoder);
 132                        break;
 133                }
 134
 135        if (!output)
 136                return -ENODEV;
 137
 138        /*
 139         * This assumes that the display controller will divide its parent
 140         * clock by 2 to generate the pixel clock.
 141         */
 142        err = tegra_output_setup_clock(output, dc->clk, pclk * 2);
 143        if (err < 0) {
 144                dev_err(dc->dev, "failed to setup clock: %ld\n", err);
 145                return err;
 146        }
 147
 148        rate = clk_get_rate(dc->clk);
 149        *div = (rate * 2 / pclk) - 2;
 150
 151        DRM_DEBUG_KMS("rate: %lu, div: %lu\n", rate, *div);
 152
 153        return 0;
 154}
 155
 156static int tegra_crtc_mode_set(struct drm_crtc *crtc,
 157                               struct drm_display_mode *mode,
 158                               struct drm_display_mode *adjusted,
 159                               int x, int y, struct drm_framebuffer *old_fb)
 160{
 161        struct tegra_framebuffer *fb = to_tegra_fb(crtc->fb);
 162        struct tegra_dc *dc = to_tegra_dc(crtc);
 163        unsigned int h_dda, v_dda, bpp;
 164        struct tegra_dc_window win;
 165        unsigned long div, value;
 166        int err;
 167
 168        err = tegra_crtc_setup_clk(crtc, mode, &div);
 169        if (err) {
 170                dev_err(dc->dev, "failed to setup clock for CRTC: %d\n", err);
 171                return err;
 172        }
 173
 174        /* program display mode */
 175        tegra_dc_set_timings(dc, mode);
 176
 177        value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL;
 178        tegra_dc_writel(dc, value, DC_DISP_DATA_ENABLE_OPTIONS);
 179
 180        value = tegra_dc_readl(dc, DC_COM_PIN_OUTPUT_POLARITY(1));
 181        value &= ~LVS_OUTPUT_POLARITY_LOW;
 182        value &= ~LHS_OUTPUT_POLARITY_LOW;
 183        tegra_dc_writel(dc, value, DC_COM_PIN_OUTPUT_POLARITY(1));
 184
 185        value = DISP_DATA_FORMAT_DF1P1C | DISP_ALIGNMENT_MSB |
 186                DISP_ORDER_RED_BLUE;
 187        tegra_dc_writel(dc, value, DC_DISP_DISP_INTERFACE_CONTROL);
 188
 189        tegra_dc_writel(dc, 0x00010001, DC_DISP_SHIFT_CLOCK_OPTIONS);
 190
 191        value = SHIFT_CLK_DIVIDER(div) | PIXEL_CLK_DIVIDER_PCD1;
 192        tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL);
 193
 194        /* setup window parameters */
 195        memset(&win, 0, sizeof(win));
 196        win.x.full = dfixed_const(0);
 197        win.y.full = dfixed_const(0);
 198        win.w.full = dfixed_const(mode->hdisplay);
 199        win.h.full = dfixed_const(mode->vdisplay);
 200        win.outx = 0;
 201        win.outy = 0;
 202        win.outw = mode->hdisplay;
 203        win.outh = mode->vdisplay;
 204
 205        switch (crtc->fb->pixel_format) {
 206        case DRM_FORMAT_XRGB8888:
 207                win.fmt = WIN_COLOR_DEPTH_B8G8R8A8;
 208                break;
 209
 210        case DRM_FORMAT_RGB565:
 211                win.fmt = WIN_COLOR_DEPTH_B5G6R5;
 212                break;
 213
 214        default:
 215                win.fmt = WIN_COLOR_DEPTH_B8G8R8A8;
 216                WARN_ON(1);
 217                break;
 218        }
 219
 220        bpp = crtc->fb->bits_per_pixel / 8;
 221        win.stride = crtc->fb->pitches[0];
 222
 223        /* program window registers */
 224        value = WINDOW_A_SELECT;
 225        tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
 226
 227        tegra_dc_writel(dc, win.fmt, DC_WIN_COLOR_DEPTH);
 228        tegra_dc_writel(dc, 0, DC_WIN_BYTE_SWAP);
 229
 230        value = V_POSITION(win.outy) | H_POSITION(win.outx);
 231        tegra_dc_writel(dc, value, DC_WIN_POSITION);
 232
 233        value = V_SIZE(win.outh) | H_SIZE(win.outw);
 234        tegra_dc_writel(dc, value, DC_WIN_SIZE);
 235
 236        value = V_PRESCALED_SIZE(dfixed_trunc(win.h)) |
 237                H_PRESCALED_SIZE(dfixed_trunc(win.w) * bpp);
 238        tegra_dc_writel(dc, value, DC_WIN_PRESCALED_SIZE);
 239
 240        h_dda = compute_dda_inc(win.w, win.outw, false, bpp);
 241        v_dda = compute_dda_inc(win.h, win.outh, true, bpp);
 242
 243        value = V_DDA_INC(v_dda) | H_DDA_INC(h_dda);
 244        tegra_dc_writel(dc, value, DC_WIN_DDA_INC);
 245
 246        h_dda = compute_initial_dda(win.x);
 247        v_dda = compute_initial_dda(win.y);
 248
 249        tegra_dc_writel(dc, h_dda, DC_WIN_H_INITIAL_DDA);
 250        tegra_dc_writel(dc, v_dda, DC_WIN_V_INITIAL_DDA);
 251
 252        tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE);
 253        tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE);
 254
 255        tegra_dc_writel(dc, fb->obj->paddr, DC_WINBUF_START_ADDR);
 256        tegra_dc_writel(dc, win.stride, DC_WIN_LINE_STRIDE);
 257        tegra_dc_writel(dc, dfixed_trunc(win.x) * bpp,
 258                        DC_WINBUF_ADDR_H_OFFSET);
 259        tegra_dc_writel(dc, dfixed_trunc(win.y), DC_WINBUF_ADDR_V_OFFSET);
 260
 261        value = WIN_ENABLE;
 262
 263        if (bpp < 24)
 264                value |= COLOR_EXPAND;
 265
 266        tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
 267
 268        tegra_dc_writel(dc, 0xff00, DC_WIN_BLEND_NOKEY);
 269        tegra_dc_writel(dc, 0xff00, DC_WIN_BLEND_1WIN);
 270
 271        return 0;
 272}
 273
 274static void tegra_crtc_prepare(struct drm_crtc *crtc)
 275{
 276        struct tegra_dc *dc = to_tegra_dc(crtc);
 277        unsigned int syncpt;
 278        unsigned long value;
 279
 280        /* hardware initialization */
 281        tegra_periph_reset_deassert(dc->clk);
 282        usleep_range(10000, 20000);
 283
 284        if (dc->pipe)
 285                syncpt = SYNCPT_VBLANK1;
 286        else
 287                syncpt = SYNCPT_VBLANK0;
 288
 289        /* initialize display controller */
 290        tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
 291        tegra_dc_writel(dc, 0x100 | syncpt, DC_CMD_CONT_SYNCPT_VSYNC);
 292
 293        value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | WIN_A_OF_INT;
 294        tegra_dc_writel(dc, value, DC_CMD_INT_TYPE);
 295
 296        value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
 297                WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
 298        tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY);
 299
 300        value = PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
 301                PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
 302        tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
 303
 304        value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
 305        value |= DISP_CTRL_MODE_C_DISPLAY;
 306        tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
 307
 308        /* initialize timer */
 309        value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) |
 310                WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20);
 311        tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY);
 312
 313        value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) |
 314                WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1);
 315        tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
 316
 317        value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
 318        tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
 319
 320        value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
 321        tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
 322}
 323
 324static void tegra_crtc_commit(struct drm_crtc *crtc)
 325{
 326        struct tegra_dc *dc = to_tegra_dc(crtc);
 327        unsigned long update_mask;
 328        unsigned long value;
 329
 330        update_mask = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
 331
 332        tegra_dc_writel(dc, update_mask << 8, DC_CMD_STATE_CONTROL);
 333
 334        value = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
 335        value |= FRAME_END_INT;
 336        tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
 337
 338        value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
 339        value |= FRAME_END_INT;
 340        tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
 341
 342        tegra_dc_writel(dc, update_mask, DC_CMD_STATE_CONTROL);
 343}
 344
 345static void tegra_crtc_load_lut(struct drm_crtc *crtc)
 346{
 347}
 348
 349static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
 350        .dpms = tegra_crtc_dpms,
 351        .mode_fixup = tegra_crtc_mode_fixup,
 352        .mode_set = tegra_crtc_mode_set,
 353        .prepare = tegra_crtc_prepare,
 354        .commit = tegra_crtc_commit,
 355        .load_lut = tegra_crtc_load_lut,
 356};
 357
 358static irqreturn_t tegra_drm_irq(int irq, void *data)
 359{
 360        struct tegra_dc *dc = data;
 361        unsigned long status;
 362
 363        status = tegra_dc_readl(dc, DC_CMD_INT_STATUS);
 364        tegra_dc_writel(dc, status, DC_CMD_INT_STATUS);
 365
 366        if (status & FRAME_END_INT) {
 367                /*
 368                dev_dbg(dc->dev, "%s(): frame end\n", __func__);
 369                */
 370        }
 371
 372        if (status & VBLANK_INT) {
 373                /*
 374                dev_dbg(dc->dev, "%s(): vertical blank\n", __func__);
 375                */
 376                drm_handle_vblank(dc->base.dev, dc->pipe);
 377        }
 378
 379        if (status & (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT)) {
 380                /*
 381                dev_dbg(dc->dev, "%s(): underflow\n", __func__);
 382                */
 383        }
 384
 385        return IRQ_HANDLED;
 386}
 387
 388static int tegra_dc_show_regs(struct seq_file *s, void *data)
 389{
 390        struct drm_info_node *node = s->private;
 391        struct tegra_dc *dc = node->info_ent->data;
 392
 393#define DUMP_REG(name)                                          \
 394        seq_printf(s, "%-40s %#05x %08lx\n", #name, name,       \
 395                   tegra_dc_readl(dc, name))
 396
 397        DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT);
 398        DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
 399        DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_ERROR);
 400        DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT);
 401        DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_CNTRL);
 402        DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_ERROR);
 403        DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT);
 404        DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_CNTRL);
 405        DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_ERROR);
 406        DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT);
 407        DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_CNTRL);
 408        DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_ERROR);
 409        DUMP_REG(DC_CMD_CONT_SYNCPT_VSYNC);
 410        DUMP_REG(DC_CMD_DISPLAY_COMMAND_OPTION0);
 411        DUMP_REG(DC_CMD_DISPLAY_COMMAND);
 412        DUMP_REG(DC_CMD_SIGNAL_RAISE);
 413        DUMP_REG(DC_CMD_DISPLAY_POWER_CONTROL);
 414        DUMP_REG(DC_CMD_INT_STATUS);
 415        DUMP_REG(DC_CMD_INT_MASK);
 416        DUMP_REG(DC_CMD_INT_ENABLE);
 417        DUMP_REG(DC_CMD_INT_TYPE);
 418        DUMP_REG(DC_CMD_INT_POLARITY);
 419        DUMP_REG(DC_CMD_SIGNAL_RAISE1);
 420        DUMP_REG(DC_CMD_SIGNAL_RAISE2);
 421        DUMP_REG(DC_CMD_SIGNAL_RAISE3);
 422        DUMP_REG(DC_CMD_STATE_ACCESS);
 423        DUMP_REG(DC_CMD_STATE_CONTROL);
 424        DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER);
 425        DUMP_REG(DC_CMD_REG_ACT_CONTROL);
 426        DUMP_REG(DC_COM_CRC_CONTROL);
 427        DUMP_REG(DC_COM_CRC_CHECKSUM);
 428        DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(0));
 429        DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(1));
 430        DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(2));
 431        DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(3));
 432        DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(0));
 433        DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(1));
 434        DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(2));
 435        DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(3));
 436        DUMP_REG(DC_COM_PIN_OUTPUT_DATA(0));
 437        DUMP_REG(DC_COM_PIN_OUTPUT_DATA(1));
 438        DUMP_REG(DC_COM_PIN_OUTPUT_DATA(2));
 439        DUMP_REG(DC_COM_PIN_OUTPUT_DATA(3));
 440        DUMP_REG(DC_COM_PIN_INPUT_ENABLE(0));
 441        DUMP_REG(DC_COM_PIN_INPUT_ENABLE(1));
 442        DUMP_REG(DC_COM_PIN_INPUT_ENABLE(2));
 443        DUMP_REG(DC_COM_PIN_INPUT_ENABLE(3));
 444        DUMP_REG(DC_COM_PIN_INPUT_DATA(0));
 445        DUMP_REG(DC_COM_PIN_INPUT_DATA(1));
 446        DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(0));
 447        DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(1));
 448        DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(2));
 449        DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(3));
 450        DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(4));
 451        DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(5));
 452        DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(6));
 453        DUMP_REG(DC_COM_PIN_MISC_CONTROL);
 454        DUMP_REG(DC_COM_PIN_PM0_CONTROL);
 455        DUMP_REG(DC_COM_PIN_PM0_DUTY_CYCLE);
 456        DUMP_REG(DC_COM_PIN_PM1_CONTROL);
 457        DUMP_REG(DC_COM_PIN_PM1_DUTY_CYCLE);
 458        DUMP_REG(DC_COM_SPI_CONTROL);
 459        DUMP_REG(DC_COM_SPI_START_BYTE);
 460        DUMP_REG(DC_COM_HSPI_WRITE_DATA_AB);
 461        DUMP_REG(DC_COM_HSPI_WRITE_DATA_CD);
 462        DUMP_REG(DC_COM_HSPI_CS_DC);
 463        DUMP_REG(DC_COM_SCRATCH_REGISTER_A);
 464        DUMP_REG(DC_COM_SCRATCH_REGISTER_B);
 465        DUMP_REG(DC_COM_GPIO_CTRL);
 466        DUMP_REG(DC_COM_GPIO_DEBOUNCE_COUNTER);
 467        DUMP_REG(DC_COM_CRC_CHECKSUM_LATCHED);
 468        DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS0);
 469        DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS1);
 470        DUMP_REG(DC_DISP_DISP_WIN_OPTIONS);
 471        DUMP_REG(DC_DISP_DISP_MEM_HIGH_PRIORITY);
 472        DUMP_REG(DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
 473        DUMP_REG(DC_DISP_DISP_TIMING_OPTIONS);
 474        DUMP_REG(DC_DISP_REF_TO_SYNC);
 475        DUMP_REG(DC_DISP_SYNC_WIDTH);
 476        DUMP_REG(DC_DISP_BACK_PORCH);
 477        DUMP_REG(DC_DISP_ACTIVE);
 478        DUMP_REG(DC_DISP_FRONT_PORCH);
 479        DUMP_REG(DC_DISP_H_PULSE0_CONTROL);
 480        DUMP_REG(DC_DISP_H_PULSE0_POSITION_A);
 481        DUMP_REG(DC_DISP_H_PULSE0_POSITION_B);
 482        DUMP_REG(DC_DISP_H_PULSE0_POSITION_C);
 483        DUMP_REG(DC_DISP_H_PULSE0_POSITION_D);
 484        DUMP_REG(DC_DISP_H_PULSE1_CONTROL);
 485        DUMP_REG(DC_DISP_H_PULSE1_POSITION_A);
 486        DUMP_REG(DC_DISP_H_PULSE1_POSITION_B);
 487        DUMP_REG(DC_DISP_H_PULSE1_POSITION_C);
 488        DUMP_REG(DC_DISP_H_PULSE1_POSITION_D);
 489        DUMP_REG(DC_DISP_H_PULSE2_CONTROL);
 490        DUMP_REG(DC_DISP_H_PULSE2_POSITION_A);
 491        DUMP_REG(DC_DISP_H_PULSE2_POSITION_B);
 492        DUMP_REG(DC_DISP_H_PULSE2_POSITION_C);
 493        DUMP_REG(DC_DISP_H_PULSE2_POSITION_D);
 494        DUMP_REG(DC_DISP_V_PULSE0_CONTROL);
 495        DUMP_REG(DC_DISP_V_PULSE0_POSITION_A);
 496        DUMP_REG(DC_DISP_V_PULSE0_POSITION_B);
 497        DUMP_REG(DC_DISP_V_PULSE0_POSITION_C);
 498        DUMP_REG(DC_DISP_V_PULSE1_CONTROL);
 499        DUMP_REG(DC_DISP_V_PULSE1_POSITION_A);
 500        DUMP_REG(DC_DISP_V_PULSE1_POSITION_B);
 501        DUMP_REG(DC_DISP_V_PULSE1_POSITION_C);
 502        DUMP_REG(DC_DISP_V_PULSE2_CONTROL);
 503        DUMP_REG(DC_DISP_V_PULSE2_POSITION_A);
 504        DUMP_REG(DC_DISP_V_PULSE3_CONTROL);
 505        DUMP_REG(DC_DISP_V_PULSE3_POSITION_A);
 506        DUMP_REG(DC_DISP_M0_CONTROL);
 507        DUMP_REG(DC_DISP_M1_CONTROL);
 508        DUMP_REG(DC_DISP_DI_CONTROL);
 509        DUMP_REG(DC_DISP_PP_CONTROL);
 510        DUMP_REG(DC_DISP_PP_SELECT_A);
 511        DUMP_REG(DC_DISP_PP_SELECT_B);
 512        DUMP_REG(DC_DISP_PP_SELECT_C);
 513        DUMP_REG(DC_DISP_PP_SELECT_D);
 514        DUMP_REG(DC_DISP_DISP_CLOCK_CONTROL);
 515        DUMP_REG(DC_DISP_DISP_INTERFACE_CONTROL);
 516        DUMP_REG(DC_DISP_DISP_COLOR_CONTROL);
 517        DUMP_REG(DC_DISP_SHIFT_CLOCK_OPTIONS);
 518        DUMP_REG(DC_DISP_DATA_ENABLE_OPTIONS);
 519        DUMP_REG(DC_DISP_SERIAL_INTERFACE_OPTIONS);
 520        DUMP_REG(DC_DISP_LCD_SPI_OPTIONS);
 521        DUMP_REG(DC_DISP_BORDER_COLOR);
 522        DUMP_REG(DC_DISP_COLOR_KEY0_LOWER);
 523        DUMP_REG(DC_DISP_COLOR_KEY0_UPPER);
 524        DUMP_REG(DC_DISP_COLOR_KEY1_LOWER);
 525        DUMP_REG(DC_DISP_COLOR_KEY1_UPPER);
 526        DUMP_REG(DC_DISP_CURSOR_FOREGROUND);
 527        DUMP_REG(DC_DISP_CURSOR_BACKGROUND);
 528        DUMP_REG(DC_DISP_CURSOR_START_ADDR);
 529        DUMP_REG(DC_DISP_CURSOR_START_ADDR_NS);
 530        DUMP_REG(DC_DISP_CURSOR_POSITION);
 531        DUMP_REG(DC_DISP_CURSOR_POSITION_NS);
 532        DUMP_REG(DC_DISP_INIT_SEQ_CONTROL);
 533        DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_A);
 534        DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_B);
 535        DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_C);
 536        DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_D);
 537        DUMP_REG(DC_DISP_DC_MCCIF_FIFOCTRL);
 538        DUMP_REG(DC_DISP_MCCIF_DISPLAY0A_HYST);
 539        DUMP_REG(DC_DISP_MCCIF_DISPLAY0B_HYST);
 540        DUMP_REG(DC_DISP_MCCIF_DISPLAY1A_HYST);
 541        DUMP_REG(DC_DISP_MCCIF_DISPLAY1B_HYST);
 542        DUMP_REG(DC_DISP_DAC_CRT_CTRL);
 543        DUMP_REG(DC_DISP_DISP_MISC_CONTROL);
 544        DUMP_REG(DC_DISP_SD_CONTROL);
 545        DUMP_REG(DC_DISP_SD_CSC_COEFF);
 546        DUMP_REG(DC_DISP_SD_LUT(0));
 547        DUMP_REG(DC_DISP_SD_LUT(1));
 548        DUMP_REG(DC_DISP_SD_LUT(2));
 549        DUMP_REG(DC_DISP_SD_LUT(3));
 550        DUMP_REG(DC_DISP_SD_LUT(4));
 551        DUMP_REG(DC_DISP_SD_LUT(5));
 552        DUMP_REG(DC_DISP_SD_LUT(6));
 553        DUMP_REG(DC_DISP_SD_LUT(7));
 554        DUMP_REG(DC_DISP_SD_LUT(8));
 555        DUMP_REG(DC_DISP_SD_FLICKER_CONTROL);
 556        DUMP_REG(DC_DISP_DC_PIXEL_COUNT);
 557        DUMP_REG(DC_DISP_SD_HISTOGRAM(0));
 558        DUMP_REG(DC_DISP_SD_HISTOGRAM(1));
 559        DUMP_REG(DC_DISP_SD_HISTOGRAM(2));
 560        DUMP_REG(DC_DISP_SD_HISTOGRAM(3));
 561        DUMP_REG(DC_DISP_SD_HISTOGRAM(4));
 562        DUMP_REG(DC_DISP_SD_HISTOGRAM(5));
 563        DUMP_REG(DC_DISP_SD_HISTOGRAM(6));
 564        DUMP_REG(DC_DISP_SD_HISTOGRAM(7));
 565        DUMP_REG(DC_DISP_SD_BL_TF(0));
 566        DUMP_REG(DC_DISP_SD_BL_TF(1));
 567        DUMP_REG(DC_DISP_SD_BL_TF(2));
 568        DUMP_REG(DC_DISP_SD_BL_TF(3));
 569        DUMP_REG(DC_DISP_SD_BL_CONTROL);
 570        DUMP_REG(DC_DISP_SD_HW_K_VALUES);
 571        DUMP_REG(DC_DISP_SD_MAN_K_VALUES);
 572        DUMP_REG(DC_WIN_WIN_OPTIONS);
 573        DUMP_REG(DC_WIN_BYTE_SWAP);
 574        DUMP_REG(DC_WIN_BUFFER_CONTROL);
 575        DUMP_REG(DC_WIN_COLOR_DEPTH);
 576        DUMP_REG(DC_WIN_POSITION);
 577        DUMP_REG(DC_WIN_SIZE);
 578        DUMP_REG(DC_WIN_PRESCALED_SIZE);
 579        DUMP_REG(DC_WIN_H_INITIAL_DDA);
 580        DUMP_REG(DC_WIN_V_INITIAL_DDA);
 581        DUMP_REG(DC_WIN_DDA_INC);
 582        DUMP_REG(DC_WIN_LINE_STRIDE);
 583        DUMP_REG(DC_WIN_BUF_STRIDE);
 584        DUMP_REG(DC_WIN_UV_BUF_STRIDE);
 585        DUMP_REG(DC_WIN_BUFFER_ADDR_MODE);
 586        DUMP_REG(DC_WIN_DV_CONTROL);
 587        DUMP_REG(DC_WIN_BLEND_NOKEY);
 588        DUMP_REG(DC_WIN_BLEND_1WIN);
 589        DUMP_REG(DC_WIN_BLEND_2WIN_X);
 590        DUMP_REG(DC_WIN_BLEND_2WIN_Y);
 591        DUMP_REG(DC_WIN_BLEND32WIN_XY);
 592        DUMP_REG(DC_WIN_HP_FETCH_CONTROL);
 593        DUMP_REG(DC_WINBUF_START_ADDR);
 594        DUMP_REG(DC_WINBUF_START_ADDR_NS);
 595        DUMP_REG(DC_WINBUF_START_ADDR_U);
 596        DUMP_REG(DC_WINBUF_START_ADDR_U_NS);
 597        DUMP_REG(DC_WINBUF_START_ADDR_V);
 598        DUMP_REG(DC_WINBUF_START_ADDR_V_NS);
 599        DUMP_REG(DC_WINBUF_ADDR_H_OFFSET);
 600        DUMP_REG(DC_WINBUF_ADDR_H_OFFSET_NS);
 601        DUMP_REG(DC_WINBUF_ADDR_V_OFFSET);
 602        DUMP_REG(DC_WINBUF_ADDR_V_OFFSET_NS);
 603        DUMP_REG(DC_WINBUF_UFLOW_STATUS);
 604        DUMP_REG(DC_WINBUF_AD_UFLOW_STATUS);
 605        DUMP_REG(DC_WINBUF_BD_UFLOW_STATUS);
 606        DUMP_REG(DC_WINBUF_CD_UFLOW_STATUS);
 607
 608#undef DUMP_REG
 609
 610        return 0;
 611}
 612
 613static struct drm_info_list debugfs_files[] = {
 614        { "regs", tegra_dc_show_regs, 0, NULL },
 615};
 616
 617static int tegra_dc_debugfs_init(struct tegra_dc *dc, struct drm_minor *minor)
 618{
 619        unsigned int i;
 620        char *name;
 621        int err;
 622
 623        name = kasprintf(GFP_KERNEL, "dc.%d", dc->pipe);
 624        dc->debugfs = debugfs_create_dir(name, minor->debugfs_root);
 625        kfree(name);
 626
 627        if (!dc->debugfs)
 628                return -ENOMEM;
 629
 630        dc->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
 631                                    GFP_KERNEL);
 632        if (!dc->debugfs_files) {
 633                err = -ENOMEM;
 634                goto remove;
 635        }
 636
 637        for (i = 0; i < ARRAY_SIZE(debugfs_files); i++)
 638                dc->debugfs_files[i].data = dc;
 639
 640        err = drm_debugfs_create_files(dc->debugfs_files,
 641                                       ARRAY_SIZE(debugfs_files),
 642                                       dc->debugfs, minor);
 643        if (err < 0)
 644                goto free;
 645
 646        dc->minor = minor;
 647
 648        return 0;
 649
 650free:
 651        kfree(dc->debugfs_files);
 652        dc->debugfs_files = NULL;
 653remove:
 654        debugfs_remove(dc->debugfs);
 655        dc->debugfs = NULL;
 656
 657        return err;
 658}
 659
 660static int tegra_dc_debugfs_exit(struct tegra_dc *dc)
 661{
 662        drm_debugfs_remove_files(dc->debugfs_files, ARRAY_SIZE(debugfs_files),
 663                                 dc->minor);
 664        dc->minor = NULL;
 665
 666        kfree(dc->debugfs_files);
 667        dc->debugfs_files = NULL;
 668
 669        debugfs_remove(dc->debugfs);
 670        dc->debugfs = NULL;
 671
 672        return 0;
 673}
 674
 675static int tegra_dc_drm_init(struct host1x_client *client,
 676                             struct drm_device *drm)
 677{
 678        struct tegra_dc *dc = host1x_client_to_dc(client);
 679        int err;
 680
 681        dc->pipe = drm->mode_config.num_crtc;
 682
 683        drm_crtc_init(drm, &dc->base, &tegra_crtc_funcs);
 684        drm_mode_crtc_set_gamma_size(&dc->base, 256);
 685        drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs);
 686
 687        err = tegra_dc_rgb_init(drm, dc);
 688        if (err < 0 && err != -ENODEV) {
 689                dev_err(dc->dev, "failed to initialize RGB output: %d\n", err);
 690                return err;
 691        }
 692
 693        if (IS_ENABLED(CONFIG_DEBUG_FS)) {
 694                err = tegra_dc_debugfs_init(dc, drm->primary);
 695                if (err < 0)
 696                        dev_err(dc->dev, "debugfs setup failed: %d\n", err);
 697        }
 698
 699        err = devm_request_irq(dc->dev, dc->irq, tegra_drm_irq, 0,
 700                               dev_name(dc->dev), dc);
 701        if (err < 0) {
 702                dev_err(dc->dev, "failed to request IRQ#%u: %d\n", dc->irq,
 703                        err);
 704                return err;
 705        }
 706
 707        return 0;
 708}
 709
 710static int tegra_dc_drm_exit(struct host1x_client *client)
 711{
 712        struct tegra_dc *dc = host1x_client_to_dc(client);
 713        int err;
 714
 715        devm_free_irq(dc->dev, dc->irq, dc);
 716
 717        if (IS_ENABLED(CONFIG_DEBUG_FS)) {
 718                err = tegra_dc_debugfs_exit(dc);
 719                if (err < 0)
 720                        dev_err(dc->dev, "debugfs cleanup failed: %d\n", err);
 721        }
 722
 723        err = tegra_dc_rgb_exit(dc);
 724        if (err) {
 725                dev_err(dc->dev, "failed to shutdown RGB output: %d\n", err);
 726                return err;
 727        }
 728
 729        return 0;
 730}
 731
 732static const struct host1x_client_ops dc_client_ops = {
 733        .drm_init = tegra_dc_drm_init,
 734        .drm_exit = tegra_dc_drm_exit,
 735};
 736
 737static int tegra_dc_probe(struct platform_device *pdev)
 738{
 739        struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
 740        struct resource *regs;
 741        struct tegra_dc *dc;
 742        int err;
 743
 744        dc = devm_kzalloc(&pdev->dev, sizeof(*dc), GFP_KERNEL);
 745        if (!dc)
 746                return -ENOMEM;
 747
 748        INIT_LIST_HEAD(&dc->list);
 749        dc->dev = &pdev->dev;
 750
 751        dc->clk = devm_clk_get(&pdev->dev, NULL);
 752        if (IS_ERR(dc->clk)) {
 753                dev_err(&pdev->dev, "failed to get clock\n");
 754                return PTR_ERR(dc->clk);
 755        }
 756
 757        err = clk_prepare_enable(dc->clk);
 758        if (err < 0)
 759                return err;
 760
 761        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 762        if (!regs) {
 763                dev_err(&pdev->dev, "failed to get registers\n");
 764                return -ENXIO;
 765        }
 766
 767        dc->regs = devm_request_and_ioremap(&pdev->dev, regs);
 768        if (!dc->regs) {
 769                dev_err(&pdev->dev, "failed to remap registers\n");
 770                return -ENXIO;
 771        }
 772
 773        dc->irq = platform_get_irq(pdev, 0);
 774        if (dc->irq < 0) {
 775                dev_err(&pdev->dev, "failed to get IRQ\n");
 776                return -ENXIO;
 777        }
 778
 779        INIT_LIST_HEAD(&dc->client.list);
 780        dc->client.ops = &dc_client_ops;
 781        dc->client.dev = &pdev->dev;
 782
 783        err = tegra_dc_rgb_probe(dc);
 784        if (err < 0 && err != -ENODEV) {
 785                dev_err(&pdev->dev, "failed to probe RGB output: %d\n", err);
 786                return err;
 787        }
 788
 789        err = host1x_register_client(host1x, &dc->client);
 790        if (err < 0) {
 791                dev_err(&pdev->dev, "failed to register host1x client: %d\n",
 792                        err);
 793                return err;
 794        }
 795
 796        platform_set_drvdata(pdev, dc);
 797
 798        return 0;
 799}
 800
 801static int tegra_dc_remove(struct platform_device *pdev)
 802{
 803        struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
 804        struct tegra_dc *dc = platform_get_drvdata(pdev);
 805        int err;
 806
 807        err = host1x_unregister_client(host1x, &dc->client);
 808        if (err < 0) {
 809                dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
 810                        err);
 811                return err;
 812        }
 813
 814        clk_disable_unprepare(dc->clk);
 815
 816        return 0;
 817}
 818
 819static struct of_device_id tegra_dc_of_match[] = {
 820        { .compatible = "nvidia,tegra30-dc", },
 821        { .compatible = "nvidia,tegra20-dc", },
 822        { },
 823};
 824
 825struct platform_driver tegra_dc_driver = {
 826        .driver = {
 827                .name = "tegra-dc",
 828                .owner = THIS_MODULE,
 829                .of_match_table = tegra_dc_of_match,
 830        },
 831        .probe = tegra_dc_probe,
 832        .remove = tegra_dc_remove,
 833};
 834