Linux Audio

Check our new training course

Loading...
v5.4
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Copyright (C) 2011 Samsung Electronics Co.Ltd
   4 * Authors:
   5 * Seung-Woo Kim <sw0312.kim@samsung.com>
   6 *	Inki Dae <inki.dae@samsung.com>
   7 *	Joonyoung Shim <jy0922.shim@samsung.com>
   8 *
   9 * Based on drivers/media/video/s5p-tv/hdmi_drv.c
 
 
 
 
 
 
  10 */
  11
  12#include <drm/exynos_drm.h>
  13#include <linux/clk.h>
  14#include <linux/component.h>
  15#include <linux/delay.h>
  16#include <linux/gpio/consumer.h>
  17#include <linux/hdmi.h>
 
 
 
  18#include <linux/i2c.h>
 
 
  19#include <linux/interrupt.h>
  20#include <linux/io.h>
  21#include <linux/irq.h>
  22#include <linux/kernel.h>
  23#include <linux/mfd/syscon.h>
  24#include <linux/of_address.h>
  25#include <linux/of_device.h>
  26#include <linux/of_graph.h>
  27#include <linux/platform_device.h>
  28#include <linux/pm_runtime.h>
  29#include <linux/regmap.h>
  30#include <linux/regulator/consumer.h>
  31#include <linux/wait.h>
  32
  33#include <sound/hdmi-codec.h>
  34#include <media/cec-notifier.h>
  35
  36#include <drm/drm_atomic_helper.h>
  37#include <drm/drm_edid.h>
  38#include <drm/drm_print.h>
  39#include <drm/drm_probe_helper.h>
  40
  41#include "exynos_drm_crtc.h"
  42#include "regs-hdmi.h"
  43
  44#define HOTPLUG_DEBOUNCE_MS		1100
  45
  46enum hdmi_type {
  47	HDMI_TYPE13,
  48	HDMI_TYPE14,
  49	HDMI_TYPE_COUNT
  50};
  51
  52#define HDMI_MAPPED_BASE 0xffff0000
  53
  54enum hdmi_mapped_regs {
  55	HDMI_PHY_STATUS = HDMI_MAPPED_BASE,
  56	HDMI_PHY_RSTOUT,
  57	HDMI_ACR_CON,
  58	HDMI_ACR_MCTS0,
  59	HDMI_ACR_CTS0,
  60	HDMI_ACR_N0
  61};
  62
  63static const u32 hdmi_reg_map[][HDMI_TYPE_COUNT] = {
  64	{ HDMI_V13_PHY_STATUS, HDMI_PHY_STATUS_0 },
  65	{ HDMI_V13_PHY_RSTOUT, HDMI_V14_PHY_RSTOUT },
  66	{ HDMI_V13_ACR_CON, HDMI_V14_ACR_CON },
  67	{ HDMI_V13_ACR_MCTS0, HDMI_V14_ACR_MCTS0 },
  68	{ HDMI_V13_ACR_CTS0, HDMI_V14_ACR_CTS0 },
  69	{ HDMI_V13_ACR_N0, HDMI_V14_ACR_N0 },
  70};
  71
  72static const char * const supply[] = {
  73	"vdd",
  74	"vdd_osc",
  75	"vdd_pll",
  76};
  77
  78struct hdmiphy_config {
  79	int pixel_clock;
  80	u8 conf[32];
  81};
  82
  83struct hdmiphy_configs {
  84	int count;
  85	const struct hdmiphy_config *data;
  86};
  87
  88struct string_array_spec {
  89	int count;
  90	const char * const *data;
  91};
  92
  93#define INIT_ARRAY_SPEC(a) { .count = ARRAY_SIZE(a), .data = a }
 
  94
  95struct hdmi_driver_data {
  96	unsigned int type;
  97	unsigned int is_apb_phy:1;
  98	unsigned int has_sysreg:1;
  99	struct hdmiphy_configs phy_confs;
 100	struct string_array_spec clk_gates;
 101	/*
 102	 * Array of triplets (p_off, p_on, clock), where p_off and p_on are
 103	 * required parents of clock when HDMI-PHY is respectively off or on.
 104	 */
 105	struct string_array_spec clk_muxes;
 106};
 107
 108struct hdmi_audio {
 109	struct platform_device		*pdev;
 110	struct hdmi_audio_infoframe	infoframe;
 111	struct hdmi_codec_params	params;
 112	bool				mute;
 
 
 
 
 
 
 
 113};
 114
 115struct hdmi_context {
 116	struct drm_encoder		encoder;
 117	struct device			*dev;
 118	struct drm_device		*drm_dev;
 119	struct drm_connector		connector;
 
 
 120	bool				dvi_mode;
 121	struct delayed_work		hotplug_work;
 122	struct cec_notifier		*notifier;
 123	const struct hdmi_driver_data	*drv_data;
 124
 
 125	void __iomem			*regs;
 126	void __iomem			*regs_hdmiphy;
 
 
 
 127	struct i2c_client		*hdmiphy_port;
 128	struct i2c_adapter		*ddc_adpt;
 129	struct gpio_desc		*hpd_gpio;
 130	int				irq;
 131	struct regmap			*pmureg;
 132	struct regmap			*sysreg;
 133	struct clk			**clk_gates;
 134	struct clk			**clk_muxes;
 135	struct regulator_bulk_data	regul_bulk[ARRAY_SIZE(supply)];
 136	struct regulator		*reg_hdmi_en;
 137	struct exynos_drm_clk		phy_clk;
 138	struct drm_bridge		*bridge;
 139
 140	/* mutex protecting subsequent fields below */
 141	struct mutex			mutex;
 142	struct hdmi_audio		audio;
 143	bool				powered;
 144};
 145
 146static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
 147{
 148	return container_of(e, struct hdmi_context, encoder);
 149}
 150
 151static inline struct hdmi_context *connector_to_hdmi(struct drm_connector *c)
 152{
 153	return container_of(c, struct hdmi_context, connector);
 154}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 155
 156static const struct hdmiphy_config hdmiphy_v13_configs[] = {
 157	{
 158		.pixel_clock = 27000000,
 159		.conf = {
 160			0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
 161			0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
 162			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
 163			0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
 164		},
 165	},
 166	{
 167		.pixel_clock = 27027000,
 168		.conf = {
 169			0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
 170			0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
 171			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
 172			0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
 173		},
 174	},
 175	{
 176		.pixel_clock = 74176000,
 177		.conf = {
 178			0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
 179			0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
 180			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
 181			0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x80,
 182		},
 183	},
 184	{
 185		.pixel_clock = 74250000,
 186		.conf = {
 187			0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
 188			0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
 189			0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
 190			0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x80,
 191		},
 192	},
 193	{
 194		.pixel_clock = 148500000,
 195		.conf = {
 196			0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
 197			0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
 198			0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
 199			0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x80,
 200		},
 201	},
 202};
 203
 204static const struct hdmiphy_config hdmiphy_v14_configs[] = {
 205	{
 206		.pixel_clock = 25200000,
 207		.conf = {
 208			0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
 209			0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 210			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 211			0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 212		},
 213	},
 214	{
 215		.pixel_clock = 27000000,
 216		.conf = {
 217			0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
 218			0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 219			0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 220			0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 221		},
 222	},
 223	{
 224		.pixel_clock = 27027000,
 225		.conf = {
 226			0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
 227			0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 228			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 229			0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 230		},
 231	},
 232	{
 233		.pixel_clock = 36000000,
 234		.conf = {
 235			0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
 236			0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 237			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 238			0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 239		},
 240	},
 241	{
 242		.pixel_clock = 40000000,
 243		.conf = {
 244			0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
 245			0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 246			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 247			0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 248		},
 249	},
 250	{
 251		.pixel_clock = 65000000,
 252		.conf = {
 253			0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
 254			0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 255			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 256			0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 257		},
 258	},
 259	{
 260		.pixel_clock = 71000000,
 261		.conf = {
 262			0x01, 0xd1, 0x3b, 0x35, 0x40, 0x0c, 0x04, 0x08,
 263			0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 264			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 265			0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 266		},
 267	},
 268	{
 269		.pixel_clock = 73250000,
 270		.conf = {
 271			0x01, 0xd1, 0x3d, 0x35, 0x40, 0x18, 0x02, 0x08,
 272			0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 273			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 274			0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 275		},
 276	},
 277	{
 278		.pixel_clock = 74176000,
 279		.conf = {
 280			0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
 281			0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 282			0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 283			0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 284		},
 285	},
 286	{
 287		.pixel_clock = 74250000,
 288		.conf = {
 289			0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
 290			0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 291			0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 292			0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 293		},
 294	},
 295	{
 296		.pixel_clock = 83500000,
 297		.conf = {
 298			0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
 299			0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 300			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 301			0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 302		},
 303	},
 304	{
 305		.pixel_clock = 85500000,
 306		.conf = {
 307			0x01, 0xd1, 0x24, 0x11, 0x40, 0x40, 0xd0, 0x08,
 308			0x84, 0xa0, 0xd6, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 309			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 310			0x54, 0x90, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 311		},
 312	},
 313	{
 314		.pixel_clock = 106500000,
 315		.conf = {
 316			0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
 317			0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 318			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 319			0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 320		},
 321	},
 322	{
 323		.pixel_clock = 108000000,
 324		.conf = {
 325			0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
 326			0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 327			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 328			0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 329		},
 330	},
 331	{
 332		.pixel_clock = 115500000,
 333		.conf = {
 334			0x01, 0xd1, 0x30, 0x12, 0x40, 0x40, 0x10, 0x08,
 335			0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 336			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 337			0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 338		},
 339	},
 340	{
 341		.pixel_clock = 119000000,
 342		.conf = {
 343			0x01, 0xd1, 0x32, 0x1a, 0x40, 0x30, 0xd8, 0x08,
 344			0x04, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 345			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 346			0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 347		},
 348	},
 349	{
 350		.pixel_clock = 146250000,
 351		.conf = {
 352			0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
 353			0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 354			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 355			0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 356		},
 357	},
 358	{
 359		.pixel_clock = 148500000,
 360		.conf = {
 361			0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
 362			0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 363			0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 364			0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 365		},
 366	},
 367};
 368
 369static const struct hdmiphy_config hdmiphy_5420_configs[] = {
 370	{
 371		.pixel_clock = 25200000,
 372		.conf = {
 373			0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
 374			0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 375			0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
 376			0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 377		},
 378	},
 379	{
 380		.pixel_clock = 27000000,
 381		.conf = {
 382			0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
 383			0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 384			0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 385			0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 386		},
 387	},
 388	{
 389		.pixel_clock = 27027000,
 390		.conf = {
 391			0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
 392			0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 393			0x26, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 394			0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 395		},
 396	},
 397	{
 398		.pixel_clock = 36000000,
 399		.conf = {
 400			0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
 401			0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 402			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 403			0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 404		},
 405	},
 406	{
 407		.pixel_clock = 40000000,
 408		.conf = {
 409			0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
 410			0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 411			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 412			0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 413		},
 414	},
 415	{
 416		.pixel_clock = 65000000,
 417		.conf = {
 418			0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
 419			0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 420			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 421			0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 422		},
 423	},
 424	{
 425		.pixel_clock = 71000000,
 426		.conf = {
 427			0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
 428			0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 429			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 430			0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 431		},
 432	},
 433	{
 434		.pixel_clock = 73250000,
 435		.conf = {
 436			0x01, 0xD1, 0x1F, 0x10, 0x40, 0x78, 0x8D, 0xC8,
 437			0x81, 0xE8, 0xB7, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 438			0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 439			0x54, 0xA8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 440		},
 441	},
 442	{
 443		.pixel_clock = 74176000,
 444		.conf = {
 445			0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
 446			0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 447			0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 448			0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 449		},
 450	},
 451	{
 452		.pixel_clock = 74250000,
 453		.conf = {
 454			0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
 455			0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 456			0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
 457			0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 458		},
 459	},
 460	{
 461		.pixel_clock = 83500000,
 462		.conf = {
 463			0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
 464			0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 465			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 466			0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 467		},
 468	},
 469	{
 470		.pixel_clock = 88750000,
 471		.conf = {
 472			0x01, 0xD1, 0x25, 0x11, 0x40, 0x18, 0xFF, 0xC8,
 473			0x83, 0xE8, 0xDE, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 474			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 475			0x54, 0x45, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 476		},
 477	},
 478	{
 479		.pixel_clock = 106500000,
 480		.conf = {
 481			0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
 482			0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 483			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 484			0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 485		},
 486	},
 487	{
 488		.pixel_clock = 108000000,
 489		.conf = {
 490			0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
 491			0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 492			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 493			0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 494		},
 495	},
 496	{
 497		.pixel_clock = 115500000,
 498		.conf = {
 499			0x01, 0xD1, 0x30, 0x14, 0x40, 0x0C, 0x03, 0xC8,
 500			0x88, 0xE8, 0x21, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 501			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 502			0x54, 0x6A, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 503		},
 504	},
 505	{
 506		.pixel_clock = 146250000,
 507		.conf = {
 508			0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
 509			0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 510			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 511			0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 512		},
 513	},
 514	{
 515		.pixel_clock = 148500000,
 516		.conf = {
 517			0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
 518			0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 519			0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
 520			0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80,
 521		},
 522	},
 523};
 524
 525static const struct hdmiphy_config hdmiphy_5433_configs[] = {
 526	{
 527		.pixel_clock = 27000000,
 528		.conf = {
 529			0x01, 0x51, 0x2d, 0x75, 0x01, 0x00, 0x88, 0x02,
 530			0x72, 0x50, 0x44, 0x8c, 0x27, 0x00, 0x7c, 0xac,
 531			0xd6, 0x2b, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 532			0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 533		},
 534	},
 535	{
 536		.pixel_clock = 27027000,
 537		.conf = {
 538			0x01, 0x51, 0x2d, 0x72, 0x64, 0x09, 0x88, 0xc3,
 539			0x71, 0x50, 0x44, 0x8c, 0x27, 0x00, 0x7c, 0xac,
 540			0xd6, 0x2b, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 541			0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 542		},
 543	},
 544	{
 545		.pixel_clock = 40000000,
 546		.conf = {
 547			0x01, 0x51, 0x32, 0x55, 0x01, 0x00, 0x88, 0x02,
 548			0x4d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 549			0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 550			0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 551		},
 552	},
 553	{
 554		.pixel_clock = 50000000,
 555		.conf = {
 556			0x01, 0x51, 0x34, 0x40, 0x64, 0x09, 0x88, 0xc3,
 557			0x3d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 558			0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 559			0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 560		},
 561	},
 562	{
 563		.pixel_clock = 65000000,
 564		.conf = {
 565			0x01, 0x51, 0x36, 0x31, 0x40, 0x10, 0x04, 0xc6,
 566			0x2e, 0xe8, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 567			0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 568			0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 569		},
 570	},
 571	{
 572		.pixel_clock = 74176000,
 573		.conf = {
 574			0x01, 0x51, 0x3E, 0x35, 0x5B, 0xDE, 0x88, 0x42,
 575			0x53, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 576			0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 577			0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 578		},
 579	},
 580	{
 581		.pixel_clock = 74250000,
 582		.conf = {
 583			0x01, 0x51, 0x3E, 0x35, 0x40, 0xF0, 0x88, 0xC2,
 584			0x52, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 585			0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 586			0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 587		},
 588	},
 589	{
 590		.pixel_clock = 108000000,
 591		.conf = {
 592			0x01, 0x51, 0x2d, 0x15, 0x01, 0x00, 0x88, 0x02,
 593			0x72, 0x52, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 594			0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 595			0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 596		},
 597	},
 598	{
 599		.pixel_clock = 148500000,
 600		.conf = {
 601			0x01, 0x51, 0x1f, 0x00, 0x40, 0xf8, 0x88, 0xc1,
 602			0x52, 0x52, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5,
 603			0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
 604			0x08, 0x10, 0x01, 0x01, 0x48, 0x4a, 0x00, 0x40,
 605		},
 606	},
 607	{
 608		.pixel_clock = 297000000,
 609		.conf = {
 610			0x01, 0x51, 0x3E, 0x05, 0x40, 0xF0, 0x88, 0xC2,
 611			0x52, 0x53, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
 612			0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
 613			0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
 614		},
 615	},
 616};
 617
 618static const char * const hdmi_clk_gates4[] = {
 619	"hdmi", "sclk_hdmi"
 620};
 621
 622static const char * const hdmi_clk_muxes4[] = {
 623	"sclk_pixel", "sclk_hdmiphy", "mout_hdmi"
 624};
 625
 626static const char * const hdmi_clk_gates5433[] = {
 627	"hdmi_pclk", "hdmi_i_pclk", "i_tmds_clk", "i_pixel_clk", "i_spdif_clk"
 628};
 629
 630static const char * const hdmi_clk_muxes5433[] = {
 631	"oscclk", "tmds_clko", "tmds_clko_user",
 632	"oscclk", "pixel_clko", "pixel_clko_user"
 633};
 634
 635static const struct hdmi_driver_data exynos4210_hdmi_driver_data = {
 636	.type		= HDMI_TYPE13,
 637	.phy_confs	= INIT_ARRAY_SPEC(hdmiphy_v13_configs),
 638	.clk_gates	= INIT_ARRAY_SPEC(hdmi_clk_gates4),
 639	.clk_muxes	= INIT_ARRAY_SPEC(hdmi_clk_muxes4),
 640};
 641
 642static const struct hdmi_driver_data exynos4212_hdmi_driver_data = {
 643	.type		= HDMI_TYPE14,
 644	.phy_confs	= INIT_ARRAY_SPEC(hdmiphy_v14_configs),
 645	.clk_gates	= INIT_ARRAY_SPEC(hdmi_clk_gates4),
 646	.clk_muxes	= INIT_ARRAY_SPEC(hdmi_clk_muxes4),
 647};
 648
 649static const struct hdmi_driver_data exynos5420_hdmi_driver_data = {
 650	.type		= HDMI_TYPE14,
 651	.is_apb_phy	= 1,
 652	.phy_confs	= INIT_ARRAY_SPEC(hdmiphy_5420_configs),
 653	.clk_gates	= INIT_ARRAY_SPEC(hdmi_clk_gates4),
 654	.clk_muxes	= INIT_ARRAY_SPEC(hdmi_clk_muxes4),
 655};
 656
 657static const struct hdmi_driver_data exynos5433_hdmi_driver_data = {
 658	.type		= HDMI_TYPE14,
 659	.is_apb_phy	= 1,
 660	.has_sysreg     = 1,
 661	.phy_confs	= INIT_ARRAY_SPEC(hdmiphy_5433_configs),
 662	.clk_gates	= INIT_ARRAY_SPEC(hdmi_clk_gates5433),
 663	.clk_muxes	= INIT_ARRAY_SPEC(hdmi_clk_muxes5433),
 664};
 665
 666static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id)
 667{
 668	if ((reg_id & 0xffff0000) == HDMI_MAPPED_BASE)
 669		return hdmi_reg_map[reg_id & 0xffff][hdata->drv_data->type];
 670	return reg_id;
 671}
 672
 673static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
 674{
 675	return readl(hdata->regs + hdmi_map_reg(hdata, reg_id));
 676}
 677
 678static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
 679				 u32 reg_id, u8 value)
 680{
 681	writel(value, hdata->regs + hdmi_map_reg(hdata, reg_id));
 682}
 683
 684static inline void hdmi_reg_writev(struct hdmi_context *hdata, u32 reg_id,
 685				   int bytes, u32 val)
 686{
 687	reg_id = hdmi_map_reg(hdata, reg_id);
 688
 689	while (--bytes >= 0) {
 690		writel(val & 0xff, hdata->regs + reg_id);
 691		val >>= 8;
 692		reg_id += 4;
 693	}
 694}
 695
 696static inline void hdmi_reg_write_buf(struct hdmi_context *hdata, u32 reg_id,
 697				      u8 *buf, int size)
 698{
 699	for (reg_id = hdmi_map_reg(hdata, reg_id); size; --size, reg_id += 4)
 700		writel(*buf++, hdata->regs + reg_id);
 701}
 702
 703static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
 704				 u32 reg_id, u32 value, u32 mask)
 705{
 706	u32 old;
 707
 708	reg_id = hdmi_map_reg(hdata, reg_id);
 709	old = readl(hdata->regs + reg_id);
 710	value = (value & mask) | (old & ~mask);
 711	writel(value, hdata->regs + reg_id);
 712}
 713
 714static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
 715			u32 reg_offset, const u8 *buf, u32 len)
 716{
 717	if ((reg_offset + len) > 32)
 718		return -EINVAL;
 719
 720	if (hdata->hdmiphy_port) {
 721		int ret;
 722
 723		ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
 724		if (ret == len)
 725			return 0;
 726		return ret;
 727	} else {
 728		int i;
 729		for (i = 0; i < len; i++)
 730			writel(buf[i], hdata->regs_hdmiphy +
 731				((reg_offset + i)<<2));
 732		return 0;
 733	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 734}
 735
 736static int hdmi_clk_enable_gates(struct hdmi_context *hdata)
 737{
 738	int i, ret;
 739
 740	for (i = 0; i < hdata->drv_data->clk_gates.count; ++i) {
 741		ret = clk_prepare_enable(hdata->clk_gates[i]);
 742		if (!ret)
 743			continue;
 744
 745		dev_err(hdata->dev, "Cannot enable clock '%s', %d\n",
 746			hdata->drv_data->clk_gates.data[i], ret);
 747		while (i--)
 748			clk_disable_unprepare(hdata->clk_gates[i]);
 749		return ret;
 750	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 751
 752	return 0;
 753}
 754
 755static void hdmi_clk_disable_gates(struct hdmi_context *hdata)
 756{
 757	int i = hdata->drv_data->clk_gates.count;
 758
 759	while (i--)
 760		clk_disable_unprepare(hdata->clk_gates[i]);
 761}
 762
 763static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
 764{
 765	struct device *dev = hdata->dev;
 766	int ret = 0;
 767	int i;
 768
 769	for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) {
 770		struct clk **c = &hdata->clk_muxes[i];
 771
 772		ret = clk_set_parent(c[2], c[to_phy]);
 773		if (!ret)
 774			continue;
 775
 776		dev_err(dev, "Cannot set clock parent of '%s' to '%s', %d\n",
 777			hdata->drv_data->clk_muxes.data[i + 2],
 778			hdata->drv_data->clk_muxes.data[i + to_phy], ret);
 779	}
 780
 781	return ret;
 782}
 783
 784static int hdmi_audio_infoframe_apply(struct hdmi_context *hdata)
 785{
 786	struct hdmi_audio_infoframe *infoframe = &hdata->audio.infoframe;
 787	u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)];
 788	int len;
 789
 790	len = hdmi_audio_infoframe_pack(infoframe, buf, sizeof(buf));
 791	if (len < 0)
 792		return len;
 793
 794	hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_EVERY_VSYNC);
 795	hdmi_reg_write_buf(hdata, HDMI_AUI_HEADER0, buf, len);
 
 
 
 
 
 
 796
 797	return 0;
 798}
 799
 800static void hdmi_reg_infoframes(struct hdmi_context *hdata)
 
 801{
 802	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
 803	union hdmi_infoframe frm;
 804	u8 buf[25];
 805	int ret;
 806
 807	if (hdata->dvi_mode) {
 808		hdmi_reg_writeb(hdata, HDMI_AVI_CON,
 809				HDMI_AVI_CON_DO_NOT_TRANSMIT);
 810		hdmi_reg_writeb(hdata, HDMI_VSI_CON,
 811				HDMI_VSI_CON_DO_NOT_TRANSMIT);
 812		hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
 813		return;
 814	}
 815
 816	ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
 817						       &hdata->connector, m);
 818	if (!ret)
 819		ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf));
 820	if (ret > 0) {
 821		hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
 822		hdmi_reg_write_buf(hdata, HDMI_AVI_HEADER0, buf, ret);
 823	} else {
 824		DRM_INFO("%s: invalid AVI infoframe (%d)\n", __func__, ret);
 825	}
 826
 827	ret = drm_hdmi_vendor_infoframe_from_display_mode(&frm.vendor.hdmi,
 828							  &hdata->connector, m);
 829	if (!ret)
 830		ret = hdmi_vendor_infoframe_pack(&frm.vendor.hdmi, buf,
 831				sizeof(buf));
 832	if (ret > 0) {
 833		hdmi_reg_writeb(hdata, HDMI_VSI_CON, HDMI_VSI_CON_EVERY_VSYNC);
 834		hdmi_reg_write_buf(hdata, HDMI_VSI_HEADER0, buf, 3);
 835		hdmi_reg_write_buf(hdata, HDMI_VSI_DATA(0), buf + 3, ret - 3);
 836	}
 837
 838	hdmi_audio_infoframe_apply(hdata);
 839}
 840
 841static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
 842				bool force)
 843{
 844	struct hdmi_context *hdata = connector_to_hdmi(connector);
 845
 846	if (gpiod_get_value(hdata->hpd_gpio))
 847		return connector_status_connected;
 848
 849	cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
 850	return connector_status_disconnected;
 851}
 852
 853static void hdmi_connector_destroy(struct drm_connector *connector)
 
 854{
 855	drm_connector_unregister(connector);
 856	drm_connector_cleanup(connector);
 857}
 858
 859static const struct drm_connector_funcs hdmi_connector_funcs = {
 860	.fill_modes = drm_helper_probe_single_connector_modes,
 861	.detect = hdmi_detect,
 862	.destroy = hdmi_connector_destroy,
 863	.reset = drm_atomic_helper_connector_reset,
 864	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 865	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 866};
 867
 868static int hdmi_get_modes(struct drm_connector *connector)
 869{
 870	struct hdmi_context *hdata = connector_to_hdmi(connector);
 871	struct edid *edid;
 872	int ret;
 873
 874	if (!hdata->ddc_adpt)
 875		return -ENODEV;
 876
 877	edid = drm_get_edid(connector, hdata->ddc_adpt);
 878	if (!edid)
 
 
 
 
 
 
 
 879		return -ENODEV;
 
 880
 881	hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
 882	DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n",
 883			  (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
 884			  edid->width_cm, edid->height_cm);
 885
 886	drm_connector_update_edid_property(connector, edid);
 887	cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid);
 888
 889	ret = drm_add_edid_modes(connector, edid);
 890
 891	kfree(edid);
 892
 893	return ret;
 894}
 895
 896static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
 897{
 898	const struct hdmiphy_configs *confs = &hdata->drv_data->phy_confs;
 899	int i;
 900
 901	for (i = 0; i < confs->count; i++)
 902		if (confs->data[i].pixel_clock == pixel_clock)
 903			return i;
 
 
 
 
 
 
 
 
 
 
 
 
 904
 905	DRM_DEV_DEBUG_KMS(hdata->dev, "Could not find phy config for %d\n",
 906			  pixel_clock);
 907	return -EINVAL;
 908}
 909
 910static int hdmi_mode_valid(struct drm_connector *connector,
 911			struct drm_display_mode *mode)
 912{
 913	struct hdmi_context *hdata = connector_to_hdmi(connector);
 914	int ret;
 915
 916	DRM_DEV_DEBUG_KMS(hdata->dev,
 917			  "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
 918			  mode->hdisplay, mode->vdisplay, mode->vrefresh,
 919			  (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
 920			  false, mode->clock * 1000);
 
 
 
 
 
 
 
 
 921
 922	ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
 923	if (ret < 0)
 924		return MODE_BAD;
 925
 926	return MODE_OK;
 927}
 928
 929static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
 930	.get_modes = hdmi_get_modes,
 931	.mode_valid = hdmi_mode_valid,
 932};
 933
 934static int hdmi_create_connector(struct drm_encoder *encoder)
 935{
 936	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 937	struct drm_connector *connector = &hdata->connector;
 938	int ret;
 939
 940	connector->interlace_allowed = true;
 941	connector->polled = DRM_CONNECTOR_POLL_HPD;
 942
 943	ret = drm_connector_init(hdata->drm_dev, connector,
 944			&hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
 945	if (ret) {
 946		DRM_DEV_ERROR(hdata->dev,
 947			      "Failed to initialize connector with drm\n");
 948		return ret;
 949	}
 950
 951	drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
 952	drm_connector_attach_encoder(connector, encoder);
 953
 954	if (hdata->bridge) {
 955		ret = drm_bridge_attach(encoder, hdata->bridge, NULL);
 956		if (ret)
 957			DRM_DEV_ERROR(hdata->dev, "Failed to attach bridge\n");
 958	}
 959
 960	return ret;
 961}
 962
 963static bool hdmi_mode_fixup(struct drm_encoder *encoder,
 964			    const struct drm_display_mode *mode,
 965			    struct drm_display_mode *adjusted_mode)
 966{
 967	struct drm_device *dev = encoder->dev;
 968	struct drm_connector *connector;
 969	struct drm_display_mode *m;
 970	struct drm_connector_list_iter conn_iter;
 971	int mode_ok;
 972
 973	drm_mode_set_crtcinfo(adjusted_mode, 0);
 974
 975	drm_connector_list_iter_begin(dev, &conn_iter);
 976	drm_for_each_connector_iter(connector, &conn_iter) {
 977		if (connector->encoder == encoder)
 978			break;
 979	}
 980	if (connector)
 981		drm_connector_get(connector);
 982	drm_connector_list_iter_end(&conn_iter);
 983
 984	if (!connector)
 985		return true;
 986
 987	mode_ok = hdmi_mode_valid(connector, adjusted_mode);
 988
 989	if (mode_ok == MODE_OK)
 990		goto cleanup;
 991
 992	/*
 993	 * Find the most suitable mode and copy it to adjusted_mode.
 994	 */
 995	list_for_each_entry(m, &connector->modes, head) {
 996		mode_ok = hdmi_mode_valid(connector, m);
 997
 998		if (mode_ok == MODE_OK) {
 999			DRM_INFO("desired mode doesn't exist so\n");
1000			DRM_INFO("use the most suitable mode among modes.\n");
1001
1002			DRM_DEV_DEBUG_KMS(dev->dev,
1003					  "Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1004					  m->hdisplay, m->vdisplay,
1005					  m->vrefresh);
1006
1007			drm_mode_copy(adjusted_mode, m);
1008			break;
1009		}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1010	}
1011
1012cleanup:
1013	drm_connector_put(connector);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1014
1015	return true;
 
 
 
1016}
1017
1018static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
1019{
1020	u32 n, cts;
 
 
 
1021
1022	cts = (freq % 9) ? 27000 : 30000;
1023	n = 128 * freq / (27000000 / cts);
 
1024
1025	hdmi_reg_writev(hdata, HDMI_ACR_N0, 3, n);
1026	hdmi_reg_writev(hdata, HDMI_ACR_MCTS0, 3, cts);
1027	hdmi_reg_writev(hdata, HDMI_ACR_CTS0, 3, cts);
1028	hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1029}
1030
1031static void hdmi_audio_config(struct hdmi_context *hdata)
1032{
1033	u32 bit_ch = 1;
1034	u32 data_num, val;
1035	int i;
1036
1037	switch (hdata->audio.params.sample_width) {
1038	case 20:
1039		data_num = 2;
 
1040		break;
1041	case 24:
1042		data_num = 3;
 
1043		break;
1044	default:
1045		data_num = 1;
1046		bit_ch = 0;
1047		break;
1048	}
1049
1050	hdmi_reg_acr(hdata, hdata->audio.params.sample_rate);
 
1051
1052	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1053				| HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1054				| HDMI_I2S_MUX_ENABLE);
1055
1056	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1057			| HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1058
1059	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
 
 
 
 
 
 
1060	hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1061	hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1062
1063	val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1064	hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1065
1066	/* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1067	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1068			| HDMI_I2S_SEL_LRCK(6));
1069
1070	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(3)
1071			| HDMI_I2S_SEL_SDATA0(4));
1072
1073	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1074			| HDMI_I2S_SEL_SDATA2(2));
1075
1076	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1077
1078	/* I2S_CON_1 & 2 */
1079	hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1080			| HDMI_I2S_L_CH_LOW_POL);
1081	hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1082			| HDMI_I2S_SET_BIT_CH(bit_ch)
1083			| HDMI_I2S_SET_SDATA_BIT(data_num)
1084			| HDMI_I2S_BASIC_FORMAT);
1085
1086	/* Configuration of the audio channel status registers */
1087	for (i = 0; i < HDMI_I2S_CH_ST_MAXNUM; i++)
1088		hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST(i),
1089				hdata->audio.params.iec.status[i]);
 
 
 
 
 
 
 
 
 
 
1090
1091	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1092}
1093
1094static void hdmi_audio_control(struct hdmi_context *hdata)
1095{
1096	bool enable = !hdata->audio.mute;
1097
1098	if (hdata->dvi_mode)
1099		return;
1100
1101	hdmi_reg_writeb(hdata, HDMI_AUI_CON, enable ?
1102			HDMI_AVI_CON_EVERY_VSYNC : HDMI_AUI_CON_NO_TRAN);
1103	hdmi_reg_writemask(hdata, HDMI_CON_0, enable ?
1104			HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1105}
1106
1107static void hdmi_start(struct hdmi_context *hdata, bool start)
1108{
1109	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1110	u32 val = start ? HDMI_TG_EN : 0;
1111
1112	if (m->flags & DRM_MODE_FLAG_INTERLACE)
1113		val |= HDMI_FIELD_EN;
 
 
1114
1115	hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1116	hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
 
 
 
1117}
1118
1119static void hdmi_conf_init(struct hdmi_context *hdata)
1120{
1121	/* disable HPD interrupts from HDMI IP block, use GPIO instead */
1122	hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1123		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
 
 
 
1124
1125	/* choose HDMI mode */
1126	hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1127		HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1128	/* apply video pre-amble and guard band in HDMI mode only */
1129	hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1130	/* disable bluescreen */
1131	hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1132
1133	if (hdata->dvi_mode) {
 
1134		hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1135				HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1136		hdmi_reg_writeb(hdata, HDMI_CON_2,
1137				HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1138	}
1139
1140	if (hdata->drv_data->type == HDMI_TYPE13) {
1141		/* choose bluescreen (fecal) color */
1142		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1143		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1144		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1145
1146		/* enable AVI packet every vsync, fixes purple line problem */
1147		hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1148		/* force RGB, look to CEA-861-D, table 7 for more detail */
1149		hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1150		hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1151
1152		hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1153		hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1154		hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1155	} else {
1156		hdmi_reg_infoframes(hdata);
1157
1158		/* enable AVI packet every vsync, fixes purple line problem */
 
 
1159		hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1160	}
1161}
1162
1163static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
1164{
 
 
 
 
1165	int tries;
1166
1167	for (tries = 0; tries < 10; ++tries) {
1168		u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
1169
1170		if (val & HDMI_PHY_STATUS_READY) {
1171			DRM_DEV_DEBUG_KMS(hdata->dev,
1172					  "PLL stabilized after %d tries\n",
1173					  tries);
1174			return;
1175		}
1176		usleep_range(10, 20);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1177	}
1178
1179	DRM_DEV_ERROR(hdata->dev, "PLL could not reach steady state\n");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1180}
1181
1182static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1183{
1184	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1185	unsigned int val;
1186
1187	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1188	hdmi_reg_writev(hdata, HDMI_V13_H_V_LINE_0, 3,
1189			(m->htotal << 12) | m->vtotal);
1190
1191	val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1192	hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, val);
1193
1194	val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1195	hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, val);
1196
1197	val = (m->hsync_start - m->hdisplay - 2);
1198	val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1199	val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
1200	hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1201
1202	/*
1203	 * Quirk requirement for exynos HDMI IP design,
1204	 * 2 pixels less than the actual calculation for hsync_start
1205	 * and end.
1206	 */
1207
1208	/* Following values & calculations differ for different type of modes */
1209	if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1210		val = ((m->vsync_end - m->vdisplay) / 2);
1211		val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1212		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1213
1214		val = m->vtotal / 2;
1215		val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1216		hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1217
1218		val = (m->vtotal +
1219			((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1220		val |= m->vtotal << 11;
1221		hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, val);
1222
1223		val = ((m->vtotal / 2) + 7);
1224		val |= ((m->vtotal / 2) + 2) << 12;
1225		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, val);
1226
1227		val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1228		val |= ((m->htotal / 2) +
1229			(m->hsync_start - m->hdisplay)) << 12;
1230		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, val);
1231
1232		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1233				(m->vtotal - m->vdisplay) / 2);
1234		hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1235
1236		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1237	} else {
1238		val = m->vtotal;
1239		val |= (m->vtotal - m->vdisplay) << 11;
1240		hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1241
1242		hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, 0);
1243
1244		val = (m->vsync_end - m->vdisplay);
1245		val |= ((m->vsync_start - m->vdisplay) << 12);
1246		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1247
1248		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, 0x1001);
1249		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, 0x1001);
1250		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1251				m->vtotal - m->vdisplay);
1252		hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1253	}
1254
1255	hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1256	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1257	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1258	hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1259}
1260
1261static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1262{
1263	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1264	struct drm_display_mode *am =
1265				&hdata->encoder.crtc->state->adjusted_mode;
1266	int hquirk = 0;
1267
1268	/*
1269	 * In case video mode coming from CRTC differs from requested one HDMI
1270	 * sometimes is able to almost properly perform conversion - only
1271	 * first line is distorted.
1272	 */
1273	if ((m->vdisplay != am->vdisplay) &&
1274	    (m->hdisplay == 1280 || m->hdisplay == 1024 || m->hdisplay == 1366))
1275		hquirk = 258;
1276
1277	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1278	hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1279	hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1280	hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
1281			(m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
1282	hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1283			(m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1284	hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
1285			(m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1286
1287	/*
1288	 * Quirk requirement for exynos 5 HDMI IP design,
1289	 * 2 pixels less than the actual calculation for hsync_start
1290	 * and end.
1291	 */
1292
1293	/* Following values & calculations differ for different type of modes */
1294	if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1295		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1296			(m->vsync_end - m->vdisplay) / 2);
1297		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1298			(m->vsync_start - m->vdisplay) / 2);
1299		hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal / 2);
1300		hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1301				(m->vtotal - m->vdisplay) / 2);
1302		hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2,
1303				m->vtotal - m->vdisplay / 2);
1304		hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, m->vtotal);
1305		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2,
1306				(m->vtotal / 2) + 7);
1307		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2,
1308				(m->vtotal / 2) + 2);
1309		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2,
1310			(m->htotal / 2) + (m->hsync_start - m->hdisplay));
1311		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2,
1312			(m->htotal / 2) + (m->hsync_start - m->hdisplay));
1313		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1314				(m->vtotal - m->vdisplay) / 2);
1315		hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1316		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2,
1317				m->vtotal - m->vdisplay / 2);
1318		hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2,
1319				(m->vtotal / 2) + 1);
1320		hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2,
1321				(m->vtotal / 2) + 1);
1322		hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2,
1323				(m->vtotal / 2) + 1);
1324		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1325		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1326	} else {
1327		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1328			m->vsync_end - m->vdisplay);
1329		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1330			m->vsync_start - m->vdisplay);
1331		hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal);
1332		hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1333				m->vtotal - m->vdisplay);
1334		hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2, 0xffff);
1335		hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, 0xffff);
1336		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2, 0xffff);
1337		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2, 0xffff);
1338		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2, 0xffff);
1339		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2, 0xffff);
1340		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1341				m->vtotal - m->vdisplay);
1342		hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1343	}
1344
1345	hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1346			m->hsync_start - m->hdisplay - 2);
1347	hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
1348			m->hsync_end - m->hdisplay - 2);
1349	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_1_0, 2, 0xffff);
1350	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_2_0, 2, 0xffff);
1351	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_3_0, 2, 0xffff);
1352	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_4_0, 2, 0xffff);
1353	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_5_0, 2, 0xffff);
1354	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_6_0, 2, 0xffff);
1355	hdmi_reg_writev(hdata, HDMI_V_BLANK_F2_0, 2, 0xffff);
1356	hdmi_reg_writev(hdata, HDMI_V_BLANK_F3_0, 2, 0xffff);
1357	hdmi_reg_writev(hdata, HDMI_V_BLANK_F4_0, 2, 0xffff);
1358	hdmi_reg_writev(hdata, HDMI_V_BLANK_F5_0, 2, 0xffff);
1359	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 2, 0xffff);
1360	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 2, 0xffff);
1361	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 2, 0xffff);
1362	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 2, 0xffff);
1363	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 2, 0xffff);
1364	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 2, 0xffff);
1365	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1366	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
1367
1368	hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1369	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2,
1370					m->htotal - m->hdisplay - hquirk);
1371	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk);
1372	hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1373	if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1374		hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
1375}
1376
1377static void hdmi_mode_apply(struct hdmi_context *hdata)
1378{
1379	if (hdata->drv_data->type == HDMI_TYPE13)
1380		hdmi_v13_mode_apply(hdata);
1381	else
1382		hdmi_v14_mode_apply(hdata);
1383
1384	hdmi_start(hdata, true);
1385}
1386
1387static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1388{
1389	hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1);
1390	usleep_range(10000, 12000);
1391	hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1);
1392	usleep_range(10000, 12000);
1393	hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
1394	usleep_range(10000, 12000);
1395	hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
1396	usleep_range(10000, 12000);
1397}
1398
1399static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable)
1400{
1401	u8 v = enable ? HDMI_PHY_ENABLE_MODE_SET : HDMI_PHY_DISABLE_MODE_SET;
 
 
 
 
 
 
 
 
 
 
 
 
1402
1403	if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1404		writel(v, hdata->regs_hdmiphy + HDMIPHY5433_MODE_SET_DONE);
 
 
 
1405}
1406
1407static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1408{
1409	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
 
 
 
1410	int ret;
1411	const u8 *phy_conf;
1412
1413	ret = hdmi_find_phy_conf(hdata, m->clock * 1000);
1414	if (ret < 0) {
1415		DRM_DEV_ERROR(hdata->dev, "failed to find hdmiphy conf\n");
1416		return;
1417	}
1418	phy_conf = hdata->drv_data->phy_confs.data[ret].conf;
1419
1420	hdmi_clk_set_parents(hdata, false);
1421
1422	hdmiphy_conf_reset(hdata);
 
 
 
 
1423
1424	hdmiphy_enable_mode_set(hdata, true);
1425	ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32);
1426	if (ret) {
1427		DRM_DEV_ERROR(hdata->dev, "failed to configure hdmiphy\n");
1428		return;
1429	}
1430	hdmiphy_enable_mode_set(hdata, false);
1431	hdmi_clk_set_parents(hdata, true);
1432	usleep_range(10000, 12000);
1433	hdmiphy_wait_for_pll(hdata);
1434}
1435
1436/* Should be called with hdata->mutex mutex held */
1437static void hdmi_conf_apply(struct hdmi_context *hdata)
1438{
1439	hdmi_start(hdata, false);
1440	hdmi_conf_init(hdata);
1441	hdmi_audio_config(hdata);
1442	hdmi_mode_apply(hdata);
1443	hdmi_audio_control(hdata);
1444}
1445
1446static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1447{
1448	if (!hdata->sysreg)
 
 
 
 
1449		return;
 
1450
1451	regmap_update_bits(hdata->sysreg, EXYNOS5433_SYSREG_DISP_HDMI_PHY,
1452			   SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1453}
1454
1455/* Should be called with hdata->mutex mutex held. */
1456static void hdmiphy_enable(struct hdmi_context *hdata)
1457{
1458	if (hdata->powered)
1459		return;
 
1460
1461	pm_runtime_get_sync(hdata->dev);
 
 
 
1462
1463	if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
1464		DRM_DEV_DEBUG_KMS(hdata->dev,
1465				  "failed to enable regulator bulk\n");
1466
1467	regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1468			PMU_HDMI_PHY_ENABLE_BIT, 1);
1469
1470	hdmi_set_refclk(hdata, true);
 
 
 
1471
1472	hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
1473
1474	hdmiphy_conf_apply(hdata);
 
 
1475
1476	hdata->powered = true;
1477}
1478
1479/* Should be called with hdata->mutex mutex held. */
1480static void hdmiphy_disable(struct hdmi_context *hdata)
 
