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                .pixel_clock = 154000000,
 527                .conf = {
 528                        0x01, 0xD1, 0x20, 0x01, 0x40, 0x30, 0x08, 0xCC,
 529                        0x8C, 0xE8, 0xC1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 530                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x86,
 531                        0x54, 0x3F, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 532                },
 533        },
 534};
 535
 536static const struct hdmiphy_config hdmiphy_5433_configs[] = {
 537        {
 538                .pixel_clock = 27000000,
 539                .conf = {
 540                        0x01, 0x51, 0x2d, 0x75, 0x01, 0x00, 0x88, 0x02,
 541                        0x72, 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 = 27027000,
 548                .conf = {
 549                        0x01, 0x51, 0x2d, 0x72, 0x64, 0x09, 0x88, 0xc3,
 550                        0x71, 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 = 40000000,
 557                .conf = {
 558                        0x01, 0x51, 0x32, 0x55, 0x01, 0x00, 0x88, 0x02,
 559                        0x4d, 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 = 50000000,
 566                .conf = {
 567                        0x01, 0x51, 0x34, 0x40, 0x64, 0x09, 0x88, 0xc3,
 568                        0x3d, 0x50, 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 = 65000000,
 575                .conf = {
 576                        0x01, 0x51, 0x36, 0x31, 0x40, 0x10, 0x04, 0xc6,
 577                        0x2e, 0xe8, 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 = 74176000,
 584                .conf = {
 585                        0x01, 0x51, 0x3E, 0x35, 0x5B, 0xDE, 0x88, 0x42,
 586                        0x53, 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 = 74250000,
 593                .conf = {
 594                        0x01, 0x51, 0x3E, 0x35, 0x40, 0xF0, 0x88, 0xC2,
 595                        0x52, 0x51, 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 = 108000000,
 602                .conf = {
 603                        0x01, 0x51, 0x2d, 0x15, 0x01, 0x00, 0x88, 0x02,
 604                        0x72, 0x52, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 605                        0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 606                        0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 607                },
 608        },
 609        {
 610                .pixel_clock = 148500000,
 611                .conf = {
 612                        0x01, 0x51, 0x1f, 0x00, 0x40, 0xf8, 0x88, 0xc1,
 613                        0x52, 0x52, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5,
 614                        0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
 615                        0x08, 0x10, 0x01, 0x01, 0x48, 0x4a, 0x00, 0x40,
 616                },
 617        },
 618        {
 619                .pixel_clock = 297000000,
 620                .conf = {
 621                        0x01, 0x51, 0x3E, 0x05, 0x40, 0xF0, 0x88, 0xC2,
 622                        0x52, 0x53, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 623                        0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 624                        0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 625                },
 626        },
 627};
 628
 629static const char * const hdmi_clk_gates4[] = {
 630        "hdmi", "sclk_hdmi"
 631};
 632
 633static const char * const hdmi_clk_muxes4[] = {
 634        "sclk_pixel", "sclk_hdmiphy", "mout_hdmi"
 635};
 636
 637static const char * const hdmi_clk_gates5433[] = {
 638        "hdmi_pclk", "hdmi_i_pclk", "i_tmds_clk", "i_pixel_clk", "i_spdif_clk"
 639};
 640
 641static const char * const hdmi_clk_muxes5433[] = {
 642        "oscclk", "tmds_clko", "tmds_clko_user",
 643        "oscclk", "pixel_clko", "pixel_clko_user"
 644};
 645
 646static const struct hdmi_driver_data exynos4210_hdmi_driver_data = {
 647        .type           = HDMI_TYPE13,
 648        .phy_confs      = INIT_ARRAY_SPEC(hdmiphy_v13_configs),
 649        .clk_gates      = INIT_ARRAY_SPEC(hdmi_clk_gates4),
 650        .clk_muxes      = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
 651};
 652
 653static const struct hdmi_driver_data exynos4212_hdmi_driver_data = {
 654        .type           = HDMI_TYPE14,
 655        .phy_confs      = INIT_ARRAY_SPEC(hdmiphy_v14_configs),
 656        .clk_gates      = INIT_ARRAY_SPEC(hdmi_clk_gates4),
 657        .clk_muxes      = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
 658};
 659
 660static const struct hdmi_driver_data exynos5420_hdmi_driver_data = {
 661        .type           = HDMI_TYPE14,
 662        .is_apb_phy     = 1,
 663        .phy_confs      = INIT_ARRAY_SPEC(hdmiphy_5420_configs),
 664        .clk_gates      = INIT_ARRAY_SPEC(hdmi_clk_gates4),
 665        .clk_muxes      = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
 666};
 667
 668static const struct hdmi_driver_data exynos5433_hdmi_driver_data = {
 669        .type           = HDMI_TYPE14,
 670        .is_apb_phy     = 1,
 671        .has_sysreg     = 1,
 672        .phy_confs      = INIT_ARRAY_SPEC(hdmiphy_5433_configs),
 673        .clk_gates      = INIT_ARRAY_SPEC(hdmi_clk_gates5433),
 674        .clk_muxes      = INIT_ARRAY_SPEC(hdmi_clk_muxes5433),
 675};
 676
 677static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id)
 678{
 679        if ((reg_id & 0xffff0000) == HDMI_MAPPED_BASE)
 680                return hdmi_reg_map[reg_id & 0xffff][hdata->drv_data->type];
 681        return reg_id;
 682}
 683
 684static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
 685{
 686        return readl(hdata->regs + hdmi_map_reg(hdata, reg_id));
 687}
 688
 689static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
 690                                 u32 reg_id, u8 value)
 691{
 692        writel(value, hdata->regs + hdmi_map_reg(hdata, reg_id));
 693}
 694
 695static inline void hdmi_reg_writev(struct hdmi_context *hdata, u32 reg_id,
 696                                   int bytes, u32 val)
 697{
 698        reg_id = hdmi_map_reg(hdata, reg_id);
 699
 700        while (--bytes >= 0) {
 701                writel(val & 0xff, hdata->regs + reg_id);
 702                val >>= 8;
 703                reg_id += 4;
 704        }
 705}
 706
 707static inline void hdmi_reg_write_buf(struct hdmi_context *hdata, u32 reg_id,
 708                                      u8 *buf, int size)
 709{
 710        for (reg_id = hdmi_map_reg(hdata, reg_id); size; --size, reg_id += 4)
 711                writel(*buf++, hdata->regs + reg_id);
 712}
 713
 714static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
 715                                 u32 reg_id, u32 value, u32 mask)
 716{
 717        u32 old;
 718
 719        reg_id = hdmi_map_reg(hdata, reg_id);
 720        old = readl(hdata->regs + reg_id);
 721        value = (value & mask) | (old & ~mask);
 722        writel(value, hdata->regs + reg_id);
 723}
 724
 725static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
 726                        u32 reg_offset, const u8 *buf, u32 len)
 727{
 728        if ((reg_offset + len) > 32)
 729                return -EINVAL;
 730
 731        if (hdata->hdmiphy_port) {
 732                int ret;
 733
 734                ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
 735                if (ret == len)
 736                        return 0;
 737                return ret;
 738        } else {
 739                int i;
 740                for (i = 0; i < len; i++)
 741                        writel(buf[i], hdata->regs_hdmiphy +
 742                                ((reg_offset + i)<<2));
 743                return 0;
 744        }
 745}
 746
 747static int hdmi_clk_enable_gates(struct hdmi_context *hdata)
 748{
 749        int i, ret;
 750
 751        for (i = 0; i < hdata->drv_data->clk_gates.count; ++i) {
 752                ret = clk_prepare_enable(hdata->clk_gates[i]);
 753                if (!ret)
 754                        continue;
 755
 756                dev_err(hdata->dev, "Cannot enable clock '%s', %d\n",
 757                        hdata->drv_data->clk_gates.data[i], ret);
 758                while (i--)
 759                        clk_disable_unprepare(hdata->clk_gates[i]);
 760                return ret;
 761        }
 762
 763        return 0;
 764}
 765
 766static void hdmi_clk_disable_gates(struct hdmi_context *hdata)
 767{
 768        int i = hdata->drv_data->clk_gates.count;
 769
 770        while (i--)
 771                clk_disable_unprepare(hdata->clk_gates[i]);
 772}
 773
 774static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
 775{
 776        struct device *dev = hdata->dev;
 777        int ret = 0;
 778        int i;
 779
 780        for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) {
 781                struct clk **c = &hdata->clk_muxes[i];
 782
 783                ret = clk_set_parent(c[2], c[to_phy]);
 784                if (!ret)
 785                        continue;
 786
 787                dev_err(dev, "Cannot set clock parent of '%s' to '%s', %d\n",
 788                        hdata->drv_data->clk_muxes.data[i + 2],
 789                        hdata->drv_data->clk_muxes.data[i + to_phy], ret);
 790        }
 791
 792        return ret;
 793}
 794
 795static int hdmi_audio_infoframe_apply(struct hdmi_context *hdata)
 796{
 797        struct hdmi_audio_infoframe *infoframe = &hdata->audio.infoframe;
 798        u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)];
 799        int len;
 800
 801        len = hdmi_audio_infoframe_pack(infoframe, buf, sizeof(buf));
 802        if (len < 0)
 803                return len;
 804
 805        hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_EVERY_VSYNC);
 806        hdmi_reg_write_buf(hdata, HDMI_AUI_HEADER0, buf, len);
 807
 808        return 0;
 809}
 810
 811static void hdmi_reg_infoframes(struct hdmi_context *hdata)
 812{
 813        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
 814        union hdmi_infoframe frm;
 815        u8 buf[25];
 816        int ret;
 817
 818        if (hdata->dvi_mode) {
 819                hdmi_reg_writeb(hdata, HDMI_AVI_CON,
 820                                HDMI_AVI_CON_DO_NOT_TRANSMIT);
 821                hdmi_reg_writeb(hdata, HDMI_VSI_CON,
 822                                HDMI_VSI_CON_DO_NOT_TRANSMIT);
 823                hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
 824                return;
 825        }
 826
 827        ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
 828                                                       &hdata->connector, m);
 829        if (!ret)
 830                ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf));
 831        if (ret > 0) {
 832                hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
 833                hdmi_reg_write_buf(hdata, HDMI_AVI_HEADER0, buf, ret);
 834        } else {
 835                DRM_INFO("%s: invalid AVI infoframe (%d)\n", __func__, ret);
 836        }
 837
 838        ret = drm_hdmi_vendor_infoframe_from_display_mode(&frm.vendor.hdmi,
 839                                                          &hdata->connector, m);
 840        if (!ret)
 841                ret = hdmi_vendor_infoframe_pack(&frm.vendor.hdmi, buf,
 842                                sizeof(buf));
 843        if (ret > 0) {
 844                hdmi_reg_writeb(hdata, HDMI_VSI_CON, HDMI_VSI_CON_EVERY_VSYNC);
 845                hdmi_reg_write_buf(hdata, HDMI_VSI_HEADER0, buf, 3);
 846                hdmi_reg_write_buf(hdata, HDMI_VSI_DATA(0), buf + 3, ret - 3);
 847        }
 848
 849        hdmi_audio_infoframe_apply(hdata);
 850}
 851
 852static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
 853                                bool force)
 854{
 855        struct hdmi_context *hdata = connector_to_hdmi(connector);
 856
 857        if (gpiod_get_value(hdata->hpd_gpio))
 858                return connector_status_connected;
 859
 860        cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
 861        return connector_status_disconnected;
 862}
 863
 864static void hdmi_connector_destroy(struct drm_connector *connector)
 865{
 866        struct hdmi_context *hdata = connector_to_hdmi(connector);
 867
 868        cec_notifier_conn_unregister(hdata->notifier);
 869
 870        drm_connector_unregister(connector);
 871        drm_connector_cleanup(connector);
 872}
 873
 874static const struct drm_connector_funcs hdmi_connector_funcs = {
 875        .fill_modes = drm_helper_probe_single_connector_modes,
 876        .detect = hdmi_detect,
 877        .destroy = hdmi_connector_destroy,
 878        .reset = drm_atomic_helper_connector_reset,
 879        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 880        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 881};
 882
 883static int hdmi_get_modes(struct drm_connector *connector)
 884{
 885        struct hdmi_context *hdata = connector_to_hdmi(connector);
 886        struct edid *edid;
 887        int ret;
 888
 889        if (!hdata->ddc_adpt)
 890                return -ENODEV;
 891
 892        edid = drm_get_edid(connector, hdata->ddc_adpt);
 893        if (!edid)
 894                return -ENODEV;
 895
 896        hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
 897        DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n",
 898                          (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
 899                          edid->width_cm, edid->height_cm);
 900
 901        drm_connector_update_edid_property(connector, edid);
 902        cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid);
 903
 904        ret = drm_add_edid_modes(connector, edid);
 905
 906        kfree(edid);
 907
 908        return ret;
 909}
 910
 911static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
 912{
 913        const struct hdmiphy_configs *confs = &hdata->drv_data->phy_confs;
 914        int i;
 915
 916        for (i = 0; i < confs->count; i++)
 917                if (confs->data[i].pixel_clock == pixel_clock)
 918                        return i;
 919
 920        DRM_DEV_DEBUG_KMS(hdata->dev, "Could not find phy config for %d\n",
 921                          pixel_clock);
 922        return -EINVAL;
 923}
 924
 925static int hdmi_mode_valid(struct drm_connector *connector,
 926                        struct drm_display_mode *mode)
 927{
 928        struct hdmi_context *hdata = connector_to_hdmi(connector);
 929        int ret;
 930
 931        DRM_DEV_DEBUG_KMS(hdata->dev,
 932                          "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
 933                          mode->hdisplay, mode->vdisplay,
 934                          drm_mode_vrefresh(mode),
 935                          (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
 936                          false, mode->clock * 1000);
 937
 938        ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
 939        if (ret < 0)
 940                return MODE_BAD;
 941
 942        return MODE_OK;
 943}
 944
 945static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
 946        .get_modes = hdmi_get_modes,
 947        .mode_valid = hdmi_mode_valid,
 948};
 949
 950static int hdmi_create_connector(struct drm_encoder *encoder)
 951{
 952        struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 953        struct drm_connector *connector = &hdata->connector;
 954        struct cec_connector_info conn_info;
 955        int ret;
 956
 957        connector->interlace_allowed = true;
 958        connector->polled = DRM_CONNECTOR_POLL_HPD;
 959
 960        ret = drm_connector_init_with_ddc(hdata->drm_dev, connector,
 961                                          &hdmi_connector_funcs,
 962                                          DRM_MODE_CONNECTOR_HDMIA,
 963                                          hdata->ddc_adpt);
 964        if (ret) {
 965                DRM_DEV_ERROR(hdata->dev,
 966                              "Failed to initialize connector with drm\n");
 967                return ret;
 968        }
 969
 970        drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
 971        drm_connector_attach_encoder(connector, encoder);
 972
 973        if (hdata->bridge)
 974                ret = drm_bridge_attach(encoder, hdata->bridge, NULL, 0);
 975
 976        cec_fill_conn_info_from_drm(&conn_info, connector);
 977
 978        hdata->notifier = cec_notifier_conn_register(hdata->dev, NULL,
 979                                                     &conn_info);
 980        if (!hdata->notifier) {
 981                ret = -ENOMEM;
 982                DRM_DEV_ERROR(hdata->dev, "Failed to allocate CEC notifier\n");
 983        }
 984
 985        return ret;
 986}
 987
 988static bool hdmi_mode_fixup(struct drm_encoder *encoder,
 989                            const struct drm_display_mode *mode,
 990                            struct drm_display_mode *adjusted_mode)
 991{
 992        struct drm_device *dev = encoder->dev;
 993        struct drm_connector *connector;
 994        struct drm_display_mode *m;
 995        struct drm_connector_list_iter conn_iter;
 996        int mode_ok;
 997
 998        drm_mode_set_crtcinfo(adjusted_mode, 0);
 999
1000        drm_connector_list_iter_begin(dev, &conn_iter);
1001        drm_for_each_connector_iter(connector, &conn_iter) {
1002                if (connector->encoder == encoder)
1003                        break;
1004        }
1005        if (connector)
1006                drm_connector_get(connector);
1007        drm_connector_list_iter_end(&conn_iter);
1008
1009        if (!connector)
1010                return true;
1011
1012        mode_ok = hdmi_mode_valid(connector, adjusted_mode);
1013
1014        if (mode_ok == MODE_OK)
1015                goto cleanup;
1016
1017        /*
1018         * Find the most suitable mode and copy it to adjusted_mode.
1019         */
1020        list_for_each_entry(m, &connector->modes, head) {
1021                mode_ok = hdmi_mode_valid(connector, m);
1022
1023                if (mode_ok == MODE_OK) {
1024                        DRM_INFO("desired mode doesn't exist so\n");
1025                        DRM_INFO("use the most suitable mode among modes.\n");
1026
1027                        DRM_DEV_DEBUG_KMS(dev->dev,
1028                                          "Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1029                                          m->hdisplay, m->vdisplay,
1030                                          drm_mode_vrefresh(m));
1031
1032                        drm_mode_copy(adjusted_mode, m);
1033                        break;
1034                }
1035        }
1036
1037cleanup:
1038        drm_connector_put(connector);
1039
1040        return true;
1041}
1042
1043static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
1044{
1045        u32 n, cts;
1046
1047        cts = (freq % 9) ? 27000 : 30000;
1048        n = 128 * freq / (27000000 / cts);
1049
1050        hdmi_reg_writev(hdata, HDMI_ACR_N0, 3, n);
1051        hdmi_reg_writev(hdata, HDMI_ACR_MCTS0, 3, cts);
1052        hdmi_reg_writev(hdata, HDMI_ACR_CTS0, 3, cts);
1053        hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1054}
1055
1056static void hdmi_audio_config(struct hdmi_context *hdata)
1057{
1058        u32 bit_ch = 1;
1059        u32 data_num, val;
1060        int i;
1061
1062        switch (hdata->audio.params.sample_width) {
1063        case 20:
1064                data_num = 2;
1065                break;
1066        case 24:
1067                data_num = 3;
1068                break;
1069        default:
1070                data_num = 1;
1071                bit_ch = 0;
1072                break;
1073        }
1074
1075        hdmi_reg_acr(hdata, hdata->audio.params.sample_rate);
1076
1077        hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1078                                | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1079                                | HDMI_I2S_MUX_ENABLE);
1080
1081        hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1082                        | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1083
1084        hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1085        hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1086        hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1087
1088        val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1089        hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1090
1091        /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1092        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1093                        | HDMI_I2S_SEL_LRCK(6));
1094
1095        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(3)
1096                        | HDMI_I2S_SEL_SDATA0(4));
1097
1098        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1099                        | HDMI_I2S_SEL_SDATA2(2));
1100
1101        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1102
1103        /* I2S_CON_1 & 2 */
1104        hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1105                        | HDMI_I2S_L_CH_LOW_POL);
1106        hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1107                        | HDMI_I2S_SET_BIT_CH(bit_ch)
1108                        | HDMI_I2S_SET_SDATA_BIT(data_num)
1109                        | HDMI_I2S_BASIC_FORMAT);
1110
1111        /* Configuration of the audio channel status registers */
1112        for (i = 0; i < HDMI_I2S_CH_ST_MAXNUM; i++)
1113                hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST(i),
1114                                hdata->audio.params.iec.status[i]);
1115
1116        hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1117}
1118
1119static void hdmi_audio_control(struct hdmi_context *hdata)
1120{
1121        bool enable = !hdata->audio.mute;
1122
1123        if (hdata->dvi_mode)
1124                return;
1125
1126        hdmi_reg_writeb(hdata, HDMI_AUI_CON, enable ?
1127                        HDMI_AVI_CON_EVERY_VSYNC : HDMI_AUI_CON_NO_TRAN);
1128        hdmi_reg_writemask(hdata, HDMI_CON_0, enable ?
1129                        HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1130}
1131
1132static void hdmi_start(struct hdmi_context *hdata, bool start)
1133{
1134        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1135        u32 val = start ? HDMI_TG_EN : 0;
1136
1137        if (m->flags & DRM_MODE_FLAG_INTERLACE)
1138                val |= HDMI_FIELD_EN;
1139
1140        hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1141        hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1142}
1143
1144static void hdmi_conf_init(struct hdmi_context *hdata)
1145{
1146        /* disable HPD interrupts from HDMI IP block, use GPIO instead */
1147        hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1148                HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1149
1150        /* choose HDMI mode */
1151        hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1152                HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1153        /* apply video pre-amble and guard band in HDMI mode only */
1154        hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1155        /* disable bluescreen */
1156        hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1157
1158        if (hdata->dvi_mode) {
1159                hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1160                                HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1161                hdmi_reg_writeb(hdata, HDMI_CON_2,
1162                                HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1163        }
1164
1165        if (hdata->drv_data->type == HDMI_TYPE13) {
1166                /* choose bluescreen (fecal) color */
1167                hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1168                hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1169                hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1170
1171                /* enable AVI packet every vsync, fixes purple line problem */
1172                hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1173                /* force RGB, look to CEA-861-D, table 7 for more detail */
1174                hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1175                hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1176
1177                hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1178                hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1179                hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1180        } else {
1181                hdmi_reg_infoframes(hdata);
1182
1183                /* enable AVI packet every vsync, fixes purple line problem */
1184                hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1185        }
1186}
1187
1188static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
1189{
1190        int tries;
1191
1192        for (tries = 0; tries < 10; ++tries) {
1193                u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
1194
1195                if (val & HDMI_PHY_STATUS_READY) {
1196                        DRM_DEV_DEBUG_KMS(hdata->dev,
1197                                          "PLL stabilized after %d tries\n",
1198                                          tries);
1199                        return;
1200                }
1201                usleep_range(10, 20);
1202        }
1203
1204        DRM_DEV_ERROR(hdata->dev, "PLL could not reach steady state\n");
1205}
1206
1207static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1208{
1209        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1210        unsigned int val;
1211
1212        hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1213        hdmi_reg_writev(hdata, HDMI_V13_H_V_LINE_0, 3,
1214                        (m->htotal << 12) | m->vtotal);
1215
1216        val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1217        hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, val);
1218
1219        val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1220        hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, val);
1221
1222        val = (m->hsync_start - m->hdisplay - 2);
1223        val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1224        val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
1225        hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1226
1227        /*
1228         * Quirk requirement for exynos HDMI IP design,
1229         * 2 pixels less than the actual calculation for hsync_start
1230         * and end.
1231         */
1232
1233        /* Following values & calculations differ for different type of modes */
1234        if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1235                val = ((m->vsync_end - m->vdisplay) / 2);
1236                val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1237                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1238
1239                val = m->vtotal / 2;
1240                val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1241                hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1242
1243                val = (m->vtotal +
1244                        ((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1245                val |= m->vtotal << 11;
1246                hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, val);
1247
1248                val = ((m->vtotal / 2) + 7);
1249                val |= ((m->vtotal / 2) + 2) << 12;
1250                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, val);
1251
1252                val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1253                val |= ((m->htotal / 2) +
1254                        (m->hsync_start - m->hdisplay)) << 12;
1255                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, val);
1256
1257                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1258                                (m->vtotal - m->vdisplay) / 2);
1259                hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1260
1261                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1262        } else {
1263                val = m->vtotal;
1264                val |= (m->vtotal - m->vdisplay) << 11;
1265                hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1266
1267                hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, 0);
1268
1269                val = (m->vsync_end - m->vdisplay);
1270                val |= ((m->vsync_start - m->vdisplay) << 12);
1271                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1272
1273                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, 0x1001);
1274                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, 0x1001);
1275                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1276                                m->vtotal - m->vdisplay);
1277                hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1278        }
1279
1280        hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1281        hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1282        hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1283        hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1284}
1285
1286static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1287{
1288        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1289        struct drm_display_mode *am =
1290                                &hdata->encoder.crtc->state->adjusted_mode;
1291        int hquirk = 0;
1292
1293        /*
1294         * In case video mode coming from CRTC differs from requested one HDMI
1295         * sometimes is able to almost properly perform conversion - only
1296         * first line is distorted.
1297         */
1298        if ((m->vdisplay != am->vdisplay) &&
1299            (m->hdisplay == 1280 || m->hdisplay == 1024 || m->hdisplay == 1366))
1300                hquirk = 258;
1301
1302        hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1303        hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1304        hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1305        hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
1306                        (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
1307        hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1308                        (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1309        hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
1310                        (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1311
1312        /*
1313         * Quirk requirement for exynos 5 HDMI IP design,
1314         * 2 pixels less than the actual calculation for hsync_start
1315         * and end.
1316         */
1317
1318        /* Following values & calculations differ for different type of modes */
1319        if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1320                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1321                        (m->vsync_end - m->vdisplay) / 2);
1322                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1323                        (m->vsync_start - m->vdisplay) / 2);
1324                hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal / 2);
1325                hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1326                                (m->vtotal - m->vdisplay) / 2);
1327                hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2,
1328                                m->vtotal - m->vdisplay / 2);
1329                hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, m->vtotal);
1330                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2,
1331                                (m->vtotal / 2) + 7);
1332                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2,
1333                                (m->vtotal / 2) + 2);
1334                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2,
1335                        (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1336                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2,
1337                        (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1338                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1339                                (m->vtotal - m->vdisplay) / 2);
1340                hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1341                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2,
1342                                m->vtotal - m->vdisplay / 2);
1343                hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2,
1344                                (m->vtotal / 2) + 1);
1345                hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2,
1346                                (m->vtotal / 2) + 1);
1347                hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2,
1348                                (m->vtotal / 2) + 1);
1349                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1350                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1351        } else {
1352                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1353                        m->vsync_end - m->vdisplay);
1354                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1355                        m->vsync_start - m->vdisplay);
1356                hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal);
1357                hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1358                                m->vtotal - m->vdisplay);
1359                hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2, 0xffff);
1360                hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, 0xffff);
1361                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2, 0xffff);
1362                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2, 0xffff);
1363                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2, 0xffff);
1364                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2, 0xffff);
1365                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1366                                m->vtotal - m->vdisplay);
1367                hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1368        }
1369
1370        hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1371                        m->hsync_start - m->hdisplay - 2);
1372        hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
1373                        m->hsync_end - m->hdisplay - 2);
1374        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_1_0, 2, 0xffff);
1375        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_2_0, 2, 0xffff);
1376        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_3_0, 2, 0xffff);
1377        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_4_0, 2, 0xffff);
1378        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_5_0, 2, 0xffff);
1379        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_6_0, 2, 0xffff);
1380        hdmi_reg_writev(hdata, HDMI_V_BLANK_F2_0, 2, 0xffff);
1381        hdmi_reg_writev(hdata, HDMI_V_BLANK_F3_0, 2, 0xffff);
1382        hdmi_reg_writev(hdata, HDMI_V_BLANK_F4_0, 2, 0xffff);
1383        hdmi_reg_writev(hdata, HDMI_V_BLANK_F5_0, 2, 0xffff);
1384        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 2, 0xffff);
1385        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 2, 0xffff);
1386        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 2, 0xffff);
1387        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 2, 0xffff);
1388        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 2, 0xffff);
1389        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 2, 0xffff);
1390        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1391        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
1392
1393        hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1394        hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2,
1395                                        m->htotal - m->hdisplay - hquirk);
1396        hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk);
1397        hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1398        if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1399                hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
1400}
1401
1402static void hdmi_mode_apply(struct hdmi_context *hdata)
1403{
1404        if (hdata->drv_data->type == HDMI_TYPE13)
1405                hdmi_v13_mode_apply(hdata);
1406        else
1407                hdmi_v14_mode_apply(hdata);
1408
1409        hdmi_start(hdata, true);
1410}
1411
1412static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1413{
1414        hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1);
1415        usleep_range(10000, 12000);
1416        hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1);
1417        usleep_range(10000, 12000);
1418        hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
1419        usleep_range(10000, 12000);
1420        hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
1421        usleep_range(10000, 12000);
1422}
1423
1424static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable)
1425{
1426        u8 v = enable ? HDMI_PHY_ENABLE_MODE_SET : HDMI_PHY_DISABLE_MODE_SET;
1427
1428        if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1429                writel(v, hdata->regs_hdmiphy + HDMIPHY5433_MODE_SET_DONE);
1430}
1431
1432static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1433{
1434        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1435        int ret;
1436        const u8 *phy_conf;
1437
1438        ret = hdmi_find_phy_conf(hdata, m->clock * 1000);
1439        if (ret < 0) {
1440                DRM_DEV_ERROR(hdata->dev, "failed to find hdmiphy conf\n");
1441                return;
1442        }
1443        phy_conf = hdata->drv_data->phy_confs.data[ret].conf;
1444
1445        hdmi_clk_set_parents(hdata, false);
1446
1447        hdmiphy_conf_reset(hdata);
1448
1449        hdmiphy_enable_mode_set(hdata, true);
1450        ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32);
1451        if (ret) {
1452                DRM_DEV_ERROR(hdata->dev, "failed to configure hdmiphy\n");
1453                return;
1454        }
1455        hdmiphy_enable_mode_set(hdata, false);
1456        hdmi_clk_set_parents(hdata, true);
1457        usleep_range(10000, 12000);
1458        hdmiphy_wait_for_pll(hdata);
1459}
1460
1461/* Should be called with hdata->mutex mutex held */
1462static void hdmi_conf_apply(struct hdmi_context *hdata)
1463{
1464        hdmi_start(hdata, false);
1465        hdmi_conf_init(hdata);
1466        hdmi_audio_config(hdata);
1467        hdmi_mode_apply(hdata);
1468        hdmi_audio_control(hdata);
1469}
1470
1471static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1472{
1473        if (!hdata->sysreg)
1474                return;
1475
1476        regmap_update_bits(hdata->sysreg, EXYNOS5433_SYSREG_DISP_HDMI_PHY,
1477                           SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1478}
1479
1480/* Should be called with hdata->mutex mutex held. */
1481static void hdmiphy_enable(struct hdmi_context *hdata)
1482{
1483        int ret;
1484
1485        if (hdata->powered)
1486                return;
1487
1488        ret = pm_runtime_resume_and_get(hdata->dev);
1489        if (ret < 0) {
1490                dev_err(hdata->dev, "failed to enable HDMIPHY device.\n");
1491                return;
1492        }
1493
1494        if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
1495                DRM_DEV_DEBUG_KMS(hdata->dev,
1496                                  "failed to enable regulator bulk\n");
1497
1498        regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1499                        PMU_HDMI_PHY_ENABLE_BIT, 1);
1500
1501        hdmi_set_refclk(hdata, true);
1502
1503        hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
1504
1505        hdmiphy_conf_apply(hdata);
1506
1507        hdata->powered = true;
1508}
1509
1510/* Should be called with hdata->mutex mutex held. */
1511static void hdmiphy_disable(struct hdmi_context *hdata)
1512{
1513        if (!hdata->powered)
1514                return;
1515
1516        hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1517
1518        hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
1519
1520        hdmi_set_refclk(hdata, false);
1521
1522        regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1523                        PMU_HDMI_PHY_ENABLE_BIT, 0);
1524
1525        regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1526
1527        pm_runtime_put_sync(hdata->dev);
1528
1529        hdata->powered = false;
1530}
1531
1532static void hdmi_enable(struct drm_encoder *encoder)
1533{
1534        struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1535
1536        mutex_lock(&hdata->mutex);
1537
1538        hdmiphy_enable(hdata);
1539        hdmi_conf_apply(hdata);
1540
1541        mutex_unlock(&hdata->mutex);
1542}
1543
1544static void hdmi_disable(struct drm_encoder *encoder)
1545{
1546        struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1547
1548        mutex_lock(&hdata->mutex);
1549
1550        if (hdata->powered) {
1551                /*
1552                 * The SFRs of VP and Mixer are updated by Vertical Sync of
1553                 * Timing generator which is a part of HDMI so the sequence
1554                 * to disable TV Subsystem should be as following,
1555                 *      VP -> Mixer -> HDMI
1556                 *
1557                 * To achieve such sequence HDMI is disabled together with
1558                 * HDMI PHY, via pipe clock callback.
1559                 */
1560                mutex_unlock(&hdata->mutex);
1561                cancel_delayed_work(&hdata->hotplug_work);
1562                if (hdata->notifier)
1563                        cec_notifier_phys_addr_invalidate(hdata->notifier);
1564                return;
1565        }
1566
1567        mutex_unlock(&hdata->mutex);
1568}
1569
1570static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
1571        .mode_fixup     = hdmi_mode_fixup,
1572        .enable         = hdmi_enable,
1573        .disable        = hdmi_disable,
1574};
1575
1576static void hdmi_audio_shutdown(struct device *dev, void *data)
1577{
1578        struct hdmi_context *hdata = dev_get_drvdata(dev);
1579
1580        mutex_lock(&hdata->mutex);
1581
1582        hdata->audio.mute = true;
1583
1584        if (hdata->powered)
1585                hdmi_audio_control(hdata);
1586
1587        mutex_unlock(&hdata->mutex);
1588}
1589
1590static int hdmi_audio_hw_params(struct device *dev, void *data,
1591                                struct hdmi_codec_daifmt *daifmt,
1592                                struct hdmi_codec_params *params)
1593{
1594        struct hdmi_context *hdata = dev_get_drvdata(dev);
1595
1596        if (daifmt->fmt != HDMI_I2S || daifmt->bit_clk_inv ||
1597            daifmt->frame_clk_inv || daifmt->bit_clk_master ||
1598            daifmt->frame_clk_master) {
1599                dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__,
1600                        daifmt->bit_clk_inv, daifmt->frame_clk_inv,
1601                        daifmt->bit_clk_master,
1602                        daifmt->frame_clk_master);
1603                return -EINVAL;
1604        }
1605
1606        mutex_lock(&hdata->mutex);
1607
1608        hdata->audio.params = *params;
1609
1610        if (hdata->powered) {
1611                hdmi_audio_config(hdata);
1612                hdmi_audio_infoframe_apply(hdata);
1613        }
1614
1615        mutex_unlock(&hdata->mutex);
1616
1617        return 0;
1618}
1619
1620static int hdmi_audio_mute(struct device *dev, void *data,
1621                           bool mute, int direction)
1622{
1623        struct hdmi_context *hdata = dev_get_drvdata(dev);
1624
1625        mutex_lock(&hdata->mutex);
1626
1627        hdata->audio.mute = mute;
1628
1629        if (hdata->powered)
1630                hdmi_audio_control(hdata);
1631
1632        mutex_unlock(&hdata->mutex);
1633
1634        return 0;
1635}
1636
1637static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
1638                              size_t len)
1639{
1640        struct hdmi_context *hdata = dev_get_drvdata(dev);
1641        struct drm_connector *connector = &hdata->connector;
1642
1643        memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
1644
1645        return 0;
1646}
1647
1648static const struct hdmi_codec_ops audio_codec_ops = {
1649        .hw_params = hdmi_audio_hw_params,
1650        .audio_shutdown = hdmi_audio_shutdown,
1651        .mute_stream = hdmi_audio_mute,
1652        .get_eld = hdmi_audio_get_eld,
1653        .no_capture_mute = 1,
1654};
1655
1656static int hdmi_register_audio_device(struct hdmi_context *hdata)
1657{
1658        struct hdmi_codec_pdata codec_data = {
1659                .ops = &audio_codec_ops,
1660                .max_i2s_channels = 6,
1661                .i2s = 1,
1662        };
1663
1664        hdata->audio.pdev = platform_device_register_data(
1665                hdata->dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
1666                &codec_data, sizeof(codec_data));
1667
1668        return PTR_ERR_OR_ZERO(hdata->audio.pdev);
1669}
1670
1671static void hdmi_hotplug_work_func(struct work_struct *work)
1672{
1673        struct hdmi_context *hdata;
1674
1675        hdata = container_of(work, struct hdmi_context, hotplug_work.work);
1676
1677        if (hdata->drm_dev)
1678                drm_helper_hpd_irq_event(hdata->drm_dev);
1679}
1680
1681static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1682{
1683        struct hdmi_context *hdata = arg;
1684
1685        mod_delayed_work(system_wq, &hdata->hotplug_work,
1686                        msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
1687
1688        return IRQ_HANDLED;
1689}
1690
1691static int hdmi_clks_get(struct hdmi_context *hdata,
1692                         const struct string_array_spec *names,
1693                         struct clk **clks)
1694{
1695        struct device *dev = hdata->dev;
1696        int i;
1697
1698        for (i = 0; i < names->count; ++i) {
1699                struct clk *clk = devm_clk_get(dev, names->data[i]);
1700
1701                if (IS_ERR(clk)) {
1702                        int ret = PTR_ERR(clk);
1703
1704                        dev_err(dev, "Cannot get clock %s, %d\n",
1705                                names->data[i], ret);
1706
1707                        return ret;
1708                }
1709
1710                clks[i] = clk;
1711        }
1712
1713        return 0;
1714}
1715
1716static int hdmi_clk_init(struct hdmi_context *hdata)
1717{
1718        const struct hdmi_driver_data *drv_data = hdata->drv_data;
1719        int count = drv_data->clk_gates.count + drv_data->clk_muxes.count;
1720        struct device *dev = hdata->dev;
1721        struct clk **clks;
1722        int ret;
1723
1724        if (!count)
1725                return 0;
1726
1727        clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL);
1728        if (!clks)
1729                return -ENOMEM;
1730
1731        hdata->clk_gates = clks;
1732        hdata->clk_muxes = clks + drv_data->clk_gates.count;
1733
1734        ret = hdmi_clks_get(hdata, &drv_data->clk_gates, hdata->clk_gates);
1735        if (ret)
1736                return ret;
1737
1738        return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes);
1739}
1740
1741
1742static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
1743{
1744        struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
1745                                                  phy_clk);
1746        mutex_lock(&hdata->mutex);
1747
1748        if (enable)
1749                hdmiphy_enable(hdata);
1750        else
1751                hdmiphy_disable(hdata);
1752
1753        mutex_unlock(&hdata->mutex);
1754}
1755
1756static int hdmi_bridge_init(struct hdmi_context *hdata)
1757{
1758        struct device *dev = hdata->dev;
1759        struct device_node *ep, *np;
1760
1761        ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1);
1762        if (!ep)
1763                return 0;
1764
1765        np = of_graph_get_remote_port_parent(ep);
1766        of_node_put(ep);
1767        if (!np) {
1768                DRM_DEV_ERROR(dev, "failed to get remote port parent");
1769                return -EINVAL;
1770        }
1771
1772        hdata->bridge = of_drm_find_bridge(np);
1773        of_node_put(np);
1774
1775        if (!hdata->bridge)
1776                return -EPROBE_DEFER;
1777
1778        return 0;
1779}
1780
1781static int hdmi_resources_init(struct hdmi_context *hdata)
1782{
1783        struct device *dev = hdata->dev;
1784        int i, ret;
1785
1786        DRM_DEV_DEBUG_KMS(dev, "HDMI resource init\n");
1787
1788        hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
1789        if (IS_ERR(hdata->hpd_gpio)) {
1790                DRM_DEV_ERROR(dev, "cannot get hpd gpio property\n");
1791                return PTR_ERR(hdata->hpd_gpio);
1792        }
1793
1794        hdata->irq = gpiod_to_irq(hdata->hpd_gpio);
1795        if (hdata->irq < 0) {
1796                DRM_DEV_ERROR(dev, "failed to get GPIO irq\n");
1797                return  hdata->irq;
1798        }
1799
1800        ret = hdmi_clk_init(hdata);
1801        if (ret)
1802                return ret;
1803
1804        ret = hdmi_clk_set_parents(hdata, false);
1805        if (ret)
1806                return ret;
1807
1808        for (i = 0; i < ARRAY_SIZE(supply); ++i)
1809                hdata->regul_bulk[i].supply = supply[i];
1810
1811        ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
1812        if (ret)
1813                return dev_err_probe(dev, ret, "failed to get regulators\n");
1814
1815        hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en");
1816
1817        if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV)
1818                if (IS_ERR(hdata->reg_hdmi_en))
1819                        return PTR_ERR(hdata->reg_hdmi_en);
1820
1821        return hdmi_bridge_init(hdata);
1822}
1823
1824static const struct of_device_id hdmi_match_types[] = {
1825        {
1826                .compatible = "samsung,exynos4210-hdmi",
1827                .data = &exynos4210_hdmi_driver_data,
1828        }, {
1829                .compatible = "samsung,exynos4212-hdmi",
1830                .data = &exynos4212_hdmi_driver_data,
1831        }, {
1832                .compatible = "samsung,exynos5420-hdmi",
1833                .data = &exynos5420_hdmi_driver_data,
1834        }, {
1835                .compatible = "samsung,exynos5433-hdmi",
1836                .data = &exynos5433_hdmi_driver_data,
1837        }, {
1838                /* end node */
1839        }
1840};
1841MODULE_DEVICE_TABLE (of, hdmi_match_types);
1842
1843static int hdmi_bind(struct device *dev, struct device *master, void *data)
1844{
1845        struct drm_device *drm_dev = data;
1846        struct hdmi_context *hdata = dev_get_drvdata(dev);
1847        struct drm_encoder *encoder = &hdata->encoder;
1848        struct exynos_drm_crtc *crtc;
1849        int ret;
1850
1851        hdata->drm_dev = drm_dev;
1852
1853        hdata->phy_clk.enable = hdmiphy_clk_enable;
1854
1855        drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
1856
1857        drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
1858
1859        ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_HDMI);
1860        if (ret < 0)
1861                return ret;
1862
1863        crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI);
1864        crtc->pipe_clk = &hdata->phy_clk;
1865
1866        ret = hdmi_create_connector(encoder);
1867        if (ret) {
1868                DRM_DEV_ERROR(dev, "failed to create connector ret = %d\n",
1869                              ret);
1870                drm_encoder_cleanup(encoder);
1871                return ret;
1872        }
1873
1874        return 0;
1875}
1876
1877static void hdmi_unbind(struct device *dev, struct device *master, void *data)
1878{
1879}
1880
1881static const struct component_ops hdmi_component_ops = {
1882        .bind   = hdmi_bind,
1883        .unbind = hdmi_unbind,
1884};
1885
1886static int hdmi_get_ddc_adapter(struct hdmi_context *hdata)
1887{
1888        const char *compatible_str = "samsung,exynos4210-hdmiddc";
1889        struct device_node *np;
1890        struct i2c_adapter *adpt;
1891
1892        np = of_find_compatible_node(NULL, NULL, compatible_str);
1893        if (np)
1894                np = of_get_next_parent(np);
1895        else
1896                np = of_parse_phandle(hdata->dev->of_node, "ddc", 0);
1897
1898        if (!np) {
1899                DRM_DEV_ERROR(hdata->dev,
1900                              "Failed to find ddc node in device tree\n");
1901                return -ENODEV;
1902        }
1903
1904        adpt = of_find_i2c_adapter_by_node(np);
1905        of_node_put(np);
1906
1907        if (!adpt) {
1908                DRM_INFO("Failed to get ddc i2c adapter by node\n");
1909                return -EPROBE_DEFER;
1910        }
1911
1912        hdata->ddc_adpt = adpt;
1913
1914        return 0;
1915}
1916
1917static int hdmi_get_phy_io(struct hdmi_context *hdata)
1918{
1919        const char *compatible_str = "samsung,exynos4212-hdmiphy";
1920        struct device_node *np;
1921        int ret = 0;
1922
1923        np = of_find_compatible_node(NULL, NULL, compatible_str);
1924        if (!np) {
1925                np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
1926                if (!np) {
1927                        DRM_DEV_ERROR(hdata->dev,
1928                                      "Failed to find hdmiphy node in device tree\n");
1929                        return -ENODEV;
1930                }
1931        }
1932
1933        if (hdata->drv_data->is_apb_phy) {
1934                hdata->regs_hdmiphy = of_iomap(np, 0);
1935                if (!hdata->regs_hdmiphy) {
1936                        DRM_DEV_ERROR(hdata->dev,
1937                                      "failed to ioremap hdmi phy\n");
1938                        ret = -ENOMEM;
1939                        goto out;
1940                }
1941        } else {
1942                hdata->hdmiphy_port = of_find_i2c_device_by_node(np);
1943                if (!hdata->hdmiphy_port) {
1944                        DRM_INFO("Failed to get hdmi phy i2c client\n");
1945                        ret = -EPROBE_DEFER;
1946                        goto out;
1947                }
1948        }
1949
1950out:
1951        of_node_put(np);
1952        return ret;
1953}
1954
1955static int hdmi_probe(struct platform_device *pdev)
1956{
1957        struct hdmi_audio_infoframe *audio_infoframe;
1958        struct device *dev = &pdev->dev;
1959        struct hdmi_context *hdata;
1960        int ret;
1961
1962        hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
1963        if (!hdata)
1964                return -ENOMEM;
1965
1966        hdata->drv_data = of_device_get_match_data(dev);
1967
1968        platform_set_drvdata(pdev, hdata);
1969
1970        hdata->dev = dev;
1971
1972        mutex_init(&hdata->mutex);
1973
1974        ret = hdmi_resources_init(hdata);
1975        if (ret) {
1976                if (ret != -EPROBE_DEFER)
1977                        DRM_DEV_ERROR(dev, "hdmi_resources_init failed\n");
1978                return ret;
1979        }
1980
1981        hdata->regs = devm_platform_ioremap_resource(pdev, 0);
1982        if (IS_ERR(hdata->regs)) {
1983                ret = PTR_ERR(hdata->regs);
1984                return ret;
1985        }
1986
1987        ret = hdmi_get_ddc_adapter(hdata);
1988        if (ret)
1989                return ret;
1990
1991        ret = hdmi_get_phy_io(hdata);
1992        if (ret)
1993                goto err_ddc;
1994
1995        INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
1996
1997        ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
1998                        hdmi_irq_thread, IRQF_TRIGGER_RISING |
1999                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2000                        "hdmi", hdata);
2001        if (ret) {
2002                DRM_DEV_ERROR(dev, "failed to register hdmi interrupt\n");
2003                goto err_hdmiphy;
2004        }
2005
2006        hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
2007                        "samsung,syscon-phandle");
2008        if (IS_ERR(hdata->pmureg)) {
2009                DRM_DEV_ERROR(dev, "syscon regmap lookup failed.\n");
2010                ret = -EPROBE_DEFER;
2011                goto err_hdmiphy;
2012        }
2013
2014        if (hdata->drv_data->has_sysreg) {
2015                hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
2016                                "samsung,sysreg-phandle");
2017                if (IS_ERR(hdata->sysreg)) {
2018                        DRM_DEV_ERROR(dev, "sysreg regmap lookup failed.\n");
2019                        ret = -EPROBE_DEFER;
2020                        goto err_hdmiphy;
2021                }
2022        }
2023
2024        if (!IS_ERR(hdata->reg_hdmi_en)) {
2025                ret = regulator_enable(hdata->reg_hdmi_en);
2026                if (ret) {
2027                        DRM_DEV_ERROR(dev,
2028                              "failed to enable hdmi-en regulator\n");
2029                        goto err_hdmiphy;
2030                }
2031        }
2032
2033        pm_runtime_enable(dev);
2034
2035        audio_infoframe = &hdata->audio.infoframe;
2036        hdmi_audio_infoframe_init(audio_infoframe);
2037        audio_infoframe->coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
2038        audio_infoframe->sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
2039        audio_infoframe->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
2040        audio_infoframe->channels = 2;
2041
2042        ret = hdmi_register_audio_device(hdata);
2043        if (ret)
2044                goto err_rpm_disable;
2045
2046        ret = component_add(&pdev->dev, &hdmi_component_ops);
2047        if (ret)
2048                goto err_unregister_audio;
2049
2050        return ret;
2051
2052err_unregister_audio:
2053        platform_device_unregister(hdata->audio.pdev);
2054
2055err_rpm_disable:
2056        pm_runtime_disable(dev);
2057        if (!IS_ERR(hdata->reg_hdmi_en))
2058                regulator_disable(hdata->reg_hdmi_en);
2059err_hdmiphy:
2060        if (hdata->hdmiphy_port)
2061                put_device(&hdata->hdmiphy_port->dev);
2062        if (hdata->regs_hdmiphy)
2063                iounmap(hdata->regs_hdmiphy);
2064err_ddc:
2065        put_device(&hdata->ddc_adpt->dev);
2066
2067        return ret;
2068}
2069
2070static int hdmi_remove(struct platform_device *pdev)
2071{
2072        struct hdmi_context *hdata = platform_get_drvdata(pdev);
2073
2074        cancel_delayed_work_sync(&hdata->hotplug_work);
2075
2076        component_del(&pdev->dev, &hdmi_component_ops);
2077        platform_device_unregister(hdata->audio.pdev);
2078
2079        pm_runtime_disable(&pdev->dev);
2080
2081        if (!IS_ERR(hdata->reg_hdmi_en))
2082                regulator_disable(hdata->reg_hdmi_en);
2083
2084        if (hdata->hdmiphy_port)
2085                put_device(&hdata->hdmiphy_port->dev);
2086
2087        if (hdata->regs_hdmiphy)
2088                iounmap(hdata->regs_hdmiphy);
2089
2090        put_device(&hdata->ddc_adpt->dev);
2091
2092        mutex_destroy(&hdata->mutex);
2093
2094        return 0;
2095}
2096
2097static int __maybe_unused exynos_hdmi_suspend(struct device *dev)
2098{
2099        struct hdmi_context *hdata = dev_get_drvdata(dev);
2100
2101        hdmi_clk_disable_gates(hdata);
2102
2103        return 0;
2104}
2105
2106static int __maybe_unused exynos_hdmi_resume(struct device *dev)
2107{
2108        struct hdmi_context *hdata = dev_get_drvdata(dev);
2109        int ret;
2110
2111        ret = hdmi_clk_enable_gates(hdata);
2112        if (ret < 0)
2113                return ret;
2114
2115        return 0;
2116}
2117
2118static const struct dev_pm_ops exynos_hdmi_pm_ops = {
2119        SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
2120        SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
2121                                pm_runtime_force_resume)
2122};
2123
2124struct platform_driver hdmi_driver = {
2125        .probe          = hdmi_probe,
2126        .remove         = hdmi_remove,
2127        .driver         = {
2128                .name   = "exynos-hdmi",
2129                .owner  = THIS_MODULE,
2130                .pm     = &exynos_hdmi_pm_ops,
2131                .of_match_table = hdmi_match_types,
2132        },
2133};
2134