Linux Audio

Check our new training course

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