1481{
1482	if (!hdata->powered)
1483		return;
1484
1485	hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1486
1487	hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
1488
1489	hdmi_set_refclk(hdata, false);
1490
1491	regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1492			PMU_HDMI_PHY_ENABLE_BIT, 0);
 
 
1493
1494	regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
 
 
1495
1496	pm_runtime_put_sync(hdata->dev);
 
 
 
 
 
 
 
 
1497
1498	hdata->powered = false;
 
 
 
 
 
 
1499}
1500
1501static void hdmi_enable(struct drm_encoder *encoder)
1502{
1503	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1504
1505	mutex_lock(&hdata->mutex);
1506
1507	hdmiphy_enable(hdata);
1508	hdmi_conf_apply(hdata);
1509
1510	mutex_unlock(&hdata->mutex);
 
 
 
 
1511}
1512
1513static void hdmi_disable(struct drm_encoder *encoder)
 
1514{
1515	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1516
1517	mutex_lock(&hdata->mutex);
1518
1519	if (hdata->powered) {
1520		/*
1521		 * The SFRs of VP and Mixer are updated by Vertical Sync of
1522		 * Timing generator which is a part of HDMI so the sequence
1523		 * to disable TV Subsystem should be as following,
1524		 *	VP -> Mixer -> HDMI
1525		 *
1526		 * To achieve such sequence HDMI is disabled together with
1527		 * HDMI PHY, via pipe clock callback.
1528		 */
1529		mutex_unlock(&hdata->mutex);
1530		cancel_delayed_work(&hdata->hotplug_work);
1531		cec_notifier_set_phys_addr(hdata->notifier,
1532					   CEC_PHYS_ADDR_INVALID);
1533		return;
1534	}
1535
1536	mutex_unlock(&hdata->mutex);
1537}
1538
1539static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
1540	.mode_fixup	= hdmi_mode_fixup,
1541	.enable		= hdmi_enable,
1542	.disable	= hdmi_disable,
1543};
1544
1545static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
1546	.destroy = drm_encoder_cleanup,
1547};
1548
1549static void hdmi_audio_shutdown(struct device *dev, void *data)
1550{
1551	struct hdmi_context *hdata = dev_get_drvdata(dev);
1552
1553	mutex_lock(&hdata->mutex);
1554
1555	hdata->audio.mute = true;
1556
1557	if (hdata->powered)
1558		hdmi_audio_control(hdata);
1559
1560	mutex_unlock(&hdata->mutex);
1561}
1562
1563static int hdmi_audio_hw_params(struct device *dev, void *data,
1564				struct hdmi_codec_daifmt *daifmt,
1565				struct hdmi_codec_params *params)
1566{
1567	struct hdmi_context *hdata = dev_get_drvdata(dev);
1568
1569	if (daifmt->fmt != HDMI_I2S || daifmt->bit_clk_inv ||
1570	    daifmt->frame_clk_inv || daifmt->bit_clk_master ||
1571	    daifmt->frame_clk_master) {
1572		dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__,
1573			daifmt->bit_clk_inv, daifmt->frame_clk_inv,
1574			daifmt->bit_clk_master,
1575			daifmt->frame_clk_master);
1576		return -EINVAL;
1577	}
1578
1579	mutex_lock(&hdata->mutex);
1580
1581	hdata->audio.params = *params;
1582
 
