linux/drivers/staging/imx-drm/imx-hdmi.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License as published by
   6 * the Free Software Foundation; either version 2 of the License, or
   7 * (at your option) any later version.
   8 *
   9 * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
  10 * for SLISHDMI13T and SLIPHDMIT IP cores
  11 *
  12 * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  13 */
  14
  15#include <linux/component.h>
  16#include <linux/irq.h>
  17#include <linux/delay.h>
  18#include <linux/err.h>
  19#include <linux/clk.h>
  20#include <linux/hdmi.h>
  21#include <linux/regmap.h>
  22#include <linux/mfd/syscon.h>
  23#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  24#include <linux/of_device.h>
  25
  26#include <drm/drmP.h>
  27#include <drm/drm_crtc_helper.h>
  28#include <drm/drm_edid.h>
  29#include <drm/drm_encoder_slave.h>
  30#include <video/imx-ipu-v3.h>
  31
  32#include "imx-hdmi.h"
  33#include "imx-drm.h"
  34
  35#define HDMI_EDID_LEN           512
  36
  37#define RGB                     0
  38#define YCBCR444                1
  39#define YCBCR422_16BITS         2
  40#define YCBCR422_8BITS          3
  41#define XVYCC444                4
  42
  43enum hdmi_datamap {
  44        RGB444_8B = 0x01,
  45        RGB444_10B = 0x03,
  46        RGB444_12B = 0x05,
  47        RGB444_16B = 0x07,
  48        YCbCr444_8B = 0x09,
  49        YCbCr444_10B = 0x0B,
  50        YCbCr444_12B = 0x0D,
  51        YCbCr444_16B = 0x0F,
  52        YCbCr422_8B = 0x16,
  53        YCbCr422_10B = 0x14,
  54        YCbCr422_12B = 0x12,
  55};
  56
  57enum imx_hdmi_devtype {
  58        IMX6Q_HDMI,
  59        IMX6DL_HDMI,
  60};
  61
  62static const u16 csc_coeff_default[3][4] = {
  63        { 0x2000, 0x0000, 0x0000, 0x0000 },
  64        { 0x0000, 0x2000, 0x0000, 0x0000 },
  65        { 0x0000, 0x0000, 0x2000, 0x0000 }
  66};
  67
  68static const u16 csc_coeff_rgb_out_eitu601[3][4] = {
  69        { 0x2000, 0x6926, 0x74fd, 0x010e },
  70        { 0x2000, 0x2cdd, 0x0000, 0x7e9a },
  71        { 0x2000, 0x0000, 0x38b4, 0x7e3b }
  72};
  73
  74static const u16 csc_coeff_rgb_out_eitu709[3][4] = {
  75        { 0x2000, 0x7106, 0x7a02, 0x00a7 },
  76        { 0x2000, 0x3264, 0x0000, 0x7e6d },
  77        { 0x2000, 0x0000, 0x3b61, 0x7e25 }
  78};
  79
  80static const u16 csc_coeff_rgb_in_eitu601[3][4] = {
  81        { 0x2591, 0x1322, 0x074b, 0x0000 },
  82        { 0x6535, 0x2000, 0x7acc, 0x0200 },
  83        { 0x6acd, 0x7534, 0x2000, 0x0200 }
  84};
  85
  86static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
  87        { 0x2dc5, 0x0d9b, 0x049e, 0x0000 },
  88        { 0x62f0, 0x2000, 0x7d11, 0x0200 },
  89        { 0x6756, 0x78ab, 0x2000, 0x0200 }
  90};
  91
  92struct hdmi_vmode {
  93        bool mdvi;
  94        bool mhsyncpolarity;
  95        bool mvsyncpolarity;
  96        bool minterlaced;
  97        bool mdataenablepolarity;
  98
  99        unsigned int mpixelclock;
 100        unsigned int mpixelrepetitioninput;
 101        unsigned int mpixelrepetitionoutput;
 102};
 103
 104struct hdmi_data_info {
 105        unsigned int enc_in_format;
 106        unsigned int enc_out_format;
 107        unsigned int enc_color_depth;
 108        unsigned int colorimetry;
 109        unsigned int pix_repet_factor;
 110        unsigned int hdcp_enable;
 111        struct hdmi_vmode video_mode;
 112};
 113
 114struct imx_hdmi {
 115        struct drm_connector connector;
 116        struct drm_encoder encoder;
 117
 118        enum imx_hdmi_devtype dev_type;
 119        struct device *dev;
 120        struct clk *isfr_clk;
 121        struct clk *iahb_clk;
 122
 123        struct hdmi_data_info hdmi_data;
 124        int vic;
 125
 126        u8 edid[HDMI_EDID_LEN];
 127        bool cable_plugin;
 128
 129        bool phy_enabled;
 130        struct drm_display_mode previous_mode;
 131
 132        struct regmap *regmap;
 133        struct i2c_adapter *ddc;
 134        void __iomem *regs;
 135
 136        unsigned int sample_rate;
 137        int ratio;
 138};
 139
 140static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di)
 141{
 142        regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
 143                           IMX6Q_GPR3_HDMI_MUX_CTL_MASK,
 144                           ipu_di << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
 145}
 146
 147static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset)
 148{
 149        writeb(val, hdmi->regs + offset);
 150}
 151
 152static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset)
 153{
 154        return readb(hdmi->regs + offset);
 155}
 156
 157static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
 158{
 159        u8 val = hdmi_readb(hdmi, reg) & ~mask;
 160
 161        val |= data & mask;
 162        hdmi_writeb(hdmi, val, reg);
 163}
 164
 165static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg,
 166                      u8 shift, u8 mask)
 167{
 168        hdmi_modb(hdmi, data << shift, mask, reg);
 169}
 170
 171static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
 172                                         unsigned int value)
 173{
 174        hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1);
 175        hdmi_writeb(hdmi, (value >> 8) & 0xff, HDMI_AUD_N2);
 176        hdmi_writeb(hdmi, (value >> 16) & 0x0f, HDMI_AUD_N3);
 177
 178        /* nshift factor = 0 */
 179        hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
 180}
 181
 182static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts)
 183{
 184        /* Must be set/cleared first */
 185        hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
 186
 187        hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
 188        hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
 189        hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
 190                    HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
 191}
 192
 193static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
 194                                   unsigned int ratio)
 195{
 196        unsigned int n = (128 * freq) / 1000;
 197
 198        switch (freq) {
 199        case 32000:
 200                if (pixel_clk == 25170000)
 201                        n = (ratio == 150) ? 9152 : 4576;
 202                else if (pixel_clk == 27020000)
 203                        n = (ratio == 150) ? 8192 : 4096;
 204                else if (pixel_clk == 74170000 || pixel_clk == 148350000)
 205                        n = 11648;
 206                else
 207                        n = 4096;
 208                break;
 209
 210        case 44100:
 211                if (pixel_clk == 25170000)
 212                        n = 7007;
 213                else if (pixel_clk == 74170000)
 214                        n = 17836;
 215                else if (pixel_clk == 148350000)
 216                        n = (ratio == 150) ? 17836 : 8918;
 217                else
 218                        n = 6272;
 219                break;
 220
 221        case 48000:
 222                if (pixel_clk == 25170000)
 223                        n = (ratio == 150) ? 9152 : 6864;
 224                else if (pixel_clk == 27020000)
 225                        n = (ratio == 150) ? 8192 : 6144;
 226                else if (pixel_clk == 74170000)
 227                        n = 11648;
 228                else if (pixel_clk == 148350000)
 229                        n = (ratio == 150) ? 11648 : 5824;
 230                else
 231                        n = 6144;
 232                break;
 233
 234        case 88200:
 235                n = hdmi_compute_n(44100, pixel_clk, ratio) * 2;
 236                break;
 237
 238        case 96000:
 239                n = hdmi_compute_n(48000, pixel_clk, ratio) * 2;
 240                break;
 241
 242        case 176400:
 243                n = hdmi_compute_n(44100, pixel_clk, ratio) * 4;
 244                break;
 245
 246        case 192000:
 247                n = hdmi_compute_n(48000, pixel_clk, ratio) * 4;
 248                break;
 249
 250        default:
 251                break;
 252        }
 253
 254        return n;
 255}
 256
 257static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
 258                                     unsigned int ratio)
 259{
 260        unsigned int cts = 0;
 261
 262        pr_debug("%s: freq: %d pixel_clk: %ld ratio: %d\n", __func__, freq,
 263                 pixel_clk, ratio);
 264
 265        switch (freq) {
 266        case 32000:
 267                if (pixel_clk == 297000000) {
 268                        cts = 222750;
 269                        break;
 270                }
 271        case 48000:
 272        case 96000:
 273        case 192000:
 274                switch (pixel_clk) {
 275                case 25200000:
 276                case 27000000:
 277                case 54000000:
 278                case 74250000:
 279                case 148500000:
 280                        cts = pixel_clk / 1000;
 281                        break;
 282                case 297000000:
 283                        cts = 247500;
 284                        break;
 285                /*
 286                 * All other TMDS clocks are not supported by
 287                 * DWC_hdmi_tx. The TMDS clocks divided or
 288                 * multiplied by 1,001 coefficients are not
 289                 * supported.
 290                 */
 291                default:
 292                        break;
 293                }
 294                break;
 295        case 44100:
 296        case 88200:
 297        case 176400:
 298                switch (pixel_clk) {
 299                case 25200000:
 300                        cts = 28000;
 301                        break;
 302                case 27000000:
 303                        cts = 30000;
 304                        break;
 305                case 54000000:
 306                        cts = 60000;
 307                        break;
 308                case 74250000:
 309                        cts = 82500;
 310                        break;
 311                case 148500000:
 312                        cts = 165000;
 313                        break;
 314                case 297000000:
 315                        cts = 247500;
 316                        break;
 317                default:
 318                        break;
 319                }
 320                break;
 321        default:
 322                break;
 323        }
 324        if (ratio == 100)
 325                return cts;
 326        else
 327                return (cts * ratio) / 100;
 328}
 329
 330static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
 331        unsigned long pixel_clk)
 332{
 333        unsigned int clk_n, clk_cts;
 334
 335        clk_n = hdmi_compute_n(hdmi->sample_rate, pixel_clk,
 336                               hdmi->ratio);
 337        clk_cts = hdmi_compute_cts(hdmi->sample_rate, pixel_clk,
 338                                   hdmi->ratio);
 339
 340        if (!clk_cts) {
 341                dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n",
 342                         __func__, pixel_clk);
 343                return;
 344        }
 345
 346        dev_dbg(hdmi->dev, "%s: samplerate=%d  ratio=%d  pixelclk=%lu  N=%d cts=%d\n",
 347                __func__, hdmi->sample_rate, hdmi->ratio,
 348                pixel_clk, clk_n, clk_cts);
 349
 350        hdmi_set_clock_regenerator_n(hdmi, clk_n);
 351        hdmi_regenerate_cts(hdmi, clk_cts);
 352}
 353
 354static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi)
 355{
 356        hdmi_set_clk_regenerator(hdmi, 74250000);
 357}
 358
 359static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi)
 360{
 361        hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock);
 362}
 363
 364/*
 365 * this submodule is responsible for the video data synchronization.
 366 * for example, for RGB 4:4:4 input, the data map is defined as
 367 *                      pin{47~40} <==> R[7:0]
 368 *                      pin{31~24} <==> G[7:0]
 369 *                      pin{15~8}  <==> B[7:0]
 370 */
 371static void hdmi_video_sample(struct imx_hdmi *hdmi)
 372{
 373        int color_format = 0;
 374        u8 val;
 375
 376        if (hdmi->hdmi_data.enc_in_format == RGB) {
 377                if (hdmi->hdmi_data.enc_color_depth == 8)
 378                        color_format = 0x01;
 379                else if (hdmi->hdmi_data.enc_color_depth == 10)
 380                        color_format = 0x03;
 381                else if (hdmi->hdmi_data.enc_color_depth == 12)
 382                        color_format = 0x05;
 383                else if (hdmi->hdmi_data.enc_color_depth == 16)
 384                        color_format = 0x07;
 385                else
 386                        return;
 387        } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) {
 388                if (hdmi->hdmi_data.enc_color_depth == 8)
 389                        color_format = 0x09;
 390                else if (hdmi->hdmi_data.enc_color_depth == 10)
 391                        color_format = 0x0B;
 392                else if (hdmi->hdmi_data.enc_color_depth == 12)
 393                        color_format = 0x0D;
 394                else if (hdmi->hdmi_data.enc_color_depth == 16)
 395                        color_format = 0x0F;
 396                else
 397                        return;
 398        } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) {
 399                if (hdmi->hdmi_data.enc_color_depth == 8)
 400                        color_format = 0x16;
 401                else if (hdmi->hdmi_data.enc_color_depth == 10)
 402                        color_format = 0x14;
 403                else if (hdmi->hdmi_data.enc_color_depth == 12)
 404                        color_format = 0x12;
 405                else
 406                        return;
 407        }
 408
 409        val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
 410                ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
 411                HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
 412        hdmi_writeb(hdmi, val, HDMI_TX_INVID0);
 413
 414        /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */
 415        val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
 416                HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
 417                HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
 418        hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING);
 419        hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0);
 420        hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1);
 421        hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0);
 422        hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1);
 423        hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0);
 424        hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1);
 425}
 426
 427static int is_color_space_conversion(struct imx_hdmi *hdmi)
 428{
 429        return hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format;
 430}
 431
 432static int is_color_space_decimation(struct imx_hdmi *hdmi)
 433{
 434        if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS)
 435                return 0;
 436        if (hdmi->hdmi_data.enc_in_format == RGB ||
 437            hdmi->hdmi_data.enc_in_format == YCBCR444)
 438                return 1;
 439        return 0;
 440}
 441
 442static int is_color_space_interpolation(struct imx_hdmi *hdmi)
 443{
 444        if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS)
 445                return 0;
 446        if (hdmi->hdmi_data.enc_out_format == RGB ||
 447            hdmi->hdmi_data.enc_out_format == YCBCR444)
 448                return 1;
 449        return 0;
 450}
 451
 452static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
 453{
 454        const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
 455        unsigned i;
 456        u32 csc_scale = 1;
 457
 458        if (is_color_space_conversion(hdmi)) {
 459                if (hdmi->hdmi_data.enc_out_format == RGB) {
 460                        if (hdmi->hdmi_data.colorimetry ==
 461                                        HDMI_COLORIMETRY_ITU_601)
 462                                csc_coeff = &csc_coeff_rgb_out_eitu601;
 463                        else
 464                                csc_coeff = &csc_coeff_rgb_out_eitu709;
 465                } else if (hdmi->hdmi_data.enc_in_format == RGB) {
 466                        if (hdmi->hdmi_data.colorimetry ==
 467                                        HDMI_COLORIMETRY_ITU_601)
 468                                csc_coeff = &csc_coeff_rgb_in_eitu601;
 469                        else
 470                                csc_coeff = &csc_coeff_rgb_in_eitu709;
 471                        csc_scale = 0;
 472                }
 473        }
 474
 475        /* The CSC registers are sequential, alternating MSB then LSB */
 476        for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) {
 477                u16 coeff_a = (*csc_coeff)[0][i];
 478                u16 coeff_b = (*csc_coeff)[1][i];
 479                u16 coeff_c = (*csc_coeff)[2][i];
 480
 481                hdmi_writeb(hdmi, coeff_a & 0xff,
 482                        HDMI_CSC_COEF_A1_LSB + i * 2);
 483                hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2);
 484                hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2);
 485                hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2);
 486                hdmi_writeb(hdmi, coeff_c & 0xff,
 487                        HDMI_CSC_COEF_C1_LSB + i * 2);
 488                hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2);
 489        }
 490
 491        hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK,
 492                  HDMI_CSC_SCALE);
 493}
 494
 495static void hdmi_video_csc(struct imx_hdmi *hdmi)
 496{
 497        int color_depth = 0;
 498        int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
 499        int decimation = 0;
 500
 501        /* YCC422 interpolation to 444 mode */
 502        if (is_color_space_interpolation(hdmi))
 503                interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
 504        else if (is_color_space_decimation(hdmi))
 505                decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
 506
 507        if (hdmi->hdmi_data.enc_color_depth == 8)
 508                color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
 509        else if (hdmi->hdmi_data.enc_color_depth == 10)
 510                color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
 511        else if (hdmi->hdmi_data.enc_color_depth == 12)
 512                color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
 513        else if (hdmi->hdmi_data.enc_color_depth == 16)
 514                color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
 515        else
 516                return;
 517
 518        /* Configure the CSC registers */
 519        hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG);
 520        hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK,
 521                  HDMI_CSC_SCALE);
 522
 523        imx_hdmi_update_csc_coeffs(hdmi);
 524}
 525
 526/*
 527 * HDMI video packetizer is used to packetize the data.
 528 * for example, if input is YCC422 mode or repeater is used,
 529 * data should be repacked this module can be bypassed.
 530 */
 531static void hdmi_video_packetize(struct imx_hdmi *hdmi)
 532{
 533        unsigned int color_depth = 0;
 534        unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
 535        unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
 536        struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
 537        u8 val, vp_conf;
 538
 539        if (hdmi_data->enc_out_format == RGB
 540                || hdmi_data->enc_out_format == YCBCR444) {
 541                if (!hdmi_data->enc_color_depth)
 542                        output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
 543                else if (hdmi_data->enc_color_depth == 8) {
 544                        color_depth = 4;
 545                        output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
 546                } else if (hdmi_data->enc_color_depth == 10)
 547                        color_depth = 5;
 548                else if (hdmi_data->enc_color_depth == 12)
 549                        color_depth = 6;
 550                else if (hdmi_data->enc_color_depth == 16)
 551                        color_depth = 7;
 552                else
 553                        return;
 554        } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
 555                if (!hdmi_data->enc_color_depth ||
 556                    hdmi_data->enc_color_depth == 8)
 557                        remap_size = HDMI_VP_REMAP_YCC422_16bit;
 558                else if (hdmi_data->enc_color_depth == 10)
 559                        remap_size = HDMI_VP_REMAP_YCC422_20bit;
 560                else if (hdmi_data->enc_color_depth == 12)
 561                        remap_size = HDMI_VP_REMAP_YCC422_24bit;
 562                else
 563                        return;
 564                output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
 565        } else
 566                return;
 567
 568        /* set the packetizer registers */
 569        val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
 570                HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
 571                ((hdmi_data->pix_repet_factor <<
 572                HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
 573                HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
 574        hdmi_writeb(hdmi, val, HDMI_VP_PR_CD);
 575
 576        hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE,
 577                  HDMI_VP_STUFF_PR_STUFFING_MASK, HDMI_VP_STUFF);
 578
 579        /* Data from pixel repeater block */
 580        if (hdmi_data->pix_repet_factor > 1) {
 581                vp_conf = HDMI_VP_CONF_PR_EN_ENABLE |
 582                          HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
 583        } else { /* data from packetizer block */
 584                vp_conf = HDMI_VP_CONF_PR_EN_DISABLE |
 585                          HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
 586        }
 587
 588        hdmi_modb(hdmi, vp_conf,
 589                  HDMI_VP_CONF_PR_EN_MASK |
 590                  HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF);
 591
 592        hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET,
 593                  HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF);
 594
 595        hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP);
 596
 597        if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
 598                vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE |
 599                          HDMI_VP_CONF_PP_EN_ENABLE |
 600                          HDMI_VP_CONF_YCC422_EN_DISABLE;
 601        } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
 602                vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE |
 603                          HDMI_VP_CONF_PP_EN_DISABLE |
 604                          HDMI_VP_CONF_YCC422_EN_ENABLE;
 605        } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
 606                vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE |
 607                          HDMI_VP_CONF_PP_EN_DISABLE |
 608                          HDMI_VP_CONF_YCC422_EN_DISABLE;
 609        } else {
 610                return;
 611        }
 612
 613        hdmi_modb(hdmi, vp_conf,
 614                  HDMI_VP_CONF_BYPASS_EN_MASK | HDMI_VP_CONF_PP_EN_ENMASK |
 615                  HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF);
 616
 617        hdmi_modb(hdmi, HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
 618                        HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE,
 619                  HDMI_VP_STUFF_PP_STUFFING_MASK |
 620                  HDMI_VP_STUFF_YCC422_STUFFING_MASK, HDMI_VP_STUFF);
 621
 622        hdmi_modb(hdmi, output_select, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK,
 623                  HDMI_VP_CONF);
 624}
 625
 626static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi,
 627                                                unsigned char bit)
 628{
 629        hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET,
 630                  HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
 631}
 632
 633static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi,
 634                                                unsigned char bit)
 635{
 636        hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
 637                  HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
 638}
 639
 640static inline void hdmi_phy_test_clock(struct imx_hdmi *hdmi,
 641                                                unsigned char bit)
 642{
 643        hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
 644                  HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
 645}
 646
 647static inline void hdmi_phy_test_din(struct imx_hdmi *hdmi,
 648                                                unsigned char bit)
 649{
 650        hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
 651}
 652
 653static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi,
 654                                                unsigned char bit)
 655{
 656        hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
 657}
 658
 659static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec)
 660{
 661        while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
 662                if (msec-- == 0)
 663                        return false;
 664                udelay(1000);
 665        }
 666        return true;
 667}
 668
 669static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
 670                              unsigned char addr)
 671{
 672        hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
 673        hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
 674        hdmi_writeb(hdmi, (unsigned char)(data >> 8),
 675                HDMI_PHY_I2CM_DATAO_1_ADDR);
 676        hdmi_writeb(hdmi, (unsigned char)(data >> 0),
 677                HDMI_PHY_I2CM_DATAO_0_ADDR);
 678        hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
 679                HDMI_PHY_I2CM_OPERATION_ADDR);
 680        hdmi_phy_wait_i2c_done(hdmi, 1000);
 681}
 682
 683static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
 684                                     unsigned char addr)
 685{
 686        __hdmi_phy_i2c_write(hdmi, data, addr);
 687        return 0;
 688}
 689
 690static void imx_hdmi_phy_enable_power(struct imx_hdmi *hdmi, u8 enable)
 691{
 692        hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 693                         HDMI_PHY_CONF0_PDZ_OFFSET,
 694                         HDMI_PHY_CONF0_PDZ_MASK);
 695}
 696
 697static void imx_hdmi_phy_enable_tmds(struct imx_hdmi *hdmi, u8 enable)
 698{
 699        hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 700                         HDMI_PHY_CONF0_ENTMDS_OFFSET,
 701                         HDMI_PHY_CONF0_ENTMDS_MASK);
 702}
 703
 704static void imx_hdmi_phy_gen2_pddq(struct imx_hdmi *hdmi, u8 enable)
 705{
 706        hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 707                         HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
 708                         HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
 709}
 710
 711static void imx_hdmi_phy_gen2_txpwron(struct imx_hdmi *hdmi, u8 enable)
 712{
 713        hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 714                         HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
 715                         HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
 716}
 717
 718static void imx_hdmi_phy_sel_data_en_pol(struct imx_hdmi *hdmi, u8 enable)
 719{
 720        hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 721                         HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
 722                         HDMI_PHY_CONF0_SELDATAENPOL_MASK);
 723}
 724
 725static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
 726{
 727        hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 728                         HDMI_PHY_CONF0_SELDIPIF_OFFSET,
 729                         HDMI_PHY_CONF0_SELDIPIF_MASK);
 730}
 731
 732enum {
 733        RES_8,
 734        RES_10,
 735        RES_12,
 736        RES_MAX,
 737};
 738
 739struct mpll_config {
 740        unsigned long mpixelclock;
 741        struct {
 742                u16 cpce;
 743                u16 gmp;
 744        } res[RES_MAX];
 745};
 746
 747static const struct mpll_config mpll_config[] = {
 748        {
 749                45250000, {
 750                        { 0x01e0, 0x0000 },
 751                        { 0x21e1, 0x0000 },
 752                        { 0x41e2, 0x0000 }
 753                },
 754        }, {
 755                92500000, {
 756                        { 0x0140, 0x0005 },
 757                        { 0x2141, 0x0005 },
 758                        { 0x4142, 0x0005 },
 759                },
 760        }, {
 761                148500000, {
 762                        { 0x00a0, 0x000a },
 763                        { 0x20a1, 0x000a },
 764                        { 0x40a2, 0x000a },
 765                },
 766        }, {
 767                ~0UL, {
 768                        { 0x00a0, 0x000a },
 769                        { 0x2001, 0x000f },
 770                        { 0x4002, 0x000f },
 771                },
 772        }
 773};
 774
 775struct curr_ctrl {
 776        unsigned long mpixelclock;
 777        u16 curr[RES_MAX];
 778};
 779
 780static const struct curr_ctrl curr_ctrl[] = {
 781        /*      pixelclk     bpp8    bpp10   bpp12 */
 782        {
 783                 54000000, { 0x091c, 0x091c, 0x06dc },
 784        }, {
 785                 58400000, { 0x091c, 0x06dc, 0x06dc },
 786        }, {
 787                 72000000, { 0x06dc, 0x06dc, 0x091c },
 788        }, {
 789                 74250000, { 0x06dc, 0x0b5c, 0x091c },
 790        }, {
 791                118800000, { 0x091c, 0x091c, 0x06dc },
 792        }, {
 793                216000000, { 0x06dc, 0x0b5c, 0x091c },
 794        }
 795};
 796
 797static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 798                              unsigned char res, int cscon)
 799{
 800        unsigned res_idx, i;
 801        u8 val, msec;
 802
 803        if (prep)
 804                return -EINVAL;
 805
 806        switch (res) {
 807        case 0: /* color resolution 0 is 8 bit colour depth */
 808        case 8:
 809                res_idx = RES_8;
 810                break;
 811        case 10:
 812                res_idx = RES_10;
 813                break;
 814        case 12:
 815                res_idx = RES_12;
 816                break;
 817        default:
 818                return -EINVAL;
 819        }
 820
 821        /* Enable csc path */
 822        if (cscon)
 823                val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
 824        else
 825                val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;
 826
 827        hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);
 828
 829        /* gen2 tx power off */
 830        imx_hdmi_phy_gen2_txpwron(hdmi, 0);
 831
 832        /* gen2 pddq */
 833        imx_hdmi_phy_gen2_pddq(hdmi, 1);
 834
 835        /* PHY reset */
 836        hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
 837        hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
 838
 839        hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
 840
 841        hdmi_phy_test_clear(hdmi, 1);
 842        hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
 843                        HDMI_PHY_I2CM_SLAVE_ADDR);
 844        hdmi_phy_test_clear(hdmi, 0);
 845
 846        /* PLL/MPLL Cfg - always match on final entry */
 847        for (i = 0; i < ARRAY_SIZE(mpll_config) - 1; i++)
 848                if (hdmi->hdmi_data.video_mode.mpixelclock <=
 849                    mpll_config[i].mpixelclock)
 850                        break;
 851
 852        hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].cpce, 0x06);
 853        hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].gmp, 0x15);
 854
 855        for (i = 0; i < ARRAY_SIZE(curr_ctrl); i++)
 856                if (hdmi->hdmi_data.video_mode.mpixelclock <=
 857                    curr_ctrl[i].mpixelclock)
 858                        break;
 859
 860        if (i >= ARRAY_SIZE(curr_ctrl)) {
 861                dev_err(hdmi->dev,
 862                                "Pixel clock %d - unsupported by HDMI\n",
 863                                hdmi->hdmi_data.video_mode.mpixelclock);
 864                return -EINVAL;
 865        }
 866
 867        /* CURRCTRL */
 868        hdmi_phy_i2c_write(hdmi, curr_ctrl[i].curr[res_idx], 0x10);
 869
 870        hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);  /* PLLPHBYCTRL */
 871        hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
 872        /* RESISTANCE TERM 133Ohm Cfg */
 873        hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);  /* TXTERM */
 874        /* PREEMP Cgf 0.00 */
 875        hdmi_phy_i2c_write(hdmi, 0x800d, 0x09);  /* CKSYMTXCTRL */
 876        /* TX/CK LVL 10 */
 877        hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E);  /* VLEVCTRL */
 878        /* REMOVE CLK TERM */
 879        hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */
 880
 881        imx_hdmi_phy_enable_power(hdmi, 1);
 882
 883        /* toggle TMDS enable */
 884        imx_hdmi_phy_enable_tmds(hdmi, 0);
 885        imx_hdmi_phy_enable_tmds(hdmi, 1);
 886
 887        /* gen2 tx power on */
 888        imx_hdmi_phy_gen2_txpwron(hdmi, 1);
 889        imx_hdmi_phy_gen2_pddq(hdmi, 0);
 890
 891        /*Wait for PHY PLL lock */
 892        msec = 5;
 893        do {
 894                val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
 895                if (!val)
 896                        break;
 897
 898                if (msec == 0) {
 899                        dev_err(hdmi->dev, "PHY PLL not locked\n");
 900                        return -ETIMEDOUT;
 901                }
 902
 903                udelay(1000);
 904                msec--;
 905        } while (1);
 906
 907        return 0;
 908}
 909
 910static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
 911{
 912        int i, ret;
 913        bool cscon = false;
 914
 915        /*check csc whether needed activated in HDMI mode */
 916        cscon = (is_color_space_conversion(hdmi) &&
 917                        !hdmi->hdmi_data.video_mode.mdvi);
 918
 919        /* HDMI Phy spec says to do the phy initialization sequence twice */
 920        for (i = 0; i < 2; i++) {
 921                imx_hdmi_phy_sel_data_en_pol(hdmi, 1);
 922                imx_hdmi_phy_sel_interface_control(hdmi, 0);
 923                imx_hdmi_phy_enable_tmds(hdmi, 0);
 924                imx_hdmi_phy_enable_power(hdmi, 0);
 925
 926                /* Enable CSC */
 927                ret = hdmi_phy_configure(hdmi, 0, 8, cscon);
 928                if (ret)
 929                        return ret;
 930        }
 931
 932        hdmi->phy_enabled = true;
 933        return 0;
 934}
 935
 936static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
 937{
 938        u8 de;
 939
 940        if (hdmi->hdmi_data.video_mode.mdataenablepolarity)
 941                de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH;
 942        else
 943                de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW;
 944
 945        /* disable rx detect */
 946        hdmi_modb(hdmi, HDMI_A_HDCPCFG0_RXDETECT_DISABLE,
 947                  HDMI_A_HDCPCFG0_RXDETECT_MASK, HDMI_A_HDCPCFG0);
 948
 949        hdmi_modb(hdmi, de, HDMI_A_VIDPOLCFG_DATAENPOL_MASK, HDMI_A_VIDPOLCFG);
 950
 951        hdmi_modb(hdmi, HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE,
 952                  HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
 953}
 954
 955static void hdmi_config_AVI(struct imx_hdmi *hdmi)
 956{
 957        u8 val, pix_fmt, under_scan;
 958        u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
 959        bool aspect_16_9;
 960
 961        aspect_16_9 = false; /* FIXME */
 962
 963        /* AVI Data Byte 1 */
 964        if (hdmi->hdmi_data.enc_out_format == YCBCR444)
 965                pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444;
 966        else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS)
 967                pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422;
 968        else
 969                pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;
 970
 971                under_scan =  HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
 972
 973        /*
 974         * Active format identification data is present in the AVI InfoFrame.
 975         * Under scan info, no bar data
 976         */
 977        val = pix_fmt | under_scan |
 978                HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT |
 979                HDMI_FC_AVICONF0_BAR_DATA_NO_DATA;
 980
 981        hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0);
 982
 983        /* AVI Data Byte 2 -Set the Aspect Ratio */
 984        if (aspect_16_9) {
 985                act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9;
 986                coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9;
 987        } else {
 988                act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3;
 989                coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3;
 990        }
 991
 992        /* Set up colorimetry */
 993        if (hdmi->hdmi_data.enc_out_format == XVYCC444) {
 994                colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO;
 995                if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
 996                        ext_colorimetry =
 997                                HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
 998                else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/
 999                        ext_colorimetry =
1000                                HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
1001        } else if (hdmi->hdmi_data.enc_out_format != RGB) {
1002                if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
1003                        colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
1004                else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/
1005                        colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR;
1006                ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
1007        } else { /* Carries no data */
1008                colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA;
1009                ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
1010        }
1011
1012        val = colorimetry | coded_ratio | act_ratio;
1013        hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1);
1014
1015        /* AVI Data Byte 3 */
1016        val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry |
1017                HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT |
1018                HDMI_FC_AVICONF2_SCALING_NONE;
1019        hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2);
1020
1021        /* AVI Data Byte 4 */
1022        hdmi_writeb(hdmi, hdmi->vic, HDMI_FC_AVIVID);
1023
1024        /* AVI Data Byte 5- set up input and output pixel repetition */
1025        val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) <<
1026                HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
1027                HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
1028                ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput <<
1029                HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
1030                HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
1031        hdmi_writeb(hdmi, val, HDMI_FC_PRCONF);
1032
1033        /* IT Content and quantization range = don't care */
1034        val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS |
1035                HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED;
1036        hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3);
1037
1038        /* AVI Data Bytes 6-13 */
1039        hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB0);
1040        hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB1);
1041        hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB0);
1042        hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB1);
1043        hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB0);
1044        hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB1);
1045        hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB0);
1046        hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB1);
1047}
1048
1049static void hdmi_av_composer(struct imx_hdmi *hdmi,
1050                             const struct drm_display_mode *mode)
1051{
1052        u8 inv_val;
1053        struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
1054        int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
1055
1056        vmode->mhsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PHSYNC);
1057        vmode->mvsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PVSYNC);
1058        vmode->minterlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
1059        vmode->mpixelclock = mode->clock * 1000;
1060
1061        dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
1062
1063        /* Set up HDMI_FC_INVIDCONF */
1064        inv_val = (hdmi->hdmi_data.hdcp_enable ?
1065                HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
1066                HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
1067
1068        inv_val |= (vmode->mvsyncpolarity ?
1069                HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
1070                HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
1071
1072        inv_val |= (vmode->mhsyncpolarity ?
1073                HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
1074                HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
1075
1076        inv_val |= (vmode->mdataenablepolarity ?
1077                HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
1078                HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
1079
1080        if (hdmi->vic == 39)
1081                inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
1082        else
1083                inv_val |= (vmode->minterlaced ?
1084                        HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
1085                        HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW);
1086
1087        inv_val |= (vmode->minterlaced ?
1088                HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
1089                HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE);
1090
1091        inv_val |= (vmode->mdvi ?
1092                HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE :
1093                HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE);
1094
1095        hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
1096
1097        /* Set up horizontal active pixel width */
1098        hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1);
1099        hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0);
1100
1101        /* Set up vertical active lines */
1102        hdmi_writeb(hdmi, mode->vdisplay >> 8, HDMI_FC_INVACTV1);
1103        hdmi_writeb(hdmi, mode->vdisplay, HDMI_FC_INVACTV0);
1104
1105        /* Set up horizontal blanking pixel region width */
1106        hblank = mode->htotal - mode->hdisplay;
1107        hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1);
1108        hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0);
1109
1110        /* Set up vertical blanking pixel region width */
1111        vblank = mode->vtotal - mode->vdisplay;
1112        hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK);
1113
1114        /* Set up HSYNC active edge delay width (in pixel clks) */
1115        h_de_hs = mode->hsync_start - mode->hdisplay;
1116        hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1);
1117        hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0);
1118
1119        /* Set up VSYNC active edge delay (in lines) */
1120        v_de_vs = mode->vsync_start - mode->vdisplay;
1121        hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY);
1122
1123        /* Set up HSYNC active pulse width (in pixel clks) */
1124        hsync_len = mode->hsync_end - mode->hsync_start;
1125        hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
1126        hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0);
1127
1128        /* Set up VSYNC active edge delay (in lines) */
1129        vsync_len = mode->vsync_end - mode->vsync_start;
1130        hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
1131}
1132
1133static void imx_hdmi_phy_disable(struct imx_hdmi *hdmi)
1134{
1135        if (!hdmi->phy_enabled)
1136                return;
1137
1138        imx_hdmi_phy_enable_tmds(hdmi, 0);
1139        imx_hdmi_phy_enable_power(hdmi, 0);
1140
1141        hdmi->phy_enabled = false;
1142}
1143
1144/* HDMI Initialization Step B.4 */
1145static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
1146{
1147        u8 clkdis;
1148
1149        /* control period minimum duration */
1150        hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
1151        hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
1152        hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC);
1153
1154        /* Set to fill TMDS data channels */
1155        hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM);
1156        hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM);
1157        hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
1158
1159        /* Enable pixel clock and tmds data path */
1160        clkdis = 0x7F;
1161        clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
1162        hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
1163
1164        clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
1165        hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
1166
1167        /* Enable csc path */
1168        if (is_color_space_conversion(hdmi)) {
1169                clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
1170                hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
1171        }
1172}
1173
1174static void hdmi_enable_audio_clk(struct imx_hdmi *hdmi)
1175{
1176        hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
1177}
1178
1179/* Workaround to clear the overflow condition */
1180static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
1181{
1182        int count;
1183        u8 val;
1184
1185        /* TMDS software reset */
1186        hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
1187
1188        val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
1189        if (hdmi->dev_type == IMX6DL_HDMI) {
1190                hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
1191                return;
1192        }
1193
1194        for (count = 0; count < 4; count++)
1195                hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
1196}
1197
1198static void hdmi_enable_overflow_interrupts(struct imx_hdmi *hdmi)
1199{
1200        hdmi_writeb(hdmi, 0, HDMI_FC_MASK2);
1201        hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2);
1202}
1203
1204static void hdmi_disable_overflow_interrupts(struct imx_hdmi *hdmi)
1205{
1206        hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
1207                    HDMI_IH_MUTE_FC_STAT2);
1208}
1209
1210static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
1211{
1212        int ret;
1213
1214        hdmi_disable_overflow_interrupts(hdmi);
1215
1216        hdmi->vic = drm_match_cea_mode(mode);
1217
1218        if (!hdmi->vic) {
1219                dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n");
1220                hdmi->hdmi_data.video_mode.mdvi = true;
1221        } else {
1222                dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
1223                hdmi->hdmi_data.video_mode.mdvi = false;
1224        }
1225
1226        if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
1227                (hdmi->vic == 21) || (hdmi->vic == 22) ||
1228                (hdmi->vic == 2) || (hdmi->vic == 3) ||
1229                (hdmi->vic == 17) || (hdmi->vic == 18))
1230                hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
1231        else
1232                hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
1233
1234        if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
1235                (hdmi->vic == 12) || (hdmi->vic == 13) ||
1236                (hdmi->vic == 14) || (hdmi->vic == 15) ||
1237                (hdmi->vic == 25) || (hdmi->vic == 26) ||
1238                (hdmi->vic == 27) || (hdmi->vic == 28) ||
1239                (hdmi->vic == 29) || (hdmi->vic == 30) ||
1240                (hdmi->vic == 35) || (hdmi->vic == 36) ||
1241                (hdmi->vic == 37) || (hdmi->vic == 38))
1242                hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
1243        else
1244                hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
1245
1246        hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
1247
1248        /* TODO: Get input format from IPU (via FB driver interface) */
1249        hdmi->hdmi_data.enc_in_format = RGB;
1250
1251        hdmi->hdmi_data.enc_out_format = RGB;
1252
1253        hdmi->hdmi_data.enc_color_depth = 8;
1254        hdmi->hdmi_data.pix_repet_factor = 0;
1255        hdmi->hdmi_data.hdcp_enable = 0;
1256        hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
1257
1258        /* HDMI Initialization Step B.1 */
1259        hdmi_av_composer(hdmi, mode);
1260
1261        /* HDMI Initializateion Step B.2 */
1262        ret = imx_hdmi_phy_init(hdmi);
1263        if (ret)
1264                return ret;
1265
1266        /* HDMI Initialization Step B.3 */
1267        imx_hdmi_enable_video_path(hdmi);
1268
1269        /* not for DVI mode */
1270        if (hdmi->hdmi_data.video_mode.mdvi)
1271                dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
1272        else {
1273                dev_dbg(hdmi->dev, "%s CEA mode\n", __func__);
1274
1275                /* HDMI Initialization Step E - Configure audio */
1276                hdmi_clk_regenerator_update_pixel_clock(hdmi);
1277                hdmi_enable_audio_clk(hdmi);
1278
1279                /* HDMI Initialization Step F - Configure AVI InfoFrame */
1280                hdmi_config_AVI(hdmi);
1281        }
1282
1283        hdmi_video_packetize(hdmi);
1284        hdmi_video_csc(hdmi);
1285        hdmi_video_sample(hdmi);
1286        hdmi_tx_hdcp_config(hdmi);
1287
1288        imx_hdmi_clear_overflow(hdmi);
1289        if (hdmi->cable_plugin && !hdmi->hdmi_data.video_mode.mdvi)
1290                hdmi_enable_overflow_interrupts(hdmi);
1291
1292        return 0;
1293}
1294
1295/* Wait until we are registered to enable interrupts */
1296static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
1297{
1298        hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
1299                    HDMI_PHY_I2CM_INT_ADDR);
1300
1301        hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
1302                    HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
1303                    HDMI_PHY_I2CM_CTLINT_ADDR);
1304
1305        /* enable cable hot plug irq */
1306        hdmi_writeb(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
1307
1308        /* Clear Hotplug interrupts */
1309        hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
1310
1311        return 0;
1312}
1313
1314static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
1315{
1316        u8 ih_mute;
1317
1318        /*
1319         * Boot up defaults are:
1320         * HDMI_IH_MUTE   = 0x03 (disabled)
1321         * HDMI_IH_MUTE_* = 0x00 (enabled)
1322         *
1323         * Disable top level interrupt bits in HDMI block
1324         */
1325        ih_mute = hdmi_readb(hdmi, HDMI_IH_MUTE) |
1326                  HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
1327                  HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
1328
1329        hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
1330
1331        /* by default mask all interrupts */
1332        hdmi_writeb(hdmi, 0xff, HDMI_VP_MASK);
1333        hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK0);
1334        hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK1);
1335        hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK2);
1336        hdmi_writeb(hdmi, 0xff, HDMI_PHY_MASK0);
1337        hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_INT_ADDR);
1338        hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_CTLINT_ADDR);
1339        hdmi_writeb(hdmi, 0xff, HDMI_AUD_INT);
1340        hdmi_writeb(hdmi, 0xff, HDMI_AUD_SPDIFINT);
1341        hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
1342        hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
1343        hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
1344        hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
1345        hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
1346        hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
1347
1348        /* Disable interrupts in the IH_MUTE_* registers */
1349        hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0);
1350        hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1);
1351        hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2);
1352        hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0);
1353        hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_PHY_STAT0);
1354        hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0);
1355        hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0);
1356        hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0);
1357        hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
1358        hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
1359
1360        /* Enable top level interrupt bits in HDMI block */
1361        ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
1362                    HDMI_IH_MUTE_MUTE_ALL_INTERRUPT);
1363        hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
1364}
1365
1366static void imx_hdmi_poweron(struct imx_hdmi *hdmi)
1367{
1368        imx_hdmi_setup(hdmi, &hdmi->previous_mode);
1369}
1370
1371static void imx_hdmi_poweroff(struct imx_hdmi *hdmi)
1372{
1373        imx_hdmi_phy_disable(hdmi);
1374}
1375
1376static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
1377                                                        *connector, bool force)
1378{
1379        struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
1380                                             connector);
1381
1382        return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
1383                connector_status_connected : connector_status_disconnected;
1384}
1385
1386static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
1387{
1388        struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
1389                                             connector);
1390        struct edid *edid;
1391        int ret;
1392
1393        if (!hdmi->ddc)
1394                return 0;
1395
1396        edid = drm_get_edid(connector, hdmi->ddc);
1397        if (edid) {
1398                dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
1399                        edid->width_cm, edid->height_cm);
1400
1401                drm_mode_connector_update_edid_property(connector, edid);
1402                ret = drm_add_edid_modes(connector, edid);
1403                kfree(edid);
1404        } else {
1405                dev_dbg(hdmi->dev, "failed to get edid\n");
1406        }
1407
1408        return 0;
1409}
1410
1411static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector
1412                                                           *connector)
1413{
1414        struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
1415                                             connector);
1416
1417        return &hdmi->encoder;
1418}
1419
1420static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
1421                        struct drm_display_mode *mode,
1422                        struct drm_display_mode *adjusted_mode)
1423{
1424        struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
1425
1426        imx_hdmi_setup(hdmi, mode);
1427
1428        /* Store the display mode for plugin/DKMS poweron events */
1429        memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
1430}
1431
1432static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
1433                        const struct drm_display_mode *mode,
1434                        struct drm_display_mode *adjusted_mode)
1435{
1436        return true;
1437}
1438
1439static void imx_hdmi_encoder_disable(struct drm_encoder *encoder)
1440{
1441}
1442
1443static void imx_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode)
1444{
1445        struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
1446
1447        if (mode)
1448                imx_hdmi_poweroff(hdmi);
1449        else
1450                imx_hdmi_poweron(hdmi);
1451}
1452
1453static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
1454{
1455        struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
1456
1457        imx_hdmi_poweroff(hdmi);
1458        imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
1459}
1460
1461static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
1462{
1463        struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
1464        int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
1465
1466        imx_hdmi_set_ipu_di_mux(hdmi, mux);
1467
1468        imx_hdmi_poweron(hdmi);
1469}
1470
1471static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
1472        .destroy = imx_drm_encoder_destroy,
1473};
1474
1475static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
1476        .dpms = imx_hdmi_encoder_dpms,
1477        .prepare = imx_hdmi_encoder_prepare,
1478        .commit = imx_hdmi_encoder_commit,
1479        .mode_set = imx_hdmi_encoder_mode_set,
1480        .mode_fixup = imx_hdmi_encoder_mode_fixup,
1481        .disable = imx_hdmi_encoder_disable,
1482};
1483
1484static struct drm_connector_funcs imx_hdmi_connector_funcs = {
1485        .dpms = drm_helper_connector_dpms,
1486        .fill_modes = drm_helper_probe_single_connector_modes,
1487        .detect = imx_hdmi_connector_detect,
1488        .destroy = imx_drm_connector_destroy,
1489};
1490
1491static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
1492        .get_modes = imx_hdmi_connector_get_modes,
1493        .best_encoder = imx_hdmi_connector_best_encoder,
1494};
1495
1496static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
1497{
1498        struct imx_hdmi *hdmi = dev_id;
1499        u8 intr_stat;
1500
1501        intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
1502        if (intr_stat)
1503                hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
1504
1505        return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE;
1506}
1507
1508static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
1509{
1510        struct imx_hdmi *hdmi = dev_id;
1511        u8 intr_stat;
1512        u8 phy_int_pol;
1513
1514        intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
1515
1516        phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);
1517
1518        if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
1519                if (phy_int_pol & HDMI_PHY_HPD) {
1520                        dev_dbg(hdmi->dev, "EVENT=plugin\n");
1521
1522                        hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);
1523
1524                        imx_hdmi_poweron(hdmi);
1525                } else {
1526                        dev_dbg(hdmi->dev, "EVENT=plugout\n");
1527
1528                        hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
1529                                HDMI_PHY_POL0);
1530
1531                        imx_hdmi_poweroff(hdmi);
1532                }
1533                drm_helper_hpd_irq_event(hdmi->connector.dev);
1534        }
1535
1536        hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
1537        hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
1538
1539        return IRQ_HANDLED;
1540}
1541
1542static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
1543{
1544        int ret;
1545
1546        ret = imx_drm_encoder_parse_of(drm, &hdmi->encoder,
1547                                       hdmi->dev->of_node);
1548        if (ret)
1549                return ret;
1550
1551        hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
1552
1553        drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs);
1554        drm_encoder_init(drm, &hdmi->encoder, &imx_hdmi_encoder_funcs,
1555                         DRM_MODE_ENCODER_TMDS);
1556
1557        drm_connector_helper_add(&hdmi->connector,
1558                        &imx_hdmi_connector_helper_funcs);
1559        drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs,
1560                           DRM_MODE_CONNECTOR_HDMIA);
1561
1562        hdmi->connector.encoder = &hdmi->encoder;
1563
1564        drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder);
1565
1566        return 0;
1567}
1568
1569static struct platform_device_id imx_hdmi_devtype[] = {
1570        {
1571                .name = "imx6q-hdmi",
1572                .driver_data = IMX6Q_HDMI,
1573        }, {
1574                .name = "imx6dl-hdmi",
1575                .driver_data = IMX6DL_HDMI,
1576        }, { /* sentinel */ }
1577};
1578MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
1579
1580static const struct of_device_id imx_hdmi_dt_ids[] = {
1581{ .compatible = "fsl,imx6q-hdmi", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
1582{ .compatible = "fsl,imx6dl-hdmi", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
1583{ /* sentinel */ }
1584};
1585MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
1586
1587static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
1588{
1589        struct platform_device *pdev = to_platform_device(dev);
1590        const struct of_device_id *of_id =
1591                                of_match_device(imx_hdmi_dt_ids, dev);
1592        struct drm_device *drm = data;
1593        struct device_node *np = dev->of_node;
1594        struct device_node *ddc_node;
1595        struct imx_hdmi *hdmi;
1596        struct resource *iores;
1597        int ret, irq;
1598
1599        hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
1600        if (!hdmi)
1601                return -ENOMEM;
1602
1603        hdmi->dev = dev;
1604        hdmi->sample_rate = 48000;
1605        hdmi->ratio = 100;
1606
1607        if (of_id) {
1608                const struct platform_device_id *device_id = of_id->data;
1609
1610                hdmi->dev_type = device_id->driver_data;
1611        }
1612
1613        ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
1614        if (ddc_node) {
1615                hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
1616                if (!hdmi->ddc)
1617                        dev_dbg(hdmi->dev, "failed to read ddc node\n");
1618
1619                of_node_put(ddc_node);
1620        } else {
1621                dev_dbg(hdmi->dev, "no ddc property found\n");
1622        }
1623
1624        irq = platform_get_irq(pdev, 0);
1625        if (irq < 0)
1626                return irq;
1627
1628        ret = devm_request_threaded_irq(dev, irq, imx_hdmi_hardirq,
1629                                        imx_hdmi_irq, IRQF_SHARED,
1630                                        dev_name(dev), hdmi);
1631        if (ret)
1632                return ret;
1633
1634        iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1635        hdmi->regs = devm_ioremap_resource(dev, iores);
1636        if (IS_ERR(hdmi->regs))
1637                return PTR_ERR(hdmi->regs);
1638
1639        hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
1640        if (IS_ERR(hdmi->regmap))
1641                return PTR_ERR(hdmi->regmap);
1642
1643        hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
1644        if (IS_ERR(hdmi->isfr_clk)) {
1645                ret = PTR_ERR(hdmi->isfr_clk);
1646                dev_err(hdmi->dev,
1647                        "Unable to get HDMI isfr clk: %d\n", ret);
1648                return ret;
1649        }
1650
1651        ret = clk_prepare_enable(hdmi->isfr_clk);
1652        if (ret) {
1653                dev_err(hdmi->dev,
1654                        "Cannot enable HDMI isfr clock: %d\n", ret);
1655                return ret;
1656        }
1657
1658        hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
1659        if (IS_ERR(hdmi->iahb_clk)) {
1660                ret = PTR_ERR(hdmi->iahb_clk);
1661                dev_err(hdmi->dev,
1662                        "Unable to get HDMI iahb clk: %d\n", ret);
1663                goto err_isfr;
1664        }
1665
1666        ret = clk_prepare_enable(hdmi->iahb_clk);
1667        if (ret) {
1668                dev_err(hdmi->dev,
1669                        "Cannot enable HDMI iahb clock: %d\n", ret);
1670                goto err_isfr;
1671        }
1672
1673        /* Product and revision IDs */
1674        dev_info(dev,
1675                "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
1676                hdmi_readb(hdmi, HDMI_DESIGN_ID),
1677                hdmi_readb(hdmi, HDMI_REVISION_ID),
1678                hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
1679                hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
1680
1681        initialize_hdmi_ih_mutes(hdmi);
1682
1683        /*
1684         * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
1685         * N and cts values before enabling phy
1686         */
1687        hdmi_init_clk_regenerator(hdmi);
1688
1689        /*
1690         * Configure registers related to HDMI interrupt
1691         * generation before registering IRQ.
1692         */
1693        hdmi_writeb(hdmi, HDMI_PHY_HPD, HDMI_PHY_POL0);
1694
1695        /* Clear Hotplug interrupts */
1696        hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
1697
1698        ret = imx_hdmi_fb_registered(hdmi);
1699        if (ret)
1700                goto err_iahb;
1701
1702        ret = imx_hdmi_register(drm, hdmi);
1703        if (ret)
1704                goto err_iahb;
1705
1706        /* Unmute interrupts */
1707        hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
1708
1709        dev_set_drvdata(dev, hdmi);
1710
1711        return 0;
1712
1713err_iahb:
1714        clk_disable_unprepare(hdmi->iahb_clk);
1715err_isfr:
1716        clk_disable_unprepare(hdmi->isfr_clk);
1717
1718        return ret;
1719}
1720
1721static void imx_hdmi_unbind(struct device *dev, struct device *master,
1722        void *data)
1723{
1724        struct imx_hdmi *hdmi = dev_get_drvdata(dev);
1725
1726        /* Disable all interrupts */
1727        hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
1728
1729        hdmi->connector.funcs->destroy(&hdmi->connector);
1730        hdmi->encoder.funcs->destroy(&hdmi->encoder);
1731
1732        clk_disable_unprepare(hdmi->iahb_clk);
1733        clk_disable_unprepare(hdmi->isfr_clk);
1734        i2c_put_adapter(hdmi->ddc);
1735}
1736
1737static const struct component_ops hdmi_ops = {
1738        .bind   = imx_hdmi_bind,
1739        .unbind = imx_hdmi_unbind,
1740};
1741
1742static int imx_hdmi_platform_probe(struct platform_device *pdev)
1743{
1744        return component_add(&pdev->dev, &hdmi_ops);
1745}
1746
1747static int imx_hdmi_platform_remove(struct platform_device *pdev)
1748{
1749        component_del(&pdev->dev, &hdmi_ops);
1750        return 0;
1751}
1752
1753static struct platform_driver imx_hdmi_driver = {
1754        .probe  = imx_hdmi_platform_probe,
1755        .remove = imx_hdmi_platform_remove,
1756        .driver = {
1757                .name = "imx-hdmi",
1758                .owner = THIS_MODULE,
1759                .of_match_table = imx_hdmi_dt_ids,
1760        },
1761};
1762
1763module_platform_driver(imx_hdmi_driver);
1764
1765MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
1766MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver");
1767MODULE_LICENSE("GPL");
1768MODULE_ALIAS("platform:imx-hdmi");
1769