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