1583	if (hdata->powered) {
1584		hdmi_audio_config(hdata);
1585		hdmi_audio_infoframe_apply(hdata);
1586	}
1587
1588	mutex_unlock(&hdata->mutex);
1589
1590	return 0;
1591}
1592
1593static int hdmi_audio_digital_mute(struct device *dev, void *data, bool mute)
1594{
1595	struct hdmi_context *hdata = dev_get_drvdata(dev);
1596
1597	mutex_lock(&hdata->mutex);
1598
1599	hdata->audio.mute = mute;
1600
1601	if (hdata->powered)
1602		hdmi_audio_control(hdata);
 
1603
1604	mutex_unlock(&hdata->mutex);
1605
1606	return 0;
 
 
 
1607}
1608
1609static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
1610			      size_t len)
1611{
1612	struct hdmi_context *hdata = dev_get_drvdata(dev);
1613	struct drm_connector *connector = &hdata->connector;
1614
1615	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
1616
1617	return 0;
1618}
1619
1620static const struct hdmi_codec_ops audio_codec_ops = {
1621	.hw_params = hdmi_audio_hw_params,
1622	.audio_shutdown = hdmi_audio_shutdown,
1623	.digital_mute = hdmi_audio_digital_mute,
1624	.get_eld = hdmi_audio_get_eld,
1625};
1626
1627static int hdmi_register_audio_device(struct hdmi_context *hdata)
1628{
1629	struct hdmi_codec_pdata codec_data = {
1630		.ops = &audio_codec_ops,
1631		.max_i2s_channels = 6,
1632		.i2s = 1,
1633	};
1634
1635	hdata->audio.pdev = platform_device_register_data(
1636		hdata->dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
1637		&codec_data, sizeof(codec_data));
1638
1639	return PTR_ERR_OR_ZERO(hdata->audio.pdev);
1640}
1641
1642static void hdmi_hotplug_work_func(struct work_struct *work)
1643{
1644	struct hdmi_context *hdata;
 
 
1645
1646	hdata = container_of(work, struct hdmi_context, hotplug_work.work);
 
 
 
1647
1648	if (hdata->drm_dev)
1649		drm_helper_hpd_irq_event(hdata->drm_dev);
1650}
1651
1652static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1653{
1654	struct hdmi_context *hdata = arg;
1655
1656	mod_delayed_work(system_wq, &hdata->hotplug_work,
1657			msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
1658
1659	return IRQ_HANDLED;
 
1660}
1661
1662static int hdmi_clks_get(struct hdmi_context *hdata,
1663			 const struct string_array_spec *names,
1664			 struct clk **clks)
1665{
1666	struct device *dev = hdata->dev;
1667	int i;
1668
1669	for (i = 0; i < names->count; ++i) {
1670		struct clk *clk = devm_clk_get(dev, names->data[i]);
1671
1672		if (IS_ERR(clk)) {
1673			int ret = PTR_ERR(clk);
1674
1675			dev_err(dev, "Cannot get clock %s, %d\n",
1676				names->data[i], ret);
1677
1678			return ret;
1679		}
1680
1681		clks[i] = clk;
 
 
1682	}
1683
1684	return 0;
1685}
1686
1687static int hdmi_clk_init(struct hdmi_context *hdata)
1688{
1689	const struct hdmi_driver_data *drv_data = hdata->drv_data;
1690	int count = drv_data->clk_gates.count + drv_data->clk_muxes.count;
1691	struct device *dev = hdata->dev;
1692	struct clk **clks;
1693	int ret;
1694
1695	if (!count)
1696		return 0;
1697
1698	clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL);
1699	if (!clks)
1700		return -ENOMEM;
1701
1702	hdata->clk_gates = clks;
1703	hdata->clk_muxes = clks + drv_data->clk_gates.count;
1704
1705	ret = hdmi_clks_get(hdata, &drv_data->clk_gates, hdata->clk_gates);
1706	if (ret)
1707		return ret;
 
 
 
 
1708
1709	return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes);
1710}
 
 
1711
 
 
1712
1713static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
1714{
1715	struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
1716						  phy_clk);
1717	mutex_lock(&hdata->mutex);
1718
1719	if (enable)
1720		hdmiphy_enable(hdata);
1721	else
1722		hdmiphy_disable(hdata);
1723
1724	mutex_unlock(&hdata->mutex);
 
1725}
1726
1727static int hdmi_bridge_init(struct hdmi_context *hdata)
1728{
1729	struct device *dev = hdata->dev;
1730	struct device_node *ep, *np;
1731
1732	ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1);
1733	if (!ep)
1734		return 0;
1735
1736	np = of_graph_get_remote_port_parent(ep);
1737	of_node_put(ep);
1738	if (!np) {
1739		DRM_DEV_ERROR(dev, "failed to get remote port parent");
1740		return -EINVAL;
 
 
 
 
 
 
 
 
 
 
1741	}
 
1742
1743	hdata->bridge = of_drm_find_bridge(np);
1744	of_node_put(np);
1745
1746	if (!hdata->bridge)
1747		return -EPROBE_DEFER;
1748
1749	return 0;
 
1750}
1751
1752static int hdmi_resources_init(struct hdmi_context *hdata)
1753{
1754	struct device *dev = hdata->dev;
 
 
 
 
 
 
 
1755	int i, ret;
1756
1757	DRM_DEV_DEBUG_KMS(dev, "HDMI resource init\n");
1758
1759	hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
1760	if (IS_ERR(hdata->hpd_gpio)) {
1761		DRM_DEV_ERROR(dev, "cannot get hpd gpio property\n");
1762		return PTR_ERR(hdata->hpd_gpio);
1763	}
1764
1765	hdata->irq = gpiod_to_irq(hdata->hpd_gpio);
1766	if (hdata->irq < 0) {
1767		DRM_DEV_ERROR(dev, "failed to get GPIO irq\n");
1768		return  hdata->irq;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1769	}
1770
1771	ret = hdmi_clk_init(hdata);
1772	if (ret)
1773		return ret;
1774
1775	ret = hdmi_clk_set_parents(hdata, false);
1776	if (ret)
1777		return ret;
1778
1779	for (i = 0; i < ARRAY_SIZE(supply); ++i)
1780		hdata->regul_bulk[i].supply = supply[i];
1781
1782	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
1783	if (ret) {
1784		if (ret != -EPROBE_DEFER)
1785			DRM_DEV_ERROR(dev, "failed to get regulators\n");
1786		return ret;
1787	}
1788
1789	hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en");
1790
1791	if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV) {
1792		if (IS_ERR(hdata->reg_hdmi_en))
1793			return PTR_ERR(hdata->reg_hdmi_en);
1794
1795		ret = regulator_enable(hdata->reg_hdmi_en);
1796		if (ret) {
1797			DRM_DEV_ERROR(dev,
1798				      "failed to enable hdmi-en regulator\n");
1799			return ret;
1800		}
1801	}
1802
1803	return hdmi_bridge_init(hdata);
1804}
1805
1806static const struct of_device_id hdmi_match_types[] = {
1807	{
1808		.compatible = "samsung,exynos4210-hdmi",
1809		.data = &exynos4210_hdmi_driver_data,
1810	}, {
1811		.compatible = "samsung,exynos4212-hdmi",
1812		.data = &exynos4212_hdmi_driver_data,
1813	}, {
1814		.compatible = "samsung,exynos5420-hdmi",
1815		.data = &exynos5420_hdmi_driver_data,
1816	}, {
1817		.compatible = "samsung,exynos5433-hdmi",
1818		.data = &exynos5433_hdmi_driver_data,
1819	}, {
1820		/* end node */
1821	}
1822};
1823MODULE_DEVICE_TABLE (of, hdmi_match_types);
1824
1825static int hdmi_bind(struct device *dev, struct device *master, void *data)
1826{
1827	struct drm_device *drm_dev = data;
1828	struct hdmi_context *hdata = dev_get_drvdata(dev);
1829	struct drm_encoder *encoder = &hdata->encoder;
1830	struct exynos_drm_crtc *crtc;
1831	int ret;
1832
1833	hdata->drm_dev = drm_dev;
1834
1835	hdata->phy_clk.enable = hdmiphy_clk_enable;
1836
1837	drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
1838			 DRM_MODE_ENCODER_TMDS, NULL);
1839
1840	drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
1841
1842	ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_HDMI);
1843	if (ret < 0)
1844		return ret;
1845
1846	crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI);
1847	crtc->pipe_clk = &hdata->phy_clk;
1848
1849	ret = hdmi_create_connector(encoder);
1850	if (ret) {
1851		DRM_DEV_ERROR(dev, "failed to create connector ret = %d\n",
1852			      ret);
1853		drm_encoder_cleanup(encoder);
1854		return ret;
1855	}
 
