root/drivers/gpu/drm/exynos/exynos_hdmi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. encoder_to_hdmi
  2. connector_to_hdmi
  3. hdmi_map_reg
  4. hdmi_reg_read
  5. hdmi_reg_writeb
  6. hdmi_reg_writev
  7. hdmi_reg_write_buf
  8. hdmi_reg_writemask
  9. hdmiphy_reg_write_buf
  10. hdmi_clk_enable_gates
  11. hdmi_clk_disable_gates
  12. hdmi_clk_set_parents
  13. hdmi_audio_infoframe_apply
  14. hdmi_reg_infoframes
  15. hdmi_detect
  16. hdmi_connector_destroy
  17. hdmi_get_modes
  18. hdmi_find_phy_conf
  19. hdmi_mode_valid
  20. hdmi_create_connector
  21. hdmi_mode_fixup
  22. hdmi_reg_acr
  23. hdmi_audio_config
  24. hdmi_audio_control
  25. hdmi_start
  26. hdmi_conf_init
  27. hdmiphy_wait_for_pll
  28. hdmi_v13_mode_apply
  29. hdmi_v14_mode_apply
  30. hdmi_mode_apply
  31. hdmiphy_conf_reset
  32. hdmiphy_enable_mode_set
  33. hdmiphy_conf_apply
  34. hdmi_conf_apply
  35. hdmi_set_refclk
  36. hdmiphy_enable
  37. hdmiphy_disable
  38. hdmi_enable
  39. hdmi_disable
  40. hdmi_audio_shutdown
  41. hdmi_audio_hw_params
  42. hdmi_audio_digital_mute
  43. hdmi_audio_get_eld
  44. hdmi_register_audio_device
  45. hdmi_hotplug_work_func
  46. hdmi_irq_thread
  47. hdmi_clks_get
  48. hdmi_clk_init
  49. hdmiphy_clk_enable
  50. hdmi_bridge_init
  51. hdmi_resources_init
  52. hdmi_bind
  53. hdmi_unbind
  54. hdmi_get_ddc_adapter
  55. hdmi_get_phy_io
  56. hdmi_probe
  57. hdmi_remove
  58. exynos_hdmi_suspend
  59. exynos_hdmi_resume

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

/* [<][>][^][v][top][bottom][index][help] */