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