linux/drivers/gpu/drm/sti/sti_hdmi.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) STMicroelectronics SA 2014
   3 * Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
   4 * License terms:  GNU General Public License (GPL), version 2
   5 */
   6
   7#include <linux/clk.h>
   8#include <linux/component.h>
   9#include <linux/hdmi.h>
  10#include <linux/module.h>
  11#include <linux/of_gpio.h>
  12#include <linux/platform_device.h>
  13#include <linux/reset.h>
  14
  15#include <drm/drmP.h>
  16#include <drm/drm_atomic_helper.h>
  17#include <drm/drm_crtc_helper.h>
  18#include <drm/drm_edid.h>
  19
  20#include "sti_hdmi.h"
  21#include "sti_hdmi_tx3g4c28phy.h"
  22#include "sti_hdmi_tx3g0c55phy.h"
  23#include "sti_vtg.h"
  24
  25#define HDMI_CFG                        0x0000
  26#define HDMI_INT_EN                     0x0004
  27#define HDMI_INT_STA                    0x0008
  28#define HDMI_INT_CLR                    0x000C
  29#define HDMI_STA                        0x0010
  30#define HDMI_ACTIVE_VID_XMIN            0x0100
  31#define HDMI_ACTIVE_VID_XMAX            0x0104
  32#define HDMI_ACTIVE_VID_YMIN            0x0108
  33#define HDMI_ACTIVE_VID_YMAX            0x010C
  34#define HDMI_DFLT_CHL0_DAT              0x0110
  35#define HDMI_DFLT_CHL1_DAT              0x0114
  36#define HDMI_DFLT_CHL2_DAT              0x0118
  37#define HDMI_SW_DI_1_HEAD_WORD          0x0210
  38#define HDMI_SW_DI_1_PKT_WORD0          0x0214
  39#define HDMI_SW_DI_1_PKT_WORD1          0x0218
  40#define HDMI_SW_DI_1_PKT_WORD2          0x021C
  41#define HDMI_SW_DI_1_PKT_WORD3          0x0220
  42#define HDMI_SW_DI_1_PKT_WORD4          0x0224
  43#define HDMI_SW_DI_1_PKT_WORD5          0x0228
  44#define HDMI_SW_DI_1_PKT_WORD6          0x022C
  45#define HDMI_SW_DI_CFG                  0x0230
  46#define HDMI_SW_DI_2_HEAD_WORD          0x0600
  47#define HDMI_SW_DI_2_PKT_WORD0          0x0604
  48#define HDMI_SW_DI_2_PKT_WORD1          0x0608
  49#define HDMI_SW_DI_2_PKT_WORD2          0x060C
  50#define HDMI_SW_DI_2_PKT_WORD3          0x0610
  51#define HDMI_SW_DI_2_PKT_WORD4          0x0614
  52#define HDMI_SW_DI_2_PKT_WORD5          0x0618
  53#define HDMI_SW_DI_2_PKT_WORD6          0x061C
  54
  55#define HDMI_IFRAME_SLOT_AVI            1
  56#define HDMI_IFRAME_SLOT_AUDIO          2
  57
  58#define  XCAT(prefix, x, suffix)        prefix ## x ## suffix
  59#define  HDMI_SW_DI_N_HEAD_WORD(x)      XCAT(HDMI_SW_DI_, x, _HEAD_WORD)
  60#define  HDMI_SW_DI_N_PKT_WORD0(x)      XCAT(HDMI_SW_DI_, x, _PKT_WORD0)
  61#define  HDMI_SW_DI_N_PKT_WORD1(x)      XCAT(HDMI_SW_DI_, x, _PKT_WORD1)
  62#define  HDMI_SW_DI_N_PKT_WORD2(x)      XCAT(HDMI_SW_DI_, x, _PKT_WORD2)
  63#define  HDMI_SW_DI_N_PKT_WORD3(x)      XCAT(HDMI_SW_DI_, x, _PKT_WORD3)
  64#define  HDMI_SW_DI_N_PKT_WORD4(x)      XCAT(HDMI_SW_DI_, x, _PKT_WORD4)
  65#define  HDMI_SW_DI_N_PKT_WORD5(x)      XCAT(HDMI_SW_DI_, x, _PKT_WORD5)
  66#define  HDMI_SW_DI_N_PKT_WORD6(x)      XCAT(HDMI_SW_DI_, x, _PKT_WORD6)
  67
  68#define HDMI_IFRAME_DISABLED            0x0
  69#define HDMI_IFRAME_SINGLE_SHOT         0x1
  70#define HDMI_IFRAME_FIELD               0x2
  71#define HDMI_IFRAME_FRAME               0x3
  72#define HDMI_IFRAME_MASK                0x3
  73#define HDMI_IFRAME_CFG_DI_N(x, n)       ((x) << ((n-1)*4)) /* n from 1 to 6 */
  74
  75#define HDMI_CFG_DEVICE_EN              BIT(0)
  76#define HDMI_CFG_HDMI_NOT_DVI           BIT(1)
  77#define HDMI_CFG_HDCP_EN                BIT(2)
  78#define HDMI_CFG_ESS_NOT_OESS           BIT(3)
  79#define HDMI_CFG_H_SYNC_POL_NEG         BIT(4)
  80#define HDMI_CFG_SINK_TERM_DET_EN       BIT(5)
  81#define HDMI_CFG_V_SYNC_POL_NEG         BIT(6)
  82#define HDMI_CFG_422_EN                 BIT(8)
  83#define HDMI_CFG_FIFO_OVERRUN_CLR       BIT(12)
  84#define HDMI_CFG_FIFO_UNDERRUN_CLR      BIT(13)
  85#define HDMI_CFG_SW_RST_EN              BIT(31)
  86
  87#define HDMI_INT_GLOBAL                 BIT(0)
  88#define HDMI_INT_SW_RST                 BIT(1)
  89#define HDMI_INT_PIX_CAP                BIT(3)
  90#define HDMI_INT_HOT_PLUG               BIT(4)
  91#define HDMI_INT_DLL_LCK                BIT(5)
  92#define HDMI_INT_NEW_FRAME              BIT(6)
  93#define HDMI_INT_GENCTRL_PKT            BIT(7)
  94#define HDMI_INT_SINK_TERM_PRESENT      BIT(11)
  95
  96#define HDMI_DEFAULT_INT (HDMI_INT_SINK_TERM_PRESENT \
  97                        | HDMI_INT_DLL_LCK \
  98                        | HDMI_INT_HOT_PLUG \
  99                        | HDMI_INT_GLOBAL)
 100
 101#define HDMI_WORKING_INT (HDMI_INT_SINK_TERM_PRESENT \
 102                        | HDMI_INT_GENCTRL_PKT \
 103                        | HDMI_INT_NEW_FRAME \
 104                        | HDMI_INT_DLL_LCK \
 105                        | HDMI_INT_HOT_PLUG \
 106                        | HDMI_INT_PIX_CAP \
 107                        | HDMI_INT_SW_RST \
 108                        | HDMI_INT_GLOBAL)
 109
 110#define HDMI_STA_SW_RST                 BIT(1)
 111
 112#define HDMI_INFOFRAME_HEADER_TYPE(x)    (((x) & 0xff) <<  0)
 113#define HDMI_INFOFRAME_HEADER_VERSION(x) (((x) & 0xff) <<  8)
 114#define HDMI_INFOFRAME_HEADER_LEN(x)     (((x) & 0x0f) << 16)
 115
 116struct sti_hdmi_connector {
 117        struct drm_connector drm_connector;
 118        struct drm_encoder *encoder;
 119        struct sti_hdmi *hdmi;
 120};
 121
 122#define to_sti_hdmi_connector(x) \
 123        container_of(x, struct sti_hdmi_connector, drm_connector)
 124
 125u32 hdmi_read(struct sti_hdmi *hdmi, int offset)
 126{
 127        return readl(hdmi->regs + offset);
 128}
 129
 130void hdmi_write(struct sti_hdmi *hdmi, u32 val, int offset)
 131{
 132        writel(val, hdmi->regs + offset);
 133}
 134
 135/**
 136 * HDMI interrupt handler threaded
 137 *
 138 * @irq: irq number
 139 * @arg: connector structure
 140 */
 141static irqreturn_t hdmi_irq_thread(int irq, void *arg)
 142{
 143        struct sti_hdmi *hdmi = arg;
 144
 145        /* Hot plug/unplug IRQ */
 146        if (hdmi->irq_status & HDMI_INT_HOT_PLUG) {
 147                hdmi->hpd = readl(hdmi->regs + HDMI_STA) & HDMI_STA_HOT_PLUG;
 148                if (hdmi->drm_dev)
 149                        drm_helper_hpd_irq_event(hdmi->drm_dev);
 150        }
 151
 152        /* Sw reset and PLL lock are exclusive so we can use the same
 153         * event to signal them
 154         */
 155        if (hdmi->irq_status & (HDMI_INT_SW_RST | HDMI_INT_DLL_LCK)) {
 156                hdmi->event_received = true;
 157                wake_up_interruptible(&hdmi->wait_event);
 158        }
 159
 160        return IRQ_HANDLED;
 161}
 162
 163/**
 164 * HDMI interrupt handler
 165 *
 166 * @irq: irq number
 167 * @arg: connector structure
 168 */
 169static irqreturn_t hdmi_irq(int irq, void *arg)
 170{
 171        struct sti_hdmi *hdmi = arg;
 172
 173        /* read interrupt status */
 174        hdmi->irq_status = hdmi_read(hdmi, HDMI_INT_STA);
 175
 176        /* clear interrupt status */
 177        hdmi_write(hdmi, hdmi->irq_status, HDMI_INT_CLR);
 178
 179        /* force sync bus write */
 180        hdmi_read(hdmi, HDMI_INT_STA);
 181
 182        return IRQ_WAKE_THREAD;
 183}
 184
 185/**
 186 * Set hdmi active area depending on the drm display mode selected
 187 *
 188 * @hdmi: pointer on the hdmi internal structure
 189 */
 190static void hdmi_active_area(struct sti_hdmi *hdmi)
 191{
 192        u32 xmin, xmax;
 193        u32 ymin, ymax;
 194
 195        xmin = sti_vtg_get_pixel_number(hdmi->mode, 0);
 196        xmax = sti_vtg_get_pixel_number(hdmi->mode, hdmi->mode.hdisplay - 1);
 197        ymin = sti_vtg_get_line_number(hdmi->mode, 0);
 198        ymax = sti_vtg_get_line_number(hdmi->mode, hdmi->mode.vdisplay - 1);
 199
 200        hdmi_write(hdmi, xmin, HDMI_ACTIVE_VID_XMIN);
 201        hdmi_write(hdmi, xmax, HDMI_ACTIVE_VID_XMAX);
 202        hdmi_write(hdmi, ymin, HDMI_ACTIVE_VID_YMIN);
 203        hdmi_write(hdmi, ymax, HDMI_ACTIVE_VID_YMAX);
 204}
 205
 206/**
 207 * Overall hdmi configuration
 208 *
 209 * @hdmi: pointer on the hdmi internal structure
 210 */
 211static void hdmi_config(struct sti_hdmi *hdmi)
 212{
 213        u32 conf;
 214
 215        DRM_DEBUG_DRIVER("\n");
 216
 217        /* Clear overrun and underrun fifo */
 218        conf = HDMI_CFG_FIFO_OVERRUN_CLR | HDMI_CFG_FIFO_UNDERRUN_CLR;
 219
 220        /* Enable HDMI mode not DVI */
 221        conf |= HDMI_CFG_HDMI_NOT_DVI | HDMI_CFG_ESS_NOT_OESS;
 222
 223        /* Enable sink term detection */
 224        conf |= HDMI_CFG_SINK_TERM_DET_EN;
 225
 226        /* Set Hsync polarity */
 227        if (hdmi->mode.flags & DRM_MODE_FLAG_NHSYNC) {
 228                DRM_DEBUG_DRIVER("H Sync Negative\n");
 229                conf |= HDMI_CFG_H_SYNC_POL_NEG;
 230        }
 231
 232        /* Set Vsync polarity */
 233        if (hdmi->mode.flags & DRM_MODE_FLAG_NVSYNC) {
 234                DRM_DEBUG_DRIVER("V Sync Negative\n");
 235                conf |= HDMI_CFG_V_SYNC_POL_NEG;
 236        }
 237
 238        /* Enable HDMI */
 239        conf |= HDMI_CFG_DEVICE_EN;
 240
 241        hdmi_write(hdmi, conf, HDMI_CFG);
 242}
 243
 244/**
 245 * Helper to concatenate infoframe in 32 bits word
 246 *
 247 * @ptr: pointer on the hdmi internal structure
 248 * @data: infoframe to write
 249 * @size: size to write
 250 */
 251static inline unsigned int hdmi_infoframe_subpack(const u8 *ptr, size_t size)
 252{
 253        unsigned long value = 0;
 254        size_t i;
 255
 256        for (i = size; i > 0; i--)
 257                value = (value << 8) | ptr[i - 1];
 258
 259        return value;
 260}
 261
 262/**
 263 * Helper to write info frame
 264 *
 265 * @hdmi: pointer on the hdmi internal structure
 266 * @data: infoframe to write
 267 * @size: size to write
 268 */
 269static void hdmi_infoframe_write_infopack(struct sti_hdmi *hdmi, const u8 *data)
 270{
 271        const u8 *ptr = data;
 272        u32 val, slot, mode, i;
 273        u32 head_offset, pack_offset;
 274        size_t size;
 275
 276        switch (*ptr) {
 277        case HDMI_INFOFRAME_TYPE_AVI:
 278                slot = HDMI_IFRAME_SLOT_AVI;
 279                mode = HDMI_IFRAME_FIELD;
 280                head_offset = HDMI_SW_DI_N_HEAD_WORD(HDMI_IFRAME_SLOT_AVI);
 281                pack_offset = HDMI_SW_DI_N_PKT_WORD0(HDMI_IFRAME_SLOT_AVI);
 282                size = HDMI_AVI_INFOFRAME_SIZE;
 283                break;
 284
 285        case HDMI_INFOFRAME_TYPE_AUDIO:
 286                slot = HDMI_IFRAME_SLOT_AUDIO;
 287                mode = HDMI_IFRAME_FRAME;
 288                head_offset = HDMI_SW_DI_N_HEAD_WORD(HDMI_IFRAME_SLOT_AUDIO);
 289                pack_offset = HDMI_SW_DI_N_PKT_WORD0(HDMI_IFRAME_SLOT_AUDIO);
 290                size = HDMI_AUDIO_INFOFRAME_SIZE;
 291                break;
 292
 293        default:
 294                DRM_ERROR("unsupported infoframe type: %#x\n", *ptr);
 295                return;
 296        }
 297
 298        /* Disable transmission slot for updated infoframe */
 299        val = hdmi_read(hdmi, HDMI_SW_DI_CFG);
 300        val &= ~HDMI_IFRAME_CFG_DI_N(HDMI_IFRAME_MASK, slot);
 301        hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
 302
 303        val = HDMI_INFOFRAME_HEADER_TYPE(*ptr++);
 304        val |= HDMI_INFOFRAME_HEADER_VERSION(*ptr++);
 305        val |= HDMI_INFOFRAME_HEADER_LEN(*ptr++);
 306        writel(val, hdmi->regs + head_offset);
 307
 308        /*
 309         * Each subpack contains 4 bytes
 310         * The First Bytes of the first subpacket must contain the checksum
 311         * Packet size in increase by one.
 312         */
 313        for (i = 0; i < size; i += sizeof(u32)) {
 314                size_t num;
 315
 316                num = min_t(size_t, size - i, sizeof(u32));
 317                val = hdmi_infoframe_subpack(ptr, num);
 318                ptr += sizeof(u32);
 319                writel(val, hdmi->regs + pack_offset + i);
 320        }
 321
 322        /* Enable transmission slot for updated infoframe */
 323        val = hdmi_read(hdmi, HDMI_SW_DI_CFG);
 324        val |= HDMI_IFRAME_CFG_DI_N(HDMI_IFRAME_FIELD, slot);
 325        hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
 326}
 327
 328/**
 329 * Prepare and configure the AVI infoframe
 330 *
 331 * AVI infoframe are transmitted at least once per two video field and
 332 * contains information about HDMI transmission mode such as color space,
 333 * colorimetry, ...
 334 *
 335 * @hdmi: pointer on the hdmi internal structure
 336 *
 337 * Return negative value if error occurs
 338 */
 339static int hdmi_avi_infoframe_config(struct sti_hdmi *hdmi)
 340{
 341        struct drm_display_mode *mode = &hdmi->mode;
 342        struct hdmi_avi_infoframe infoframe;
 343        u8 buffer[HDMI_INFOFRAME_SIZE(AVI)];
 344        int ret;
 345
 346        DRM_DEBUG_DRIVER("\n");
 347
 348        ret = drm_hdmi_avi_infoframe_from_display_mode(&infoframe, mode);
 349        if (ret < 0) {
 350                DRM_ERROR("failed to setup AVI infoframe: %d\n", ret);
 351                return ret;
 352        }
 353
 354        /* fixed infoframe configuration not linked to the mode */
 355        infoframe.colorspace = HDMI_COLORSPACE_RGB;
 356        infoframe.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
 357        infoframe.colorimetry = HDMI_COLORIMETRY_NONE;
 358
 359        ret = hdmi_avi_infoframe_pack(&infoframe, buffer, sizeof(buffer));
 360        if (ret < 0) {
 361                DRM_ERROR("failed to pack AVI infoframe: %d\n", ret);
 362                return ret;
 363        }
 364
 365        hdmi_infoframe_write_infopack(hdmi, buffer);
 366
 367        return 0;
 368}
 369
 370/**
 371 * Prepare and configure the AUDIO infoframe
 372 *
 373 * AUDIO infoframe are transmitted once per frame and
 374 * contains information about HDMI transmission mode such as audio codec,
 375 * sample size, ...
 376 *
 377 * @hdmi: pointer on the hdmi internal structure
 378 *
 379 * Return negative value if error occurs
 380 */
 381static int hdmi_audio_infoframe_config(struct sti_hdmi *hdmi)
 382{
 383        struct hdmi_audio_infoframe infofame;
 384        u8 buffer[HDMI_INFOFRAME_SIZE(AUDIO)];
 385        int ret;
 386
 387        ret = hdmi_audio_infoframe_init(&infofame);
 388        if (ret < 0) {
 389                DRM_ERROR("failed to setup audio infoframe: %d\n", ret);
 390                return ret;
 391        }
 392
 393        infofame.channels = 2;
 394
 395        ret = hdmi_audio_infoframe_pack(&infofame, buffer, sizeof(buffer));
 396        if (ret < 0) {
 397                DRM_ERROR("failed to pack audio infoframe: %d\n", ret);
 398                return ret;
 399        }
 400
 401        hdmi_infoframe_write_infopack(hdmi, buffer);
 402
 403        return 0;
 404}
 405
 406/**
 407 * Software reset of the hdmi subsystem
 408 *
 409 * @hdmi: pointer on the hdmi internal structure
 410 *
 411 */
 412#define HDMI_TIMEOUT_SWRESET  100   /*milliseconds */
 413static void hdmi_swreset(struct sti_hdmi *hdmi)
 414{
 415        u32 val;
 416
 417        DRM_DEBUG_DRIVER("\n");
 418
 419        /* Enable hdmi_audio clock only during hdmi reset */
 420        if (clk_prepare_enable(hdmi->clk_audio))
 421                DRM_INFO("Failed to prepare/enable hdmi_audio clk\n");
 422
 423        /* Sw reset */
 424        hdmi->event_received = false;
 425
 426        val = hdmi_read(hdmi, HDMI_CFG);
 427        val |= HDMI_CFG_SW_RST_EN;
 428        hdmi_write(hdmi, val, HDMI_CFG);
 429
 430        /* Wait reset completed */
 431        wait_event_interruptible_timeout(hdmi->wait_event,
 432                                         hdmi->event_received == true,
 433                                         msecs_to_jiffies
 434                                         (HDMI_TIMEOUT_SWRESET));
 435
 436        /*
 437         * HDMI_STA_SW_RST bit is set to '1' when SW_RST bit in HDMI_CFG is
 438         * set to '1' and clk_audio is running.
 439         */
 440        if ((hdmi_read(hdmi, HDMI_STA) & HDMI_STA_SW_RST) == 0)
 441                DRM_DEBUG_DRIVER("Warning: HDMI sw reset timeout occurs\n");
 442
 443        val = hdmi_read(hdmi, HDMI_CFG);
 444        val &= ~HDMI_CFG_SW_RST_EN;
 445        hdmi_write(hdmi, val, HDMI_CFG);
 446
 447        /* Disable hdmi_audio clock. Not used anymore for drm purpose */
 448        clk_disable_unprepare(hdmi->clk_audio);
 449}
 450
 451static void sti_hdmi_disable(struct drm_bridge *bridge)
 452{
 453        struct sti_hdmi *hdmi = bridge->driver_private;
 454
 455        u32 val = hdmi_read(hdmi, HDMI_CFG);
 456
 457        if (!hdmi->enabled)
 458                return;
 459
 460        DRM_DEBUG_DRIVER("\n");
 461
 462        /* Disable HDMI */
 463        val &= ~HDMI_CFG_DEVICE_EN;
 464        hdmi_write(hdmi, val, HDMI_CFG);
 465
 466        hdmi_write(hdmi, 0xffffffff, HDMI_INT_CLR);
 467
 468        /* Stop the phy */
 469        hdmi->phy_ops->stop(hdmi);
 470
 471        /* Set the default channel data to be a dark red */
 472        hdmi_write(hdmi, 0x0000, HDMI_DFLT_CHL0_DAT);
 473        hdmi_write(hdmi, 0x0000, HDMI_DFLT_CHL1_DAT);
 474        hdmi_write(hdmi, 0x0060, HDMI_DFLT_CHL2_DAT);
 475
 476        /* Disable/unprepare hdmi clock */
 477        clk_disable_unprepare(hdmi->clk_phy);
 478        clk_disable_unprepare(hdmi->clk_tmds);
 479        clk_disable_unprepare(hdmi->clk_pix);
 480
 481        hdmi->enabled = false;
 482}
 483
 484static void sti_hdmi_pre_enable(struct drm_bridge *bridge)
 485{
 486        struct sti_hdmi *hdmi = bridge->driver_private;
 487
 488        DRM_DEBUG_DRIVER("\n");
 489
 490        if (hdmi->enabled)
 491                return;
 492
 493        /* Prepare/enable clocks */
 494        if (clk_prepare_enable(hdmi->clk_pix))
 495                DRM_ERROR("Failed to prepare/enable hdmi_pix clk\n");
 496        if (clk_prepare_enable(hdmi->clk_tmds))
 497                DRM_ERROR("Failed to prepare/enable hdmi_tmds clk\n");
 498        if (clk_prepare_enable(hdmi->clk_phy))
 499                DRM_ERROR("Failed to prepare/enable hdmi_rejec_pll clk\n");
 500
 501        hdmi->enabled = true;
 502
 503        /* Program hdmi serializer and start phy */
 504        if (!hdmi->phy_ops->start(hdmi)) {
 505                DRM_ERROR("Unable to start hdmi phy\n");
 506                return;
 507        }
 508
 509        /* Program hdmi active area */
 510        hdmi_active_area(hdmi);
 511
 512        /* Enable working interrupts */
 513        hdmi_write(hdmi, HDMI_WORKING_INT, HDMI_INT_EN);
 514
 515        /* Program hdmi config */
 516        hdmi_config(hdmi);
 517
 518        /* Program AVI infoframe */
 519        if (hdmi_avi_infoframe_config(hdmi))
 520                DRM_ERROR("Unable to configure AVI infoframe\n");
 521
 522        /* Program AUDIO infoframe */
 523        if (hdmi_audio_infoframe_config(hdmi))
 524                DRM_ERROR("Unable to configure AUDIO infoframe\n");
 525
 526        /* Sw reset */
 527        hdmi_swreset(hdmi);
 528}
 529
 530static void sti_hdmi_set_mode(struct drm_bridge *bridge,
 531                struct drm_display_mode *mode,
 532                struct drm_display_mode *adjusted_mode)
 533{
 534        struct sti_hdmi *hdmi = bridge->driver_private;
 535        int ret;
 536
 537        DRM_DEBUG_DRIVER("\n");
 538
 539        /* Copy the drm display mode in the connector local structure */
 540        memcpy(&hdmi->mode, mode, sizeof(struct drm_display_mode));
 541
 542        /* Update clock framerate according to the selected mode */
 543        ret = clk_set_rate(hdmi->clk_pix, mode->clock * 1000);
 544        if (ret < 0) {
 545                DRM_ERROR("Cannot set rate (%dHz) for hdmi_pix clk\n",
 546                          mode->clock * 1000);
 547                return;
 548        }
 549        ret = clk_set_rate(hdmi->clk_phy, mode->clock * 1000);
 550        if (ret < 0) {
 551                DRM_ERROR("Cannot set rate (%dHz) for hdmi_rejection_pll clk\n",
 552                          mode->clock * 1000);
 553                return;
 554        }
 555}
 556
 557static void sti_hdmi_bridge_nope(struct drm_bridge *bridge)
 558{
 559        /* do nothing */
 560}
 561
 562static const struct drm_bridge_funcs sti_hdmi_bridge_funcs = {
 563        .pre_enable = sti_hdmi_pre_enable,
 564        .enable = sti_hdmi_bridge_nope,
 565        .disable = sti_hdmi_disable,
 566        .post_disable = sti_hdmi_bridge_nope,
 567        .mode_set = sti_hdmi_set_mode,
 568};
 569
 570static int sti_hdmi_connector_get_modes(struct drm_connector *connector)
 571{
 572        struct sti_hdmi_connector *hdmi_connector
 573                = to_sti_hdmi_connector(connector);
 574        struct sti_hdmi *hdmi = hdmi_connector->hdmi;
 575        struct edid *edid;
 576        int count;
 577
 578        DRM_DEBUG_DRIVER("\n");
 579
 580        edid = drm_get_edid(connector, hdmi->ddc_adapt);
 581        if (!edid)
 582                goto fail;
 583
 584        count = drm_add_edid_modes(connector, edid);
 585        drm_mode_connector_update_edid_property(connector, edid);
 586
 587        kfree(edid);
 588        return count;
 589
 590fail:
 591        DRM_ERROR("Can not read HDMI EDID\n");
 592        return 0;
 593}
 594
 595#define CLK_TOLERANCE_HZ 50
 596
 597static int sti_hdmi_connector_mode_valid(struct drm_connector *connector,
 598                                        struct drm_display_mode *mode)
 599{
 600        int target = mode->clock * 1000;
 601        int target_min = target - CLK_TOLERANCE_HZ;
 602        int target_max = target + CLK_TOLERANCE_HZ;
 603        int result;
 604        struct sti_hdmi_connector *hdmi_connector
 605                = to_sti_hdmi_connector(connector);
 606        struct sti_hdmi *hdmi = hdmi_connector->hdmi;
 607
 608
 609        result = clk_round_rate(hdmi->clk_pix, target);
 610
 611        DRM_DEBUG_DRIVER("target rate = %d => available rate = %d\n",
 612                         target, result);
 613
 614        if ((result < target_min) || (result > target_max)) {
 615                DRM_DEBUG_DRIVER("hdmi pixclk=%d not supported\n", target);
 616                return MODE_BAD;
 617        }
 618
 619        return MODE_OK;
 620}
 621
 622struct drm_encoder *sti_hdmi_best_encoder(struct drm_connector *connector)
 623{
 624        struct sti_hdmi_connector *hdmi_connector
 625                = to_sti_hdmi_connector(connector);
 626
 627        /* Best encoder is the one associated during connector creation */
 628        return hdmi_connector->encoder;
 629}
 630
 631static struct drm_connector_helper_funcs sti_hdmi_connector_helper_funcs = {
 632        .get_modes = sti_hdmi_connector_get_modes,
 633        .mode_valid = sti_hdmi_connector_mode_valid,
 634        .best_encoder = sti_hdmi_best_encoder,
 635};
 636
 637/* get detection status of display device */
 638static enum drm_connector_status
 639sti_hdmi_connector_detect(struct drm_connector *connector, bool force)
 640{
 641        struct sti_hdmi_connector *hdmi_connector
 642                = to_sti_hdmi_connector(connector);
 643        struct sti_hdmi *hdmi = hdmi_connector->hdmi;
 644
 645        DRM_DEBUG_DRIVER("\n");
 646
 647        if (hdmi->hpd) {
 648                DRM_DEBUG_DRIVER("hdmi cable connected\n");
 649                return connector_status_connected;
 650        }
 651
 652        DRM_DEBUG_DRIVER("hdmi cable disconnected\n");
 653        return connector_status_disconnected;
 654}
 655
 656static void sti_hdmi_connector_destroy(struct drm_connector *connector)
 657{
 658        struct sti_hdmi_connector *hdmi_connector
 659                = to_sti_hdmi_connector(connector);
 660
 661        drm_connector_unregister(connector);
 662        drm_connector_cleanup(connector);
 663        kfree(hdmi_connector);
 664}
 665
 666static struct drm_connector_funcs sti_hdmi_connector_funcs = {
 667        .dpms = drm_atomic_helper_connector_dpms,
 668        .fill_modes = drm_helper_probe_single_connector_modes,
 669        .detect = sti_hdmi_connector_detect,
 670        .destroy = sti_hdmi_connector_destroy,
 671        .reset = drm_atomic_helper_connector_reset,
 672        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 673        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 674};
 675
 676static struct drm_encoder *sti_hdmi_find_encoder(struct drm_device *dev)
 677{
 678        struct drm_encoder *encoder;
 679
 680        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 681                if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
 682                        return encoder;
 683        }
 684
 685        return NULL;
 686}
 687
 688static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
 689{
 690        struct sti_hdmi *hdmi = dev_get_drvdata(dev);
 691        struct drm_device *drm_dev = data;
 692        struct drm_encoder *encoder;
 693        struct sti_hdmi_connector *connector;
 694        struct drm_connector *drm_connector;
 695        struct drm_bridge *bridge;
 696        struct device_node *ddc;
 697        int err;
 698
 699        ddc = of_parse_phandle(dev->of_node, "ddc", 0);
 700        if (ddc) {
 701                hdmi->ddc_adapt = of_find_i2c_adapter_by_node(ddc);
 702                if (!hdmi->ddc_adapt) {
 703                        err = -EPROBE_DEFER;
 704                        of_node_put(ddc);
 705                        return err;
 706                }
 707
 708                of_node_put(ddc);
 709        }
 710
 711        /* Set the drm device handle */
 712        hdmi->drm_dev = drm_dev;
 713
 714        encoder = sti_hdmi_find_encoder(drm_dev);
 715        if (!encoder)
 716                goto err_adapt;
 717
 718        connector = devm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
 719        if (!connector)
 720                goto err_adapt;
 721
 722
 723        connector->hdmi = hdmi;
 724
 725        bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);
 726        if (!bridge)
 727                goto err_adapt;
 728
 729        bridge->driver_private = hdmi;
 730        bridge->funcs = &sti_hdmi_bridge_funcs;
 731        drm_bridge_attach(drm_dev, bridge);
 732
 733        encoder->bridge = bridge;
 734        connector->encoder = encoder;
 735
 736        drm_connector = (struct drm_connector *)connector;
 737
 738        drm_connector->polled = DRM_CONNECTOR_POLL_HPD;
 739
 740        drm_connector_init(drm_dev, drm_connector,
 741                        &sti_hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
 742        drm_connector_helper_add(drm_connector,
 743                        &sti_hdmi_connector_helper_funcs);
 744
 745        err = drm_connector_register(drm_connector);
 746        if (err)
 747                goto err_connector;
 748
 749        err = drm_mode_connector_attach_encoder(drm_connector, encoder);
 750        if (err) {
 751                DRM_ERROR("Failed to attach a connector to a encoder\n");
 752                goto err_sysfs;
 753        }
 754
 755        /* Enable default interrupts */
 756        hdmi_write(hdmi, HDMI_DEFAULT_INT, HDMI_INT_EN);
 757
 758        return 0;
 759
 760err_sysfs:
 761        drm_connector_unregister(drm_connector);
 762err_connector:
 763        drm_connector_cleanup(drm_connector);
 764err_adapt:
 765        put_device(&hdmi->ddc_adapt->dev);
 766        return -EINVAL;
 767}
 768
 769static void sti_hdmi_unbind(struct device *dev,
 770                struct device *master, void *data)
 771{
 772        /* do nothing */
 773}
 774
 775static const struct component_ops sti_hdmi_ops = {
 776        .bind = sti_hdmi_bind,
 777        .unbind = sti_hdmi_unbind,
 778};
 779
 780static const struct of_device_id hdmi_of_match[] = {
 781        {
 782                .compatible = "st,stih416-hdmi",
 783                .data = &tx3g0c55phy_ops,
 784        }, {
 785                .compatible = "st,stih407-hdmi",
 786                .data = &tx3g4c28phy_ops,
 787        }, {
 788                /* end node */
 789        }
 790};
 791MODULE_DEVICE_TABLE(of, hdmi_of_match);
 792
 793static int sti_hdmi_probe(struct platform_device *pdev)
 794{
 795        struct device *dev = &pdev->dev;
 796        struct sti_hdmi *hdmi;
 797        struct device_node *np = dev->of_node;
 798        struct resource *res;
 799        int ret;
 800
 801        DRM_INFO("%s\n", __func__);
 802
 803        hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
 804        if (!hdmi)
 805                return -ENOMEM;
 806
 807        hdmi->dev = pdev->dev;
 808
 809        /* Get resources */
 810        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi-reg");
 811        if (!res) {
 812                DRM_ERROR("Invalid hdmi resource\n");
 813                return -ENOMEM;
 814        }
 815        hdmi->regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
 816        if (!hdmi->regs)
 817                return -ENOMEM;
 818
 819        if (of_device_is_compatible(np, "st,stih416-hdmi")) {
 820                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 821                                                   "syscfg");
 822                if (!res) {
 823                        DRM_ERROR("Invalid syscfg resource\n");
 824                        return -ENOMEM;
 825                }
 826                hdmi->syscfg = devm_ioremap_nocache(dev, res->start,
 827                                                    resource_size(res));
 828                if (!hdmi->syscfg)
 829                        return -ENOMEM;
 830
 831        }
 832
 833        hdmi->phy_ops = (struct hdmi_phy_ops *)
 834                of_match_node(hdmi_of_match, np)->data;
 835
 836        /* Get clock resources */
 837        hdmi->clk_pix = devm_clk_get(dev, "pix");
 838        if (IS_ERR(hdmi->clk_pix)) {
 839                DRM_ERROR("Cannot get hdmi_pix clock\n");
 840                return PTR_ERR(hdmi->clk_pix);
 841        }
 842
 843        hdmi->clk_tmds = devm_clk_get(dev, "tmds");
 844        if (IS_ERR(hdmi->clk_tmds)) {
 845                DRM_ERROR("Cannot get hdmi_tmds clock\n");
 846                return PTR_ERR(hdmi->clk_tmds);
 847        }
 848
 849        hdmi->clk_phy = devm_clk_get(dev, "phy");
 850        if (IS_ERR(hdmi->clk_phy)) {
 851                DRM_ERROR("Cannot get hdmi_phy clock\n");
 852                return PTR_ERR(hdmi->clk_phy);
 853        }
 854
 855        hdmi->clk_audio = devm_clk_get(dev, "audio");
 856        if (IS_ERR(hdmi->clk_audio)) {
 857                DRM_ERROR("Cannot get hdmi_audio clock\n");
 858                return PTR_ERR(hdmi->clk_audio);
 859        }
 860
 861        hdmi->hpd = readl(hdmi->regs + HDMI_STA) & HDMI_STA_HOT_PLUG;
 862
 863        init_waitqueue_head(&hdmi->wait_event);
 864
 865        hdmi->irq = platform_get_irq_byname(pdev, "irq");
 866
 867        ret = devm_request_threaded_irq(dev, hdmi->irq, hdmi_irq,
 868                        hdmi_irq_thread, IRQF_ONESHOT, dev_name(dev), hdmi);
 869        if (ret) {
 870                DRM_ERROR("Failed to register HDMI interrupt\n");
 871                return ret;
 872        }
 873
 874        hdmi->reset = devm_reset_control_get(dev, "hdmi");
 875        /* Take hdmi out of reset */
 876        if (!IS_ERR(hdmi->reset))
 877                reset_control_deassert(hdmi->reset);
 878
 879        platform_set_drvdata(pdev, hdmi);
 880
 881        return component_add(&pdev->dev, &sti_hdmi_ops);
 882}
 883
 884static int sti_hdmi_remove(struct platform_device *pdev)
 885{
 886        struct sti_hdmi *hdmi = dev_get_drvdata(&pdev->dev);
 887
 888        if (hdmi->ddc_adapt)
 889                put_device(&hdmi->ddc_adapt->dev);
 890
 891        component_del(&pdev->dev, &sti_hdmi_ops);
 892        return 0;
 893}
 894
 895struct platform_driver sti_hdmi_driver = {
 896        .driver = {
 897                .name = "sti-hdmi",
 898                .owner = THIS_MODULE,
 899                .of_match_table = hdmi_of_match,
 900        },
 901        .probe = sti_hdmi_probe,
 902        .remove = sti_hdmi_remove,
 903};
 904
 905module_platform_driver(sti_hdmi_driver);
 906
 907MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 908MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 909MODULE_LICENSE("GPL");
 910