1856
1857	return 0;
1858}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1859
1860static void hdmi_unbind(struct device *dev, struct device *master, void *data)
1861{
1862}
1863
1864static const struct component_ops hdmi_component_ops = {
1865	.bind	= hdmi_bind,
1866	.unbind = hdmi_unbind,
1867};
1868
1869static int hdmi_get_ddc_adapter(struct hdmi_context *hdata)
1870{
1871	const char *compatible_str = "samsung,exynos4210-hdmiddc";
1872	struct device_node *np;
1873	struct i2c_adapter *adpt;
1874
1875	np = of_find_compatible_node(NULL, NULL, compatible_str);
1876	if (np)
1877		np = of_get_next_parent(np);
1878	else
1879		np = of_parse_phandle(hdata->dev->of_node, "ddc", 0);
1880
1881	if (!np) {
1882		DRM_DEV_ERROR(hdata->dev,
1883			      "Failed to find ddc node in device tree\n");
1884		return -ENODEV;
1885	}
1886
1887	adpt = of_find_i2c_adapter_by_node(np);
1888	of_node_put(np);
1889
1890	if (!adpt) {
1891		DRM_INFO("Failed to get ddc i2c adapter by node\n");
1892		return -EPROBE_DEFER;
1893	}
1894
1895	hdata->ddc_adpt = adpt;
1896
1897	return 0;
1898}
1899
1900static int hdmi_get_phy_io(struct hdmi_context *hdata)
1901{
1902	const char *compatible_str = "samsung,exynos4212-hdmiphy";
1903	struct device_node *np;
1904	int ret = 0;
1905
1906	np = of_find_compatible_node(NULL, NULL, compatible_str);
1907	if (!np) {
1908		np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
1909		if (!np) {
1910			DRM_DEV_ERROR(hdata->dev,
1911				      "Failed to find hdmiphy node in device tree\n");
1912			return -ENODEV;
1913		}
1914	}
1915
1916	if (hdata->drv_data->is_apb_phy) {
1917		hdata->regs_hdmiphy = of_iomap(np, 0);
1918		if (!hdata->regs_hdmiphy) {
1919			DRM_DEV_ERROR(hdata->dev,
1920				      "failed to ioremap hdmi phy\n");
1921			ret = -ENOMEM;
1922			goto out;
1923		}
1924	} else {
1925		hdata->hdmiphy_port = of_find_i2c_device_by_node(np);
1926		if (!hdata->hdmiphy_port) {
1927			DRM_INFO("Failed to get hdmi phy i2c client\n");
1928			ret = -EPROBE_DEFER;
1929			goto out;
1930		}
1931	}
1932
1933out:
1934	of_node_put(np);
1935	return ret;
1936}
1937
1938static int hdmi_probe(struct platform_device *pdev)
1939{
1940	struct hdmi_audio_infoframe *audio_infoframe;
1941	struct device *dev = &pdev->dev;
 
1942	struct hdmi_context *hdata;
 
1943	struct resource *res;
1944	int ret;
1945
1946	hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
1947	if (!hdata)
 
 
 
 
 
 
 
 
 
1948		return -ENOMEM;
 
1949
1950	hdata->drv_data = of_device_get_match_data(dev);
 
 
 
 
 
1951
1952	platform_set_drvdata(pdev, hdata);
1953
1954	hdata->dev = dev;
 
1955
1956	mutex_init(&hdata->mutex);
 
 
 
 
 
1957
1958	ret = hdmi_resources_init(hdata);
1959	if (ret) {
1960		if (ret != -EPROBE_DEFER)
1961			DRM_DEV_ERROR(dev, "hdmi_resources_init failed\n");
1962		return ret;
1963	}
1964
1965	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1966	hdata->regs = devm_ioremap_resource(dev, res);
1967	if (IS_ERR(hdata->regs)) {
1968		ret = PTR_ERR(hdata->regs);
1969		return ret;
1970	}
1971
1972	ret = hdmi_get_ddc_adapter(hdata);
1973	if (ret)
1974		return ret;
 
 
 
 
1975
1976	ret = hdmi_get_phy_io(hdata);
1977	if (ret)
1978		goto err_ddc;
 
 
 
1979
1980	INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
 
 
 
 
 
1981
1982	ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
1983			hdmi_irq_thread, IRQF_TRIGGER_RISING |
1984			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1985			"hdmi", hdata);
1986	if (ret) {
1987		DRM_DEV_ERROR(dev, "failed to register hdmi interrupt\n");
1988		goto err_hdmiphy;
1989	}
1990
1991	hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
1992			"samsung,syscon-phandle");
1993	if (IS_ERR(hdata->pmureg)) {
1994		DRM_DEV_ERROR(dev, "syscon regmap lookup failed.\n");
1995		ret = -EPROBE_DEFER;
 
1996		goto err_hdmiphy;
1997	}
1998
1999	if (hdata->drv_data->has_sysreg) {
2000		hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
2001				"samsung,sysreg-phandle");
2002		if (IS_ERR(hdata->sysreg)) {
2003			DRM_DEV_ERROR(dev, "sysreg regmap lookup failed.\n");
2004			ret = -EPROBE_DEFER;
2005			goto err_hdmiphy;
2006		}
2007	}
2008
2009	hdata->notifier = cec_notifier_get(&pdev->dev);
2010	if (hdata->notifier == NULL) {
2011		ret = -ENOMEM;
 
 
 
2012		goto err_hdmiphy;
2013	}
2014
2015	pm_runtime_enable(dev);
 
2016
2017	audio_infoframe = &hdata->audio.infoframe;
2018	hdmi_audio_infoframe_init(audio_infoframe);
2019	audio_infoframe->coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
2020	audio_infoframe->sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
2021	audio_infoframe->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
2022	audio_infoframe->channels = 2;
2023
2024	ret = hdmi_register_audio_device(hdata);
2025	if (ret)
2026		goto err_notifier_put;
2027
2028	ret = component_add(&pdev->dev, &hdmi_component_ops);
2029	if (ret)
2030		goto err_unregister_audio;
2031
2032	return ret;
 
2033
2034err_unregister_audio:
2035	platform_device_unregister(hdata->audio.pdev);
2036
2037err_notifier_put:
2038	cec_notifier_put(hdata->notifier);
2039	pm_runtime_disable(dev);
2040
 
 
2041err_hdmiphy:
2042	if (hdata->hdmiphy_port)
2043		put_device(&hdata->hdmiphy_port->dev);
2044	if (hdata->regs_hdmiphy)
2045		iounmap(hdata->regs_hdmiphy);
2046err_ddc:
2047	put_device(&hdata->ddc_adpt->dev);
2048
 
 
 
 
 
 
 
 
 
2049	return ret;
2050}
2051
2052static int hdmi_remove(struct platform_device *pdev)
2053{
2054	struct hdmi_context *hdata = platform_get_drvdata(pdev);
 
 
2055
2056	cancel_delayed_work_sync(&hdata->hotplug_work);
2057	cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
2058
2059	component_del(&pdev->dev, &hdmi_component_ops);
2060	platform_device_unregister(hdata->audio.pdev);
2061
2062	cec_notifier_put(hdata->notifier);
2063	pm_runtime_disable(&pdev->dev);
2064
2065	if (!IS_ERR(hdata->reg_hdmi_en))
2066		regulator_disable(hdata->reg_hdmi_en);
2067
2068	if (hdata->hdmiphy_port)
2069		put_device(&hdata->hdmiphy_port->dev);
2070
2071	if (hdata->regs_hdmiphy)
2072		iounmap(hdata->regs_hdmiphy);
2073
2074	put_device(&hdata->ddc_adpt->dev);
 
 
 
2075
2076	mutex_destroy(&hdata->mutex);
2077
2078	return 0;
2079}
2080
2081static int __maybe_unused exynos_hdmi_suspend(struct device *dev)
 
2082{
2083	struct hdmi_context *hdata = dev_get_drvdata(dev);
 
 
 
 
 
 
 
 
2084
2085	hdmi_clk_disable_gates(hdata);
2086
2087	return 0;
2088}
2089
2090static int __maybe_unused exynos_hdmi_resume(struct device *dev)
2091{
2092	struct hdmi_context *hdata = dev_get_drvdata(dev);
2093	int ret;
2094
2095	ret = hdmi_clk_enable_gates(hdata);
2096	if (ret < 0)
2097		return ret;
2098
 
 
2099	return 0;
2100}
 
