Linux Audio

Check our new training course

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