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/drmP.h>
  13#include <drm/drm_atomic_helper.h>
  14#include <drm/drm_edid.h>
  15#include <drm/drm_probe_helper.h>
  16
  17#include "regs-hdmi.h"
  18
  19#include <linux/kernel.h>
  20#include <linux/wait.h>
  21#include <linux/i2c.h>
  22#include <linux/platform_device.h>
  23#include <linux/interrupt.h>
  24#include <linux/irq.h>
  25#include <linux/delay.h>
  26#include <linux/pm_runtime.h>
  27#include <linux/clk.h>
  28#include <linux/gpio/consumer.h>
  29#include <linux/regulator/consumer.h>
  30#include <linux/io.h>
  31#include <linux/of_address.h>
  32#include <linux/of_device.h>
  33#include <linux/of_graph.h>
  34#include <linux/hdmi.h>
  35#include <linux/component.h>
  36#include <linux/mfd/syscon.h>
  37#include <linux/regmap.h>
  38#include <sound/hdmi-codec.h>
  39#include <drm/exynos_drm.h>
  40
  41#include <media/cec-notifier.h>
  42
  43#include "exynos_drm_crtc.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        drm_connector_unregister(connector);
 857        drm_connector_cleanup(connector);
 858}
 859
 860static const struct drm_connector_funcs hdmi_connector_funcs = {
 861        .fill_modes = drm_helper_probe_single_connector_modes,
 862        .detect = hdmi_detect,
 863        .destroy = hdmi_connector_destroy,
 864        .reset = drm_atomic_helper_connector_reset,
 865        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 866        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 867};
 868
 869static int hdmi_get_modes(struct drm_connector *connector)
 870{
 871        struct hdmi_context *hdata = connector_to_hdmi(connector);
 872        struct edid *edid;
 873        int ret;
 874
 875        if (!hdata->ddc_adpt)
 876                return -ENODEV;
 877
 878        edid = drm_get_edid(connector, hdata->ddc_adpt);
 879        if (!edid)
 880                return -ENODEV;
 881
 882        hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
 883        DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n",
 884                          (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
 885                          edid->width_cm, edid->height_cm);
 886
 887        drm_connector_update_edid_property(connector, edid);
 888        cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid);
 889
 890        ret = drm_add_edid_modes(connector, edid);
 891
 892        kfree(edid);
 893
 894        return ret;
 895}
 896
 897static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
 898{
 899        const struct hdmiphy_configs *confs = &hdata->drv_data->phy_confs;
 900        int i;
 901
 902        for (i = 0; i < confs->count; i++)
 903                if (confs->data[i].pixel_clock == pixel_clock)
 904                        return i;
 905
 906        DRM_DEV_DEBUG_KMS(hdata->dev, "Could not find phy config for %d\n",
 907                          pixel_clock);
 908        return -EINVAL;
 909}
 910
 911static int hdmi_mode_valid(struct drm_connector *connector,
 912                        struct drm_display_mode *mode)
 913{
 914        struct hdmi_context *hdata = connector_to_hdmi(connector);
 915        int ret;
 916
 917        DRM_DEV_DEBUG_KMS(hdata->dev,
 918                          "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
 919                          mode->hdisplay, mode->vdisplay, mode->vrefresh,
 920                          (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
 921                          false, mode->clock * 1000);
 922
 923        ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
 924        if (ret < 0)
 925                return MODE_BAD;
 926
 927        return MODE_OK;
 928}
 929
 930static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
 931        .get_modes = hdmi_get_modes,
 932        .mode_valid = hdmi_mode_valid,
 933};
 934
 935static int hdmi_create_connector(struct drm_encoder *encoder)
 936{
 937        struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 938        struct drm_connector *connector = &hdata->connector;
 939        int ret;
 940
 941        connector->interlace_allowed = true;
 942        connector->polled = DRM_CONNECTOR_POLL_HPD;
 943
 944        ret = drm_connector_init(hdata->drm_dev, connector,
 945                        &hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
 946        if (ret) {
 947                DRM_DEV_ERROR(hdata->dev,
 948                              "Failed to initialize connector with drm\n");
 949                return ret;
 950        }
 951
 952        drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
 953        drm_connector_attach_encoder(connector, encoder);
 954
 955        if (hdata->bridge) {
 956                ret = drm_bridge_attach(encoder, hdata->bridge, NULL);
 957                if (ret)
 958                        DRM_DEV_ERROR(hdata->dev, "Failed to attach bridge\n");
 959        }
 960
 961        return ret;
 962}
 963
 964static bool hdmi_mode_fixup(struct drm_encoder *encoder,
 965                            const struct drm_display_mode *mode,
 966                            struct drm_display_mode *adjusted_mode)
 967{
 968        struct drm_device *dev = encoder->dev;
 969        struct drm_connector *connector;
 970        struct drm_display_mode *m;
 971        struct drm_connector_list_iter conn_iter;
 972        int mode_ok;
 973
 974        drm_mode_set_crtcinfo(adjusted_mode, 0);
 975
 976        drm_connector_list_iter_begin(dev, &conn_iter);
 977        drm_for_each_connector_iter(connector, &conn_iter) {
 978                if (connector->encoder == encoder)
 979                        break;
 980        }
 981        if (connector)
 982                drm_connector_get(connector);
 983        drm_connector_list_iter_end(&conn_iter);
 984
 985        if (!connector)
 986                return true;
 987
 988        mode_ok = hdmi_mode_valid(connector, adjusted_mode);
 989
 990        if (mode_ok == MODE_OK)
 991                goto cleanup;
 992
 993        /*
 994         * Find the most suitable mode and copy it to adjusted_mode.
 995         */
 996        list_for_each_entry(m, &connector->modes, head) {
 997                mode_ok = hdmi_mode_valid(connector, m);
 998
 999                if (mode_ok == MODE_OK) {
1000                        DRM_INFO("desired mode doesn't exist so\n");
1001                        DRM_INFO("use the most suitable mode among modes.\n");
1002
1003                        DRM_DEV_DEBUG_KMS(dev->dev,
1004                                          "Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1005                                          m->hdisplay, m->vdisplay,
1006                                          m->vrefresh);
1007
1008                        drm_mode_copy(adjusted_mode, m);
1009                        break;
1010                }
1011        }
1012
1013cleanup:
1014        drm_connector_put(connector);
1015
1016        return true;
1017}
1018
1019static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
1020{
1021        u32 n, cts;
1022
1023        cts = (freq % 9) ? 27000 : 30000;
1024        n = 128 * freq / (27000000 / cts);
1025
1026        hdmi_reg_writev(hdata, HDMI_ACR_N0, 3, n);
1027        hdmi_reg_writev(hdata, HDMI_ACR_MCTS0, 3, cts);
1028        hdmi_reg_writev(hdata, HDMI_ACR_CTS0, 3, cts);
1029        hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1030}
1031
1032static void hdmi_audio_config(struct hdmi_context *hdata)
1033{
1034        u32 bit_ch = 1;
1035        u32 data_num, val;
1036        int i;
1037
1038        switch (hdata->audio.params.sample_width) {
1039        case 20:
1040                data_num = 2;
1041                break;
1042        case 24:
1043                data_num = 3;
1044                break;
1045        default:
1046                data_num = 1;
1047                bit_ch = 0;
1048                break;
1049        }
1050
1051        hdmi_reg_acr(hdata, hdata->audio.params.sample_rate);
1052
1053        hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1054                                | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1055                                | HDMI_I2S_MUX_ENABLE);
1056
1057        hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1058                        | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1059
1060        hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1061        hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1062        hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1063
1064        val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1065        hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1066
1067        /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1068        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1069                        | HDMI_I2S_SEL_LRCK(6));
1070
1071        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(3)
1072                        | HDMI_I2S_SEL_SDATA0(4));
1073
1074        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1075                        | HDMI_I2S_SEL_SDATA2(2));
1076
1077        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1078
1079        /* I2S_CON_1 & 2 */
1080        hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1081                        | HDMI_I2S_L_CH_LOW_POL);
1082        hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1083                        | HDMI_I2S_SET_BIT_CH(bit_ch)
1084                        | HDMI_I2S_SET_SDATA_BIT(data_num)
1085                        | HDMI_I2S_BASIC_FORMAT);
1086
1087        /* Configuration of the audio channel status registers */
1088        for (i = 0; i < HDMI_I2S_CH_ST_MAXNUM; i++)
1089                hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST(i),
1090                                hdata->audio.params.iec.status[i]);
1091
1092        hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1093}
1094
1095static void hdmi_audio_control(struct hdmi_context *hdata)
1096{
1097        bool enable = !hdata->audio.mute;
1098
1099        if (hdata->dvi_mode)
1100                return;
1101
1102        hdmi_reg_writeb(hdata, HDMI_AUI_CON, enable ?
1103                        HDMI_AVI_CON_EVERY_VSYNC : HDMI_AUI_CON_NO_TRAN);
1104        hdmi_reg_writemask(hdata, HDMI_CON_0, enable ?
1105                        HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1106}
1107
1108static void hdmi_start(struct hdmi_context *hdata, bool start)
1109{
1110        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1111        u32 val = start ? HDMI_TG_EN : 0;
1112
1113        if (m->flags & DRM_MODE_FLAG_INTERLACE)
1114                val |= HDMI_FIELD_EN;
1115
1116        hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1117        hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1118}
1119
1120static void hdmi_conf_init(struct hdmi_context *hdata)
1121{
1122        /* disable HPD interrupts from HDMI IP block, use GPIO instead */
1123        hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1124                HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1125
1126        /* choose HDMI mode */
1127        hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1128                HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1129        /* apply video pre-amble and guard band in HDMI mode only */
1130        hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1131        /* disable bluescreen */
1132        hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1133
1134        if (hdata->dvi_mode) {
1135                hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1136                                HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1137                hdmi_reg_writeb(hdata, HDMI_CON_2,
1138                                HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1139        }
1140
1141        if (hdata->drv_data->type == HDMI_TYPE13) {
1142                /* choose bluescreen (fecal) color */
1143                hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1144                hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1145                hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1146
1147                /* enable AVI packet every vsync, fixes purple line problem */
1148                hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1149                /* force RGB, look to CEA-861-D, table 7 for more detail */
1150                hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1151                hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1152
1153                hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1154                hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1155                hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1156        } else {
1157                hdmi_reg_infoframes(hdata);
1158
1159                /* enable AVI packet every vsync, fixes purple line problem */
1160                hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1161        }
1162}
1163
1164static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
1165{
1166        int tries;
1167
1168        for (tries = 0; tries < 10; ++tries) {
1169                u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
1170
1171                if (val & HDMI_PHY_STATUS_READY) {
1172                        DRM_DEV_DEBUG_KMS(hdata->dev,
1173                                          "PLL stabilized after %d tries\n",
1174                                          tries);
1175                        return;
1176                }
1177                usleep_range(10, 20);
1178        }
1179
1180        DRM_DEV_ERROR(hdata->dev, "PLL could not reach steady state\n");
1181}
1182
1183static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1184{
1185        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1186        unsigned int val;
1187
1188        hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1189        hdmi_reg_writev(hdata, HDMI_V13_H_V_LINE_0, 3,
1190                        (m->htotal << 12) | m->vtotal);
1191
1192        val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1193        hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, val);
1194
1195        val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1196        hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, val);
1197
1198        val = (m->hsync_start - m->hdisplay - 2);
1199        val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1200        val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
1201        hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1202
1203        /*
1204         * Quirk requirement for exynos HDMI IP design,
1205         * 2 pixels less than the actual calculation for hsync_start
1206         * and end.
1207         */
1208
1209        /* Following values & calculations differ for different type of modes */
1210        if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1211                val = ((m->vsync_end - m->vdisplay) / 2);
1212                val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1213                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1214
1215                val = m->vtotal / 2;
1216                val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1217                hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1218
1219                val = (m->vtotal +
1220                        ((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1221                val |= m->vtotal << 11;
1222                hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, val);
1223
1224                val = ((m->vtotal / 2) + 7);
1225                val |= ((m->vtotal / 2) + 2) << 12;
1226                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, val);
1227
1228                val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1229                val |= ((m->htotal / 2) +
1230                        (m->hsync_start - m->hdisplay)) << 12;
1231                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, val);
1232
1233                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1234                                (m->vtotal - m->vdisplay) / 2);
1235                hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1236
1237                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1238        } else {
1239                val = m->vtotal;
1240                val |= (m->vtotal - m->vdisplay) << 11;
1241                hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1242
1243                hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, 0);
1244
1245                val = (m->vsync_end - m->vdisplay);
1246                val |= ((m->vsync_start - m->vdisplay) << 12);
1247                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1248
1249                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, 0x1001);
1250                hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, 0x1001);
1251                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1252                                m->vtotal - m->vdisplay);
1253                hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1254        }
1255
1256        hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1257        hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1258        hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1259        hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1260}
1261
1262static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1263{
1264        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1265        struct drm_display_mode *am =
1266                                &hdata->encoder.crtc->state->adjusted_mode;
1267        int hquirk = 0;
1268
1269        /*
1270         * In case video mode coming from CRTC differs from requested one HDMI
1271         * sometimes is able to almost properly perform conversion - only
1272         * first line is distorted.
1273         */
1274        if ((m->vdisplay != am->vdisplay) &&
1275            (m->hdisplay == 1280 || m->hdisplay == 1024 || m->hdisplay == 1366))
1276                hquirk = 258;
1277
1278        hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1279        hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1280        hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1281        hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
1282                        (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
1283        hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1284                        (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1285        hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
1286                        (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1287
1288        /*
1289         * Quirk requirement for exynos 5 HDMI IP design,
1290         * 2 pixels less than the actual calculation for hsync_start
1291         * and end.
1292         */
1293
1294        /* Following values & calculations differ for different type of modes */
1295        if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1296                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1297                        (m->vsync_end - m->vdisplay) / 2);
1298                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1299                        (m->vsync_start - m->vdisplay) / 2);
1300                hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal / 2);
1301                hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1302                                (m->vtotal - m->vdisplay) / 2);
1303                hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2,
1304                                m->vtotal - m->vdisplay / 2);
1305                hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, m->vtotal);
1306                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2,
1307                                (m->vtotal / 2) + 7);
1308                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2,
1309                                (m->vtotal / 2) + 2);
1310                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2,
1311                        (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1312                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2,
1313                        (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1314                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1315                                (m->vtotal - m->vdisplay) / 2);
1316                hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1317                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2,
1318                                m->vtotal - m->vdisplay / 2);
1319                hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2,
1320                                (m->vtotal / 2) + 1);
1321                hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2,
1322                                (m->vtotal / 2) + 1);
1323                hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2,
1324                                (m->vtotal / 2) + 1);
1325                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1326                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1327        } else {
1328                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1329                        m->vsync_end - m->vdisplay);
1330                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1331                        m->vsync_start - m->vdisplay);
1332                hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal);
1333                hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1334                                m->vtotal - m->vdisplay);
1335                hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2, 0xffff);
1336                hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, 0xffff);
1337                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2, 0xffff);
1338                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2, 0xffff);
1339                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2, 0xffff);
1340                hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2, 0xffff);
1341                hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1342                                m->vtotal - m->vdisplay);
1343                hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1344        }
1345
1346        hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1347                        m->hsync_start - m->hdisplay - 2);
1348        hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
1349                        m->hsync_end - m->hdisplay - 2);
1350        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_1_0, 2, 0xffff);
1351        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_2_0, 2, 0xffff);
1352        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_3_0, 2, 0xffff);
1353        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_4_0, 2, 0xffff);
1354        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_5_0, 2, 0xffff);
1355        hdmi_reg_writev(hdata, HDMI_VACT_SPACE_6_0, 2, 0xffff);
1356        hdmi_reg_writev(hdata, HDMI_V_BLANK_F2_0, 2, 0xffff);
1357        hdmi_reg_writev(hdata, HDMI_V_BLANK_F3_0, 2, 0xffff);
1358        hdmi_reg_writev(hdata, HDMI_V_BLANK_F4_0, 2, 0xffff);
1359        hdmi_reg_writev(hdata, HDMI_V_BLANK_F5_0, 2, 0xffff);
1360        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 2, 0xffff);
1361        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 2, 0xffff);
1362        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 2, 0xffff);
1363        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 2, 0xffff);
1364        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 2, 0xffff);
1365        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 2, 0xffff);
1366        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1367        hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
1368
1369        hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1370        hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2,
1371                                        m->htotal - m->hdisplay - hquirk);
1372        hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk);
1373        hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1374        if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1375                hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
1376}
1377
1378static void hdmi_mode_apply(struct hdmi_context *hdata)
1379{
1380        if (hdata->drv_data->type == HDMI_TYPE13)
1381                hdmi_v13_mode_apply(hdata);
1382        else
1383                hdmi_v14_mode_apply(hdata);
1384
1385        hdmi_start(hdata, true);
1386}
1387
1388static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1389{
1390        hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1);
1391        usleep_range(10000, 12000);
1392        hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1);
1393        usleep_range(10000, 12000);
1394        hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
1395        usleep_range(10000, 12000);
1396        hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
1397        usleep_range(10000, 12000);
1398}
1399
1400static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable)
1401{
1402        u8 v = enable ? HDMI_PHY_ENABLE_MODE_SET : HDMI_PHY_DISABLE_MODE_SET;
1403
1404        if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1405                writel(v, hdata->regs_hdmiphy + HDMIPHY5433_MODE_SET_DONE);
1406}
1407
1408static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1409{
1410        struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1411        int ret;
1412        const u8 *phy_conf;
1413
1414        ret = hdmi_find_phy_conf(hdata, m->clock * 1000);
1415        if (ret < 0) {
1416                DRM_DEV_ERROR(hdata->dev, "failed to find hdmiphy conf\n");
1417                return;
1418        }
1419        phy_conf = hdata->drv_data->phy_confs.data[ret].conf;
1420
1421        hdmi_clk_set_parents(hdata, false);
1422
1423        hdmiphy_conf_reset(hdata);
1424
1425        hdmiphy_enable_mode_set(hdata, true);
1426        ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32);
1427        if (ret) {
1428                DRM_DEV_ERROR(hdata->dev, "failed to configure hdmiphy\n");
1429                return;
1430        }
1431        hdmiphy_enable_mode_set(hdata, false);
1432        hdmi_clk_set_parents(hdata, true);
1433        usleep_range(10000, 12000);
1434        hdmiphy_wait_for_pll(hdata);
1435}
1436
1437/* Should be called with hdata->mutex mutex held */
1438static void hdmi_conf_apply(struct hdmi_context *hdata)
1439{
1440        hdmi_start(hdata, false);
1441        hdmi_conf_init(hdata);
1442        hdmi_audio_config(hdata);
1443        hdmi_mode_apply(hdata);
1444        hdmi_audio_control(hdata);
1445}
1446
1447static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1448{
1449        if (!hdata->sysreg)
1450                return;
1451
1452        regmap_update_bits(hdata->sysreg, EXYNOS5433_SYSREG_DISP_HDMI_PHY,
1453                           SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1454}
1455
1456/* Should be called with hdata->mutex mutex held. */
1457static void hdmiphy_enable(struct hdmi_context *hdata)
1458{
1459        if (hdata->powered)
1460                return;
1461
1462        pm_runtime_get_sync(hdata->dev);
1463
1464        if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
1465                DRM_DEV_DEBUG_KMS(hdata->dev,
1466                                  "failed to enable regulator bulk\n");
1467
1468        regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1469                        PMU_HDMI_PHY_ENABLE_BIT, 1);
1470
1471        hdmi_set_refclk(hdata, true);
1472
1473        hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
1474
1475        hdmiphy_conf_apply(hdata);
1476
1477        hdata->powered = true;
1478}
1479
1480/* Should be called with hdata->mutex mutex held. */
1481static void hdmiphy_disable(struct hdmi_context *hdata)
1482{
1483        if (!hdata->powered)
1484                return;
1485
1486        hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1487
1488        hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
1489
1490        hdmi_set_refclk(hdata, false);
1491
1492        regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1493                        PMU_HDMI_PHY_ENABLE_BIT, 0);
1494
1495        regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1496
1497        pm_runtime_put_sync(hdata->dev);
1498
1499        hdata->powered = false;
1500}
1501
1502static void hdmi_enable(struct drm_encoder *encoder)
1503{
1504        struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1505
1506        mutex_lock(&hdata->mutex);
1507
1508        hdmiphy_enable(hdata);
1509        hdmi_conf_apply(hdata);
1510
1511        mutex_unlock(&hdata->mutex);
1512}
1513
1514static void hdmi_disable(struct drm_encoder *encoder)
1515{
1516        struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1517
1518        mutex_lock(&hdata->mutex);
1519
1520        if (hdata->powered) {
1521                /*
1522                 * The SFRs of VP and Mixer are updated by Vertical Sync of
1523                 * Timing generator which is a part of HDMI so the sequence
1524                 * to disable TV Subsystem should be as following,
1525                 *      VP -> Mixer -> HDMI
1526                 *
1527                 * To achieve such sequence HDMI is disabled together with
1528                 * HDMI PHY, via pipe clock callback.
1529                 */
1530                mutex_unlock(&hdata->mutex);
1531                cancel_delayed_work(&hdata->hotplug_work);
1532                cec_notifier_set_phys_addr(hdata->notifier,
1533                                           CEC_PHYS_ADDR_INVALID);
1534                return;
1535        }
1536
1537        mutex_unlock(&hdata->mutex);
1538}
1539
1540static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
1541        .mode_fixup     = hdmi_mode_fixup,
1542        .enable         = hdmi_enable,
1543        .disable        = hdmi_disable,
1544};
1545
1546static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
1547        .destroy = drm_encoder_cleanup,
1548};
1549
1550static void hdmi_audio_shutdown(struct device *dev, void *data)
1551{
1552        struct hdmi_context *hdata = dev_get_drvdata(dev);
1553
1554        mutex_lock(&hdata->mutex);
1555
1556        hdata->audio.mute = true;
1557
1558        if (hdata->powered)
1559                hdmi_audio_control(hdata);
1560
1561        mutex_unlock(&hdata->mutex);
1562}
1563
1564static int hdmi_audio_hw_params(struct device *dev, void *data,
1565                                struct hdmi_codec_daifmt *daifmt,
1566                                struct hdmi_codec_params *params)
1567{
1568        struct hdmi_context *hdata = dev_get_drvdata(dev);
1569
1570        if (daifmt->fmt != HDMI_I2S || daifmt->bit_clk_inv ||
1571            daifmt->frame_clk_inv || daifmt->bit_clk_master ||
1572            daifmt->frame_clk_master) {
1573                dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__,
1574                        daifmt->bit_clk_inv, daifmt->frame_clk_inv,
1575                        daifmt->bit_clk_master,
1576                        daifmt->frame_clk_master);
1577                return -EINVAL;
1578        }
1579
1580        mutex_lock(&hdata->mutex);
1581
1582        hdata->audio.params = *params;
1583
1584        if (hdata->powered) {
1585                hdmi_audio_config(hdata);
1586                hdmi_audio_infoframe_apply(hdata);
1587        }
1588
1589        mutex_unlock(&hdata->mutex);
1590
1591        return 0;
1592}
1593
1594static int hdmi_audio_digital_mute(struct device *dev, void *data, bool mute)
1595{
1596        struct hdmi_context *hdata = dev_get_drvdata(dev);
1597
1598        mutex_lock(&hdata->mutex);
1599
1600        hdata->audio.mute = mute;
1601
1602        if (hdata->powered)
1603                hdmi_audio_control(hdata);
1604
1605        mutex_unlock(&hdata->mutex);
1606
1607        return 0;
1608}
1609
1610static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
1611                              size_t len)
1612{
1613        struct hdmi_context *hdata = dev_get_drvdata(dev);
1614        struct drm_connector *connector = &hdata->connector;
1615
1616        memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
1617
1618        return 0;
1619}
1620
1621static const struct hdmi_codec_ops audio_codec_ops = {
1622        .hw_params = hdmi_audio_hw_params,
1623        .audio_shutdown = hdmi_audio_shutdown,
1624        .digital_mute = hdmi_audio_digital_mute,
1625        .get_eld = hdmi_audio_get_eld,
1626};
1627
1628static int hdmi_register_audio_device(struct hdmi_context *hdata)
1629{
1630        struct hdmi_codec_pdata codec_data = {
1631                .ops = &audio_codec_ops,
1632                .max_i2s_channels = 6,
1633                .i2s = 1,
1634        };
1635
1636        hdata->audio.pdev = platform_device_register_data(
1637                hdata->dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
1638                &codec_data, sizeof(codec_data));
1639
1640        return PTR_ERR_OR_ZERO(hdata->audio.pdev);
1641}
1642
1643static void hdmi_hotplug_work_func(struct work_struct *work)
1644{
1645        struct hdmi_context *hdata;
1646
1647        hdata = container_of(work, struct hdmi_context, hotplug_work.work);
1648
1649        if (hdata->drm_dev)
1650                drm_helper_hpd_irq_event(hdata->drm_dev);
1651}
1652
1653static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1654{
1655        struct hdmi_context *hdata = arg;
1656
1657        mod_delayed_work(system_wq, &hdata->hotplug_work,
1658                        msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
1659
1660        return IRQ_HANDLED;
1661}
1662
1663static int hdmi_clks_get(struct hdmi_context *hdata,
1664                         const struct string_array_spec *names,
1665                         struct clk **clks)
1666{
1667        struct device *dev = hdata->dev;
1668        int i;
1669
1670        for (i = 0; i < names->count; ++i) {
1671                struct clk *clk = devm_clk_get(dev, names->data[i]);
1672
1673                if (IS_ERR(clk)) {
1674                        int ret = PTR_ERR(clk);
1675
1676                        dev_err(dev, "Cannot get clock %s, %d\n",
1677                                names->data[i], ret);
1678
1679                        return ret;
1680                }
1681
1682                clks[i] = clk;
1683        }
1684
1685        return 0;
1686}
1687
1688static int hdmi_clk_init(struct hdmi_context *hdata)
1689{
1690        const struct hdmi_driver_data *drv_data = hdata->drv_data;
1691        int count = drv_data->clk_gates.count + drv_data->clk_muxes.count;
1692        struct device *dev = hdata->dev;
1693        struct clk **clks;
1694        int ret;
1695
1696        if (!count)
1697                return 0;
1698
1699        clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL);
1700        if (!clks)
1701                return -ENOMEM;
1702
1703        hdata->clk_gates = clks;
1704        hdata->clk_muxes = clks + drv_data->clk_gates.count;
1705
1706        ret = hdmi_clks_get(hdata, &drv_data->clk_gates, hdata->clk_gates);
1707        if (ret)
1708                return ret;
1709
1710        return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes);
1711}
1712
1713
1714static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
1715{
1716        struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
1717                                                  phy_clk);
1718        mutex_lock(&hdata->mutex);
1719
1720        if (enable)
1721                hdmiphy_enable(hdata);
1722        else
1723                hdmiphy_disable(hdata);
1724
1725        mutex_unlock(&hdata->mutex);
1726}
1727
1728static int hdmi_bridge_init(struct hdmi_context *hdata)
1729{
1730        struct device *dev = hdata->dev;
1731        struct device_node *ep, *np;
1732
1733        ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1);
1734        if (!ep)
1735                return 0;
1736
1737        np = of_graph_get_remote_port_parent(ep);
1738        of_node_put(ep);
1739        if (!np) {
1740                DRM_DEV_ERROR(dev, "failed to get remote port parent");
1741                return -EINVAL;
1742        }
1743
1744        hdata->bridge = of_drm_find_bridge(np);
1745        of_node_put(np);
1746
1747        if (!hdata->bridge)
1748                return -EPROBE_DEFER;
1749
1750        return 0;
1751}
1752
1753static int hdmi_resources_init(struct hdmi_context *hdata)
1754{
1755        struct device *dev = hdata->dev;
1756        int i, ret;
1757
1758        DRM_DEV_DEBUG_KMS(dev, "HDMI resource init\n");
1759
1760        hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
1761        if (IS_ERR(hdata->hpd_gpio)) {
1762                DRM_DEV_ERROR(dev, "cannot get hpd gpio property\n");
1763                return PTR_ERR(hdata->hpd_gpio);
1764        }
1765
1766        hdata->irq = gpiod_to_irq(hdata->hpd_gpio);
1767        if (hdata->irq < 0) {
1768                DRM_DEV_ERROR(dev, "failed to get GPIO irq\n");
1769                return  hdata->irq;
1770        }
1771
1772        ret = hdmi_clk_init(hdata);
1773        if (ret)
1774                return ret;
1775
1776        ret = hdmi_clk_set_parents(hdata, false);
1777        if (ret)
1778                return ret;
1779
1780        for (i = 0; i < ARRAY_SIZE(supply); ++i)
1781                hdata->regul_bulk[i].supply = supply[i];
1782
1783        ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
1784        if (ret) {
1785                if (ret != -EPROBE_DEFER)
1786                        DRM_DEV_ERROR(dev, "failed to get regulators\n");
1787                return ret;
1788        }
1789
1790        hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en");
1791
1792        if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV) {
1793                if (IS_ERR(hdata->reg_hdmi_en))
1794                        return PTR_ERR(hdata->reg_hdmi_en);
1795
1796                ret = regulator_enable(hdata->reg_hdmi_en);
1797                if (ret) {
1798                        DRM_DEV_ERROR(dev,
1799                                      "failed to enable hdmi-en regulator\n");
1800                        return ret;
1801                }
1802        }
1803
1804        return hdmi_bridge_init(hdata);
1805}
1806
1807static const struct of_device_id hdmi_match_types[] = {
1808        {
1809                .compatible = "samsung,exynos4210-hdmi",
1810                .data = &exynos4210_hdmi_driver_data,
1811        }, {
1812                .compatible = "samsung,exynos4212-hdmi",
1813                .data = &exynos4212_hdmi_driver_data,
1814        }, {
1815                .compatible = "samsung,exynos5420-hdmi",
1816                .data = &exynos5420_hdmi_driver_data,
1817        }, {
1818                .compatible = "samsung,exynos5433-hdmi",
1819                .data = &exynos5433_hdmi_driver_data,
1820        }, {
1821                /* end node */
1822        }
1823};
1824MODULE_DEVICE_TABLE (of, hdmi_match_types);
1825
1826static int hdmi_bind(struct device *dev, struct device *master, void *data)
1827{
1828        struct drm_device *drm_dev = data;
1829        struct hdmi_context *hdata = dev_get_drvdata(dev);
1830        struct drm_encoder *encoder = &hdata->encoder;
1831        struct exynos_drm_crtc *crtc;
1832        int ret;
1833
1834        hdata->drm_dev = drm_dev;
1835
1836        hdata->phy_clk.enable = hdmiphy_clk_enable;
1837
1838        drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
1839                         DRM_MODE_ENCODER_TMDS, NULL);
1840
1841        drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
1842
1843        ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_HDMI);
1844        if (ret < 0)
1845                return ret;
1846
1847        crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI);
1848        crtc->pipe_clk = &hdata->phy_clk;
1849
1850        ret = hdmi_create_connector(encoder);
1851        if (ret) {
1852                DRM_DEV_ERROR(dev, "failed to create connector ret = %d\n",
1853                              ret);
1854                drm_encoder_cleanup(encoder);
1855                return ret;
1856        }
1857
1858        return 0;
1859}
1860
1861static void hdmi_unbind(struct device *dev, struct device *master, void *data)
1862{
1863}
1864
1865static const struct component_ops hdmi_component_ops = {
1866        .bind   = hdmi_bind,
1867        .unbind = hdmi_unbind,
1868};
1869
1870static int hdmi_get_ddc_adapter(struct hdmi_context *hdata)
1871{
1872        const char *compatible_str = "samsung,exynos4210-hdmiddc";
1873        struct device_node *np;
1874        struct i2c_adapter *adpt;
1875
1876        np = of_find_compatible_node(NULL, NULL, compatible_str);
1877        if (np)
1878                np = of_get_next_parent(np);
1879        else
1880                np = of_parse_phandle(hdata->dev->of_node, "ddc", 0);
1881
1882        if (!np) {
1883                DRM_DEV_ERROR(hdata->dev,
1884                              "Failed to find ddc node in device tree\n");
1885                return -ENODEV;
1886        }
1887
1888        adpt = of_find_i2c_adapter_by_node(np);
1889        of_node_put(np);
1890
1891        if (!adpt) {
1892                DRM_INFO("Failed to get ddc i2c adapter by node\n");
1893                return -EPROBE_DEFER;
1894        }
1895
1896        hdata->ddc_adpt = adpt;
1897
1898        return 0;
1899}
1900
1901static int hdmi_get_phy_io(struct hdmi_context *hdata)
1902{
1903        const char *compatible_str = "samsung,exynos4212-hdmiphy";
1904        struct device_node *np;
1905        int ret = 0;
1906
1907        np = of_find_compatible_node(NULL, NULL, compatible_str);
1908        if (!np) {
1909                np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
1910                if (!np) {
1911                        DRM_DEV_ERROR(hdata->dev,
1912                                      "Failed to find hdmiphy node in device tree\n");
1913                        return -ENODEV;
1914                }
1915        }
1916
1917        if (hdata->drv_data->is_apb_phy) {
1918                hdata->regs_hdmiphy = of_iomap(np, 0);
1919                if (!hdata->regs_hdmiphy) {
1920                        DRM_DEV_ERROR(hdata->dev,
1921                                      "failed to ioremap hdmi phy\n");
1922                        ret = -ENOMEM;
1923                        goto out;
1924                }
1925        } else {
1926                hdata->hdmiphy_port = of_find_i2c_device_by_node(np);
1927                if (!hdata->hdmiphy_port) {
1928                        DRM_INFO("Failed to get hdmi phy i2c client\n");
1929                        ret = -EPROBE_DEFER;
1930                        goto out;
1931                }
1932        }
1933
1934out:
1935        of_node_put(np);
1936        return ret;
1937}
1938
1939static int hdmi_probe(struct platform_device *pdev)
1940{
1941        struct hdmi_audio_infoframe *audio_infoframe;
1942        struct device *dev = &pdev->dev;
1943        struct hdmi_context *hdata;
1944        struct resource *res;
1945        int ret;
1946
1947        hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
1948        if (!hdata)
1949                return -ENOMEM;
1950
1951        hdata->drv_data = of_device_get_match_data(dev);
1952
1953        platform_set_drvdata(pdev, hdata);
1954
1955        hdata->dev = dev;
1956
1957        mutex_init(&hdata->mutex);
1958
1959        ret = hdmi_resources_init(hdata);
1960        if (ret) {
1961                if (ret != -EPROBE_DEFER)
1962                        DRM_DEV_ERROR(dev, "hdmi_resources_init failed\n");
1963                return ret;
1964        }
1965
1966        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1967        hdata->regs = devm_ioremap_resource(dev, res);
1968        if (IS_ERR(hdata->regs)) {
1969                ret = PTR_ERR(hdata->regs);
1970                return ret;
1971        }
1972
1973        ret = hdmi_get_ddc_adapter(hdata);
1974        if (ret)
1975                return ret;
1976
1977        ret = hdmi_get_phy_io(hdata);
1978        if (ret)
1979                goto err_ddc;
1980
1981        INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
1982
1983        ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
1984                        hdmi_irq_thread, IRQF_TRIGGER_RISING |
1985                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1986                        "hdmi", hdata);
1987        if (ret) {
1988                DRM_DEV_ERROR(dev, "failed to register hdmi interrupt\n");
1989                goto err_hdmiphy;
1990        }
1991
1992        hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
1993                        "samsung,syscon-phandle");
1994        if (IS_ERR(hdata->pmureg)) {
1995                DRM_DEV_ERROR(dev, "syscon regmap lookup failed.\n");
1996                ret = -EPROBE_DEFER;
1997                goto err_hdmiphy;
1998        }
1999
2000        if (hdata->drv_data->has_sysreg) {
2001                hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
2002                                "samsung,sysreg-phandle");
2003                if (IS_ERR(hdata->sysreg)) {
2004                        DRM_DEV_ERROR(dev, "sysreg regmap lookup failed.\n");
2005                        ret = -EPROBE_DEFER;
2006                        goto err_hdmiphy;
2007                }
2008        }
2009
2010        hdata->notifier = cec_notifier_get(&pdev->dev);
2011        if (hdata->notifier == NULL) {
2012                ret = -ENOMEM;
2013                goto err_hdmiphy;
2014        }
2015
2016        pm_runtime_enable(dev);
2017
2018        audio_infoframe = &hdata->audio.infoframe;
2019        hdmi_audio_infoframe_init(audio_infoframe);
2020        audio_infoframe->coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
2021        audio_infoframe->sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
2022        audio_infoframe->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
2023        audio_infoframe->channels = 2;
2024
2025        ret = hdmi_register_audio_device(hdata);
2026        if (ret)
2027                goto err_notifier_put;
2028
2029        ret = component_add(&pdev->dev, &hdmi_component_ops);
2030        if (ret)
2031                goto err_unregister_audio;
2032
2033        return ret;
2034
2035err_unregister_audio:
2036        platform_device_unregister(hdata->audio.pdev);
2037
2038err_notifier_put:
2039        cec_notifier_put(hdata->notifier);
2040        pm_runtime_disable(dev);
2041
2042err_hdmiphy:
2043        if (hdata->hdmiphy_port)
2044                put_device(&hdata->hdmiphy_port->dev);
2045        if (hdata->regs_hdmiphy)
2046                iounmap(hdata->regs_hdmiphy);
2047err_ddc:
2048        put_device(&hdata->ddc_adpt->dev);
2049
2050        return ret;
2051}
2052
2053static int hdmi_remove(struct platform_device *pdev)
2054{
2055        struct hdmi_context *hdata = platform_get_drvdata(pdev);
2056
2057        cancel_delayed_work_sync(&hdata->hotplug_work);
2058        cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
2059
2060        component_del(&pdev->dev, &hdmi_component_ops);
2061        platform_device_unregister(hdata->audio.pdev);
2062
2063        cec_notifier_put(hdata->notifier);
2064        pm_runtime_disable(&pdev->dev);
2065
2066        if (!IS_ERR(hdata->reg_hdmi_en))
2067                regulator_disable(hdata->reg_hdmi_en);
2068
2069        if (hdata->hdmiphy_port)
2070                put_device(&hdata->hdmiphy_port->dev);
2071
2072        if (hdata->regs_hdmiphy)
2073                iounmap(hdata->regs_hdmiphy);
2074
2075        put_device(&hdata->ddc_adpt->dev);
2076
2077        mutex_destroy(&hdata->mutex);
2078
2079        return 0;
2080}
2081
2082static int __maybe_unused exynos_hdmi_suspend(struct device *dev)
2083{
2084        struct hdmi_context *hdata = dev_get_drvdata(dev);
2085
2086        hdmi_clk_disable_gates(hdata);
2087
2088        return 0;
2089}
2090
2091static int __maybe_unused exynos_hdmi_resume(struct device *dev)
2092{
2093        struct hdmi_context *hdata = dev_get_drvdata(dev);
2094        int ret;
2095
2096        ret = hdmi_clk_enable_gates(hdata);
2097        if (ret < 0)
2098                return ret;
2099
2100        return 0;
2101}
2102
2103static const struct dev_pm_ops exynos_hdmi_pm_ops = {
2104        SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
2105        SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
2106                                pm_runtime_force_resume)
2107};
2108
2109struct platform_driver hdmi_driver = {
2110        .probe          = hdmi_probe,
2111        .remove         = hdmi_remove,
2112        .driver         = {
2113                .name   = "exynos-hdmi",
2114                .owner  = THIS_MODULE,
2115                .pm     = &exynos_hdmi_pm_ops,
2116                .of_match_table = hdmi_match_types,
2117        },
2118};
2119