2101
2102static const struct dev_pm_ops exynos_hdmi_pm_ops = {
2103	SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
2104	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
2105				pm_runtime_force_resume)
2106};
2107
2108struct platform_driver hdmi_driver = {
2109	.probe		= hdmi_probe,
2110	.remove		= hdmi_remove,
2111	.driver		= {
2112		.name	= "exynos-hdmi",
2113		.owner	= THIS_MODULE,
2114		.pm	= &exynos_hdmi_pm_ops,
2115		.of_match_table = hdmi_match_types,
2116	},
2117};
v3.5.6
 
   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 "drmP.h"
  18#include "drm_edid.h"
  19#include "drm_crtc_helper.h"
  20
  21#include "regs-hdmi.h"
  22
  23#include <linux/kernel.h>
  24#include <linux/spinlock.h>
  25#include <linux/wait.h>
  26#include <linux/i2c.h>
  27#include <linux/module.h>
  28#include <linux/platform_device.h>
  29#include <linux/interrupt.h>
 
  30#include <linux/irq.h>
  31#include <linux/delay.h>
 
 
 
 
 
  32#include <linux/pm_runtime.h>
  33#include <linux/clk.h>
  34#include <linux/regulator/consumer.h>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  35
  36#include <drm/exynos_drm.h>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  37
  38#include "exynos_drm_drv.h"
  39#include "exynos_drm_hdmi.h"
  40
  41#include "exynos_hdmi.h"
 
 
 
 
 
 
 
 
 
 
 
  42
  43#define MAX_WIDTH		1920
  44#define MAX_HEIGHT		1080
  45#define get_hdmi_context(dev)	platform_get_drvdata(to_platform_device(dev))
  46
  47struct hdmi_resources {
  48	struct clk			*hdmi;
  49	struct clk			*sclk_hdmi;
  50	struct clk			*sclk_pixel;
  51	struct clk			*sclk_hdmiphy;
  52	struct clk			*hdmiphy;
  53	struct regulator_bulk_data	*regul_bulk;
  54	int				regul_count;
  55};
  56
  57struct hdmi_context {
 
  58	struct device			*dev;
  59	struct drm_device		*drm_dev;
  60	bool				hpd;
  61	bool				powered;
  62	bool				is_v13;
  63	bool				dvi_mode;
  64	struct mutex			hdmi_mutex;
 
 
  65
  66	struct resource			*regs_res;
  67	void __iomem			*regs;
  68	unsigned int			external_irq;
  69	unsigned int			internal_irq;
  70
  71	struct i2c_client		*ddc_port;
  72	struct i2c_client		*hdmiphy_port;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  73
  74	/* current hdmiphy conf index */
  75	int cur_conf;
 
 
  76
  77	struct hdmi_resources		res;
  78	void				*parent_ctx;
  79
  80	void				(*cfg_hpd)(bool external);
  81	int				(*get_hpd)(void);
  82};
  83
  84/* HDMI Version 1.3 */
  85static const u8 hdmiphy_v13_conf27[32] = {
  86	0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
  87	0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
  88	0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
  89	0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
  90};
  91
  92static const u8 hdmiphy_v13_conf27_027[32] = {
  93	0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
  94	0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
  95	0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
  96	0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
  97};
  98
  99static const u8 hdmiphy_v13_conf74_175[32] = {
 100	0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
 101	0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
 102	0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
 103	0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
 104};
 105
 106static const u8 hdmiphy_v13_conf74_25[32] = {
 107	0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
 108	0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
 109	0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
 110	0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
 111};
 112
 113static const u8 hdmiphy_v13_conf148_5[32] = {
 114	0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
 115	0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
 116	0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
 117	0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
 118};
 119
 120struct hdmi_v13_tg_regs {
 121	u8 cmd;
 122	u8 h_fsz_l;
 123	u8 h_fsz_h;
 124	u8 hact_st_l;
 125	u8 hact_st_h;
 126	u8 hact_sz_l;
 127	u8 hact_sz_h;
 128	u8 v_fsz_l;
 129	u8 v_fsz_h;
 130	u8 vsync_l;
 131	u8 vsync_h;
 132	u8 vsync2_l;
 133	u8 vsync2_h;
 134	u8 vact_st_l;
 135	u8 vact_st_h;
 136	u8 vact_sz_l;
 137	u8 vact_sz_h;
 138	u8 field_chg_l;
 139	u8 field_chg_h;
 140	u8 vact_st2_l;
 141	u8 vact_st2_h;
 142	u8 vsync_top_hdmi_l;
 143	u8 vsync_top_hdmi_h;
 144	u8 vsync_bot_hdmi_l;
 145	u8 vsync_bot_hdmi_h;
 146	u8 field_top_hdmi_l;
 147	u8 field_top_hdmi_h;
 148	u8 field_bot_hdmi_l;
 149	u8 field_bot_hdmi_h;
 150};
 151
 152struct hdmi_v13_core_regs {
 153	u8 h_blank[2];
 154	u8 v_blank[3];
 155	u8 h_v_line[3];
 156	u8 vsync_pol[1];
 157	u8 int_pro_mode[1];
 158	u8 v_blank_f[3];
 159	u8 h_sync_gen[3];
 160	u8 v_sync_gen1[3];
 161	u8 v_sync_gen2[3];
 162	u8 v_sync_gen3[3];
 163};
 164
 165struct hdmi_v13_preset_conf {
 166	struct hdmi_v13_core_regs core;
 167	struct hdmi_v13_tg_regs tg;
 168};
 169
 170struct hdmi_v13_conf {
 171	int width;
 172	int height;
 173	int vrefresh;
 174	bool interlace;
 175	const u8 *hdmiphy_data;
 176	const struct hdmi_v13_preset_conf *conf;
 177};
 178
 179static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = {
 180	.core = {
 181		.h_blank = {0x8a, 0x00},
 182		.v_blank = {0x0d, 0x6a, 0x01},
 183		.h_v_line = {0x0d, 0xa2, 0x35},
 184		.vsync_pol = {0x01},
 185		.int_pro_mode = {0x00},
 186		.v_blank_f = {0x00, 0x00, 0x00},
 187		.h_sync_gen = {0x0e, 0x30, 0x11},
 188		.v_sync_gen1 = {0x0f, 0x90, 0x00},
 189		/* other don't care */
 190	},
 191	.tg = {
 192		0x00, /* cmd */
 193		0x5a, 0x03, /* h_fsz */
 194		0x8a, 0x00, 0xd0, 0x02, /* hact */
 195		0x0d, 0x02, /* v_fsz */
 196		0x01, 0x00, 0x33, 0x02, /* vsync */
 197		0x2d, 0x00, 0xe0, 0x01, /* vact */
 198		0x33, 0x02, /* field_chg */
 199		0x49, 0x02, /* vact_st2 */
 200		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
 201		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 202	},
 203};
 204
 205static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = {
 206	.core = {
 207		.h_blank = {0x72, 0x01},
 208		.v_blank = {0xee, 0xf2, 0x00},
 209		.h_v_line = {0xee, 0x22, 0x67},
 210		.vsync_pol = {0x00},
 211		.int_pro_mode = {0x00},
 212		.v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
 213		.h_sync_gen = {0x6c, 0x50, 0x02},
 214		.v_sync_gen1 = {0x0a, 0x50, 0x00},
 215		.v_sync_gen2 = {0x01, 0x10, 0x00},
 216		.v_sync_gen3 = {0x01, 0x10, 0x00},
 217		/* other don't care */
 218	},
 219	.tg = {
 220		0x00, /* cmd */
 221		0x72, 0x06, /* h_fsz */
 222		0x71, 0x01, 0x01, 0x05, /* hact */
 223		0xee, 0x02, /* v_fsz */
 224		0x01, 0x00, 0x33, 0x02, /* vsync */
 225		0x1e, 0x00, 0xd0, 0x02, /* vact */
 226		0x33, 0x02, /* field_chg */
 227		0x49, 0x02, /* vact_st2 */
 228		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
 229		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 230	},
 231};
 232
 233static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = {
 234	.core = {
 235		.h_blank = {0xd0, 0x02},
 236		.v_blank = {0x32, 0xB2, 0x00},
 237		.h_v_line = {0x65, 0x04, 0xa5},
 238		.vsync_pol = {0x00},
 239		.int_pro_mode = {0x01},
 240		.v_blank_f = {0x49, 0x2A, 0x23},
 241		.h_sync_gen = {0x0E, 0xEA, 0x08},
 242		.v_sync_gen1 = {0x07, 0x20, 0x00},
 243		.v_sync_gen2 = {0x39, 0x42, 0x23},
 244		.v_sync_gen3 = {0x38, 0x87, 0x73},
 245		/* other don't care */
 246	},
 247	.tg = {
 248		0x00, /* cmd */
 249		0x50, 0x0A, /* h_fsz */
 250		0xCF, 0x02, 0x81, 0x07, /* hact */
 251		0x65, 0x04, /* v_fsz */
 252		0x01, 0x00, 0x33, 0x02, /* vsync */
 253		0x16, 0x00, 0x1c, 0x02, /* vact */
 254		0x33, 0x02, /* field_chg */
 255		0x49, 0x02, /* vact_st2 */
 256		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
 257		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 258	},
 259};
 260
 261static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = {
 262	.core = {
 263		.h_blank = {0xd0, 0x02},
 264		.v_blank = {0x65, 0x6c, 0x01},
 265		.h_v_line = {0x65, 0x04, 0xa5},
 266		.vsync_pol = {0x00},
 267		.int_pro_mode = {0x00},
 268		.v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
 269		.h_sync_gen = {0x0e, 0xea, 0x08},
 270		.v_sync_gen1 = {0x09, 0x40, 0x00},
 271		.v_sync_gen2 = {0x01, 0x10, 0x00},
 272		.v_sync_gen3 = {0x01, 0x10, 0x00},
 273		/* other don't care */
 274	},
 275	.tg = {
 276		0x00, /* cmd */
 277		0x50, 0x0A, /* h_fsz */
 278		0xCF, 0x02, 0x81, 0x07, /* hact */
 279		0x65, 0x04, /* v_fsz */
 280		0x01, 0x00, 0x33, 0x02, /* vsync */
 281		0x2d, 0x00, 0x38, 0x04, /* vact */
 282		0x33, 0x02, /* field_chg */
 283		0x48, 0x02, /* vact_st2 */
 284		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
 285		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 286	},
 287};
 288
 289static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = {
 290	.core = {
 291		.h_blank = {0x18, 0x01},
 292		.v_blank = {0x32, 0xB2, 0x00},
 293		.h_v_line = {0x65, 0x84, 0x89},
 294		.vsync_pol = {0x00},
 295		.int_pro_mode = {0x01},
 296		.v_blank_f = {0x49, 0x2A, 0x23},
 297		.h_sync_gen = {0x56, 0x08, 0x02},
 298		.v_sync_gen1 = {0x07, 0x20, 0x00},
 299		.v_sync_gen2 = {0x39, 0x42, 0x23},
 300		.v_sync_gen3 = {0xa4, 0x44, 0x4a},
 301		/* other don't care */
 302	},
 303	.tg = {
 304		0x00, /* cmd */
 305		0x98, 0x08, /* h_fsz */
 306		0x17, 0x01, 0x81, 0x07, /* hact */
 307		0x65, 0x04, /* v_fsz */
 308		0x01, 0x00, 0x33, 0x02, /* vsync */
 309		0x16, 0x00, 0x1c, 0x02, /* vact */
 310		0x33, 0x02, /* field_chg */
 311		0x49, 0x02, /* vact_st2 */
 312		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
 313		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 314	},
 315};
 316
 317static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = {
 318	.core = {
 319		.h_blank = {0x18, 0x01},
 320		.v_blank = {0x65, 0x6c, 0x01},
 321		.h_v_line = {0x65, 0x84, 0x89},
 322		.vsync_pol = {0x00},
 323		.int_pro_mode = {0x00},
 324		.v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
 325		.h_sync_gen = {0x56, 0x08, 0x02},
 326		.v_sync_gen1 = {0x09, 0x40, 0x00},
 327		.v_sync_gen2 = {0x01, 0x10, 0x00},
 328		.v_sync_gen3 = {0x01, 0x10, 0x00},
 329		/* other don't care */
 330	},
 331	.tg = {
 332		0x00, /* cmd */
 333		0x98, 0x08, /* h_fsz */
 334		0x17, 0x01, 0x81, 0x07, /* hact */
 335		0x65, 0x04, /* v_fsz */
 336		0x01, 0x00, 0x33, 0x02, /* vsync */
 337		0x2d, 0x00, 0x38, 0x04, /* vact */
 338		0x33, 0x02, /* field_chg */
 339		0x48, 0x02, /* vact_st2 */
 340		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
 341		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 342	},
 343};
 344
 345static const struct hdmi_v13_conf hdmi_v13_confs[] = {
 346	{ 1280, 720, 60, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
 347	{ 1280, 720, 50, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
 348	{ 720, 480, 60, false, hdmiphy_v13_conf27_027, &hdmi_v13_conf_480p },
 349	{ 1920, 1080, 50, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i50 },
 350	{ 1920, 1080, 50, false, hdmiphy_v13_conf148_5,
 351				 &hdmi_v13_conf_1080p50 },
 352	{ 1920, 1080, 60, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i60 },
 353	{ 1920, 1080, 60, false, hdmiphy_v13_conf148_5,
 354				 &hdmi_v13_conf_1080p60 },
 355};
 356
 357/* HDMI Version 1.4 */
 358static const u8 hdmiphy_conf27_027[32] = {
 359	0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
 360	0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 361	0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 362	0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
 363};
 364
 365static const u8 hdmiphy_conf74_176[32] = {
 366	0x01, 0xd1, 0x1f, 0x10, 0x40, 0x5b, 0xef, 0x08,
 367	0x81, 0xa0, 0xb9, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 368	0x5a, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 369	0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
 370};
 371
 372static const u8 hdmiphy_conf74_25[32] = {
 373	0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
 374	0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 375	0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 376	0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
 377};
 378
 379static const u8 hdmiphy_conf148_5[32] = {
 380	0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
 381	0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 382	0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 383	0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
 384};
 385
 386struct hdmi_tg_regs {
 387	u8 cmd;
 388	u8 h_fsz_l;
 389	u8 h_fsz_h;
 390	u8 hact_st_l;
 391	u8 hact_st_h;
 392	u8 hact_sz_l;
 393	u8 hact_sz_h;
 394	u8 v_fsz_l;
 395	u8 v_fsz_h;
 396	u8 vsync_l;
 397	u8 vsync_h;
 398	u8 vsync2_l;
 399	u8 vsync2_h;
 400	u8 vact_st_l;
 401	u8 vact_st_h;
 402	u8 vact_sz_l;
 403	u8 vact_sz_h;
 404	u8 field_chg_l;
 405	u8 field_chg_h;
 406	u8 vact_st2_l;
 407	u8 vact_st2_h;
 408	u8 vact_st3_l;
 409	u8 vact_st3_h;
 410	u8 vact_st4_l;
 411	u8 vact_st4_h;
 412	u8 vsync_top_hdmi_l;
 413	u8 vsync_top_hdmi_h;
 414	u8 vsync_bot_hdmi_l;
 415	u8 vsync_bot_hdmi_h;
 416	u8 field_top_hdmi_l;
 417	u8 field_top_hdmi_h;
 418	u8 field_bot_hdmi_l;
 419	u8 field_bot_hdmi_h;
 420	u8 tg_3d;
 421};
 422
 423struct hdmi_core_regs {
 424	u8 h_blank[2];
 425	u8 v2_blank[2];
 426	u8 v1_blank[2];
 427	u8 v_line[2];
 428	u8 h_line[2];
 429	u8 hsync_pol[1];
 430	u8 vsync_pol[1];
 431	u8 int_pro_mode[1];
 432	u8 v_blank_f0[2];
 433	u8 v_blank_f1[2];
 434	u8 h_sync_start[2];
 435	u8 h_sync_end[2];
 436	u8 v_sync_line_bef_2[2];
 437	u8 v_sync_line_bef_1[2];
 438	u8 v_sync_line_aft_2[2];
 439	u8 v_sync_line_aft_1[2];
 440	u8 v_sync_line_aft_pxl_2[2];
 441	u8 v_sync_line_aft_pxl_1[2];
 442	u8 v_blank_f2[2]; /* for 3D mode */
 443	u8 v_blank_f3[2]; /* for 3D mode */
 444	u8 v_blank_f4[2]; /* for 3D mode */
 445	u8 v_blank_f5[2]; /* for 3D mode */
 446	u8 v_sync_line_aft_3[2];
 447	u8 v_sync_line_aft_4[2];
 448	u8 v_sync_line_aft_5[2];
 449	u8 v_sync_line_aft_6[2];
 450	u8 v_sync_line_aft_pxl_3[2];
 451	u8 v_sync_line_aft_pxl_4[2];
 452	u8 v_sync_line_aft_pxl_5[2];
 453	u8 v_sync_line_aft_pxl_6[2];
 454	u8 vact_space_1[2];
 455	u8 vact_space_2[2];
 456	u8 vact_space_3[2];
 457	u8 vact_space_4[2];
 458	u8 vact_space_5[2];
 459	u8 vact_space_6[2];
 460};
 461
 462struct hdmi_preset_conf {
 463	struct hdmi_core_regs core;
 464	struct hdmi_tg_regs tg;
 465};
 466
 467struct hdmi_conf {
 468	int width;
 469	int height;
 470	int vrefresh;
 471	bool interlace;
 472	const u8 *hdmiphy_data;
 473	const struct hdmi_preset_conf *conf;
 474};
 475
 476static const struct hdmi_preset_conf hdmi_conf_480p60 = {
 477	.core = {
 478		.h_blank = {0x8a, 0x00},
 479		.v2_blank = {0x0d, 0x02},
 480		.v1_blank = {0x2d, 0x00},
 481		.v_line = {0x0d, 0x02},
 482		.h_line = {0x5a, 0x03},
 483		.hsync_pol = {0x01},
 484		.vsync_pol = {0x01},
 485		.int_pro_mode = {0x00},
 486		.v_blank_f0 = {0xff, 0xff},
 487		.v_blank_f1 = {0xff, 0xff},
 488		.h_sync_start = {0x0e, 0x00},
 489		.h_sync_end = {0x4c, 0x00},
 490		.v_sync_line_bef_2 = {0x0f, 0x00},
 491		.v_sync_line_bef_1 = {0x09, 0x00},
 492		.v_sync_line_aft_2 = {0xff, 0xff},
 493		.v_sync_line_aft_1 = {0xff, 0xff},
 494		.v_sync_line_aft_pxl_2 = {0xff, 0xff},
 495		.v_sync_line_aft_pxl_1 = {0xff, 0xff},
 496		.v_blank_f2 = {0xff, 0xff},
 497		.v_blank_f3 = {0xff, 0xff},
 498		.v_blank_f4 = {0xff, 0xff},
 499		.v_blank_f5 = {0xff, 0xff},
 500		.v_sync_line_aft_3 = {0xff, 0xff},
 501		.v_sync_line_aft_4 = {0xff, 0xff},
 502		.v_sync_line_aft_5 = {0xff, 0xff},
 503		.v_sync_line_aft_6 = {0xff, 0xff},
 504		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
 505		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
 506		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
 507		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
 508		.vact_space_1 = {0xff, 0xff},
 509		.vact_space_2 = {0xff, 0xff},
 510		.vact_space_3 = {0xff, 0xff},
 511		.vact_space_4 = {0xff, 0xff},
 512		.vact_space_5 = {0xff, 0xff},
 513		.vact_space_6 = {0xff, 0xff},
 514		/* other don't care */
 515	},
 516	.tg = {
 517		0x00, /* cmd */
 518		0x5a, 0x03, /* h_fsz */
 519		0x8a, 0x00, 0xd0, 0x02, /* hact */
 520		0x0d, 0x02, /* v_fsz */
 521		0x01, 0x00, 0x33, 0x02, /* vsync */
 522		0x2d, 0x00, 0xe0, 0x01, /* vact */
 523		0x33, 0x02, /* field_chg */
 524		0x48, 0x02, /* vact_st2 */
 525		0x00, 0x00, /* vact_st3 */
 526		0x00, 0x00, /* vact_st4 */
 527		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
 528		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 529		0x00, /* 3d FP */
 530	},
 531};
 532
 533static const struct hdmi_preset_conf hdmi_conf_720p50 = {
 534	.core = {
 535		.h_blank = {0xbc, 0x02},
 536		.v2_blank = {0xee, 0x02},
 537		.v1_blank = {0x1e, 0x00},
 538		.v_line = {0xee, 0x02},
 539		.h_line = {0xbc, 0x07},
 540		.hsync_pol = {0x00},
 541		.vsync_pol = {0x00},
 542		.int_pro_mode = {0x00},
 543		.v_blank_f0 = {0xff, 0xff},
 544		.v_blank_f1 = {0xff, 0xff},
 545		.h_sync_start = {0xb6, 0x01},
 546		.h_sync_end = {0xde, 0x01},
 547		.v_sync_line_bef_2 = {0x0a, 0x00},
 548		.v_sync_line_bef_1 = {0x05, 0x00},
 549		.v_sync_line_aft_2 = {0xff, 0xff},
 550		.v_sync_line_aft_1 = {0xff, 0xff},
 551		.v_sync_line_aft_pxl_2 = {0xff, 0xff},
 552		.v_sync_line_aft_pxl_1 = {0xff, 0xff},
 553		.v_blank_f2 = {0xff, 0xff},
 554		.v_blank_f3 = {0xff, 0xff},
 555		.v_blank_f4 = {0xff, 0xff},
 556		.v_blank_f5 = {0xff, 0xff},
 557		.v_sync_line_aft_3 = {0xff, 0xff},
 558		.v_sync_line_aft_4 = {0xff, 0xff},
 559		.v_sync_line_aft_5 = {0xff, 0xff},
 560		.v_sync_line_aft_6 = {0xff, 0xff},
 561		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
 562		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
 563		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
 564		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
 565		.vact_space_1 = {0xff, 0xff},
 566		.vact_space_2 = {0xff, 0xff},
 567		.vact_space_3 = {0xff, 0xff},
 568		.vact_space_4 = {0xff, 0xff},
 569		.vact_space_5 = {0xff, 0xff},
 570		.vact_space_6 = {0xff, 0xff},
 571		/* other don't care */
 572	},
 573	.tg = {
 574		0x00, /* cmd */
 575		0xbc, 0x07, /* h_fsz */
 576		0xbc, 0x02, 0x00, 0x05, /* hact */
 577		0xee, 0x02, /* v_fsz */
 578		0x01, 0x00, 0x33, 0x02, /* vsync */
 579		0x1e, 0x00, 0xd0, 0x02, /* vact */
 580		0x33, 0x02, /* field_chg */
 581		0x48, 0x02, /* vact_st2 */
 582		0x00, 0x00, /* vact_st3 */
 583		0x00, 0x00, /* vact_st4 */
 584		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
 585		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 586		0x00, /* 3d FP */
 587	},
 588};
 589
 590static const struct hdmi_preset_conf hdmi_conf_720p60 = {
 591	.core = {
 592		.h_blank = {0x72, 0x01},
 593		.v2_blank = {0xee, 0x02},
 594		.v1_blank = {0x1e, 0x00},
 595		.v_line = {0xee, 0x02},
 596		.h_line = {0x72, 0x06},
 597		.hsync_pol = {0x00},
 598		.vsync_pol = {0x00},
 599		.int_pro_mode = {0x00},
 600		.v_blank_f0 = {0xff, 0xff},
 601		.v_blank_f1 = {0xff, 0xff},
 602		.h_sync_start = {0x6c, 0x00},
 603		.h_sync_end = {0x94, 0x00},
 604		.v_sync_line_bef_2 = {0x0a, 0x00},
 605		.v_sync_line_bef_1 = {0x05, 0x00},
 606		.v_sync_line_aft_2 = {0xff, 0xff},
 607		.v_sync_line_aft_1 = {0xff, 0xff},
 608		.v_sync_line_aft_pxl_2 = {0xff, 0xff},
 609		.v_sync_line_aft_pxl_1 = {0xff, 0xff},
 610		.v_blank_f2 = {0xff, 0xff},
 611		.v_blank_f3 = {0xff, 0xff},
 612		.v_blank_f4 = {0xff, 0xff},
 613		.v_blank_f5 = {0xff, 0xff},
 614		.v_sync_line_aft_3 = {0xff, 0xff},
 615		.v_sync_line_aft_4 = {0xff, 0xff},
 616		.v_sync_line_aft_5 = {0xff, 0xff},
 617		.v_sync_line_aft_6 = {0xff, 0xff},
 618		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
 619		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
 620		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
 621		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
 622		.vact_space_1 = {0xff, 0xff},
 623		.vact_space_2 = {0xff, 0xff},
 624		.vact_space_3 = {0xff, 0xff},
 625		.vact_space_4 = {0xff, 0xff},
 626		.vact_space_5 = {0xff, 0xff},
 627		.vact_space_6 = {0xff, 0xff},
 628		/* other don't care */
 629	},
 630	.tg = {
 631		0x00, /* cmd */
 632		0x72, 0x06, /* h_fsz */
 633		0x72, 0x01, 0x00, 0x05, /* hact */
 634		0xee, 0x02, /* v_fsz */
 635		0x01, 0x00, 0x33, 0x02, /* vsync */
 636		0x1e, 0x00, 0xd0, 0x02, /* vact */
 637		0x33, 0x02, /* field_chg */
 638		0x48, 0x02, /* vact_st2 */
 639		0x00, 0x00, /* vact_st3 */
 640		0x00, 0x00, /* vact_st4 */
 641		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
 642		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 643		0x00, /* 3d FP */
 644	},
 645};
 646
 647static const struct hdmi_preset_conf hdmi_conf_1080i50 = {
 648	.core = {
 649		.h_blank = {0xd0, 0x02},
 650		.v2_blank = {0x32, 0x02},
 651		.v1_blank = {0x16, 0x00},
 652		.v_line = {0x65, 0x04},
 653		.h_line = {0x50, 0x0a},
 654		.hsync_pol = {0x00},
 655		.vsync_pol = {0x00},
 656		.int_pro_mode = {0x01},
 657		.v_blank_f0 = {0x49, 0x02},
 658		.v_blank_f1 = {0x65, 0x04},
 659		.h_sync_start = {0x0e, 0x02},
 660		.h_sync_end = {0x3a, 0x02},
 661		.v_sync_line_bef_2 = {0x07, 0x00},
 662		.v_sync_line_bef_1 = {0x02, 0x00},
 663		.v_sync_line_aft_2 = {0x39, 0x02},
 664		.v_sync_line_aft_1 = {0x34, 0x02},
 665		.v_sync_line_aft_pxl_2 = {0x38, 0x07},
 666		.v_sync_line_aft_pxl_1 = {0x38, 0x07},
 667		.v_blank_f2 = {0xff, 0xff},
 668		.v_blank_f3 = {0xff, 0xff},
 669		.v_blank_f4 = {0xff, 0xff},
 670		.v_blank_f5 = {0xff, 0xff},
 671		.v_sync_line_aft_3 = {0xff, 0xff},
 672		.v_sync_line_aft_4 = {0xff, 0xff},
 673		.v_sync_line_aft_5 = {0xff, 0xff},
 674		.v_sync_line_aft_6 = {0xff, 0xff},
 675		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
 676		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
 677		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
 678		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
 679		.vact_space_1 = {0xff, 0xff},
 680		.vact_space_2 = {0xff, 0xff},
 681		.vact_space_3 = {0xff, 0xff},
 682		.vact_space_4 = {0xff, 0xff},
 683		.vact_space_5 = {0xff, 0xff},
 684		.vact_space_6 = {0xff, 0xff},
 685		/* other don't care */
 686	},
 687	.tg = {
 688		0x00, /* cmd */
 689		0x50, 0x0a, /* h_fsz */
 690		0xd0, 0x02, 0x80, 0x07, /* hact */
 691		0x65, 0x04, /* v_fsz */
 692		0x01, 0x00, 0x33, 0x02, /* vsync */
 693		0x16, 0x00, 0x1c, 0x02, /* vact */
 694		0x33, 0x02, /* field_chg */
 695		0x49, 0x02, /* vact_st2 */
 696		0x00, 0x00, /* vact_st3 */
 697		0x00, 0x00, /* vact_st4 */
 698		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
 699		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 700		0x00, /* 3d FP */
 701	},
 702};
 703
 704static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
 705	.core = {
 706		.h_blank = {0x18, 0x01},
 707		.v2_blank = {0x32, 0x02},
 708		.v1_blank = {0x16, 0x00},
 709		.v_line = {0x65, 0x04},
 710		.h_line = {0x98, 0x08},
 711		.hsync_pol = {0x00},
 712		.vsync_pol = {0x00},
 713		.int_pro_mode = {0x01},
 714		.v_blank_f0 = {0x49, 0x02},
 715		.v_blank_f1 = {0x65, 0x04},
 716		.h_sync_start = {0x56, 0x00},
 717		.h_sync_end = {0x82, 0x00},
 718		.v_sync_line_bef_2 = {0x07, 0x00},
 719		.v_sync_line_bef_1 = {0x02, 0x00},
 720		.v_sync_line_aft_2 = {0x39, 0x02},
 721		.v_sync_line_aft_1 = {0x34, 0x02},
 722		.v_sync_line_aft_pxl_2 = {0xa4, 0x04},
 723		.v_sync_line_aft_pxl_1 = {0xa4, 0x04},
 724		.v_blank_f2 = {0xff, 0xff},
 725		.v_blank_f3 = {0xff, 0xff},
 726		.v_blank_f4 = {0xff, 0xff},
 727		.v_blank_f5 = {0xff, 0xff},
 728		.v_sync_line_aft_3 = {0xff, 0xff},
 729		.v_sync_line_aft_4 = {0xff, 0xff},
 730		.v_sync_line_aft_5 = {0xff, 0xff},
 731		.v_sync_line_aft_6 = {0xff, 0xff},
 732		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
 733		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
 734		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
 735		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
 736		.vact_space_1 = {0xff, 0xff},
 737		.vact_space_2 = {0xff, 0xff},
 738		.vact_space_3 = {0xff, 0xff},
 739		.vact_space_4 = {0xff, 0xff},
 740		.vact_space_5 = {0xff, 0xff},
 741		.vact_space_6 = {0xff, 0xff},
 742		/* other don't care */
 743	},
 744	.tg = {
 745		0x00, /* cmd */
 746		0x98, 0x08, /* h_fsz */
 747		0x18, 0x01, 0x80, 0x07, /* hact */
 748		0x65, 0x04, /* v_fsz */
 749		0x01, 0x00, 0x33, 0x02, /* vsync */
 750		0x16, 0x00, 0x1c, 0x02, /* vact */
 751		0x33, 0x02, /* field_chg */
 752		0x49, 0x02, /* vact_st2 */
 753		0x00, 0x00, /* vact_st3 */
 754		0x00, 0x00, /* vact_st4 */
 755		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
 756		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 757		0x00, /* 3d FP */
 758	},
 759};
 760
 761static const struct hdmi_preset_conf hdmi_conf_1080p30 = {
 762	.core = {
 763		.h_blank = {0x18, 0x01},
 764		.v2_blank = {0x65, 0x04},
 765		.v1_blank = {0x2d, 0x00},
 766		.v_line = {0x65, 0x04},
 767		.h_line = {0x98, 0x08},
 768		.hsync_pol = {0x00},
 769		.vsync_pol = {0x00},
 770		.int_pro_mode = {0x00},
 771		.v_blank_f0 = {0xff, 0xff},
 772		.v_blank_f1 = {0xff, 0xff},
 773		.h_sync_start = {0x56, 0x00},
 774		.h_sync_end = {0x82, 0x00},
 775		.v_sync_line_bef_2 = {0x09, 0x00},
 776		.v_sync_line_bef_1 = {0x04, 0x00},
 777		.v_sync_line_aft_2 = {0xff, 0xff},
 778		.v_sync_line_aft_1 = {0xff, 0xff},
 779		.v_sync_line_aft_pxl_2 = {0xff, 0xff},
 780		.v_sync_line_aft_pxl_1 = {0xff, 0xff},
 781		.v_blank_f2 = {0xff, 0xff},
 782		.v_blank_f3 = {0xff, 0xff},
 783		.v_blank_f4 = {0xff, 0xff},
 784		.v_blank_f5 = {0xff, 0xff},
 785		.v_sync_line_aft_3 = {0xff, 0xff},
 786		.v_sync_line_aft_4 = {0xff, 0xff},
 787		.v_sync_line_aft_5 = {0xff, 0xff},
 788		.v_sync_line_aft_6 = {0xff, 0xff},
 789		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
 790		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
 791		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
 792		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
 793		.vact_space_1 = {0xff, 0xff},
 794		.vact_space_2 = {0xff, 0xff},
 795		.vact_space_3 = {0xff, 0xff},
 796		.vact_space_4 = {0xff, 0xff},
 797		.vact_space_5 = {0xff, 0xff},
 798		.vact_space_6 = {0xff, 0xff},
 799		/* other don't care */
 800	},
 801	.tg = {
 802		0x00, /* cmd */
 803		0x98, 0x08, /* h_fsz */
 804		0x18, 0x01, 0x80, 0x07, /* hact */
 805		0x65, 0x04, /* v_fsz */
 806		0x01, 0x00, 0x33, 0x02, /* vsync */
 807		0x2d, 0x00, 0x38, 0x04, /* vact */
 808		0x33, 0x02, /* field_chg */
 809		0x48, 0x02, /* vact_st2 */
 810		0x00, 0x00, /* vact_st3 */
 811		0x00, 0x00, /* vact_st4 */
 812		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
 813		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 814		0x00, /* 3d FP */
 815	},
 816};
 817
 818static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
 819	.core = {
 820		.h_blank = {0xd0, 0x02},
 821		.v2_blank = {0x65, 0x04},
 822		.v1_blank = {0x2d, 0x00},
 823		.v_line = {0x65, 0x04},
 824		.h_line = {0x50, 0x0a},
 825		.hsync_pol = {0x00},
 826		.vsync_pol = {0x00},
 827		.int_pro_mode = {0x00},
 828		.v_blank_f0 = {0xff, 0xff},
 829		.v_blank_f1 = {0xff, 0xff},
 830		.h_sync_start = {0x0e, 0x02},
 831		.h_sync_end = {0x3a, 0x02},
 832		.v_sync_line_bef_2 = {0x09, 0x00},
 833		.v_sync_line_bef_1 = {0x04, 0x00},
 834		.v_sync_line_aft_2 = {0xff, 0xff},
 835		.v_sync_line_aft_1 = {0xff, 0xff},
 836		.v_sync_line_aft_pxl_2 = {0xff, 0xff},
 837		.v_sync_line_aft_pxl_1 = {0xff, 0xff},
 838		.v_blank_f2 = {0xff, 0xff},
 839		.v_blank_f3 = {0xff, 0xff},
 840		.v_blank_f4 = {0xff, 0xff},
 841		.v_blank_f5 = {0xff, 0xff},
 842		.v_sync_line_aft_3 = {0xff, 0xff},
 843		.v_sync_line_aft_4 = {0xff, 0xff},
 844		.v_sync_line_aft_5 = {0xff, 0xff},
 845		.v_sync_line_aft_6 = {0xff, 0xff},
 846		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
 847		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
 848		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
 849		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
 850		.vact_space_1 = {0xff, 0xff},
 851		.vact_space_2 = {0xff, 0xff},
 852		.vact_space_3 = {0xff, 0xff},
 853		.vact_space_4 = {0xff, 0xff},
 854		.vact_space_5 = {0xff, 0xff},
 855		.vact_space_6 = {0xff, 0xff},
 856		/* other don't care */
 857	},
 858	.tg = {
 859		0x00, /* cmd */
 860		0x50, 0x0a, /* h_fsz */
 861		0xd0, 0x02, 0x80, 0x07, /* hact */
 862		0x65, 0x04, /* v_fsz */
 863		0x01, 0x00, 0x33, 0x02, /* vsync */
 864		0x2d, 0x00, 0x38, 0x04, /* vact */
 865		0x33, 0x02, /* field_chg */
 866		0x48, 0x02, /* vact_st2 */
 867		0x00, 0x00, /* vact_st3 */
 868		0x00, 0x00, /* vact_st4 */
 869		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
 870		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 871		0x00, /* 3d FP */
 872	},
 873};
 874
 875static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
 876	.core = {
 877		.h_blank = {0x18, 0x01},
 878		.v2_blank = {0x65, 0x04},
 879		.v1_blank = {0x2d, 0x00},
 880		.v_line = {0x65, 0x04},
 881		.h_line = {0x98, 0x08},
 882		.hsync_pol = {0x00},
 883		.vsync_pol = {0x00},
 884		.int_pro_mode = {0x00},
 885		.v_blank_f0 = {0xff, 0xff},
 886		.v_blank_f1 = {0xff, 0xff},
 887		.h_sync_start = {0x56, 0x00},
 888		.h_sync_end = {0x82, 0x00},
 889		.v_sync_line_bef_2 = {0x09, 0x00},
 890		.v_sync_line_bef_1 = {0x04, 0x00},
 891		.v_sync_line_aft_2 = {0xff, 0xff},
 892		.v_sync_line_aft_1 = {0xff, 0xff},
 893		.v_sync_line_aft_pxl_2 = {0xff, 0xff},
 894		.v_sync_line_aft_pxl_1 = {0xff, 0xff},
 895		.v_blank_f2 = {0xff, 0xff},
 896		.v_blank_f3 = {0xff, 0xff},
 897		.v_blank_f4 = {0xff, 0xff},
 898		.v_blank_f5 = {0xff, 0xff},
 899		.v_sync_line_aft_3 = {0xff, 0xff},
 900		.v_sync_line_aft_4 = {0xff, 0xff},
 901		.v_sync_line_aft_5 = {0xff, 0xff},
 902		.v_sync_line_aft_6 = {0xff, 0xff},
 903		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
 904		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
 905		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
 906		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
 907		/* other don't care */
 908	},
 909	.tg = {
 910		0x00, /* cmd */
 911		0x98, 0x08, /* h_fsz */
 912		0x18, 0x01, 0x80, 0x07, /* hact */
 913		0x65, 0x04, /* v_fsz */
 914		0x01, 0x00, 0x33, 0x02, /* vsync */
 915		0x2d, 0x00, 0x38, 0x04, /* vact */
 916		0x33, 0x02, /* field_chg */
 917		0x48, 0x02, /* vact_st2 */
 918		0x00, 0x00, /* vact_st3 */
 919		0x00, 0x00, /* vact_st4 */
 920		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
 921		0x01, 0x00, 0x33, 0x02, /* field top/bot */
 922		0x00, /* 3d FP */
 923	},
 924};
 925
 926static const struct hdmi_conf hdmi_confs[] = {
 927	{ 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p60 },
 928	{ 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p50 },
 929	{ 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 },
 930	{ 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 },
 931	{ 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 },
 932	{ 1920, 1080, 30, false, hdmiphy_conf74_176, &hdmi_conf_1080p30 },
 933	{ 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 },
 934	{ 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 },
 935};
 936
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 937
 938static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
 939{
 940	return readl(hdata->regs + reg_id);
 941}
 942
 943static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
 944				 u32 reg_id, u8 value)
 945{
 946	writeb(value, hdata->regs + reg_id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 947}
 948
 949static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
 950				 u32 reg_id, u32 value, u32 mask)
 951{
 952	u32 old = readl(hdata->regs + reg_id);
 
 
 
 953	value = (value & mask) | (old & ~mask);
 954	writel(value, hdata->regs + reg_id);
 955}
 956
 957static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
 
 958{
 959#define DUMPREG(reg_id) \
 960	DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
 961	readl(hdata->regs + reg_id))
 962	DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
 963	DUMPREG(HDMI_INTC_FLAG);
 964	DUMPREG(HDMI_INTC_CON);
 965	DUMPREG(HDMI_HPD_STATUS);
 966	DUMPREG(HDMI_V13_PHY_RSTOUT);
 967	DUMPREG(HDMI_V13_PHY_VPLL);
 968	DUMPREG(HDMI_V13_PHY_CMU);
 969	DUMPREG(HDMI_V13_CORE_RSTOUT);
 970
 971	DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
 972	DUMPREG(HDMI_CON_0);
 973	DUMPREG(HDMI_CON_1);
 974	DUMPREG(HDMI_CON_2);
 975	DUMPREG(HDMI_SYS_STATUS);
 976	DUMPREG(HDMI_V13_PHY_STATUS);
 977	DUMPREG(HDMI_STATUS_EN);
 978	DUMPREG(HDMI_HPD);
 979	DUMPREG(HDMI_MODE_SEL);
 980	DUMPREG(HDMI_V13_HPD_GEN);
 981	DUMPREG(HDMI_V13_DC_CONTROL);
 982	DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
 983
 984	DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
 985	DUMPREG(HDMI_H_BLANK_0);
 986	DUMPREG(HDMI_H_BLANK_1);
 987	DUMPREG(HDMI_V13_V_BLANK_0);
 988	DUMPREG(HDMI_V13_V_BLANK_1);
 989	DUMPREG(HDMI_V13_V_BLANK_2);
 990	DUMPREG(HDMI_V13_H_V_LINE_0);
 991	DUMPREG(HDMI_V13_H_V_LINE_1);
 992	DUMPREG(HDMI_V13_H_V_LINE_2);
 993	DUMPREG(HDMI_VSYNC_POL);
 994	DUMPREG(HDMI_INT_PRO_MODE);
 995	DUMPREG(HDMI_V13_V_BLANK_F_0);
 996	DUMPREG(HDMI_V13_V_BLANK_F_1);
 997	DUMPREG(HDMI_V13_V_BLANK_F_2);
 998	DUMPREG(HDMI_V13_H_SYNC_GEN_0);
 999	DUMPREG(HDMI_V13_H_SYNC_GEN_1);
