linux/drivers/gpu/drm/exynos/exynos_hdmi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Copyright (C) 2011 Samsung Electronics Co.Ltd
   4 * Authors:
   5 * Seung-Woo Kim <sw0312.kim@samsung.com>
   6 *      Inki Dae <inki.dae@samsung.com>
   7 *      Joonyoung Shim <jy0922.shim@samsung.com>
   8 *
   9 * Based on drivers/media/video/s5p-tv/hdmi_drv.c
  10 */
  11
  12#include <drm/exynos_drm.h>
  13#include <linux/clk.h>
  14#include <linux/component.h>
  15#include <linux/delay.h>
  16#include <linux/gpio/consumer.h>
  17#include <linux/hdmi.h>
  18#include <linux/i2c.h>
  19#include <linux/interrupt.h>
  20#include <linux/io.h>
  21#include <linux/irq.h>
  22#include <linux/kernel.h>
  23#include <linux/mfd/syscon.h>
  24#include <linux/of_address.h>
  25#include <linux/of_device.h>
  26#include <linux/of_graph.h>
  27#include <linux/platform_device.h>
  28#include <linux/pm_runtime.h>
  29#include <linux/regmap.h>
  30#include <linux/regulator/consumer.h>
  31#include <linux/wait.h>
  32
  33#include <sound/hdmi-codec.h>
  34#include <media/cec-notifier.h>
  35
  36#include <drm/drm_atomic_helper.h>
  37#include <drm/drm_bridge.h>
  38#include <drm/drm_edid.h>
  39#include <drm/drm_print.h>
  40#include <drm/drm_probe_helper.h>
  41#include <drm/drm_simple_kms_helper.h>
  42
  43#include "exynos_drm_crtc.h"
  44#include "regs-hdmi.h"
  45
  46#define HOTPLUG_DEBOUNCE_MS             1100
  47
  48enum hdmi_type {
  49        HDMI_TYPE13,
  50        HDMI_TYPE14,
  51        HDMI_TYPE_COUNT
  52};
  53
  54#define HDMI_MAPPED_BASE 0xffff0000
  55
  56enum hdmi_mapped_regs {
  57        HDMI_PHY_STATUS = HDMI_MAPPED_BASE,
  58        HDMI_PHY_RSTOUT,
  59        HDMI_ACR_CON,
  60        HDMI_ACR_MCTS0,
  61        HDMI_ACR_CTS0,
  62        HDMI_ACR_N0
  63};
  64
  65static const u32 hdmi_reg_map[][HDMI_TYPE_COUNT] = {
  66        { HDMI_V13_PHY_STATUS, HDMI_PHY_STATUS_0 },
  67        { HDMI_V13_PHY_RSTOUT, HDMI_V14_PHY_RSTOUT },
  68        { HDMI_V13_ACR_CON, HDMI_V14_ACR_CON },
  69        { HDMI_V13_ACR_MCTS0, HDMI_V14_ACR_MCTS0 },
  70        { HDMI_V13_ACR_CTS0, HDMI_V14_ACR_CTS0 },
  71        { HDMI_V13_ACR_N0, HDMI_V14_ACR_N0 },
  72};
  73
  74static const char * const supply[] = {
  75        "vdd",
  76        "vdd_osc",
  77        "vdd_pll",
  78};
  79
  80struct hdmiphy_config {
  81        int pixel_clock;
  82        u8 conf[32];
  83};
  84
  85struct hdmiphy_configs {
  86        int count;
  87        const struct hdmiphy_config *data;
  88};
  89
  90struct string_array_spec {
  91        int count;
  92        const char * const *data;
  93};
  94
  95#define INIT_ARRAY_SPEC(a) { .count = ARRAY_SIZE(a), .data = a }
  96
  97struct hdmi_driver_data {
  98        unsigned int type;
  99        unsigned int is_apb_phy:1;
 100        unsigned int has_sysreg:1;
 101        struct hdmiphy_configs phy_confs;
 102        struct string_array_spec clk_gates;
 103        /*
 104         * Array of triplets (p_off, p_on, clock), where p_off and p_on are
 105         * required parents of clock when HDMI-PHY is respectively off or on.
 106         */
 107        struct string_array_spec clk_muxes;
 108};
 109
 110struct hdmi_audio {
 111        struct platform_device          *pdev;
 112        struct hdmi_audio_infoframe     infoframe;
 113        struct hdmi_codec_params        params;
 114        bool                            mute;
 115};
 116
 117struct hdmi_context {
 118        struct drm_encoder              encoder;
 119        struct device                   *dev;
 120        struct drm_device               *drm_dev;
 121        struct drm_connector            connector;
 122        bool                            dvi_mode;
 123        struct delayed_work             hotplug_work;
 124        struct cec_notifier             *notifier;
 125        const struct hdmi_driver_data   *drv_data;
 126
 127        void __iomem                    *regs;
 128        void __iomem                    *regs_hdmiphy;
 129        struct i2c_client               *hdmiphy_port;
 130        struct i2c_adapter              *ddc_adpt;
 131        struct gpio_desc                *hpd_gpio;
 132        int                             irq;
 133        struct regmap                   *pmureg;
 134        struct regmap                   *sysreg;
 135        struct clk                      **clk_gates;
 136        struct clk                      **clk_muxes;
 137        struct regulator_bulk_data      regul_bulk[ARRAY_SIZE(supply)];
 138        struct regulator                *reg_hdmi_en;
 139        struct exynos_drm_clk           phy_clk;
 140        struct drm_bridge               *bridge;
 141
 142        /* mutex protecting subsequent fields below */
 143        struct mutex                    mutex;
 144        struct hdmi_audio               audio;
 145        bool                            powered;
 146};
 147
 148static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
 149{
 150        return container_of(e, struct hdmi_context, encoder);
 151}
 152
 153static inline struct hdmi_context *connector_to_hdmi(struct drm_connector *c)
 154{
 155        return container_of(c, struct hdmi_context, connector);
 156}
 157
 158static const struct hdmiphy_config hdmiphy_v13_configs[] = {
 159        {
 160                .pixel_clock = 27000000,
 161                .conf = {
 162                        0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
 163                        0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
 164                        0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
 165                        0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
 166                },
 167        },
 168        {
 169                .pixel_clock = 27027000,
 170                .conf = {
 171                        0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
 172                        0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
 173                        0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
 174                        0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
 175                },
 176        },
 177        {
 178                .pixel_clock = 74176000,
 179                .conf = {
 180                        0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
 181                        0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
 182                        0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
 183                        0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x80,
 184                },
 185        },
 186        {
 187                .pixel_clock = 74250000,
 188                .conf = {
 189                        0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
 190                        0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
 191                        0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
 192                        0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x80,
 193                },
 194        },
 195        {
 196                .pixel_clock = 148500000,
 197                .conf = {
 198                        0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
 199                        0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
 200                        0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
 201                        0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x80,
 202                },
 203        },
 204};
 205
 206static const struct hdmiphy_config hdmiphy_v14_configs[] = {
 207        {
 208                .pixel_clock = 25200000,
 209                .conf = {
 210                        0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
 211                        0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 212                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 213                        0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 214                },
 215        },
 216        {
 217                .pixel_clock = 27000000,
 218                .conf = {
 219                        0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
 220                        0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 221                        0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 222                        0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 223                },
 224        },
 225        {
 226                .pixel_clock = 27027000,
 227                .conf = {
 228                        0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
 229                        0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 230                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 231                        0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 232                },
 233        },
 234        {
 235                .pixel_clock = 36000000,
 236                .conf = {
 237                        0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
 238                        0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 239                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 240                        0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 241                },
 242        },
 243        {
 244                .pixel_clock = 40000000,
 245                .conf = {
 246                        0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
 247                        0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 248                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 249                        0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 250                },
 251        },
 252        {
 253                .pixel_clock = 65000000,
 254                .conf = {
 255                        0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
 256                        0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 257                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 258                        0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 259                },
 260        },
 261        {
 262                .pixel_clock = 71000000,
 263                .conf = {
 264                        0x01, 0xd1, 0x3b, 0x35, 0x40, 0x0c, 0x04, 0x08,
 265                        0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 266                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 267                        0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 268                },
 269        },
 270        {
 271                .pixel_clock = 73250000,
 272                .conf = {
 273                        0x01, 0xd1, 0x3d, 0x35, 0x40, 0x18, 0x02, 0x08,
 274                        0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 275                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 276                        0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 277                },
 278        },
 279        {
 280                .pixel_clock = 74176000,
 281                .conf = {
 282                        0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
 283                        0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 284                        0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 285                        0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 286                },
 287        },
 288        {
 289                .pixel_clock = 74250000,
 290                .conf = {
 291                        0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
 292                        0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 293                        0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 294                        0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 295                },
 296        },
 297        {
 298                .pixel_clock = 83500000,
 299                .conf = {
 300                        0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
 301                        0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 302                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 303                        0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 304                },
 305        },
 306        {
 307                .pixel_clock = 85500000,
 308                .conf = {
 309                        0x01, 0xd1, 0x24, 0x11, 0x40, 0x40, 0xd0, 0x08,
 310                        0x84, 0xa0, 0xd6, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 311                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 312                        0x54, 0x90, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 313                },
 314        },
 315        {
 316                .pixel_clock = 106500000,
 317                .conf = {
 318                        0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
 319                        0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 320                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 321                        0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 322                },
 323        },
 324        {
 325                .pixel_clock = 108000000,
 326                .conf = {
 327                        0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
 328                        0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 329                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 330                        0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 331                },
 332        },
 333        {
 334                .pixel_clock = 115500000,
 335                .conf = {
 336                        0x01, 0xd1, 0x30, 0x12, 0x40, 0x40, 0x10, 0x08,
 337                        0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 338                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 339                        0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 340                },
 341        },
 342        {
 343                .pixel_clock = 119000000,
 344                .conf = {
 345                        0x01, 0xd1, 0x32, 0x1a, 0x40, 0x30, 0xd8, 0x08,
 346                        0x04, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 347                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 348                        0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 349                },
 350        },
 351        {
 352                .pixel_clock = 146250000,
 353                .conf = {
 354                        0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
 355                        0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 356                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 357                        0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 358                },
 359        },
 360        {
 361                .pixel_clock = 148500000,
 362                .conf = {
 363                        0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
 364                        0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 365                        0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 366                        0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 367                },
 368        },
 369};
 370
 371static const struct hdmiphy_config hdmiphy_5420_configs[] = {
 372        {
 373                .pixel_clock = 25200000,
 374                .conf = {
 375                        0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
 376                        0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 377                        0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
 378                        0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 379                },
 380        },
 381        {
 382                .pixel_clock = 27000000,
 383                .conf = {
 384                        0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
 385                        0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 386                        0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 387                        0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 388                },
 389        },
 390        {
 391                .pixel_clock = 27027000,
 392                .conf = {
 393                        0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
 394                        0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 395                        0x26, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 396                        0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 397                },
 398        },
 399        {
 400                .pixel_clock = 36000000,
 401                .conf = {
 402                        0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
 403                        0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 404                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 405                        0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 406                },
 407        },
 408        {
 409                .pixel_clock = 40000000,
 410                .conf = {
 411                        0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
 412                        0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 413                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 414                        0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 415                },
 416        },
 417        {
 418                .pixel_clock = 65000000,
 419                .conf = {
 420                        0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
 421                        0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 422                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 423                        0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 424                },
 425        },
 426        {
 427                .pixel_clock = 71000000,
 428                .conf = {
 429                        0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
 430                        0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 431                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 432                        0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 433                },
 434        },
 435        {
 436                .pixel_clock = 73250000,
 437                .conf = {
 438                        0x01, 0xD1, 0x1F, 0x10, 0x40, 0x78, 0x8D, 0xC8,
 439                        0x81, 0xE8, 0xB7, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 440                        0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 441                        0x54, 0xA8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 442                },
 443        },
 444        {
 445                .pixel_clock = 74176000,
 446                .conf = {
 447                        0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
 448                        0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 449                        0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 450                        0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 451                },
 452        },
 453        {
 454                .pixel_clock = 74250000,
 455                .conf = {
 456                        0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
 457                        0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 458                        0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
 459                        0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 460                },
 461        },
 462        {
 463                .pixel_clock = 83500000,
 464                .conf = {
 465                        0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
 466                        0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 467                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 468                        0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 469                },
 470        },
 471        {
 472                .pixel_clock = 88750000,
 473                .conf = {
 474                        0x01, 0xD1, 0x25, 0x11, 0x40, 0x18, 0xFF, 0xC8,
 475                        0x83, 0xE8, 0xDE, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 476                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 477                        0x54, 0x45, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 478                },
 479        },
 480        {
 481                .pixel_clock = 106500000,
 482                .conf = {
 483                        0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
 484                        0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 485                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 486                        0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 487                },
 488        },
 489        {
 490                .pixel_clock = 108000000,
 491                .conf = {
 492                        0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
 493                        0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 494                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 495                        0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 496                },
 497        },
 498        {
 499                .pixel_clock = 115500000,
 500                .conf = {
 501                        0x01, 0xD1, 0x30, 0x14, 0x40, 0x0C, 0x03, 0xC8,
 502                        0x88, 0xE8, 0x21, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 503                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 504                        0x54, 0x6A, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 505                },
 506        },
 507        {
 508                .pixel_clock = 146250000,
 509                .conf = {
 510                        0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
 511                        0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 512                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 513                        0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 514                },
 515        },
 516        {
 517                .pixel_clock = 148500000,
 518                .conf = {
 519                        0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
 520                        0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 521                        0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
 522                        0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80,
 523                },
 524        },
 525};
 526
 527static const struct hdmiphy_config hdmiphy_5433_configs[] = {
 528        {
 529                .pixel_clock = 27000000,
 530                .conf = {
 531                        0x01, 0x51, 0x2d, 0x75, 0x01, 0x00, 0x88, 0x02,
 532                        0x72, 0x50, 0x44, 0x8c, 0x27, 0x00, 0x7c, 0xac,
 533                        0xd6, 0x2b, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 534                        0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 535                },
 536        },
 537        {
 538                .pixel_clock = 27027000,
 539                .conf = {
 540                        0x01, 0x51, 0x2d, 0x72, 0x64, 0x09, 0x88, 0xc3,
 541                        0x71, 0x50, 0x44, 0x8c, 0x27, 0x00, 0x7c, 0xac,
 542                        0xd6, 0x2b, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 543                        0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 544                },
 545        },
 546        {
 547                .pixel_clock = 40000000,
 548                .conf = {
 549                        0x01, 0x51, 0x32, 0x55, 0x01, 0x00, 0x88, 0x02,
 550                        0x4d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 551                        0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 552                        0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 553                },
 554        },
 555        {
 556                .pixel_clock = 50000000,
 557                .conf = {
 558                        0x01, 0x51, 0x34, 0x40, 0x64, 0x09, 0x88, 0xc3,
 559                        0x3d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 560                        0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 561                        0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 562                },
 563        },
 564        {
 565                .pixel_clock = 65000000,
 566                .conf = {
 567                        0x01, 0x51, 0x36, 0x31, 0x40, 0x10, 0x04, 0xc6,
 568                        0x2e, 0xe8, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 569                        0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 570                        0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 571                },
 572        },
 573        {
 574                .pixel_clock = 74176000,
 575                .conf = {
 576                        0x01, 0x51, 0x3E, 0x35, 0x5B, 0xDE, 0x88, 0x42,
 577                        0x53, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 578                        0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 579                        0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 580                },
 581        },
 582        {
 583                .pixel_clock = 74250000,
 584                .conf = {
 585                        0x01, 0x51, 0x3E, 0x35, 0x40, 0xF0, 0x88, 0xC2,
 586                        0x52, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 587                        0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 588                        0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 589                },
 590        },
 591        {
 592                .pixel_clock = 108000000,
 593                .conf = {
 594                        0x01, 0x51, 0x2d, 0x15, 0x01, 0x00, 0x88, 0x02,
 595                        0x72, 0x52, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 596                        0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 597                        0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 598                },
 599        },
 600        {
 601                .pixel_clock = 148500000,
 602                .conf = {
 603                        0x01, 0x51, 0x1f, 0x00, 0x40, 0xf8, 0x88, 0xc1,
 604                        0x52, 0x52, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5,
 605                        0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
 606                        0x08, 0x10, 0x01, 0x01, 0x48, 0x4a, 0x00, 0x40,
 607                },
 608        },
 609        {
 610                .pixel_clock = 297000000,
 611                .conf = {
 612                        0x01, 0x51, 0x3E, 0x05, 0x40, 0xF0, 0x88, 0xC2,
 613                        0x52, 0x53, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 614                        0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 615                        0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 616                },
 617        },
 618};
 619
 620static const char * const hdmi_clk_gates4[] = {
 621        "hdmi", "sclk_hdmi"
 622};
 623
 624static const char * const hdmi_clk_muxes4[] = {
 625        "sclk_pixel", "sclk_hdmiphy", "mout_hdmi"
 626};
 627
 628static const char * const hdmi_clk_gates5433[] = {
 629        "hdmi_pclk", "hdmi_i_pclk", "i_tmds_clk", "i_pixel_clk", "i_spdif_clk"
 630};
 631
 632static const char * const hdmi_clk_muxes5433[] = {
 633        "oscclk", "tmds_clko", "tmds_clko_user",
 634        "oscclk", "pixel_clko", "pixel_clko_user"
 635};
 636
 637static const struct hdmi_driver_data exynos4210_hdmi_driver_data = {
 638        .type           = HDMI_TYPE13,
 639        .phy_confs      = INIT_ARRAY_SPEC(hdmiphy_v13_configs),
 640        .clk_gates      = INIT_ARRAY_SPEC(hdmi_clk_gates4),
 641        .clk_muxes      = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
 642};
 643
 644static const struct hdmi_driver_data exynos4212_hdmi_driver_data = {
 645        .type           = HDMI_TYPE14,
 646        .phy_confs      = INIT_ARRAY_SPEC(hdmiphy_v14_configs),
 647        .clk_gates      = INIT_ARRAY_SPEC(hdmi_clk_gates4),
 648        .clk_muxes      = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
 649};
 650
 651static const struct hdmi_driver_data exynos5420_hdmi_driver_data = {
 652        .type           = HDMI_TYPE14,
 653        .is_apb_phy     = 1,
 654        .phy_confs      = INIT_ARRAY_SPEC(hdmiphy_5420_configs),
 655        .clk_gates      = INIT_ARRAY_SPEC(hdmi_clk_gates4),
 656        .clk_muxes      = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
 657};
 658
 659static const struct hdmi_driver_data exynos5433_hdmi_driver_data = {
 660        .type           = HDMI_TYPE14,
 661        .is_apb_phy     = 1,
 662        .has_sysreg     = 1,
 663        .phy_confs      = INIT_ARRAY_SPEC(hdmiphy_5433_configs),
 664        .clk_gates      = INIT_ARRAY_SPEC(hdmi_clk_gates5433),
 665        .clk_muxes      = INIT_ARRAY_SPEC(hdmi_clk_muxes5433),
 666};
 667
 668static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id)
 669{
 670        if ((reg_id & 0xffff0000) == HDMI_MAPPED_BASE)
 671                return hdmi_reg_map[reg_id & 0xffff][hdata->drv_data->type];
 672        return reg_id;
 673}
 674
 675static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
 676{
 677        return readl(hdata->regs + hdmi_map_reg(hdata, reg_id));
 678}
 679
 680static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
 681                                 u32 reg_id, u8 value)
 682{
 683        writel(value, hdata->regs + hdmi_map_reg(hdata, reg_id));
 684}
 685
 686static inline void hdmi_reg_writev(struct hdmi_context *hdata, u32 reg_id,
 687                                   int bytes, u32 val)
 688{
 689        reg_id = hdmi_map_reg(hdata, reg_id);
 690
 691        while (--bytes >= 0) {
 692                writel(val & 0xff, hdata->regs + reg_id);
 693                val >>= 8;
 694                reg_id += 4;
 695        }
 696}
 697
 698static inline void hdmi_reg_write_buf(struct hdmi_context *hdata, u32 reg_id,
 699                                      u8 *buf, int size)
 700{
 701        for (reg_id = hdmi_map_reg(hdata, reg_id); size; --size, reg_id += 4)
 702                writel(*buf++, hdata->regs + reg_id);
 703}
 704
 705static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
 706                                 u32 reg_id, u32 value, u32 mask)
 707{
 708        u32 old;
 709
 710        reg_id = hdmi_map_reg(hdata, reg_id);
 711        old = readl(hdata->regs + reg_id);
 712        value = (value & mask) | (old & ~mask);
 713        writel(value, hdata->regs + reg_id);
 714}
 715
 716static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
 717                        u32 reg_offset, const u8 *buf, u32 len)
 718{
 719        if ((reg_offset + len) > 32)
 720                return -EINVAL;
 721
 722        if (hdata->hdmiphy_port) {
 723                int ret;
 724
 725                ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
 726                if (ret == len)
 727                        return 0;
 728                return ret;
 729        } else {
 730                int i;
 731                for (i = 0; i < len; i++)
 732                        writel(buf[i], hdata->regs_hdmiphy +
 733                                ((reg_offset + i)<<2));
 734                return 0;
 735        }
 736}
 737
 738static int hdmi_clk_enable_gates(struct hdmi_context *hdata)
 739{
 740        int i, ret;
 741
 742        for (i = 0; i < hdata->drv_data->clk_gates.count; ++i) {
 743                ret = clk_prepare_enable(hdata->clk_gates[i]);
 744                if (!ret)
 745                        continue;
 746
 747                dev_err(hdata->dev, "Cannot enable clock '%s', %d\n",
 748                        hdata->drv_data->clk_gates.data[i], ret);
 749                while (i--)
 750                        clk_disable_unprepare(hdata->clk_gates[i]);
 751                return ret;
 752        }
 753
 754        return 0;
 755}
 756
 757static void hdmi_clk_disable_gates(struct hdmi_context *hdata)
 758{
 759        int i = hdata->drv_data->clk_gates.count;
 760
 761        while (i--)
 762                clk_disable_unprepare(hdata->clk_gates[i]);
 763}
 764
 765static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
 766{
 767        struct device *dev = hdata->dev;
 768        int ret = 0;
 769        int i;
 770
 771        for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) {
 772                struct clk **c = &hdata->clk_muxes[i];
 773
 774                ret = clk_set_parent(c[2], c[to_phy]);
 775                if (!ret)
 776                        continue;
 777
 778                dev_err(dev, "Cannot set clock parent of '%s' to '%s', %d\n",
 779                        hdata->drv_data->clk_muxes.data[i + 2],
 780                        hdata->drv_data->clk_muxes.data[i + to_phy], ret);
 781        }
 782
 783        return ret;
 784}
 785
 786static int hdmi_audio_infoframe_apply(struct hdmi_context *hdata)
 787{
 788        struct hdmi_audio_infoframe *infoframe = &hdata->audio.infoframe;
 789        u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)];
 790        int len;
 791
 792        len = hdmi_audio_infoframe_pack(infoframe, buf, sizeof(buf));
 793        if (len < 0)
 794                return len;
 795
 796        hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_EVERY_VSYNC);
 797        hdmi_reg_write_buf(hdata, HDMI_AUI_HEADER0, buf, len);
 798
 799        return 0;
 800}
 801
 802static void hdmi_reg_infoframes(struct hdmi_context *hdata)
 803{
 804        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
 805        union hdmi_infoframe frm;
 806        u8 buf[25];
 807        int ret;
 808
 809        if (hdata->dvi_mode) {
 810                hdmi_reg_writeb(hdata, HDMI_AVI_CON,
 811                                HDMI_AVI_CON_DO_NOT_TRANSMIT);
 812                hdmi_reg_writeb(hdata, HDMI_VSI_CON,
 813                                HDMI_VSI_CON_DO_NOT_TRANSMIT);
 814                hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
 815                return;
 816        }
 817
 818        ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
 819                                                       &hdata->connector, m);
 820        if (!ret)
 821                ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf));
 822        if (ret > 0) {
 823                hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
 824                hdmi_reg_write_buf(hdata, HDMI_AVI_HEADER0, buf, ret);
 825        } else {
 826                DRM_INFO("%s: invalid AVI infoframe (%d)\n", __func__, ret);
 827        }
 828
 829        ret = drm_hdmi_vendor_infoframe_from_display_mode(&frm.vendor.hdmi,
 830                                                          &hdata->connector, m);
 831        if (!ret)
 832                ret = hdmi_vendor_infoframe_pack(&frm.vendor.hdmi, buf,
 833                                sizeof(buf));
 834        if (ret > 0) {
 835                hdmi_reg_writeb(hdata, HDMI_VSI_CON, HDMI_VSI_CON_EVERY_VSYNC);
 836                hdmi_reg_write_buf(hdata, HDMI_VSI_HEADER0, buf, 3);
 837                hdmi_reg_write_buf(hdata, HDMI_VSI_DATA(0), buf + 3, ret - 3);
 838        }
 839
 840        hdmi_audio_infoframe_apply(hdata);
 841}
 842
 843static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
 844                                bool force)
 845{
 846        struct hdmi_context *hdata = connector_to_hdmi(connector);
 847
 848        if (gpiod_get_value(hdata->hpd_gpio))
 849                return connector_status_connected;
 850
 851        cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
 852        return connector_status_disconnected;
 853}
 854
 855static void hdmi_connector_destroy(struct drm_connector *connector)
 856{
 857        struct hdmi_context *hdata = connector_to_hdmi(connector);
 858
 859        cec_notifier_conn_unregister(hdata->notifier);
 860
 861        drm_connector_unregister(connector);
 862        drm_connector_cleanup(connector);
 863}
 864
 865static const struct drm_connector_funcs hdmi_connector_funcs = {
 866        .fill_modes = drm_helper_probe_single_connector_modes,
 867        .detect = hdmi_detect,
 868        .destroy = hdmi_connector_destroy,
 869        .reset = drm_atomic_helper_connector_reset,
 870        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 871        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 872};
 873
 874static int hdmi_get_modes(struct drm_connector *connector)
 875{
 876        struct hdmi_context *hdata = connector_to_hdmi(connector);
 877        struct edid *edid;
 878        int ret;
 879
 880        if (!hdata->ddc_adpt)
 881                return -ENODEV;
 882
 883        edid = drm_get_edid(connector, hdata->ddc_adpt);
 884        if (!edid)
 885                return -ENODEV;
 886
 887        hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
 888        DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n",
 889                          (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
 890                          edid->width_cm, edid->height_cm);
 891
 892        drm_connector_update_edid_property(connector, edid);
 893        cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid);
 894
 895        ret = drm_add_edid_modes(connector, edid);
 896
 897        kfree(edid);
 898
 899        return ret;
 900}
 901
 902static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
 903{
 904        const struct hdmiphy_configs *confs = &hdata->drv_data->phy_confs;
 905        int i;
 906
 907        for (i = 0; i < confs->count; i++)
 908                if (confs->data[i].pixel_clock == pixel_clock)
 909                        return i;
 910
 911        DRM_DEV_DEBUG_KMS(hdata->dev, "Could not find phy config for %d\n",
 912                          pixel_clock);
 913        return -EINVAL;
 914}
 915
 916static int hdmi_mode_valid(struct drm_connector *connector,
 917                        struct drm_display_mode *mode)
 918{
 919        struct hdmi_context *hdata = connector_to_hdmi(connector);
 920        int ret;
 921
 922        DRM_DEV_DEBUG_KMS(hdata->dev,
 923                          "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
 924                          mode->hdisplay, mode->vdisplay,
 925                          drm_mode_vrefresh(mode),
 926                          (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
 927                          false, mode->clock * 1000);
 928
 929        ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
 930        if (ret < 0)
 931                return MODE_BAD;
 932
 933        return MODE_OK;
 934}
 935
 936static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
 937        .get_modes = hdmi_get_modes,
 938        .mode_valid = hdmi_mode_valid,
 939};
 940
 941static int hdmi_create_connector(struct drm_encoder *encoder)
 942{
 943        struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 944        struct drm_connector *connector = &hdata->connector;
 945        struct cec_connector_info conn_info;
 946        int ret;
 947
 948        connector->interlace_allowed = true;
 949        connector->polled = DRM_CONNECTOR_POLL_HPD;
 950
 951        ret = drm_connector_init_with_ddc(hdata->drm_dev, connector,
 952                                          &hdmi_connector_funcs,
 953                                          DRM_MODE_CONNECTOR_HDMIA,
 954                                          hdata->ddc_adpt);
 955        if (ret) {
 956                DRM_DEV_ERROR(hdata->dev,
 957                              "Failed to initialize connector with drm\n");
 958                return ret;
 959        }
 960
 961        drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
 962        drm_connector_attach_encoder(connector, encoder);
 963
 964        if (hdata->bridge) {
 965                ret = drm_bridge_attach(encoder, hdata->bridge, NULL, 0);
 966                if (ret)
 967                        DRM_DEV_ERROR(hdata->dev, "Failed to attach bridge\n");
 968        }
 969
 970        cec_fill_conn_info_from_drm(&conn_info, connector);
 971
 972        hdata->notifier = cec_notifier_conn_register(hdata->dev, NULL,
 973                                                     &conn_info);
 974        if (!hdata->notifier) {
 975                ret = -ENOMEM;
 976                DRM_DEV_ERROR(hdata->dev, "Failed to allocate CEC notifier\n");
 977        }
 978
 979        return ret;
 980}
 981
 982static bool hdmi_mode_fixup(struct drm_encoder *encoder,
 983                            const struct drm_display_mode *mode,
 984                            struct drm_display_mode *adjusted_mode)
 985{
 986        struct drm_device *dev = encoder->dev;
 987        struct drm_connector *connector;
 988        struct drm_display_mode *m;
 989        struct drm_connector_list_iter conn_iter;
 990        int mode_ok;
 991
 992        drm_mode_set_crtcinfo(adjusted_mode, 0);
 993
 994        drm_connector_list_iter_begin(dev, &conn_iter);
 995        drm_for_each_connector_iter(connector, &conn_iter) {
 996                if (connector->encoder == encoder)
 997                        break;
 998        }
 999        if (connector)
1000                drm_connector_get(connector);
1001        drm_connector_list_iter_end(&conn_iter);
1002
1003        if (!connector)
1004                return true;
1005
1006        mode_ok = hdmi_mode_valid(connector, adjusted_mode);
1007
1008        if (mode_ok == MODE_OK)
1009                goto cleanup;
1010
1011        /*
1012         * Find the most suitable mode and copy it to adjusted_mode.
1013         */
1014        list_for_each_entry(m, &connector->modes, head) {
1015                mode_ok = hdmi_mode_valid(connector, m);
1016
1017                if (mode_ok == MODE_OK) {
1018                        DRM_INFO("desired mode doesn't exist so\n");
1019                        DRM_INFO("use the most suitable mode among modes.\n");
1020
1021                        DRM_DEV_DEBUG_KMS(dev->dev,
1022                                          "Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1023                                          m->hdisplay, m->vdisplay,
1024                                          drm_mode_vrefresh(m));
1025
1026                        drm_mode_copy(adjusted_mode, m);
1027                        break;
1028                }
1029        }
1030
1031cleanup:
1032        drm_connector_put(connector);
1033
1034        return true;
1035}
1036
1037static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
1038{
1039        u32 n, cts;
1040
1041        cts = (freq % 9) ? 27000 : 30000;
1042        n = 128 * freq / (27000000 / cts);
1043
1044        hdmi_reg_writev(hdata, HDMI_ACR_N0, 3, n);
1045        hdmi_reg_writev(hdata, HDMI_ACR_MCTS0, 3, cts);
1046        hdmi_reg_writev(hdata, HDMI_ACR_CTS0, 3, cts);
1047        hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1048}
1049
1050static void hdmi_audio_config(struct hdmi_context *hdata)
1051{
1052        u32 bit_ch = 1;
1053        u32 data_num, val;
1054        int i;
1055
1056        switch (hdata->audio.params.sample_width) {
1057        case 20:
1058                data_num = 2;
1059                break;
1060        case 24:
1061                data_num = 3;
1062                break;
1063        default:
1064                data_num = 1;
1065                bit_ch = 0;
1066                break;
1067        }
1068
1069        hdmi_reg_acr(hdata, hdata->audio.params.sample_rate);
1070
1071        hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1072                                | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1073                                | HDMI_I2S_MUX_ENABLE);
1074
1075        hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1076                        | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1077
1078        hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1079        hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1080        hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1081
1082        val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1083        hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1084
1085        /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1086        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1087                        | HDMI_I2S_SEL_LRCK(6));
1088
1089        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(3)
1090                        | HDMI_I2S_SEL_SDATA0(4));
1091
1092        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1093                        | HDMI_I2S_SEL_SDATA2(2));
1094
1095        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1096
1097        /* I2S_CON_1 & 2 */
1098        hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1099                        | HDMI_I2S_L_CH_LOW_POL);
1100        hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1101                        | HDMI_I2S_SET_BIT_CH(bit_ch)
1102                        | HDMI_I2S_SET_SDATA_BIT(data_num)
1103                        | HDMI_I2S_BASIC_FORMAT);
1104
1105        /* Configuration of the audio channel status registers */
1106        for (i = 0; i < HDMI_I2S_CH_ST_MAXNUM; i++)
1107                hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST(i),
1108                                hdata->audio.params.iec.status[i]);
1109
1110        hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1111}
1112
1113static void hdmi_audio_control(struct hdmi_context *hdata)
1114{
1115        bool enable = !hdata->audio.mute;
1116
1117        if (hdata->dvi_mode)
1118                return;
1119
1120        hdmi_reg_writeb(hdata, HDMI_AUI_CON, enable ?
1121                        HDMI_AVI_CON_EVERY_VSYNC : HDMI_AUI_CON_NO_TRAN);
1122        hdmi_reg_writemask(hdata, HDMI_CON_0, enable ?
1123                        HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1124}
1125
1126static void hdmi_start(struct hdmi_context *hdata, bool start)
1127{
1128        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1129        u32 val = start ? HDMI_TG_EN : 0;
1130
1131        if (m->flags & DRM_MODE_FLAG_INTERLACE)
1132                val |= HDMI_FIELD_EN;
1133
1134        hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1135        hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1136}
1137
1138static void hdmi_conf_init(struct hdmi_context *hdata)
1139{
1140        /* disable HPD interrupts from HDMI IP block, use GPIO instead */
1141        hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1142                HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1143
1144        /* choose HDMI mode */
1145        hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1146                HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1147        /* apply video pre-amble and guard band in HDMI mode only */
1148        hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1149        /* disable bluescreen */
1150        hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1151
1152        if (hdata->dvi_mode) {
1153                hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1154                                HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1155                hdmi_reg_writeb(hdata, HDMI_CON_2,
1156                                HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1157        }
1158
1159        if (hdata->drv_data->type == HDMI_TYPE13) {
1160                /* choose bluescreen (fecal) color */
1161                hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1162                hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1163                hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1164
1165                /* enable AVI packet every vsync, fixes purple line problem */
1166                hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1167                /* force RGB, look to CEA-861-D, table 7 for more detail */
1168                hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1169                hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1170
1171                hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1172                hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1173                hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1174        } else {
1175                hdmi_reg_infoframes(hdata);
1176
1177                /* enable AVI packet every vsync, fixes purple line problem */
1178                hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1179        }
1180}
1181
1182static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
1183{
1184        int tries;
1185
1186        for (tries = 0; tries < 10; ++tries) {
1187                u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
1188
1189                if (val & HDMI_PHY_STATUS_READY) {
1190                        DRM_DEV_DEBUG_KMS(hdata->dev,
1191                                          "PLL stabilized after %d tries\n",
1192                                          tries);
1193                        return;
1194                }
1195                usleep_range(10, 20);
1196        }
1197
1198        DRM_DEV_ERROR(hdata->dev, "PLL could not reach steady state\n");
1199}
1200
1201static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1202{
1203        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1204        unsigned int val;
1205
1206        hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1207        hdmi_reg_writev(hdata, HDMI_V13_H_V_LINE_0, 3,
1208                        (m->htotal << 12) | m->vtotal);
1209
1210        val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1211        hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, val);
1212
1213        val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1214        hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, val);
1215
1216        val = (m->hsync_start - m->hdisplay - 2);
1217        val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1218        val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
1219        hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1220
1221        /*
1222         * Quirk requirement for exynos HDMI IP design,
1223         * 2 pixels less than the actual calculation for hsync_start
1224         * and end.
1225         */
1226
1227        /* Following values & calculations differ for different type of modes */
1228        if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1229                val = ((m->vsync_end - m->vdisplay) / 2);
1230                val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1231                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1232
1233                val = m->vtotal / 2;
1234                val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1235                hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1236
1237                val = (m->vtotal +
1238                        ((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1239                val |= m->vtotal << 11;
1240                hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, val);
1241
1242                val = ((m->vtotal / 2) + 7);
1243                val |= ((m->vtotal / 2) + 2) << 12;
1244                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, val);
1245
1246                val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1247                val |= ((m->htotal / 2) +
1248                        (m->hsync_start - m->hdisplay)) << 12;
1249                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, val);
1250
1251                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1252                                (m->vtotal - m->vdisplay) / 2);
1253                hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1254
1255                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1256        } else {
1257                val = m->vtotal;
1258                val |= (m->vtotal - m->vdisplay) << 11;
1259                hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1260
1261                hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, 0);
1262
1263                val = (m->vsync_end - m->vdisplay);
1264                val |= ((m->vsync_start - m->vdisplay) << 12);
1265                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1266
1267                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, 0x1001);
1268                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, 0x1001);
1269                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1270                                m->vtotal - m->vdisplay);
1271                hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1272        }
1273
1274        hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1275        hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1276        hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1277        hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1278}
1279
1280static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1281{
1282        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1283        struct drm_display_mode *am =
1284                                &hdata->encoder.crtc->state->adjusted_mode;
1285        int hquirk = 0;
1286
1287        /*
1288         * In case video mode coming from CRTC differs from requested one HDMI
1289         * sometimes is able to almost properly perform conversion - only
1290         * first line is distorted.
1291         */
1292        if ((m->vdisplay != am->vdisplay) &&
1293            (m->hdisplay == 1280 || m->hdisplay == 1024 || m->hdisplay == 1366))
1294                hquirk = 258;
1295
1296        hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1297        hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1298        hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1299        hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
1300                        (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
1301        hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1302                        (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1303        hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
1304                        (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1305
1306        /*
1307         * Quirk requirement for exynos 5 HDMI IP design,
1308         * 2 pixels less than the actual calculation for hsync_start
1309         * and end.
1310         */
1311
1312        /* Following values & calculations differ for different type of modes */
1313        if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1314                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1315                        (m->vsync_end - m->vdisplay) / 2);
1316                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1317                        (m->vsync_start - m->vdisplay) / 2);
1318                hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal / 2);
1319                hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1320                                (m->vtotal - m->vdisplay) / 2);
1321                hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2,
1322                                m->vtotal - m->vdisplay / 2);
1323                hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, m->vtotal);
1324                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2,
1325                                (m->vtotal / 2) + 7);
1326                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2,
1327                                (m->vtotal / 2) + 2);
1328                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2,
1329                        (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1330                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2,
1331                        (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1332                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1333                                (m->vtotal - m->vdisplay) / 2);
1334                hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1335                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2,
1336                                m->vtotal - m->vdisplay / 2);
1337                hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2,
1338                                (m->vtotal / 2) + 1);
1339                hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2,
1340                                (m->vtotal / 2) + 1);
1341                hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2,
1342                                (m->vtotal / 2) + 1);
1343                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1344                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1345        } else {
1346                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1347                        m->vsync_end - m->vdisplay);
1348                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1349                        m->vsync_start - m->vdisplay);
1350                hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal);
1351                hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1352                                m->vtotal - m->vdisplay);
1353                hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2, 0xffff);
1354                hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, 0xffff);
1355                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2, 0xffff);
1356                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2, 0xffff);
1357                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2, 0xffff);
1358                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2, 0xffff);
1359                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1360                                m->vtotal - m->vdisplay);
1361                hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1362        }
1363
1364        hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1365                        m->hsync_start - m->hdisplay - 2);
1366        hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
1367                        m->hsync_end - m->hdisplay - 2);
1368        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_1_0, 2, 0xffff);
1369        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_2_0, 2, 0xffff);
1370        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_3_0, 2, 0xffff);
1371        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_4_0, 2, 0xffff);
1372        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_5_0, 2, 0xffff);
1373        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_6_0, 2, 0xffff);
1374        hdmi_reg_writev(hdata, HDMI_V_BLANK_F2_0, 2, 0xffff);
1375        hdmi_reg_writev(hdata, HDMI_V_BLANK_F3_0, 2, 0xffff);
1376        hdmi_reg_writev(hdata, HDMI_V_BLANK_F4_0, 2, 0xffff);
1377        hdmi_reg_writev(hdata, HDMI_V_BLANK_F5_0, 2, 0xffff);
1378        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 2, 0xffff);
1379        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 2, 0xffff);
1380        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 2, 0xffff);
1381        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 2, 0xffff);
1382        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 2, 0xffff);
1383        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 2, 0xffff);
1384        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1385        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
1386
1387        hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1388        hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2,
1389                                        m->htotal - m->hdisplay - hquirk);
1390        hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk);
1391        hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1392        if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1393                hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
1394}
1395
1396static void hdmi_mode_apply(struct hdmi_context *hdata)
1397{
1398        if (hdata->drv_data->type == HDMI_TYPE13)
1399                hdmi_v13_mode_apply(hdata);
1400        else
1401                hdmi_v14_mode_apply(hdata);
1402
1403        hdmi_start(hdata, true);
1404}
1405
1406static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1407{
1408        hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1);
1409        usleep_range(10000, 12000);
1410        hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1);
1411        usleep_range(10000, 12000);
1412        hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
1413        usleep_range(10000, 12000);
1414        hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
1415        usleep_range(10000, 12000);
1416}
1417
1418static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable)
1419{
1420        u8 v = enable ? HDMI_PHY_ENABLE_MODE_SET : HDMI_PHY_DISABLE_MODE_SET;
1421
1422        if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1423                writel(v, hdata->regs_hdmiphy + HDMIPHY5433_MODE_SET_DONE);
1424}
1425
1426static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1427{
1428        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1429        int ret;
1430        const u8 *phy_conf;
1431
1432        ret = hdmi_find_phy_conf(hdata, m->clock * 1000);
1433        if (ret < 0) {
1434                DRM_DEV_ERROR(hdata->dev, "failed to find hdmiphy conf\n");
1435                return;
1436        }
1437        phy_conf = hdata->drv_data->phy_confs.data[ret].conf;
1438
1439        hdmi_clk_set_parents(hdata, false);
1440
1441        hdmiphy_conf_reset(hdata);
1442
1443        hdmiphy_enable_mode_set(hdata, true);
1444        ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32);
1445        if (ret) {
1446                DRM_DEV_ERROR(hdata->dev, "failed to configure hdmiphy\n");
1447                return;
1448        }
1449        hdmiphy_enable_mode_set(hdata, false);
1450        hdmi_clk_set_parents(hdata, true);
1451        usleep_range(10000, 12000);
1452        hdmiphy_wait_for_pll(hdata);
1453}
1454
1455/* Should be called with hdata->mutex mutex held */
1456static void hdmi_conf_apply(struct hdmi_context *hdata)
1457{
1458        hdmi_start(hdata, false);
1459        hdmi_conf_init(hdata);
1460        hdmi_audio_config(hdata);
1461        hdmi_mode_apply(hdata);
1462        hdmi_audio_control(hdata);
1463}
1464
1465static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1466{
1467        if (!hdata->sysreg)
1468                return;
1469
1470        regmap_update_bits(hdata->sysreg, EXYNOS5433_SYSREG_DISP_HDMI_PHY,
1471                           SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1472}
1473
1474/* Should be called with hdata->mutex mutex held. */
1475static void hdmiphy_enable(struct hdmi_context *hdata)
1476{
1477        if (hdata->powered)
1478                return;
1479
1480        pm_runtime_get_sync(hdata->dev);
1481
1482        if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
1483                DRM_DEV_DEBUG_KMS(hdata->dev,
1484                                  "failed to enable regulator bulk\n");
1485
1486        regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1487                        PMU_HDMI_PHY_ENABLE_BIT, 1);
1488
1489        hdmi_set_refclk(hdata, true);
1490
1491        hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
1492
1493        hdmiphy_conf_apply(hdata);
1494
1495        hdata->powered = true;
1496}
1497
1498/* Should be called with hdata->mutex mutex held. */
1499static void hdmiphy_disable(struct hdmi_context *hdata)
1500{
1501        if (!hdata->powered)
1502                return;
1503
1504        hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1505
1506        hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
1507
1508        hdmi_set_refclk(hdata, false);
1509
1510        regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1511                        PMU_HDMI_PHY_ENABLE_BIT, 0);
1512
1513        regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1514
1515        pm_runtime_put_sync(hdata->dev);
1516
1517        hdata->powered = false;
1518}
1519
1520static void hdmi_enable(struct drm_encoder *encoder)
1521{
1522        struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1523
1524        mutex_lock(&hdata->mutex);
1525
1526        hdmiphy_enable(hdata);
1527        hdmi_conf_apply(hdata);
1528
1529        mutex_unlock(&hdata->mutex);
1530}
1531
1532static void hdmi_disable(struct drm_encoder *encoder)
1533{
1534        struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1535
1536        mutex_lock(&hdata->mutex);
1537
1538        if (hdata->powered) {
1539                /*
1540                 * The SFRs of VP and Mixer are updated by Vertical Sync of
1541                 * Timing generator which is a part of HDMI so the sequence
1542                 * to disable TV Subsystem should be as following,
1543                 *      VP -> Mixer -> HDMI
1544                 *
1545                 * To achieve such sequence HDMI is disabled together with
1546                 * HDMI PHY, via pipe clock callback.
1547                 */
1548                mutex_unlock(&hdata->mutex);
1549                cancel_delayed_work(&hdata->hotplug_work);
1550                if (hdata->notifier)
1551                        cec_notifier_phys_addr_invalidate(hdata->notifier);
1552                return;
1553        }
1554
1555        mutex_unlock(&hdata->mutex);
1556}
1557
1558static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
1559        .mode_fixup     = hdmi_mode_fixup,
1560        .enable         = hdmi_enable,
1561        .disable        = hdmi_disable,
1562};
1563
1564static void hdmi_audio_shutdown(struct device *dev, void *data)
1565{
1566        struct hdmi_context *hdata = dev_get_drvdata(dev);
1567
1568        mutex_lock(&hdata->mutex);
1569
1570        hdata->audio.mute = true;
1571
1572        if (hdata->powered)
1573                hdmi_audio_control(hdata);
1574
1575        mutex_unlock(&hdata->mutex);
1576}
1577
1578static int hdmi_audio_hw_params(struct device *dev, void *data,
1579                                struct hdmi_codec_daifmt *daifmt,
1580                                struct hdmi_codec_params *params)
1581{
1582        struct hdmi_context *hdata = dev_get_drvdata(dev);
1583
1584        if (daifmt->fmt != HDMI_I2S || daifmt->bit_clk_inv ||
1585            daifmt->frame_clk_inv || daifmt->bit_clk_master ||
1586            daifmt->frame_clk_master) {
1587                dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__,
1588                        daifmt->bit_clk_inv, daifmt->frame_clk_inv,
1589                        daifmt->bit_clk_master,
1590                        daifmt->frame_clk_master);
1591                return -EINVAL;
1592        }
1593
1594        mutex_lock(&hdata->mutex);
1595
1596        hdata->audio.params = *params;
1597
1598        if (hdata->powered) {
1599                hdmi_audio_config(hdata);
1600                hdmi_audio_infoframe_apply(hdata);
1601        }
1602
1603        mutex_unlock(&hdata->mutex);
1604
1605        return 0;
1606}
1607
1608static int hdmi_audio_mute(struct device *dev, void *data,
1609                           bool mute, int direction)
1610{
1611        struct hdmi_context *hdata = dev_get_drvdata(dev);
1612
1613        mutex_lock(&hdata->mutex);
1614
1615        hdata->audio.mute = mute;
1616
1617        if (hdata->powered)
1618                hdmi_audio_control(hdata);
1619
1620        mutex_unlock(&hdata->mutex);
1621
1622        return 0;
1623}
1624
1625static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
1626                              size_t len)
1627{
1628        struct hdmi_context *hdata = dev_get_drvdata(dev);
1629        struct drm_connector *connector = &hdata->connector;
1630
1631        memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
1632
1633        return 0;
1634}
1635
1636static const struct hdmi_codec_ops audio_codec_ops = {
1637        .hw_params = hdmi_audio_hw_params,
1638        .audio_shutdown = hdmi_audio_shutdown,
1639        .mute_stream = hdmi_audio_mute,
1640        .get_eld = hdmi_audio_get_eld,
1641        .no_capture_mute = 1,
1642};
1643
1644static int hdmi_register_audio_device(struct hdmi_context *hdata)
1645{
1646        struct hdmi_codec_pdata codec_data = {
1647                .ops = &audio_codec_ops,
1648                .max_i2s_channels = 6,
1649                .i2s = 1,
1650        };
1651
1652        hdata->audio.pdev = platform_device_register_data(
1653                hdata->dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
1654                &codec_data, sizeof(codec_data));
1655
1656        return PTR_ERR_OR_ZERO(hdata->audio.pdev);
1657}
1658
1659static void hdmi_hotplug_work_func(struct work_struct *work)
1660{
1661        struct hdmi_context *hdata;
1662
1663        hdata = container_of(work, struct hdmi_context, hotplug_work.work);
1664
1665        if (hdata->drm_dev)
1666                drm_helper_hpd_irq_event(hdata->drm_dev);
1667}
1668
1669static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1670{
1671        struct hdmi_context *hdata = arg;
1672
1673        mod_delayed_work(system_wq, &hdata->hotplug_work,
1674                        msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
1675
1676        return IRQ_HANDLED;
1677}
1678
1679static int hdmi_clks_get(struct hdmi_context *hdata,
1680                         const struct string_array_spec *names,
1681                         struct clk **clks)
1682{
1683        struct device *dev = hdata->dev;
1684        int i;
1685
1686        for (i = 0; i < names->count; ++i) {
1687                struct clk *clk = devm_clk_get(dev, names->data[i]);
1688
1689                if (IS_ERR(clk)) {
1690                        int ret = PTR_ERR(clk);
1691
1692                        dev_err(dev, "Cannot get clock %s, %d\n",
1693                                names->data[i], ret);
1694
1695                        return ret;
1696                }
1697
1698                clks[i] = clk;
1699        }
1700
1701        return 0;
1702}
1703
1704static int hdmi_clk_init(struct hdmi_context *hdata)
1705{
1706        const struct hdmi_driver_data *drv_data = hdata->drv_data;
1707        int count = drv_data->clk_gates.count + drv_data->clk_muxes.count;
1708        struct device *dev = hdata->dev;
1709        struct clk **clks;
1710        int ret;
1711
1712        if (!count)
1713                return 0;
1714
1715        clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL);
1716        if (!clks)
1717                return -ENOMEM;
1718
1719        hdata->clk_gates = clks;
1720        hdata->clk_muxes = clks + drv_data->clk_gates.count;
1721
1722        ret = hdmi_clks_get(hdata, &drv_data->clk_gates, hdata->clk_gates);
1723        if (ret)
1724                return ret;
1725
1726        return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes);
1727}
1728
1729
1730static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
1731{
1732        struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
1733                                                  phy_clk);
1734        mutex_lock(&hdata->mutex);
1735
1736        if (enable)
1737                hdmiphy_enable(hdata);
1738        else
1739                hdmiphy_disable(hdata);
1740
1741        mutex_unlock(&hdata->mutex);
1742}
1743
1744static int hdmi_bridge_init(struct hdmi_context *hdata)
1745{
1746        struct device *dev = hdata->dev;
1747        struct device_node *ep, *np;
1748
1749        ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1);
1750        if (!ep)
1751                return 0;
1752
1753        np = of_graph_get_remote_port_parent(ep);
1754        of_node_put(ep);
1755        if (!np) {
1756                DRM_DEV_ERROR(dev, "failed to get remote port parent");
1757                return -EINVAL;
1758        }
1759
1760        hdata->bridge = of_drm_find_bridge(np);
1761        of_node_put(np);
1762
1763        if (!hdata->bridge)
1764                return -EPROBE_DEFER;
1765
1766        return 0;
1767}
1768
1769static int hdmi_resources_init(struct hdmi_context *hdata)
1770{
1771        struct device *dev = hdata->dev;
1772        int i, ret;
1773
1774        DRM_DEV_DEBUG_KMS(dev, "HDMI resource init\n");
1775
1776        hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
1777        if (IS_ERR(hdata->hpd_gpio)) {
1778                DRM_DEV_ERROR(dev, "cannot get hpd gpio property\n");
1779                return PTR_ERR(hdata->hpd_gpio);
1780        }
1781
1782        hdata->irq = gpiod_to_irq(hdata->hpd_gpio);
1783        if (hdata->irq < 0) {
1784                DRM_DEV_ERROR(dev, "failed to get GPIO irq\n");
1785                return  hdata->irq;
1786        }
1787
1788        ret = hdmi_clk_init(hdata);
1789        if (ret)
1790                return ret;
1791
1792        ret = hdmi_clk_set_parents(hdata, false);
1793        if (ret)
1794                return ret;
1795
1796        for (i = 0; i < ARRAY_SIZE(supply); ++i)
1797                hdata->regul_bulk[i].supply = supply[i];
1798
1799        ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
1800        if (ret) {
1801                if (ret != -EPROBE_DEFER)
1802                        DRM_DEV_ERROR(dev, "failed to get regulators\n");
1803                return ret;
1804        }
1805
1806        hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en");
1807
1808        if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV)
1809                if (IS_ERR(hdata->reg_hdmi_en))
1810                        return PTR_ERR(hdata->reg_hdmi_en);
1811
1812        return hdmi_bridge_init(hdata);
1813}
1814
1815static const struct of_device_id hdmi_match_types[] = {
1816        {
1817                .compatible = "samsung,exynos4210-hdmi",
1818                .data = &exynos4210_hdmi_driver_data,
1819        }, {
1820                .compatible = "samsung,exynos4212-hdmi",
1821                .data = &exynos4212_hdmi_driver_data,
1822        }, {
1823                .compatible = "samsung,exynos5420-hdmi",
1824                .data = &exynos5420_hdmi_driver_data,
1825        }, {
1826                .compatible = "samsung,exynos5433-hdmi",
1827                .data = &exynos5433_hdmi_driver_data,
1828        }, {
1829                /* end node */
1830        }
1831};
1832MODULE_DEVICE_TABLE (of, hdmi_match_types);
1833
1834static int hdmi_bind(struct device *dev, struct device *master, void *data)
1835{
1836        struct drm_device *drm_dev = data;
1837        struct hdmi_context *hdata = dev_get_drvdata(dev);
1838        struct drm_encoder *encoder = &hdata->encoder;
1839        struct exynos_drm_crtc *crtc;
1840        int ret;
1841
1842        hdata->drm_dev = drm_dev;
1843
1844        hdata->phy_clk.enable = hdmiphy_clk_enable;
1845
1846        drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
1847
1848        drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
1849
1850        ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_HDMI);
1851        if (ret < 0)
1852                return ret;
1853
1854        crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI);
1855        crtc->pipe_clk = &hdata->phy_clk;
1856
1857        ret = hdmi_create_connector(encoder);
1858        if (ret) {
1859                DRM_DEV_ERROR(dev, "failed to create connector ret = %d\n",
1860                              ret);
1861                drm_encoder_cleanup(encoder);
1862                return ret;
1863        }
1864
1865        return 0;
1866}
1867
1868static void hdmi_unbind(struct device *dev, struct device *master, void *data)
1869{
1870}
1871
1872static const struct component_ops hdmi_component_ops = {
1873        .bind   = hdmi_bind,
1874        .unbind = hdmi_unbind,
1875};
1876
1877static int hdmi_get_ddc_adapter(struct hdmi_context *hdata)
1878{
1879        const char *compatible_str = "samsung,exynos4210-hdmiddc";
1880        struct device_node *np;
1881        struct i2c_adapter *adpt;
1882
1883        np = of_find_compatible_node(NULL, NULL, compatible_str);
1884        if (np)
1885                np = of_get_next_parent(np);
1886        else
1887                np = of_parse_phandle(hdata->dev->of_node, "ddc", 0);
1888
1889        if (!np) {
1890                DRM_DEV_ERROR(hdata->dev,
1891                              "Failed to find ddc node in device tree\n");
1892                return -ENODEV;
1893        }
1894
1895        adpt = of_find_i2c_adapter_by_node(np);
1896        of_node_put(np);
1897
1898        if (!adpt) {
1899                DRM_INFO("Failed to get ddc i2c adapter by node\n");
1900                return -EPROBE_DEFER;
1901        }
1902
1903        hdata->ddc_adpt = adpt;
1904
1905        return 0;
1906}
1907
1908static int hdmi_get_phy_io(struct hdmi_context *hdata)
1909{
1910        const char *compatible_str = "samsung,exynos4212-hdmiphy";
1911        struct device_node *np;
1912        int ret = 0;
1913
1914        np = of_find_compatible_node(NULL, NULL, compatible_str);
1915        if (!np) {
1916                np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
1917                if (!np) {
1918                        DRM_DEV_ERROR(hdata->dev,
1919                                      "Failed to find hdmiphy node in device tree\n");
1920                        return -ENODEV;
1921                }
1922        }
1923
1924        if (hdata->drv_data->is_apb_phy) {
1925                hdata->regs_hdmiphy = of_iomap(np, 0);
1926                if (!hdata->regs_hdmiphy) {
1927                        DRM_DEV_ERROR(hdata->dev,
1928                                      "failed to ioremap hdmi phy\n");
1929                        ret = -ENOMEM;
1930                        goto out;
1931                }
1932        } else {
1933                hdata->hdmiphy_port = of_find_i2c_device_by_node(np);
1934                if (!hdata->hdmiphy_port) {
1935                        DRM_INFO("Failed to get hdmi phy i2c client\n");
1936                        ret = -EPROBE_DEFER;
1937                        goto out;
1938                }
1939        }
1940
1941out:
1942        of_node_put(np);
1943        return ret;
1944}
1945
1946static int hdmi_probe(struct platform_device *pdev)
1947{
1948        struct hdmi_audio_infoframe *audio_infoframe;
1949        struct device *dev = &pdev->dev;
1950        struct hdmi_context *hdata;
1951        struct resource *res;
1952        int ret;
1953
1954        hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
1955        if (!hdata)
1956                return -ENOMEM;
1957
1958        hdata->drv_data = of_device_get_match_data(dev);
1959
1960        platform_set_drvdata(pdev, hdata);
1961
1962        hdata->dev = dev;
1963
1964        mutex_init(&hdata->mutex);
1965
1966        ret = hdmi_resources_init(hdata);
1967        if (ret) {
1968                if (ret != -EPROBE_DEFER)
1969                        DRM_DEV_ERROR(dev, "hdmi_resources_init failed\n");
1970                return ret;
1971        }
1972
1973        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1974        hdata->regs = devm_ioremap_resource(dev, res);
1975        if (IS_ERR(hdata->regs)) {
1976                ret = PTR_ERR(hdata->regs);
1977                return ret;
1978        }
1979
1980        ret = hdmi_get_ddc_adapter(hdata);
1981        if (ret)
1982                return ret;
1983
1984        ret = hdmi_get_phy_io(hdata);
1985        if (ret)
1986                goto err_ddc;
1987
1988        INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
1989
1990        ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
1991                        hdmi_irq_thread, IRQF_TRIGGER_RISING |
1992                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1993                        "hdmi", hdata);
1994        if (ret) {
1995                DRM_DEV_ERROR(dev, "failed to register hdmi interrupt\n");
1996                goto err_hdmiphy;
1997        }
1998
1999        hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
2000                        "samsung,syscon-phandle");
2001        if (IS_ERR(hdata->pmureg)) {
2002                DRM_DEV_ERROR(dev, "syscon regmap lookup failed.\n");
2003                ret = -EPROBE_DEFER;
2004                goto err_hdmiphy;
2005        }
2006
2007        if (hdata->drv_data->has_sysreg) {
2008                hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
2009                                "samsung,sysreg-phandle");
2010                if (IS_ERR(hdata->sysreg)) {
2011                        DRM_DEV_ERROR(dev, "sysreg regmap lookup failed.\n");
2012                        ret = -EPROBE_DEFER;
2013                        goto err_hdmiphy;
2014                }
2015        }
2016
2017        if (!IS_ERR(hdata->reg_hdmi_en)) {
2018                ret = regulator_enable(hdata->reg_hdmi_en);
2019                if (ret) {
2020                        DRM_DEV_ERROR(dev,
2021                              "failed to enable hdmi-en regulator\n");
2022                        goto err_hdmiphy;
2023                }
2024        }
2025
2026        pm_runtime_enable(dev);
2027
2028        audio_infoframe = &hdata->audio.infoframe;
2029        hdmi_audio_infoframe_init(audio_infoframe);
2030        audio_infoframe->coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
2031        audio_infoframe->sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
2032        audio_infoframe->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
2033        audio_infoframe->channels = 2;
2034
2035        ret = hdmi_register_audio_device(hdata);
2036        if (ret)
2037                goto err_rpm_disable;
2038
2039        ret = component_add(&pdev->dev, &hdmi_component_ops);
2040        if (ret)
2041                goto err_unregister_audio;
2042
2043        return ret;
2044
2045err_unregister_audio:
2046        platform_device_unregister(hdata->audio.pdev);
2047
2048err_rpm_disable:
2049        pm_runtime_disable(dev);
2050        if (!IS_ERR(hdata->reg_hdmi_en))
2051                regulator_disable(hdata->reg_hdmi_en);
2052err_hdmiphy:
2053        if (hdata->hdmiphy_port)
2054                put_device(&hdata->hdmiphy_port->dev);
2055        if (hdata->regs_hdmiphy)
2056                iounmap(hdata->regs_hdmiphy);
2057err_ddc:
2058        put_device(&hdata->ddc_adpt->dev);
2059
2060        return ret;
2061}
2062
2063static int hdmi_remove(struct platform_device *pdev)
2064{
2065        struct hdmi_context *hdata = platform_get_drvdata(pdev);
2066
2067        cancel_delayed_work_sync(&hdata->hotplug_work);
2068
2069        component_del(&pdev->dev, &hdmi_component_ops);
2070        platform_device_unregister(hdata->audio.pdev);
2071
2072        pm_runtime_disable(&pdev->dev);
2073
2074        if (!IS_ERR(hdata->reg_hdmi_en))
2075                regulator_disable(hdata->reg_hdmi_en);
2076
2077        if (hdata->hdmiphy_port)
2078                put_device(&hdata->hdmiphy_port->dev);
2079
2080        if (hdata->regs_hdmiphy)
2081                iounmap(hdata->regs_hdmiphy);
2082
2083        put_device(&hdata->ddc_adpt->dev);
2084
2085        mutex_destroy(&hdata->mutex);
2086
2087        return 0;
2088}
2089
2090static int __maybe_unused exynos_hdmi_suspend(struct device *dev)
2091{
2092        struct hdmi_context *hdata = dev_get_drvdata(dev);
2093
2094        hdmi_clk_disable_gates(hdata);
2095
2096        return 0;
2097}
2098
2099static int __maybe_unused exynos_hdmi_resume(struct device *dev)
2100{
2101        struct hdmi_context *hdata = dev_get_drvdata(dev);
2102        int ret;
2103
2104        ret = hdmi_clk_enable_gates(hdata);
2105        if (ret < 0)
2106                return ret;
2107
2108        return 0;
2109}
2110
2111static const struct dev_pm_ops exynos_hdmi_pm_ops = {
2112        SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
2113        SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
2114                                pm_runtime_force_resume)
2115};
2116
2117struct platform_driver hdmi_driver = {
2118        .probe          = hdmi_probe,
2119        .remove         = hdmi_remove,
2120        .driver         = {
2121                .name   = "exynos-hdmi",
2122                .owner  = THIS_MODULE,
2123                .pm     = &exynos_hdmi_pm_ops,
2124                .of_match_table = hdmi_match_types,
2125        },
2126};
2127