1000	DUMPREG(HDMI_V13_H_SYNC_GEN_2);
1001	DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
1002	DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
1003	DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
1004	DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
1005	DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
1006	DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
1007	DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
1008	DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
1009	DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
1010
1011	DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1012	DUMPREG(HDMI_TG_CMD);
1013	DUMPREG(HDMI_TG_H_FSZ_L);
1014	DUMPREG(HDMI_TG_H_FSZ_H);
1015	DUMPREG(HDMI_TG_HACT_ST_L);
1016	DUMPREG(HDMI_TG_HACT_ST_H);
1017	DUMPREG(HDMI_TG_HACT_SZ_L);
1018	DUMPREG(HDMI_TG_HACT_SZ_H);
1019	DUMPREG(HDMI_TG_V_FSZ_L);
1020	DUMPREG(HDMI_TG_V_FSZ_H);
1021	DUMPREG(HDMI_TG_VSYNC_L);
1022	DUMPREG(HDMI_TG_VSYNC_H);
1023	DUMPREG(HDMI_TG_VSYNC2_L);
1024	DUMPREG(HDMI_TG_VSYNC2_H);
1025	DUMPREG(HDMI_TG_VACT_ST_L);
1026	DUMPREG(HDMI_TG_VACT_ST_H);
1027	DUMPREG(HDMI_TG_VACT_SZ_L);
1028	DUMPREG(HDMI_TG_VACT_SZ_H);
1029	DUMPREG(HDMI_TG_FIELD_CHG_L);
1030	DUMPREG(HDMI_TG_FIELD_CHG_H);
1031	DUMPREG(HDMI_TG_VACT_ST2_L);
1032	DUMPREG(HDMI_TG_VACT_ST2_H);
1033	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
1034	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
1035	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
1036	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
1037	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
1038	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
1039	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
1040	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
1041#undef DUMPREG
1042}
1043
1044static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
1045{
1046	int i;
1047
1048#define DUMPREG(reg_id) \
1049	DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
1050	readl(hdata->regs + reg_id))
1051
1052	DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
1053	DUMPREG(HDMI_INTC_CON);
1054	DUMPREG(HDMI_INTC_FLAG);
1055	DUMPREG(HDMI_HPD_STATUS);
1056	DUMPREG(HDMI_INTC_CON_1);
1057	DUMPREG(HDMI_INTC_FLAG_1);
1058	DUMPREG(HDMI_PHY_STATUS_0);
1059	DUMPREG(HDMI_PHY_STATUS_PLL);
1060	DUMPREG(HDMI_PHY_CON_0);
1061	DUMPREG(HDMI_PHY_RSTOUT);
1062	DUMPREG(HDMI_PHY_VPLL);
1063	DUMPREG(HDMI_PHY_CMU);
1064	DUMPREG(HDMI_CORE_RSTOUT);
1065
1066	DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
1067	DUMPREG(HDMI_CON_0);
1068	DUMPREG(HDMI_CON_1);
1069	DUMPREG(HDMI_CON_2);
1070	DUMPREG(HDMI_SYS_STATUS);
1071	DUMPREG(HDMI_PHY_STATUS_0);
1072	DUMPREG(HDMI_STATUS_EN);
1073	DUMPREG(HDMI_HPD);
1074	DUMPREG(HDMI_MODE_SEL);
1075	DUMPREG(HDMI_ENC_EN);
1076	DUMPREG(HDMI_DC_CONTROL);
1077	DUMPREG(HDMI_VIDEO_PATTERN_GEN);
1078
1079	DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
1080	DUMPREG(HDMI_H_BLANK_0);
1081	DUMPREG(HDMI_H_BLANK_1);
1082	DUMPREG(HDMI_V2_BLANK_0);
1083	DUMPREG(HDMI_V2_BLANK_1);
1084	DUMPREG(HDMI_V1_BLANK_0);
1085	DUMPREG(HDMI_V1_BLANK_1);
1086	DUMPREG(HDMI_V_LINE_0);
1087	DUMPREG(HDMI_V_LINE_1);
1088	DUMPREG(HDMI_H_LINE_0);
1089	DUMPREG(HDMI_H_LINE_1);
1090	DUMPREG(HDMI_HSYNC_POL);
1091
1092	DUMPREG(HDMI_VSYNC_POL);
1093	DUMPREG(HDMI_INT_PRO_MODE);
1094	DUMPREG(HDMI_V_BLANK_F0_0);
1095	DUMPREG(HDMI_V_BLANK_F0_1);
1096	DUMPREG(HDMI_V_BLANK_F1_0);
1097	DUMPREG(HDMI_V_BLANK_F1_1);
1098
1099	DUMPREG(HDMI_H_SYNC_START_0);
1100	DUMPREG(HDMI_H_SYNC_START_1);
1101	DUMPREG(HDMI_H_SYNC_END_0);
1102	DUMPREG(HDMI_H_SYNC_END_1);
1103
1104	DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
1105	DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
1106	DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
1107	DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
1108
1109	DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
1110	DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
1111	DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
1112	DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
1113
1114	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
1115	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
1116	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
1117	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
1118
1119	DUMPREG(HDMI_V_BLANK_F2_0);
1120	DUMPREG(HDMI_V_BLANK_F2_1);
1121	DUMPREG(HDMI_V_BLANK_F3_0);
1122	DUMPREG(HDMI_V_BLANK_F3_1);
1123	DUMPREG(HDMI_V_BLANK_F4_0);
1124	DUMPREG(HDMI_V_BLANK_F4_1);
1125	DUMPREG(HDMI_V_BLANK_F5_0);
1126	DUMPREG(HDMI_V_BLANK_F5_1);
1127
1128	DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
1129	DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
1130	DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
1131	DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
1132	DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
1133	DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
1134	DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
1135	DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
1136
1137	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
1138	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
1139	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
1140	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
1141	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
1142	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
1143	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
1144	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
1145
1146	DUMPREG(HDMI_VACT_SPACE_1_0);
1147	DUMPREG(HDMI_VACT_SPACE_1_1);
1148	DUMPREG(HDMI_VACT_SPACE_2_0);
1149	DUMPREG(HDMI_VACT_SPACE_2_1);
1150	DUMPREG(HDMI_VACT_SPACE_3_0);
1151	DUMPREG(HDMI_VACT_SPACE_3_1);
1152	DUMPREG(HDMI_VACT_SPACE_4_0);
1153	DUMPREG(HDMI_VACT_SPACE_4_1);
1154	DUMPREG(HDMI_VACT_SPACE_5_0);
1155	DUMPREG(HDMI_VACT_SPACE_5_1);
1156	DUMPREG(HDMI_VACT_SPACE_6_0);
1157	DUMPREG(HDMI_VACT_SPACE_6_1);
1158
1159	DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1160	DUMPREG(HDMI_TG_CMD);
1161	DUMPREG(HDMI_TG_H_FSZ_L);
1162	DUMPREG(HDMI_TG_H_FSZ_H);
1163	DUMPREG(HDMI_TG_HACT_ST_L);
1164	DUMPREG(HDMI_TG_HACT_ST_H);
1165	DUMPREG(HDMI_TG_HACT_SZ_L);
1166	DUMPREG(HDMI_TG_HACT_SZ_H);
1167	DUMPREG(HDMI_TG_V_FSZ_L);
1168	DUMPREG(HDMI_TG_V_FSZ_H);
1169	DUMPREG(HDMI_TG_VSYNC_L);
1170	DUMPREG(HDMI_TG_VSYNC_H);
1171	DUMPREG(HDMI_TG_VSYNC2_L);
1172	DUMPREG(HDMI_TG_VSYNC2_H);
1173	DUMPREG(HDMI_TG_VACT_ST_L);
1174	DUMPREG(HDMI_TG_VACT_ST_H);
1175	DUMPREG(HDMI_TG_VACT_SZ_L);
1176	DUMPREG(HDMI_TG_VACT_SZ_H);
1177	DUMPREG(HDMI_TG_FIELD_CHG_L);
1178	DUMPREG(HDMI_TG_FIELD_CHG_H);
1179	DUMPREG(HDMI_TG_VACT_ST2_L);
1180	DUMPREG(HDMI_TG_VACT_ST2_H);
1181	DUMPREG(HDMI_TG_VACT_ST3_L);
1182	DUMPREG(HDMI_TG_VACT_ST3_H);
1183	DUMPREG(HDMI_TG_VACT_ST4_L);
1184	DUMPREG(HDMI_TG_VACT_ST4_H);
1185	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
1186	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
1187	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
1188	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
1189	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
1190	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
1191	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
1192	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
1193	DUMPREG(HDMI_TG_3D);
1194
1195	DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
1196	DUMPREG(HDMI_AVI_CON);
1197	DUMPREG(HDMI_AVI_HEADER0);
1198	DUMPREG(HDMI_AVI_HEADER1);
1199	DUMPREG(HDMI_AVI_HEADER2);
1200	DUMPREG(HDMI_AVI_CHECK_SUM);
1201	DUMPREG(HDMI_VSI_CON);
1202	DUMPREG(HDMI_VSI_HEADER0);
1203	DUMPREG(HDMI_VSI_HEADER1);
1204	DUMPREG(HDMI_VSI_HEADER2);
1205	for (i = 0; i < 7; ++i)
1206		DUMPREG(HDMI_VSI_DATA(i));
1207
1208#undef DUMPREG
1209}
1210
1211static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
1212{
1213	if (hdata->is_v13)
1214		hdmi_v13_regs_dump(hdata, prefix);
1215	else
1216		hdmi_v14_regs_dump(hdata, prefix);
1217}
1218
1219static int hdmi_v13_conf_index(struct drm_display_mode *mode)
1220{
 
 
1221	int i;
1222
1223	for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1224		if (hdmi_v13_confs[i].width == mode->hdisplay &&
1225				hdmi_v13_confs[i].height == mode->vdisplay &&
1226				hdmi_v13_confs[i].vrefresh == mode->vrefresh &&
1227				hdmi_v13_confs[i].interlace ==
1228				((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1229				 true : false))
1230			return i;
 
 
 
1231
1232	return -EINVAL;
1233}
1234
1235static int hdmi_v14_conf_index(struct drm_display_mode *mode)
1236{
1237	int i;
 
 
 
 
 
 
1238
1239	for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i)
1240		if (hdmi_confs[i].width == mode->hdisplay &&
1241				hdmi_confs[i].height == mode->vdisplay &&
1242				hdmi_confs[i].vrefresh == mode->vrefresh &&
1243				hdmi_confs[i].interlace ==
1244				((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1245				 true : false))
1246			return i;
1247
1248	return -EINVAL;
1249}
1250
1251static int hdmi_conf_index(struct hdmi_context *hdata,
1252			   struct drm_display_mode *mode)
1253{
1254	if (hdata->is_v13)
1255		return hdmi_v13_conf_index(mode);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1256
1257	return hdmi_v14_conf_index(mode);
1258}
1259
1260static bool hdmi_is_connected(void *ctx)
 
1261{
1262	struct hdmi_context *hdata = ctx;
1263
1264	return hdata->hpd;
 
 
 
 
1265}
1266
1267static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
1268				u8 *edid, int len)
1269{
1270	struct edid *raw_edid;
1271	struct hdmi_context *hdata = ctx;
 
1272
1273	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
 
 
 
 
 
 
1274
1275	if (!hdata->ddc_port)
 
 
 
 
 
 
1276		return -ENODEV;
1277
1278	raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter);
1279	if (raw_edid) {
1280		hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid);
1281		memcpy(edid, raw_edid, min((1 + raw_edid->extensions)
1282					* EDID_LENGTH, len));
1283		DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
1284			(hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
1285			raw_edid->width_cm, raw_edid->height_cm);
1286	} else {
1287		return -ENODEV;
1288	}
1289
1290	return 0;
 
 
 
 
 
 
 
 
 
 
 
 
1291}
1292
1293static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
1294{
 
1295	int i;
1296
1297	DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1298			check_timing->xres, check_timing->yres,
1299			check_timing->refresh, (check_timing->vmode &
1300			FB_VMODE_INTERLACED) ? true : false);
1301
1302	for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1303		if (hdmi_v13_confs[i].width == check_timing->xres &&
1304			hdmi_v13_confs[i].height == check_timing->yres &&
1305			hdmi_v13_confs[i].vrefresh == check_timing->refresh &&
1306			hdmi_v13_confs[i].interlace ==
1307			((check_timing->vmode & FB_VMODE_INTERLACED) ?
1308			 true : false))
1309				return 0;
1310
1311	/* TODO */
1312
 
 
1313	return -EINVAL;
1314}
1315
1316static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
 
1317{
1318	int i;
 
1319
1320	DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1321			check_timing->xres, check_timing->yres,
1322			check_timing->refresh, (check_timing->vmode &
1323			FB_VMODE_INTERLACED) ? true : false);
1324
1325	for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++)
1326		if (hdmi_confs[i].width == check_timing->xres &&
1327			hdmi_confs[i].height == check_timing->yres &&
1328			hdmi_confs[i].vrefresh == check_timing->refresh &&
1329			hdmi_confs[i].interlace ==
1330			((check_timing->vmode & FB_VMODE_INTERLACED) ?
1331			 true : false))
1332				return 0;
1333
1334	/* TODO */
 
 
1335
1336	return -EINVAL;
1337}
1338
1339static int hdmi_check_timing(void *ctx, void *timing)
 
 
 
 
 
1340{
1341	struct hdmi_context *hdata = ctx;
1342	struct fb_videomode *check_timing = timing;
 
1343
1344	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
1345
1346	DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres,
1347			check_timing->yres, check_timing->refresh,
1348			check_timing->vmode);
 
 
 
 
1349
1350	if (hdata->is_v13)
1351		return hdmi_v13_check_timing(check_timing);
1352	else
1353		return hdmi_v14_check_timing(check_timing);
 
 
 
 
 
 
1354}
1355
1356static void hdmi_set_acr(u32 freq, u8 *acr)
 
 
1357{
1358	u32 n, cts;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1359
1360	switch (freq) {
1361	case 32000:
1362		n = 4096;
1363		cts = 27000;
1364		break;
1365	case 44100:
1366		n = 6272;
1367		cts = 30000;
1368		break;
1369	case 88200:
1370		n = 12544;
1371		cts = 30000;
1372		break;
1373	case 176400:
1374		n = 25088;
1375		cts = 30000;
1376		break;
1377	case 48000:
1378		n = 6144;
1379		cts = 27000;
1380		break;
1381	case 96000:
1382		n = 12288;
1383		cts = 27000;
1384		break;
1385	case 192000:
1386		n = 24576;
1387		cts = 27000;
1388		break;
1389	default:
1390		n = 0;
1391		cts = 0;
1392		break;
1393	}
1394
1395	acr[1] = cts >> 16;
1396	acr[2] = cts >> 8 & 0xff;
1397	acr[3] = cts & 0xff;
1398
1399	acr[4] = n >> 16;
1400	acr[5] = n >> 8 & 0xff;
1401	acr[6] = n & 0xff;
1402}
1403
1404static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
1405{
1406	hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]);
1407	hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]);
1408	hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]);
1409	hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]);
1410	hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]);
1411	hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]);
1412	hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]);
1413	hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
1414	hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
1415
1416	if (hdata->is_v13)
1417		hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
1418	else
1419		hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1420}
1421
1422static void hdmi_audio_init(struct hdmi_context *hdata)
1423{
1424	u32 sample_rate, bits_per_sample, frame_size_code;
1425	u32 data_num, bit_ch, sample_frq;
1426	u32 val;
1427	u8 acr[7];
1428
1429	sample_rate = 44100;
1430	bits_per_sample = 16;
1431	frame_size_code = 0;
1432
1433	switch (bits_per_sample) {
 
 
 
 
 
 
 
 
 
 
 
 
1434	case 20:
1435		data_num = 2;
1436		bit_ch  = 1;
1437		break;
1438	case 24:
1439		data_num = 3;
1440		bit_ch  = 1;
1441		break;
1442	default:
1443		data_num = 1;
1444		bit_ch  = 0;
1445		break;
1446	}
1447
1448	hdmi_set_acr(sample_rate, acr);
1449	hdmi_reg_acr(hdata, acr);
1450
1451	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1452				| HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1453				| HDMI_I2S_MUX_ENABLE);
1454
1455	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1456			| HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1457
1458	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1459
1460	sample_frq = (sample_rate == 44100) ? 0 :
1461			(sample_rate == 48000) ? 2 :
1462			(sample_rate == 32000) ? 3 :
1463			(sample_rate == 96000) ? 0xa : 0x0;
1464
1465	hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1466	hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1467
1468	val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1469	hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1470
1471	/* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1472	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1473			| HDMI_I2S_SEL_LRCK(6));
1474	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1475			| HDMI_I2S_SEL_SDATA2(4));
 
 
1476	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1477			| HDMI_I2S_SEL_SDATA2(2));
 
1478	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1479
1480	/* I2S_CON_1 & 2 */
1481	hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1482			| HDMI_I2S_L_CH_LOW_POL);
1483	hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1484			| HDMI_I2S_SET_BIT_CH(bit_ch)
1485			| HDMI_I2S_SET_SDATA_BIT(data_num)
1486			| HDMI_I2S_BASIC_FORMAT);
1487
1488	/* Configure register related to CUV information */
1489	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1490			| HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1491			| HDMI_I2S_COPYRIGHT
1492			| HDMI_I2S_LINEAR_PCM
1493			| HDMI_I2S_CONSUMER_FORMAT);
1494	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1495	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1496	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1497			| HDMI_I2S_SET_SMP_FREQ(sample_frq));
1498	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1499			HDMI_I2S_ORG_SMP_FREQ_44_1
1500			| HDMI_I2S_WORD_LEN_MAX24_24BITS
1501			| HDMI_I2S_WORD_LEN_MAX_24BITS);
1502
1503	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1504}
1505
1506static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1507{
 
 
1508	if (hdata->dvi_mode)
1509		return;
1510
1511	hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1512	hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
 
1513			HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1514}
1515
1516static void hdmi_conf_reset(struct hdmi_context *hdata)
1517{
1518	u32 reg;
 
1519
1520	if (hdata->is_v13)
1521		reg = HDMI_V13_CORE_RSTOUT;
1522	else
1523		reg = HDMI_CORE_RSTOUT;
1524
1525	/* resetting HDMI core */
1526	hdmi_reg_writemask(hdata, reg,  0, HDMI_CORE_SW_RSTOUT);
1527	mdelay(10);
1528	hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
1529	mdelay(10);
1530}
1531
1532static void hdmi_conf_init(struct hdmi_context *hdata)
1533{
1534	/* enable HPD interrupts */
1535	hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1536		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1537	mdelay(10);
1538	hdmi_reg_writemask(hdata, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL |
1539		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1540
1541	/* choose HDMI mode */
1542	hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1543		HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
 
 
1544	/* disable bluescreen */
1545	hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1546
1547	if (hdata->dvi_mode) {
1548		/* choose DVI mode */
1549		hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1550				HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1551		hdmi_reg_writeb(hdata, HDMI_CON_2,
1552				HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1553	}
1554
1555	if (hdata->is_v13) {
1556		/* choose bluescreen (fecal) color */
1557		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1558		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1559		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1560
1561		/* enable AVI packet every vsync, fixes purple line problem */
1562		hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1563		/* force RGB, look to CEA-861-D, table 7 for more detail */
1564		hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1565		hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1566
1567		hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1568		hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1569		hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1570	} else {
 
 
1571		/* enable AVI packet every vsync, fixes purple line problem */
1572		hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02);
1573		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5);
1574		hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1575	}
1576}
1577
1578static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
1579{
1580	const struct hdmi_v13_preset_conf *conf =
1581		hdmi_v13_confs[hdata->cur_conf].conf;
1582	const struct hdmi_v13_core_regs *core = &conf->core;
1583	const struct hdmi_v13_tg_regs *tg = &conf->tg;
1584	int tries;
1585
1586	/* setting core registers */
1587	hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1588	hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1589	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1590	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1591	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1592	hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1593	hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1594	hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1595	hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1596	hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1597	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1598	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1599	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1600	hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1601	hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1602	hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1603	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1604	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1605	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1606	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1607	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1608	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1609	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1610	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1611	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1612	/* Timing generator registers */
1613	hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1614	hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1615	hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1616	hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1617	hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1618	hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1619	hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1620	hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1621	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1622	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1623	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1624	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1625	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1626	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1627	hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1628	hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1629	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1630	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1631	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1632	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1633	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1634	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1635	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1636	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1637	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1638	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1639	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1640	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1641
1642	/* waiting for HDMIPHY's PLL to get to steady state */
1643	for (tries = 100; tries; --tries) {
1644		u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1645		if (val & HDMI_PHY_STATUS_READY)
1646			break;
1647		mdelay(1);
1648	}
1649	/* steady state not achieved */
1650	if (tries == 0) {
1651		DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1652		hdmi_regs_dump(hdata, "timing apply");
1653	}
1654
1655	clk_disable(hdata->res.sclk_hdmi);
1656	clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1657	clk_enable(hdata->res.sclk_hdmi);
1658
1659	/* enable HDMI and timing generator */
1660	hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1661	if (core->int_pro_mode[0])
1662		hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1663				HDMI_FIELD_EN);
1664	else
1665		hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1666}
1667
1668static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1669{
1670	const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf;
1671	const struct hdmi_core_regs *core = &conf->core;
1672	const struct hdmi_tg_regs *tg = &conf->tg;
1673	int tries;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1674
1675	/* setting core registers */
1676	hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1677	hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1678	hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
1679	hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
1680	hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
1681	hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
1682	hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
1683	hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1684	hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1685	hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1686	hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
1687	hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1688	hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1689	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
1690	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
1691	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
1692	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
1693	hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
1694	hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
1695	hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
1696	hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
1697	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
1698			core->v_sync_line_bef_2[0]);
1699	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
1700			core->v_sync_line_bef_2[1]);
1701	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
1702			core->v_sync_line_bef_1[0]);
1703	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1704			core->v_sync_line_bef_1[1]);
1705	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1706			core->v_sync_line_aft_2[0]);
1707	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1708			core->v_sync_line_aft_2[1]);
1709	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1710			core->v_sync_line_aft_1[0]);
1711	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1712			core->v_sync_line_aft_1[1]);
1713	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1714			core->v_sync_line_aft_pxl_2[0]);
1715	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1716			core->v_sync_line_aft_pxl_2[1]);
1717	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1718			core->v_sync_line_aft_pxl_1[0]);
1719	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1720			core->v_sync_line_aft_pxl_1[1]);
1721	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1722	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1723	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1724	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1725	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1726	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1727	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1728	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1729	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1730			core->v_sync_line_aft_3[0]);
1731	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1732			core->v_sync_line_aft_3[1]);
1733	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1734			core->v_sync_line_aft_4[0]);
1735	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1736			core->v_sync_line_aft_4[1]);
1737	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1738			core->v_sync_line_aft_5[0]);
1739	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1740			core->v_sync_line_aft_5[1]);
1741	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1742			core->v_sync_line_aft_6[0]);
1743	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1744			core->v_sync_line_aft_6[1]);
1745	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1746			core->v_sync_line_aft_pxl_3[0]);
1747	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1748			core->v_sync_line_aft_pxl_3[1]);
1749	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1750			core->v_sync_line_aft_pxl_4[0]);
1751	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1752			core->v_sync_line_aft_pxl_4[1]);
1753	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1754			core->v_sync_line_aft_pxl_5[0]);
1755	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1756			core->v_sync_line_aft_pxl_5[1]);
1757	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1758			core->v_sync_line_aft_pxl_6[0]);
1759	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1760			core->v_sync_line_aft_pxl_6[1]);
1761	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1762	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1763	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1764	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1765	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1766	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1767	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1768	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1769	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1770	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1771	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1772	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1773
1774	/* Timing generator registers */
1775	hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1776	hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1777	hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1778	hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1779	hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1780	hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1781	hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1782	hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1783	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1784	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1785	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1786	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1787	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1788	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1789	hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1790	hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1791	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1792	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1793	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1794	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1795	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l);
1796	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h);
1797	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l);
1798	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h);
1799	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1800	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1801	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1802	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1803	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1804	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1805	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1806	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1807	hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d);
1808
1809	/* waiting for HDMIPHY's PLL to get to steady state */
1810	for (tries = 100; tries; --tries) {
1811		u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
1812		if (val & HDMI_PHY_STATUS_READY)
1813			break;
1814		mdelay(1);
1815	}
1816	/* steady state not achieved */
1817	if (tries == 0) {
1818		DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1819		hdmi_regs_dump(hdata, "timing apply");
1820	}
1821
1822	clk_disable(hdata->res.sclk_hdmi);
1823	clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1824	clk_enable(hdata->res.sclk_hdmi);
1825
1826	/* enable HDMI and timing generator */
1827	hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1828	if (core->int_pro_mode[0])
1829		hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1830				HDMI_FIELD_EN);
1831	else
1832		hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1833}
1834
1835static void hdmi_timing_apply(struct hdmi_context *hdata)
1836{
1837	if (hdata->is_v13)
1838		hdmi_v13_timing_apply(hdata);
1839	else
1840		hdmi_v14_timing_apply(hdata);
 
 
1841}
1842
1843static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1844{
1845	u8 buffer[2];
1846	u32 reg;
 
 
 
 
 
 
 
1847
1848	clk_disable(hdata->res.sclk_hdmi);
1849	clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
1850	clk_enable(hdata->res.sclk_hdmi);
1851
1852	/* operation mode */
1853	buffer[0] = 0x1f;
1854	buffer[1] = 0x00;
1855
1856	if (hdata->hdmiphy_port)
1857		i2c_master_send(hdata->hdmiphy_port, buffer, 2);
1858
1859	if (hdata->is_v13)
1860		reg = HDMI_V13_PHY_RSTOUT;
1861	else
1862		reg = HDMI_PHY_RSTOUT;
1863
1864	/* reset hdmiphy */
1865	hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
1866	mdelay(10);
1867	hdmi_reg_writemask(hdata, reg,  0, HDMI_PHY_SW_RSTOUT);
1868	mdelay(10);
1869}
1870
1871static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1872{
1873	const u8 *hdmiphy_data;
1874	u8 buffer[32];
1875	u8 operation[2];
1876	u8 read_buffer[32] = {0, };
1877	int ret;
1878	int i;
1879
1880	if (!hdata->hdmiphy_port) {
1881		DRM_ERROR("hdmiphy is not attached\n");
 
1882		return;
1883	}
 
 
 
1884
1885	/* pixel clock */
1886	if (hdata->is_v13)
1887		hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
1888	else
1889		hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
1890
1891	memcpy(buffer, hdmiphy_data, 32);
1892	ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
1893	if (ret != 32) {
1894		DRM_ERROR("failed to configure HDMIPHY via I2C\n");
1895		return;
1896	}
 
 
 
 
 
1897
1898	mdelay(10);
 
 
 
 
 
 
 
 
1899
1900	/* operation mode */
1901	operation[0] = 0x1f;
1902	operation[1] = 0x80;
1903
1904	ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
1905	if (ret != 2) {
1906		DRM_ERROR("failed to enable hdmiphy\n");
1907		return;
1908	}
1909
1910	ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
1911	if (ret < 0) {
1912		DRM_ERROR("failed to read hdmiphy config\n");
 
 
 
 
 
1913		return;
1914	}
1915
1916	for (i = 0; i < ret; i++)
1917		DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
1918			"recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
1919}
1920
1921static void hdmi_conf_apply(struct hdmi_context *hdata)
1922{
1923	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1924
1925	hdmiphy_conf_reset(hdata);
1926	hdmiphy_conf_apply(hdata);
1927
1928	mutex_lock(&hdata->hdmi_mutex);
1929	hdmi_conf_reset(hdata);
1930	hdmi_conf_init(hdata);
1931	mutex_unlock(&hdata->hdmi_mutex);
1932
1933	hdmi_audio_init(hdata);
1934
1935	/* setting core registers */
1936	hdmi_timing_apply(hdata);
1937	hdmi_audio_control(hdata, true);
1938
1939	hdmi_regs_dump(hdata, "start");
1940}
1941
1942static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
1943				struct drm_display_mode *mode,
1944				struct drm_display_mode *adjusted_mode)
1945{
1946	struct drm_display_mode *m;
1947	struct hdmi_context *hdata = ctx;
1948	int index;
 
1949
1950	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1951
1952	drm_mode_set_crtcinfo(adjusted_mode, 0);
1953
1954	if (hdata->is_v13)
1955		index = hdmi_v13_conf_index(adjusted_mode);
1956	else
1957		index = hdmi_v14_conf_index(adjusted_mode);
1958
1959	/* just return if user desired mode exists. */
1960	if (index >= 0)
1961		return;
1962
1963	/*
1964	 * otherwise, find the most suitable mode among modes and change it
1965	 * to adjusted_mode.
1966	 */
1967	list_for_each_entry(m, &connector->modes, head) {
1968		if (hdata->is_v13)
1969			index = hdmi_v13_conf_index(m);
1970		else
1971			index = hdmi_v14_conf_index(m);
1972
1973		if (index >= 0) {
1974			DRM_INFO("desired mode doesn't exist so\n");
1975			DRM_INFO("use the most suitable mode among modes.\n");
1976			memcpy(adjusted_mode, m, sizeof(*m));
1977			break;
1978		}
1979	}
1980}
1981
1982static void hdmi_mode_set(void *ctx, void *mode)
1983{
1984	struct hdmi_context *hdata = ctx;
1985	int conf_idx;
 
1986
1987	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
1988
1989	conf_idx = hdmi_conf_index(hdata, mode);
1990	if (conf_idx >= 0)
1991		hdata->cur_conf = conf_idx;
1992	else
1993		DRM_DEBUG_KMS("not supported mode\n");
1994}
1995
1996static void hdmi_get_max_resol(void *ctx, unsigned int *width,
1997					unsigned int *height)
1998{
1999	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
 
2000
2001	*width = MAX_WIDTH;
2002	*height = MAX_HEIGHT;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2003}
2004
2005static void hdmi_commit(void *ctx)
 
 
 
 
 
 
 
 
 
 
2006{
2007	struct hdmi_context *hdata = ctx;
 
 
 
 
2008
2009	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
2010
2011	hdmi_conf_apply(hdata);
2012}
2013
2014static void hdmi_poweron(struct hdmi_context *hdata)
 
 
2015{
2016	struct hdmi_resources *res = &hdata->res;
 
 
 
 
 
 
 
 
 
 
2017
2018	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
 
2019
2020	mutex_lock(&hdata->hdmi_mutex);
2021	if (hdata->powered) {
2022		mutex_unlock(&hdata->hdmi_mutex);
2023		return;
2024	}
2025
2026	hdata->powered = true;
 
 
 
 
 
 
 
 
 
 
 
2027
2028	if (hdata->cfg_hpd)
2029		hdata->cfg_hpd(true);
2030	mutex_unlock(&hdata->hdmi_mutex);
2031
2032	pm_runtime_get_sync(hdata->dev);
2033
2034	regulator_bulk_enable(res->regul_count, res->regul_bulk);
2035	clk_enable(res->hdmiphy);
2036	clk_enable(res->hdmi);
2037	clk_enable(res->sclk_hdmi);
2038}
2039
2040static void hdmi_poweroff(struct hdmi_context *hdata)
 
2041{
2042	struct hdmi_resources *res = &hdata->res;
 
2043
2044	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2045
2046	mutex_lock(&hdata->hdmi_mutex);
2047	if (!hdata->powered)
2048		goto out;
2049	mutex_unlock(&hdata->hdmi_mutex);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2050
2051	/*
2052	 * The TV power domain needs any condition of hdmiphy to turn off and
2053	 * its reset state seems to meet the condition.
2054	 */
2055	hdmiphy_conf_reset(hdata);
2056
2057	clk_disable(res->sclk_hdmi);
2058	clk_disable(res->hdmi);
2059	clk_disable(res->hdmiphy);
2060	regulator_bulk_disable(res->regul_count, res->regul_bulk);
2061
2062	pm_runtime_put_sync(hdata->dev);
 
 
2063
2064	mutex_lock(&hdata->hdmi_mutex);
2065	if (hdata->cfg_hpd)
2066		hdata->cfg_hpd(false);
2067
2068	hdata->powered = false;
 
2069
2070out:
2071	mutex_unlock(&hdata->hdmi_mutex);
2072}
2073
2074static void hdmi_dpms(void *ctx, int mode)
 
 
2075{
2076	struct hdmi_context *hdata = ctx;
 
2077
2078	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
2079
2080	switch (mode) {
2081	case DRM_MODE_DPMS_ON:
2082		hdmi_poweron(hdata);
2083		break;
2084	case DRM_MODE_DPMS_STANDBY:
2085	case DRM_MODE_DPMS_SUSPEND:
2086	case DRM_MODE_DPMS_OFF:
2087		hdmi_poweroff(hdata);
2088		break;
2089	default:
2090		DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
2091		break;
2092	}
 
 
2093}
2094
2095static struct exynos_hdmi_ops hdmi_ops = {
2096	/* display */
2097	.is_connected	= hdmi_is_connected,
2098	.get_edid	= hdmi_get_edid,
2099	.check_timing	= hdmi_check_timing,
 
 
 
 
 
 
 
 
 
 
 
 
2100
2101	/* manager */
2102	.mode_fixup	= hdmi_mode_fixup,
2103	.mode_set	= hdmi_mode_set,
2104	.get_max_resol	= hdmi_get_max_resol,
2105	.commit		= hdmi_commit,
2106	.dpms		= hdmi_dpms,
2107};
2108
2109static irqreturn_t hdmi_external_irq_thread(int irq, void *arg)
2110{
2111	struct exynos_drm_hdmi_context *ctx = arg;
2112	struct hdmi_context *hdata = ctx->ctx;
2113
2114	if (!hdata->get_hpd)
2115		goto out;
2116
2117	mutex_lock(&hdata->hdmi_mutex);
2118	hdata->hpd = hdata->get_hpd();
2119	mutex_unlock(&hdata->hdmi_mutex);
 
 
2120
2121	if (ctx->drm_dev)
2122		drm_helper_hpd_irq_event(ctx->drm_dev);
 
 
2123
2124out:
2125	return IRQ_HANDLED;
2126}
2127
2128static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg)
2129{
2130	struct exynos_drm_hdmi_context *ctx = arg;
2131	struct hdmi_context *hdata = ctx->ctx;
2132	u32 intc_flag;
2133
2134	intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
2135	/* clearing flags for HPD plug/unplug */
2136	if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
2137		DRM_DEBUG_KMS("unplugged\n");
2138		hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2139			HDMI_INTC_FLAG_HPD_UNPLUG);
2140	}
2141	if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
2142		DRM_DEBUG_KMS("plugged\n");
2143		hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2144			HDMI_INTC_FLAG_HPD_PLUG);
2145	}
2146
2147	mutex_lock(&hdata->hdmi_mutex);
2148	hdata->hpd = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
2149	if (hdata->powered && hdata->hpd) {
2150		mutex_unlock(&hdata->hdmi_mutex);
2151		goto out;
2152	}
2153	mutex_unlock(&hdata->hdmi_mutex);
2154
2155	if (ctx->drm_dev)
2156		drm_helper_hpd_irq_event(ctx->drm_dev);
 
 
 
2157
2158out:
2159	return IRQ_HANDLED;
2160}
2161
2162static int __devinit hdmi_resources_init(struct hdmi_context *hdata)
2163{
2164	struct device *dev = hdata->dev;
2165	struct hdmi_resources *res = &hdata->res;
2166	static char *supply[] = {
2167		"hdmi-en",
2168		"vdd",
2169		"vdd_osc",
2170		"vdd_pll",
2171	};
2172	int i, ret;
2173
2174	DRM_DEBUG_KMS("HDMI resource init\n");
2175
2176	memset(res, 0, sizeof *res);
 
 
 
 
2177
2178	/* get clocks, power */
2179	res->hdmi = clk_get(dev, "hdmi");
2180	if (IS_ERR_OR_NULL(res->hdmi)) {
2181		DRM_ERROR("failed to get clock 'hdmi'\n");
2182		goto fail;
2183	}
2184	res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
2185	if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
2186		DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2187		goto fail;
2188	}
2189	res->sclk_pixel = clk_get(dev, "sclk_pixel");
2190	if (IS_ERR_OR_NULL(res->sclk_pixel)) {
2191		DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2192		goto fail;
2193	}
2194	res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy");
2195	if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
2196		DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2197		goto fail;
2198	}
2199	res->hdmiphy = clk_get(dev, "hdmiphy");
2200	if (IS_ERR_OR_NULL(res->hdmiphy)) {
2201		DRM_ERROR("failed to get clock 'hdmiphy'\n");
2202		goto fail;
2203	}
2204
2205	clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
2206
2207	res->regul_bulk = kzalloc(ARRAY_SIZE(supply) *
2208		sizeof res->regul_bulk[0], GFP_KERNEL);
2209	if (!res->regul_bulk) {
2210		DRM_ERROR("failed to get memory for regulators\n");
2211		goto fail;
2212	}
2213	for (i = 0; i < ARRAY_SIZE(supply); ++i) {
2214		res->regul_bulk[i].supply = supply[i];
2215		res->regul_bulk[i].consumer = NULL;
2216	}
2217	ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
 
 
 
 
 
 
 
 
 
 
 
 
2218	if (ret) {
2219		DRM_ERROR("failed to get regulators\n");
2220		goto fail;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2221	}
2222	res->regul_count = ARRAY_SIZE(supply);
2223
2224	return 0;
2225fail:
2226	DRM_ERROR("HDMI resource init - failed\n");
2227	return -ENODEV;
2228}
2229
2230static int hdmi_resources_cleanup(struct hdmi_context *hdata)
2231{
2232	struct hdmi_resources *res = &hdata->res;
2233
2234	regulator_bulk_free(res->regul_count, res->regul_bulk);
2235	/* kfree is NULL-safe */
2236	kfree(res->regul_bulk);
2237	if (!IS_ERR_OR_NULL(res->hdmiphy))
2238		clk_put(res->hdmiphy);
2239	if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
2240		clk_put(res->sclk_hdmiphy);
2241	if (!IS_ERR_OR_NULL(res->sclk_pixel))
2242		clk_put(res->sclk_pixel);
2243	if (!IS_ERR_OR_NULL(res->sclk_hdmi))
2244		clk_put(res->sclk_hdmi);
2245	if (!IS_ERR_OR_NULL(res->hdmi))
2246		clk_put(res->hdmi);
2247	memset(res, 0, sizeof *res);
2248
2249	return 0;
 
2250}
2251
2252static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
 
 
 
2253
2254void hdmi_attach_ddc_client(struct i2c_client *ddc)
2255{
2256	if (ddc)
2257		hdmi_ddc = ddc;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2258}
2259
2260void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
2261{
2262	if (hdmiphy)
2263		hdmi_hdmiphy = hdmiphy;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2264}
2265
2266static int __devinit hdmi_probe(struct platform_device *pdev)
2267{
 
2268	struct device *dev = &pdev->dev;
2269	struct exynos_drm_hdmi_context *drm_hdmi_ctx;
2270	struct hdmi_context *hdata;
2271	struct exynos_drm_hdmi_pdata *pdata;
2272	struct resource *res;
2273	int ret;
2274
2275	DRM_DEBUG_KMS("[%d]\n", __LINE__);
2276
2277	pdata = pdev->dev.platform_data;
2278	if (!pdata) {
2279		DRM_ERROR("no platform data specified\n");
2280		return -EINVAL;
2281	}
2282
2283	drm_hdmi_ctx = kzalloc(sizeof(*drm_hdmi_ctx), GFP_KERNEL);
2284	if (!drm_hdmi_ctx) {
2285		DRM_ERROR("failed to allocate common hdmi context.\n");
2286		return -ENOMEM;
2287	}
2288
2289	hdata = kzalloc(sizeof(struct hdmi_context), GFP_KERNEL);
2290	if (!hdata) {
2291		DRM_ERROR("out of memory\n");
2292		kfree(drm_hdmi_ctx);
2293		return -ENOMEM;
2294	}
2295
2296	mutex_init(&hdata->hdmi_mutex);
2297
2298	drm_hdmi_ctx->ctx = (void *)hdata;
2299	hdata->parent_ctx = (void *)drm_hdmi_ctx;
2300
2301	platform_set_drvdata(pdev, drm_hdmi_ctx);
2302
2303	hdata->is_v13 = pdata->is_v13;
2304	hdata->cfg_hpd = pdata->cfg_hpd;
2305	hdata->get_hpd = pdata->get_hpd;
2306	hdata->dev = dev;
2307
2308	ret = hdmi_resources_init(hdata);
2309	if (ret) {
2310		ret = -EINVAL;
2311		goto err_data;
 
2312	}
2313
2314	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2315	if (!res) {
2316		DRM_ERROR("failed to find registers\n");
2317		ret = -ENOENT;
2318		goto err_resource;
2319	}
2320
2321	hdata->regs_res = request_mem_region(res->start, resource_size(res),
2322					   dev_name(dev));
2323	if (!hdata->regs_res) {
2324		DRM_ERROR("failed to claim register region\n");
2325		ret = -ENOENT;
2326		goto err_resource;
2327	}
2328
2329	hdata->regs = ioremap(res->start, resource_size(res));
2330	if (!hdata->regs) {
2331		DRM_ERROR("failed to map registers\n");
2332		ret = -ENXIO;
2333		goto err_req_region;
2334	}
2335
2336	/* DDC i2c driver */
2337	if (i2c_add_driver(&ddc_driver)) {
2338		DRM_ERROR("failed to register ddc i2c driver\n");
2339		ret = -ENOENT;
2340		goto err_iomap;
2341	}
2342
2343	hdata->ddc_port = hdmi_ddc;
2344
2345	/* hdmiphy i2c driver */
2346	if (i2c_add_driver(&hdmiphy_driver)) {
2347		DRM_ERROR("failed to register hdmiphy i2c driver\n");
2348		ret = -ENOENT;
2349		goto err_ddc;
2350	}
2351
2352	hdata->hdmiphy_port = hdmi_hdmiphy;
2353
2354	hdata->external_irq = platform_get_irq_byname(pdev, "external_irq");
2355	if (hdata->external_irq < 0) {
2356		DRM_ERROR("failed to get platform irq\n");
2357		ret = hdata->external_irq;
2358		goto err_hdmiphy;
2359	}
2360
2361	hdata->internal_irq = platform_get_irq_byname(pdev, "internal_irq");
2362	if (hdata->internal_irq < 0) {
2363		DRM_ERROR("failed to get platform internal irq\n");
2364		ret = hdata->internal_irq;
2365		goto err_hdmiphy;
 
 
 
2366	}
2367
2368	ret = request_threaded_irq(hdata->external_irq, NULL,
2369			hdmi_external_irq_thread, IRQF_TRIGGER_RISING |
2370			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2371			"hdmi_external", drm_hdmi_ctx);
2372	if (ret) {
2373		DRM_ERROR("failed to register hdmi internal interrupt\n");
2374		goto err_hdmiphy;
2375	}
2376
2377	if (hdata->cfg_hpd)
2378		hdata->cfg_hpd(false);
2379
2380	ret = request_threaded_irq(hdata->internal_irq, NULL,
2381			hdmi_internal_irq_thread, IRQF_ONESHOT,
2382			"hdmi_internal", drm_hdmi_ctx);
2383	if (ret) {
2384		DRM_ERROR("failed to register hdmi internal interrupt\n");
2385		goto err_free_irq;
2386	}
 
 
 
 
 
 
 
2387
2388	/* register specific callbacks to common hdmi. */
2389	exynos_hdmi_ops_register(&hdmi_ops);
2390
2391	pm_runtime_enable(dev);
 
2392
2393	return 0;
 
 
2394
2395err_free_irq:
2396	free_irq(hdata->external_irq, drm_hdmi_ctx);
2397err_hdmiphy:
2398	i2c_del_driver(&hdmiphy_driver);
 
 
 
2399err_ddc:
2400	i2c_del_driver(&ddc_driver);
2401err_iomap:
2402	iounmap(hdata->regs);
2403err_req_region:
2404	release_mem_region(hdata->regs_res->start,
2405			resource_size(hdata->regs_res));
2406err_resource:
2407	hdmi_resources_cleanup(hdata);
2408err_data:
2409	kfree(hdata);
2410	kfree(drm_hdmi_ctx);
2411	return ret;
2412}
2413
2414static int __devexit hdmi_remove(struct platform_device *pdev)
2415{
2416	struct device *dev = &pdev->dev;
2417	struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
2418	struct hdmi_context *hdata = ctx->ctx;
2419
2420	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
2421
2422	pm_runtime_disable(dev);
 
2423
2424	free_irq(hdata->internal_irq, hdata);
 
2425
2426	hdmi_resources_cleanup(hdata);
 
2427
2428	iounmap(hdata->regs);
 
2429
2430	release_mem_region(hdata->regs_res->start,
2431			resource_size(hdata->regs_res));
2432
2433	/* hdmiphy i2c driver */
2434	i2c_del_driver(&hdmiphy_driver);
2435	/* DDC i2c driver */
2436	i2c_del_driver(&ddc_driver);
2437
2438	kfree(hdata);
2439
2440	return 0;
2441}
2442
2443#ifdef CONFIG_PM_SLEEP
2444static int hdmi_suspend(struct device *dev)
2445{
2446	struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2447	struct hdmi_context *hdata = ctx->ctx;
2448
2449	disable_irq(hdata->internal_irq);
2450	disable_irq(hdata->external_irq);
2451
2452	hdata->hpd = false;
2453	if (ctx->drm_dev)
2454		drm_helper_hpd_irq_event(ctx->drm_dev);
2455
2456	hdmi_poweroff(hdata);
2457
2458	return 0;
2459}
2460
2461static int hdmi_resume(struct device *dev)
2462{
2463	struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2464	struct hdmi_context *hdata = ctx->ctx;
 
 
 
 
2465
2466	enable_irq(hdata->external_irq);
2467	enable_irq(hdata->internal_irq);
2468	return 0;
2469}
2470#endif
2471
2472static SIMPLE_DEV_PM_OPS(hdmi_pm_ops, hdmi_suspend, hdmi_resume);
 
 
 
 
2473
2474struct platform_driver hdmi_driver = {
2475	.probe		= hdmi_probe,
2476	.remove		= __devexit_p(hdmi_remove),
2477	.driver		= {
2478		.name	= "exynos4-hdmi",
2479		.owner	= THIS_MODULE,
2480		.pm	= &hdmi_pm_ops,
 
2481	},
2482};