All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver
@ 2013-08-30  6:59 Rahul Sharma
  2013-08-30  6:59 ` [PATCH 1/7] " Rahul Sharma
                   ` (7 more replies)
  0 siblings, 8 replies; 45+ messages in thread
From: Rahul Sharma @ 2013-08-30  6:59 UTC (permalink / raw)
  To: linux-samsung-soc, dri-devel
  Cc: kgene.kim, sw0312.kim, inki.dae, seanpaul, l.stach, tomasz.figa,
	s.nawrocki, joshi, r.sh.open, Rahul Sharma

Currently, exynos hdmiphy operations and configs are kept
inside the hdmi driver. Hdmiphy related code is tightly
coupled with hdmi IP driver.

This series also removes hdmiphy dummy clock for hdmiphy
and replace it with Phy PMU Control from the hdmiphy driver.

At the end, support for exynos5420 hdmiphy is added to the
hdmiphy driver which is a platform device.

Drm related paches are based on exynos-drm-next branch at
git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git

Arch patches are dependent on 
http://www.mail-archive.com/linux-samsung-soc@vger.kernel.org/msg22195.html

Rahul Sharma (7):
  drm/exynos: move hdmiphy related code to hdmiphy driver
  drm/exynos: remove dummy hdmiphy clock
  drm/exynos: add hdmiphy pmu bit control in hdmiphy driver
  drm/exynos: add support for exynos5420 hdmiphy
  exynos/drm: fix ddc i2c device probe failure
  ARM: dts: update hdmiphy dt node for exynos5250
  ARM: dts: update hdmiphy dt node for exynos5420

 .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
 .../devicetree/bindings/video/exynos_hdmiphy.txt   |    6 +
 arch/arm/boot/dts/exynos5250-smdk5250.dts          |    9 +-
 arch/arm/boot/dts/exynos5420.dtsi                  |   12 +
 drivers/gpu/drm/exynos/exynos_ddc.c                |    5 +
 drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   13 +
 drivers/gpu/drm/exynos/exynos_hdmi.c               |  353 ++--------
 drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  738 +++++++++++++++++++-
 drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 +
 9 files changed, 868 insertions(+), 305 deletions(-)
 create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-08-30  6:59 [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Rahul Sharma
@ 2013-08-30  6:59 ` Rahul Sharma
  2013-09-03 14:45   ` Sean Paul
  2013-09-30 10:50   ` Tushar Behera
  2013-08-30  6:59 ` [PATCH 2/7] drm/exynos: remove dummy hdmiphy clock Rahul Sharma
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 45+ messages in thread
From: Rahul Sharma @ 2013-08-30  6:59 UTC (permalink / raw)
  To: linux-samsung-soc, dri-devel
  Cc: kgene.kim, sw0312.kim, inki.dae, seanpaul, l.stach, tomasz.figa,
	s.nawrocki, joshi, r.sh.open, Rahul Sharma

Exynos hdmiphy operations and configs are kept inside
the hdmi driver. Hdmiphy related code is tightly coupled
with hdmi IP driver.

This patche moves hdmiphy related code to hdmiphy driver.
It will help in cleanly supporting the hdmiphy variations
in further SoCs.

Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
---
 .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
 drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   11 +
 drivers/gpu/drm/exynos/exynos_hdmi.c               |  343 +++------------
 drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  438 +++++++++++++++++++-
 drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 ++
 5 files changed, 533 insertions(+), 296 deletions(-)
 create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h

diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
index 50decf8..240eca5 100644
--- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
+++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
@@ -25,6 +25,7 @@ Required properties:
 		sclk_pixel.
 - clock-names: aliases as per driver requirements for above clock IDs:
 	"hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi".
+- phy: it points to hdmiphy dt node.
 Example:
 
 	hdmi {
@@ -32,4 +33,5 @@ Example:
 		reg = <0x14530000 0x100000>;
 		interrupts = <0 95 0>;
 		hpd-gpio = <&gpx3 7 1>;
+		phy = <&hdmiphy>;
 	};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
index 724cab1..1c839f8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
@@ -64,4 +64,15 @@ void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx);
 void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx);
 void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
 void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
+
+int exynos_hdmiphy_driver_register(void);
+void exynos_hdmiphy_driver_unregister(void);
+
+void exynos_hdmiphy_enable(struct device *dev);
+void exynos_hdmiphy_disable(struct device *dev);
+int exynos_hdmiphy_check_mode(struct device *dev,
+				struct drm_display_mode *mode);
+int exynos_hdmiphy_set_mode(struct device *dev,
+				struct drm_display_mode *mode);
+int exynos_hdmiphy_conf_apply(struct device *dev);
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index f67ffca..3af4e4c 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -34,6 +34,8 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/of_i2c.h>
+#include <linux/of_platform.h>
 
 #include <drm/exynos_drm.h>
 
@@ -172,7 +174,6 @@ struct hdmi_v14_conf {
 };
 
 struct hdmi_conf_regs {
-	int pixel_clock;
 	int cea_video_id;
 	union {
 		struct hdmi_v13_conf v13_conf;
@@ -193,9 +194,9 @@ struct hdmi_context {
 	int				irq;
 
 	struct i2c_client		*ddc_port;
-	struct i2c_client		*hdmiphy_port;
+	struct device			*hdmiphy_dev;
 
-	/* current hdmiphy conf regs */
+	/* current hdmi ip configuration registers. */
 	struct hdmi_conf_regs		mode_conf;
 
 	struct hdmi_resources		res;
@@ -205,180 +206,6 @@ struct hdmi_context {
 	enum hdmi_type			type;
 };
 
-struct hdmiphy_config {
-	int pixel_clock;
-	u8 conf[32];
-};
-
-/* list of phy config settings */
-static const struct hdmiphy_config hdmiphy_v13_configs[] = {
-	{
-		.pixel_clock = 27000000,
-		.conf = {
-			0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
-			0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
-			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
-			0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
-		},
-	},
-	{
-		.pixel_clock = 27027000,
-		.conf = {
-			0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
-			0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
-			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
-			0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
-		},
-	},
-	{
-		.pixel_clock = 74176000,
-		.conf = {
-			0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
-			0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
-			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
-			0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
-		},
-	},
-	{
-		.pixel_clock = 74250000,
-		.conf = {
-			0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
-			0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
-			0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
-			0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
-		},
-	},
-	{
-		.pixel_clock = 148500000,
-		.conf = {
-			0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
-			0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
-			0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
-			0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
-		},
-	},
-};
-
-static const struct hdmiphy_config hdmiphy_v14_configs[] = {
-	{
-		.pixel_clock = 25200000,
-		.conf = {
-			0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
-			0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
-			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
-		},
-	},
-	{
-		.pixel_clock = 27000000,
-		.conf = {
-			0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
-			0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
-			0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
-		},
-	},
-	{
-		.pixel_clock = 27027000,
-		.conf = {
-			0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
-			0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
-			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
-		},
-	},
-	{
-		.pixel_clock = 36000000,
-		.conf = {
-			0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
-			0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
-			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
-		},
-	},
-	{
-		.pixel_clock = 40000000,
-		.conf = {
-			0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
-			0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
-			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
-		},
-	},
-	{
-		.pixel_clock = 65000000,
-		.conf = {
-			0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
-			0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
-			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
-		},
-	},
-	{
-		.pixel_clock = 74176000,
-		.conf = {
-			0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
-			0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
-			0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
-		},
-	},
-	{
-		.pixel_clock = 74250000,
-		.conf = {
-			0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
-			0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
-			0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
-		},
-	},
-	{
-		.pixel_clock = 83500000,
-		.conf = {
-			0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
-			0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
-			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
-		},
-	},
-	{
-		.pixel_clock = 106500000,
-		.conf = {
-			0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
-			0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
-			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
-		},
-	},
-	{
-		.pixel_clock = 108000000,
-		.conf = {
-			0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
-			0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
-			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
-		},
-	},
-	{
-		.pixel_clock = 146250000,
-		.conf = {
-			0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
-			0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
-			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
-		},
-	},
-	{
-		.pixel_clock = 148500000,
-		.conf = {
-			0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
-			0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
-			0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
-			0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
-		},
-	},
-};
-
 struct hdmi_infoframe {
 	enum HDMI_PACKET_TYPE type;
 	u8 ver;
@@ -769,28 +596,6 @@ static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector)
 	return raw_edid;
 }
 
-static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
-{
-	const struct hdmiphy_config *confs;
-	int count, i;
-
-	if (hdata->type == HDMI_TYPE13) {
-		confs = hdmiphy_v13_configs;
-		count = ARRAY_SIZE(hdmiphy_v13_configs);
-	} else if (hdata->type == HDMI_TYPE14) {
-		confs = hdmiphy_v14_configs;
-		count = ARRAY_SIZE(hdmiphy_v14_configs);
-	} else
-		return -EINVAL;
-
-	for (i = 0; i < count; i++)
-		if (confs[i].pixel_clock == pixel_clock)
-			return i;
-
-	DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
-	return -EINVAL;
-}
-
 static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
 {
 	struct hdmi_context *hdata = ctx;
@@ -801,7 +606,7 @@ static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
 		(mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
 		false, mode->clock * 1000);
 
-	ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
+	ret = exynos_hdmiphy_check_mode(hdata->hdmiphy_dev, mode);
 	if (ret < 0)
 		return ret;
 	return 0;
@@ -1302,19 +1107,13 @@ static void hdmi_mode_apply(struct hdmi_context *hdata)
 
 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
 {
-	u8 buffer[2];
 	u32 reg;
 
 	clk_disable_unprepare(hdata->res.sclk_hdmi);
 	clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
 	clk_prepare_enable(hdata->res.sclk_hdmi);
 
-	/* operation mode */
-	buffer[0] = 0x1f;
-	buffer[1] = 0x00;
-
-	if (hdata->hdmiphy_port)
-		i2c_master_send(hdata->hdmiphy_port, buffer, 2);
+	exynos_hdmiphy_disable(hdata->hdmiphy_dev);
 
 	if (hdata->type == HDMI_TYPE13)
 		reg = HDMI_V13_PHY_RSTOUT;
@@ -1342,66 +1141,12 @@ static void hdmiphy_poweroff(struct hdmi_context *hdata)
 			HDMI_PHY_POWER_OFF_EN);
 }
 
-static void hdmiphy_conf_apply(struct hdmi_context *hdata)
-{
-	const u8 *hdmiphy_data;
-	u8 buffer[32];
-	u8 operation[2];
-	u8 read_buffer[32] = {0, };
-	int ret;
-	int i;
-
-	if (!hdata->hdmiphy_port) {
-		DRM_ERROR("hdmiphy is not attached\n");
-		return;
-	}
-
-	/* pixel clock */
-	i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
-	if (i < 0) {
-		DRM_ERROR("failed to find hdmiphy conf\n");
-		return;
-	}
-
-	if (hdata->type == HDMI_TYPE13)
-		hdmiphy_data = hdmiphy_v13_configs[i].conf;
-	else
-		hdmiphy_data = hdmiphy_v14_configs[i].conf;
-
-	memcpy(buffer, hdmiphy_data, 32);
-	ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
-	if (ret != 32) {
-		DRM_ERROR("failed to configure HDMIPHY via I2C\n");
-		return;
-	}
-
-	usleep_range(10000, 12000);
-
-	/* operation mode */
-	operation[0] = 0x1f;
-	operation[1] = 0x80;
-
-	ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
-	if (ret != 2) {
-		DRM_ERROR("failed to enable hdmiphy\n");
-		return;
-	}
-
-	ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
-	if (ret < 0) {
-		DRM_ERROR("failed to read hdmiphy config\n");
-		return;
-	}
-
-	for (i = 0; i < ret; i++)
-		DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
-			"recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
-}
-
 static void hdmi_conf_apply(struct hdmi_context *hdata)
 {
 	hdmiphy_conf_reset(hdata);
-	hdmiphy_conf_apply(hdata);
+	exynos_hdmiphy_conf_apply(hdata->hdmiphy_dev);
+	usleep_range(10000, 12000);
+	exynos_hdmiphy_enable(hdata->hdmiphy_dev);
 
 	mutex_lock(&hdata->hdmi_mutex);
 	hdmi_conf_reset(hdata);
@@ -1434,7 +1179,6 @@ static void hdmi_v13_mode_set(struct hdmi_context *hdata,
 
 	hdata->mode_conf.cea_video_id =
 		drm_match_cea_mode((struct drm_display_mode *)m);
-	hdata->mode_conf.pixel_clock = m->clock * 1000;
 
 	hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
 	hdmi_set_reg(core->h_v_line, 3, (m->htotal << 12) | m->vtotal);
@@ -1530,7 +1274,6 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
 
 	hdata->mode_conf.cea_video_id =
 		drm_match_cea_mode((struct drm_display_mode *)m);
-	hdata->mode_conf.pixel_clock = m->clock * 1000;
 
 	hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
 	hdmi_set_reg(core->v_line, 2, m->vtotal);
@@ -1646,6 +1389,8 @@ static void hdmi_mode_set(void *ctx, struct drm_display_mode *mode)
 		hdmi_v13_mode_set(hdata, mode);
 	else
 		hdmi_v14_mode_set(hdata, mode);
+
+	exynos_hdmiphy_set_mode(hdata->hdmiphy_dev, mode);
 }
 
 static void hdmi_get_max_resol(void *ctx, unsigned int *width,
@@ -1824,7 +1569,7 @@ fail:
 	return -ENODEV;
 }
 
-static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
+static struct i2c_client *hdmi_ddc;
 
 void hdmi_attach_ddc_client(struct i2c_client *ddc)
 {
@@ -1832,12 +1577,6 @@ void hdmi_attach_ddc_client(struct i2c_client *ddc)
 		hdmi_ddc = ddc;
 }
 
-void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
-{
-	if (hdmiphy)
-		hdmi_hdmiphy = hdmiphy;
-}
-
 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
 					(struct device *dev)
 {
@@ -1862,6 +1601,50 @@ err_data:
 	return NULL;
 }
 
+static int hdmi_get_phy_device(struct hdmi_context *hdata)
+{
+	struct device_node *np;
+	struct i2c_client *client;
+	struct platform_device *pdev;
+	int ret;
+
+	/* register hdmiphy driver */
+	ret = exynos_hdmiphy_driver_register();
+	if (ret) {
+		DRM_ERROR("failed to register hdmiphy driver\n");
+		goto err;
+	}
+
+	np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
+	if (!np) {
+		DRM_ERROR("Could not find 'phy' property\n");
+		ret = -ENOENT;
+		goto err;
+	}
+
+	/* find hdmi phy on i2c bus */
+	client = of_find_i2c_device_by_node(np);
+	if (client) {
+		hdata->hdmiphy_dev = &client->dev;
+		ret = 0;
+		goto exit;
+	}
+
+	/* find hdmi phy on platform bus */
+	pdev = of_find_device_by_node(np);
+	if (pdev) {
+		hdata->hdmiphy_dev = &pdev->dev;
+		ret = 0;
+		goto exit;
+	}
+
+exit:
+	/* able to find hdmiphy on platform/i2c bus */
+err:
+	of_node_put(np);
+	return ret;
+}
+
 static struct of_device_id hdmi_match_types[] = {
 	{
 		.compatible = "samsung,exynos5-hdmi",
@@ -1939,15 +1722,13 @@ static int hdmi_probe(struct platform_device *pdev)
 
 	hdata->ddc_port = hdmi_ddc;
 
-	/* hdmiphy i2c driver */
-	if (i2c_add_driver(&hdmiphy_driver)) {
-		DRM_ERROR("failed to register hdmiphy i2c driver\n");
+	ret = hdmi_get_phy_device(hdata);
+	if (ret) {
+		DRM_ERROR("failed to get hdmiphy device\n");
 		ret = -ENOENT;
 		goto err_ddc;
 	}
 
-	hdata->hdmiphy_port = hdmi_hdmiphy;
-
 	hdata->irq = gpio_to_irq(hdata->hpd_gpio);
 	if (hdata->irq < 0) {
 		DRM_ERROR("failed to get GPIO irq\n");
@@ -1977,7 +1758,7 @@ static int hdmi_probe(struct platform_device *pdev)
 	return 0;
 
 err_hdmiphy:
-	i2c_del_driver(&hdmiphy_driver);
+	exynos_hdmiphy_driver_unregister();
 err_ddc:
 	i2c_del_driver(&ddc_driver);
 	return ret;
@@ -1989,8 +1770,8 @@ static int hdmi_remove(struct platform_device *pdev)
 
 	pm_runtime_disable(dev);
 
-	/* hdmiphy i2c driver */
-	i2c_del_driver(&hdmiphy_driver);
+	/* hdmiphy driver */
+	exynos_hdmiphy_driver_unregister();
 	/* DDC i2c driver */
 	i2c_del_driver(&ddc_driver);
 
diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
index 59abb14..82daa42 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
@@ -15,51 +15,459 @@
 
 #include <linux/kernel.h>
 #include <linux/i2c.h>
-#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/clk.h>
 
 #include "exynos_drm_drv.h"
 #include "exynos_hdmi.h"
+#include "exynos_drm_hdmi.h"
+#include "regs-hdmiphy.h"
 
+#define HDMIPHY_REG_COUNT	(32)
 
-static int hdmiphy_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
+struct hdmiphy_context {
+	struct device		*dev;
+	struct hdmiphy_config	*current_conf;
+
+	struct hdmiphy_config	*confs;
+	unsigned int		nr_confs;
+};
+
+struct hdmiphy_config {
+	int pixel_clock;
+	u8 conf[HDMIPHY_REG_COUNT];
+};
+
+struct hdmiphy_drv_data {
+	struct hdmiphy_config *confs;
+	unsigned int count;
+};
+
+/* list of all required phy config settings */
+static struct hdmiphy_config hdmiphy_4212_configs[] = {
+	{
+		.pixel_clock = 25200000,
+		.conf = {
+			0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
+			0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
+			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 27000000,
+		.conf = {
+			0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
+			0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
+			0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 27027000,
+		.conf = {
+			0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
+			0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
+			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
+		},
+	},
+	{
+		.pixel_clock = 36000000,
+		.conf = {
+			0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
+			0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
+			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 40000000,
+		.conf = {
+			0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
+			0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
+			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 65000000,
+		.conf = {
+			0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
+			0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
+			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 74176000,
+		.conf = {
+			0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
+			0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
+			0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 74250000,
+		.conf = {
+			0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
+			0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
+			0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
+		},
+	},
+	{
+		.pixel_clock = 83500000,
+		.conf = {
+			0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
+			0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
+			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 106500000,
+		.conf = {
+			0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
+			0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
+			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 108000000,
+		.conf = {
+			0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
+			0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
+			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 146250000,
+		.conf = {
+			0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
+			0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
+			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 148500000,
+		.conf = {
+			0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
+			0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
+			0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
+		},
+	},
+};
+
+static struct hdmiphy_config hdmiphy_4210_configs[] = {
+	{
+		.pixel_clock = 27000000,
+		.conf = {
+			0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
+			0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
+			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
+			0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
+		},
+	},
+	{
+		.pixel_clock = 27027000,
+		.conf = {
+			0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
+			0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
+			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
+			0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
+		},
+	},
+	{
+		.pixel_clock = 74176000,
+		.conf = {
+			0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
+			0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
+			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
+			0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
+		},
+	},
+	{
+		.pixel_clock = 74250000,
+		.conf = {
+			0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
+			0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
+			0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
+			0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
+		},
+	},
+	{
+		.pixel_clock = 148500000,
+		.conf = {
+			0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
+			0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
+			0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
+			0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
+		},
+	},
+};
+
+static struct hdmiphy_config *hdmiphy_find_conf(struct hdmiphy_context *hdata,
+			const struct drm_display_mode *mode)
+{
+	int i;
+
+	for (i = 0; i < hdata->nr_confs; i++)
+		if (hdata->confs[i].pixel_clock == (mode->clock * 1000))
+			return &hdata->confs[i];
+
+	return NULL;
+}
+
+static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata,
+			u32 reg_offset, u8 value)
+{
+	if (reg_offset >= HDMIPHY_REG_COUNT)
+		return -EINVAL;
+
+	if (i2c_verify_client(hdata->dev)) {
+		u8 buffer[2];
+		int ret;
+
+		buffer[0] = reg_offset;
+		buffer[1] = value;
+
+		ret = i2c_master_send(to_i2c_client(hdata->dev),
+				buffer, 2);
+		if (ret == 2)
+			return 0;
+		return ret;
+	} else {
+		return -EINVAL;
+	}
+}
+
+static int hdmiphy_reg_write_buf(struct hdmiphy_context *hdata,
+			u32 reg_offset, const u8 *buf, u32 len)
+{
+	if ((reg_offset + len) > HDMIPHY_REG_COUNT)
+		return -EINVAL;
+
+	if (i2c_verify_client(hdata->dev)) {
+		int ret;
+
+		ret = i2c_master_send(to_i2c_client(hdata->dev),
+				buf, len);
+		if (ret == len)
+			return 0;
+		return ret;
+	} else {
+		return -EINVAL;
+	}
+}
+
+int exynos_hdmiphy_check_mode(struct device *dev,
+			struct drm_display_mode *mode)
 {
-	hdmi_attach_hdmiphy_client(client);
+	struct hdmiphy_context *hdata = dev_get_drvdata(dev);
+	const struct hdmiphy_config *conf;
+
+	DRM_DEBUG_KMS("[%d]\n", __LINE__);
 
-	dev_info(&client->adapter->dev, "attached s5p_hdmiphy "
-		"into i2c adapter successfully\n");
+	if (!hdata) {
+		DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
+		return -EINVAL;
+	}
 
+	DRM_DEBUG("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
+		mode->hdisplay, mode->vdisplay,
+		mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		? true : false, mode->clock * 1000);
+
+	conf = hdmiphy_find_conf(hdata, mode);
+	if (!conf) {
+		DRM_DEBUG("Display Mode is not supported.\n");
+		return -EINVAL;
+	}
 	return 0;
 }
 
-static int hdmiphy_remove(struct i2c_client *client)
+int exynos_hdmiphy_set_mode(struct device *dev,
+			struct drm_display_mode *mode)
 {
-	dev_info(&client->adapter->dev, "detached s5p_hdmiphy "
-		"from i2c adapter successfully\n");
+	struct hdmiphy_context *hdata = dev_get_drvdata(dev);
+
+	DRM_DEBUG_KMS("[%d]\n", __LINE__);
+
+	hdata->current_conf = hdmiphy_find_conf(hdata, mode);
+
+	if (!hdata) {
+		DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
+		return -EINVAL;
+	}
 
+	if (!hdata->current_conf) {
+		DRM_ERROR("Display Mode is not supported.\n");
+		return -EINVAL;
+	}
 	return 0;
 }
 
-static struct of_device_id hdmiphy_match_types[] = {
+void exynos_hdmiphy_enable(struct device *dev)
+{
+	struct hdmiphy_context *hdata = dev_get_drvdata(dev);
+	int ret;
+
+	DRM_DEBUG_KMS("[%d]\n", __LINE__);
+
+	if (!hdata) {
+		DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
+		return;
+	}
+
+	ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
+			HDMIPHY_MODE_EN);
+	if (ret < 0) {
+		DRM_ERROR("failed to disable hdmiphy.\n");
+		return;
+	}
+}
+
+void exynos_hdmiphy_disable(struct device *dev)
+{
+	struct hdmiphy_context *hdata = dev_get_drvdata(dev);
+	int ret;
+
+	DRM_DEBUG_KMS("[%d]\n", __LINE__);
+
+	if (!hdata) {
+		DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
+		return;
+	}
+
+	ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, 0);
+	if (ret < 0) {
+		DRM_ERROR("failed to enable hdmiphy.\n");
+		return;
+	}
+}
+
+int exynos_hdmiphy_conf_apply(struct device *dev)
+{
+	struct hdmiphy_context *hdata = dev_get_drvdata(dev);
+	const u8 *hdmiphy_data;
+	int ret;
+
+	DRM_DEBUG_KMS("[%d]\n", __LINE__);
+
+	if (!hdata) {
+		DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
+		return -EINVAL;
+	}
+
+	/* pixel clock */
+	if (hdata->current_conf)
+		hdmiphy_data = hdata->current_conf->conf;
+	else
+		return -EINVAL;
+
+	ret = hdmiphy_reg_write_buf(hdata, 0, hdmiphy_data,
+			HDMIPHY_REG_COUNT);
+	if (ret) {
+		DRM_ERROR("failed to configure hdmiphy.\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct hdmiphy_drv_data exynos4212_hdmiphy_drv_data = {
+	.confs = hdmiphy_4212_configs,
+	.count = ARRAY_SIZE(hdmiphy_4212_configs)
+};
+
+static struct hdmiphy_drv_data exynos4210_hdmiphy_drv_data = {
+	.confs = hdmiphy_4210_configs,
+	.count = ARRAY_SIZE(hdmiphy_4210_configs)
+};
+
+static struct of_device_id hdmiphy_i2c_device_match_types[] = {
 	{
 		.compatible = "samsung,exynos5-hdmiphy",
+		.data	= &exynos4212_hdmiphy_drv_data,
 	}, {
 		.compatible = "samsung,exynos4210-hdmiphy",
+		.data	= &exynos4210_hdmiphy_drv_data,
 	}, {
 		.compatible = "samsung,exynos4212-hdmiphy",
+		.data	= &exynos4212_hdmiphy_drv_data,
 	}, {
 		/* end node */
 	}
 };
 
-struct i2c_driver hdmiphy_driver = {
+static int hdmiphy_i2c_device_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct hdmiphy_context *hdata;
+	struct hdmiphy_drv_data *drv;
+	const struct of_device_id *match;
+
+	DRM_DEBUG_KMS("[%d]\n", __LINE__);
+
+	hdata = devm_kzalloc(dev, sizeof(*hdata), GFP_KERNEL);
+	if (!hdata) {
+		DRM_ERROR("failed to allocate hdmiphy context.\n");
+		return -ENOMEM;
+	}
+
+	match = of_match_node(of_match_ptr(
+		hdmiphy_i2c_device_match_types),
+		dev->of_node);
+
+	if (match == NULL)
+		return -ENODEV;
+
+	drv = (struct hdmiphy_drv_data *)match->data;
+
+	hdata->dev = dev;
+	hdata->confs = drv->confs;
+	hdata->nr_confs = drv->count;
+
+	i2c_set_clientdata(client, hdata);
+
+	return 0;
+}
+
+static const struct i2c_device_id hdmiphy_id[] = {
+	{ },
+};
+
+struct i2c_driver hdmiphy_i2c_driver = {
 	.driver = {
 		.name	= "exynos-hdmiphy",
 		.owner	= THIS_MODULE,
-		.of_match_table = hdmiphy_match_types,
+		.of_match_table = of_match_ptr(
+				hdmiphy_i2c_device_match_types),
 	},
-	.probe		= hdmiphy_probe,
-	.remove		= hdmiphy_remove,
+	.id_table		= hdmiphy_id,
+	.probe		= hdmiphy_i2c_device_probe,
 	.command		= NULL,
 };
-EXPORT_SYMBOL(hdmiphy_driver);
+
+int exynos_hdmiphy_driver_register(void)
+{
+	int ret;
+
+	ret = i2c_add_driver(&hdmiphy_i2c_driver);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+void exynos_hdmiphy_driver_unregister(void)
+{
+	i2c_del_driver(&hdmiphy_i2c_driver);
+}
diff --git a/drivers/gpu/drm/exynos/regs-hdmiphy.h b/drivers/gpu/drm/exynos/regs-hdmiphy.h
new file mode 100644
index 0000000..d3f9d87
--- /dev/null
+++ b/drivers/gpu/drm/exynos/regs-hdmiphy.h
@@ -0,0 +1,35 @@
+/*
+ *
+ *  regs-hdmiphy.h
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * HDMI-PHY register header file for Samsung HDMI driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef SAMSUNG_REGS_HDMIPHY_H
+#define SAMSUNG_REGS_HDMIPHY_H
+
+/*
+ * Register part
+*/
+#define HDMIPHY_MODE_SET_DONE	(0x1f)
+
+/*
+ * Bit definition part
+ */
+
+/* HDMIPHY_MODE_SET_DONE */
+#define HDMIPHY_MODE_EN		(1 << 7)
+
+/* hdmiphy pmu control bits */
+#define PMU_HDMI_PHY_CONTROL_MASK	(1 << 0)
+#define PMU_HDMI_PHY_ENABLE		(1)
+#define PMU_HDMI_PHY_DISABLE		(0)
+
+#endif /* SAMSUNG_REGS_HDMIPHY_H */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 2/7] drm/exynos: remove dummy hdmiphy clock
  2013-08-30  6:59 [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Rahul Sharma
  2013-08-30  6:59 ` [PATCH 1/7] " Rahul Sharma
@ 2013-08-30  6:59 ` Rahul Sharma
  2013-09-03 15:58   ` Sean Paul
  2013-08-30  6:59 ` [PATCH 3/7] drm/exynos: add hdmiphy pmu bit control in hdmiphy driver Rahul Sharma
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 45+ messages in thread
From: Rahul Sharma @ 2013-08-30  6:59 UTC (permalink / raw)
  To: linux-samsung-soc, dri-devel
  Cc: kgene.kim, sw0312.kim, inki.dae, seanpaul, l.stach, tomasz.figa,
	s.nawrocki, joshi, r.sh.open, Rahul Sharma

hdmiphy is a dummy clock which actually controls the PMU bit
to enable/disbale hdmiphy (before CCF). This clock is cleaned
from the hdmi driver.

Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_hdmi.c |    8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 3af4e4c..cd1d921 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -84,7 +84,6 @@ struct hdmi_resources {
 	struct clk			*sclk_hdmi;
 	struct clk			*sclk_pixel;
 	struct clk			*sclk_hdmiphy;
-	struct clk			*hdmiphy;
 	struct clk			*mout_hdmi;
 	struct regulator_bulk_data	*regul_bulk;
 	int				regul_count;
@@ -1431,7 +1430,6 @@ static void hdmi_poweron(struct hdmi_context *hdata)
 	if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
 		DRM_DEBUG_KMS("failed to enable regulator bulk\n");
 
-	clk_prepare_enable(res->hdmiphy);
 	clk_prepare_enable(res->hdmi);
 	clk_prepare_enable(res->sclk_hdmi);
 
@@ -1456,7 +1454,6 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
 
 	clk_disable_unprepare(res->sclk_hdmi);
 	clk_disable_unprepare(res->hdmi);
-	clk_disable_unprepare(res->hdmiphy);
 	regulator_bulk_disable(res->regul_count, res->regul_bulk);
 
 	mutex_lock(&hdata->hdmi_mutex);
@@ -1549,11 +1546,6 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
 		DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
 		goto fail;
 	}
-	res->hdmiphy = devm_clk_get(dev, "hdmiphy");
-	if (IS_ERR(res->hdmiphy)) {
-		DRM_ERROR("failed to get clock 'hdmiphy'\n");
-		goto fail;
-	}
 	res->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
 	if (IS_ERR(res->mout_hdmi)) {
 		DRM_ERROR("failed to get clock 'mout_hdmi'\n");
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 3/7] drm/exynos: add hdmiphy pmu bit control in hdmiphy driver
  2013-08-30  6:59 [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Rahul Sharma
  2013-08-30  6:59 ` [PATCH 1/7] " Rahul Sharma
  2013-08-30  6:59 ` [PATCH 2/7] drm/exynos: remove dummy hdmiphy clock Rahul Sharma
@ 2013-08-30  6:59 ` Rahul Sharma
  2013-09-03 16:10   ` Sean Paul
  2013-08-30  6:59 ` [PATCH 4/7] drm/exynos: add support for exynos5420 hdmiphy Rahul Sharma
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 45+ messages in thread
From: Rahul Sharma @ 2013-08-30  6:59 UTC (permalink / raw)
  To: linux-samsung-soc, dri-devel
  Cc: kgene.kim, sw0312.kim, inki.dae, seanpaul, l.stach, tomasz.figa,
	s.nawrocki, joshi, r.sh.open, Rahul Sharma

Before hdmiphy operation like config, start etc, hdmiphy
bit in PMU block should be enabled. Earlier this happens
in hdmi drvier through a dummy "hdmiphy" clock.

Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
---
 .../devicetree/bindings/video/exynos_hdmiphy.txt   |    6 ++
 drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |    2 +
 drivers/gpu/drm/exynos/exynos_hdmi.c               |    2 +
 drivers/gpu/drm/exynos/exynos_hdmiphy.c            |   82 ++++++++++++++++++++
 4 files changed, 92 insertions(+)

diff --git a/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt b/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt
index 162f641..f6bf096 100644
--- a/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt
+++ b/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt
@@ -6,10 +6,16 @@ Required properties:
 	2) "samsung,exynos4210-hdmiphy".
 	3) "samsung,exynos4212-hdmiphy".
 - reg: I2C address of the hdmiphy device.
+- phy-power-control: this child node represents phy power control
+	register which is inside the pmu block (power management unit).
 
 Example:
 
 	hdmiphy {
 		compatible = "samsung,exynos4210-hdmiphy";
 		reg = <0x38>;
+
+		phy-power-control {
+				reg = <0x10040700 0x04>;
+		};
 	};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
index 1c839f8..9a14f96 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
@@ -68,6 +68,8 @@ void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
 int exynos_hdmiphy_driver_register(void);
 void exynos_hdmiphy_driver_unregister(void);
 
+void exynos_hdmiphy_poweron(struct device *dev);
+void exynos_hdmiphy_poweroff(struct device *dev);
 void exynos_hdmiphy_enable(struct device *dev);
 void exynos_hdmiphy_disable(struct device *dev);
 int exynos_hdmiphy_check_mode(struct device *dev,
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index cd1d921..a6234fc 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1131,6 +1131,7 @@ static void hdmiphy_poweron(struct hdmi_context *hdata)
 	if (hdata->type == HDMI_TYPE14)
 		hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0,
 			HDMI_PHY_POWER_OFF_EN);
+	exynos_hdmiphy_poweron(hdata->hdmiphy_dev);
 }
 
 static void hdmiphy_poweroff(struct hdmi_context *hdata)
@@ -1138,6 +1139,7 @@ static void hdmiphy_poweroff(struct hdmi_context *hdata)
 	if (hdata->type == HDMI_TYPE14)
 		hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0,
 			HDMI_PHY_POWER_OFF_EN);
+	exynos_hdmiphy_poweroff(hdata->hdmiphy_dev);
 }
 
 static void hdmi_conf_apply(struct hdmi_context *hdata)
diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
index 82daa42..b1b8a0f 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
@@ -30,6 +30,9 @@ struct hdmiphy_context {
 	struct device		*dev;
 	struct hdmiphy_config	*current_conf;
 
+	/* hdmiphy resources */
+	void __iomem		*phy_pow_ctrl_reg;
+
 	struct hdmiphy_config	*confs;
 	unsigned int		nr_confs;
 };
@@ -225,6 +228,49 @@ static struct hdmiphy_config *hdmiphy_find_conf(struct hdmiphy_context *hdata,
 	return NULL;
 }
 
+static int hdmiphy_dt_parse_power_control(struct hdmiphy_context *hdata)
+{
+	struct device_node *phy_pow_ctrl_node;
+	u32 buf[2];
+	int ret = 0;
+
+	phy_pow_ctrl_node = of_get_child_by_name(hdata->dev->of_node,
+			"phy-power-control");
+	if (!phy_pow_ctrl_node) {
+		DRM_ERROR("Failed to find phy power control node\n");
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	/* reg property holds two informations: addr of pmu register, size */
+	if (of_property_read_u32_array(phy_pow_ctrl_node, "reg",
+			(u32 *)&buf, 2)) {
+		DRM_ERROR("faild to get phy power control reg\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	hdata->phy_pow_ctrl_reg = devm_ioremap(hdata->dev, buf[0], buf[1]);
+	if (!hdata->phy_pow_ctrl_reg) {
+		DRM_ERROR("failed to ioremap phy pmu reg\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+fail:
+	of_node_put(phy_pow_ctrl_node);
+	return ret;
+}
+
+static inline void hdmiphy_pow_ctrl_reg_writemask(
+			struct hdmiphy_context *hdata,
+			u32 value, u32 mask)
+{
+	u32 old = readl(hdata->phy_pow_ctrl_reg);
+	value = (value & mask) | (old & ~mask);
+	writel(value, hdata->phy_pow_ctrl_reg);
+}
+
 static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata,
 			u32 reg_offset, u8 value)
 {
@@ -353,6 +399,36 @@ void exynos_hdmiphy_disable(struct device *dev)
 	}
 }
 
+void exynos_hdmiphy_poweron(struct device *dev)
+{
+	struct hdmiphy_context *hdata = dev_get_drvdata(dev);
+
+	DRM_DEBUG_KMS("[%d]\n", __LINE__);
+
+	if (!hdata) {
+		DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
+		return;
+	}
+
+	hdmiphy_pow_ctrl_reg_writemask(hdata, PMU_HDMI_PHY_ENABLE,
+		PMU_HDMI_PHY_CONTROL_MASK);
+}
+
+void exynos_hdmiphy_poweroff(struct device *dev)
+{
+	struct hdmiphy_context *hdata = dev_get_drvdata(dev);
+
+	DRM_DEBUG_KMS("[%d]\n", __LINE__);
+
+	if (!hdata) {
+		DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
+		return;
+	}
+
+	hdmiphy_pow_ctrl_reg_writemask(hdata, PMU_HDMI_PHY_DISABLE,
+		PMU_HDMI_PHY_CONTROL_MASK);
+}
+
 int exynos_hdmiphy_conf_apply(struct device *dev)
 {
 	struct hdmiphy_context *hdata = dev_get_drvdata(dev);
@@ -413,6 +489,7 @@ static int hdmiphy_i2c_device_probe(struct i2c_client *client,
 	struct hdmiphy_context *hdata;
 	struct hdmiphy_drv_data *drv;
 	const struct of_device_id *match;
+	int ret;
 
 	DRM_DEBUG_KMS("[%d]\n", __LINE__);
 
@@ -436,6 +513,11 @@ static int hdmiphy_i2c_device_probe(struct i2c_client *client,
 	hdata->nr_confs = drv->count;
 
 	i2c_set_clientdata(client, hdata);
+	ret = hdmiphy_dt_parse_power_control(hdata);
+	if (ret) {
+		DRM_ERROR("failed to map hdmiphy pow control reg.\n");
+		return ret;
+	}
 
 	return 0;
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 4/7] drm/exynos: add support for exynos5420 hdmiphy
  2013-08-30  6:59 [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Rahul Sharma
                   ` (2 preceding siblings ...)
  2013-08-30  6:59 ` [PATCH 3/7] drm/exynos: add hdmiphy pmu bit control in hdmiphy driver Rahul Sharma
@ 2013-08-30  6:59 ` Rahul Sharma
  2013-09-03 16:15   ` Sean Paul
  2013-08-30  6:59 ` [PATCH 5/7] exynos/drm: fix ddc i2c device probe failure Rahul Sharma
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 45+ messages in thread
From: Rahul Sharma @ 2013-08-30  6:59 UTC (permalink / raw)
  To: linux-samsung-soc, dri-devel
  Cc: kgene.kim, sw0312.kim, inki.dae, seanpaul, l.stach, tomasz.figa,
	s.nawrocki, joshi, r.sh.open, Rahul Sharma

Exynos5420 hdmiphy device is a platform device, unlike
predecessor SoCs where it used to be a I2C device. This
support is added to the hdmiphy driver.

Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_hdmiphy.c |  224 ++++++++++++++++++++++++++++++-
 1 file changed, 221 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
index b1b8a0f..33e89d9 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
@@ -32,6 +32,7 @@ struct hdmiphy_context {
 
 	/* hdmiphy resources */
 	void __iomem		*phy_pow_ctrl_reg;
+	void __iomem		*regs;
 
 	struct hdmiphy_config	*confs;
 	unsigned int		nr_confs;
@@ -48,6 +49,135 @@ struct hdmiphy_drv_data {
 };
 
 /* list of all required phy config settings */
+static struct hdmiphy_config hdmiphy_5420_configs[] = {
+	{
+		.pixel_clock = 25200000,
+		.conf = {
+			0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
+			0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
+			0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 27000000,
+		.conf = {
+			0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
+			0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
+			0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 27027000,
+		.conf = {
+			0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
+			0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
+			0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 36000000,
+		.conf = {
+			0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
+			0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
+			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 40000000,
+		.conf = {
+			0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
+			0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
+			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 65000000,
+		.conf = {
+			0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
+			0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
+			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 71000000,
+		.conf = {
+			0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
+			0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
+			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 74176000,
+		.conf = {
+			0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
+			0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
+			0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 74250000,
+		.conf = {
+			0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0xC8,
+			0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
+			0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 83500000,
+		.conf = {
+			0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
+			0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
+			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 106500000,
+		.conf = {
+			0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
+			0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
+			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 108000000,
+		.conf = {
+			0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
+			0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
+			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 146250000,
+		.conf = {
+			0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
+			0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
+			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+	{
+		.pixel_clock = 148500000,
+		.conf = {
+			0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0xC8,
+			0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
+			0x66, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
+			0x54, 0x4B, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
+};
+
 static struct hdmiphy_config hdmiphy_4212_configs[] = {
 	{
 		.pixel_clock = 25200000,
@@ -290,7 +420,8 @@ static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata,
 			return 0;
 		return ret;
 	} else {
-		return -EINVAL;
+		writeb(value, hdata->regs + (reg_offset<<2));
+		return 0;
 	}
 }
 
@@ -309,7 +440,11 @@ static int hdmiphy_reg_write_buf(struct hdmiphy_context *hdata,
 			return 0;
 		return ret;
 	} else {
-		return -EINVAL;
+		int i;
+		for (i = 0; i < len; i++)
+			writeb(buf[i], hdata->regs +
+				((reg_offset + i)<<2));
+		return 0;
 	}
 }
 
@@ -457,6 +592,11 @@ int exynos_hdmiphy_conf_apply(struct device *dev)
 	return 0;
 }
 
+static struct hdmiphy_drv_data exynos5420_hdmiphy_drv_data = {
+	.confs = hdmiphy_5420_configs,
+	.count = ARRAY_SIZE(hdmiphy_5420_configs)
+};
+
 static struct hdmiphy_drv_data exynos4212_hdmiphy_drv_data = {
 	.confs = hdmiphy_4212_configs,
 	.count = ARRAY_SIZE(hdmiphy_4212_configs)
@@ -482,6 +622,67 @@ static struct of_device_id hdmiphy_i2c_device_match_types[] = {
 	}
 };
 
+static struct of_device_id hdmiphy_platform_device_match_types[] = {
+	{
+		.compatible = "samsung,exynos5420-hdmiphy",
+		.data	= &exynos5420_hdmiphy_drv_data,
+	}, {
+		/* end node */
+	}
+};
+
+static int hdmiphy_platform_device_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct hdmiphy_context *hdata;
+	struct hdmiphy_drv_data *drv;
+	struct resource *res;
+	const struct of_device_id *match;
+	int ret;
+
+	DRM_DEBUG_KMS("[%d]\n", __LINE__);
+
+	hdata = devm_kzalloc(dev, sizeof(*hdata), GFP_KERNEL);
+	if (!hdata) {
+		DRM_ERROR("failed to allocate hdmiphy context.\n");
+		return -ENOMEM;
+	}
+
+	match = of_match_node(of_match_ptr(
+		hdmiphy_platform_device_match_types),
+		dev->of_node);
+
+	if (match == NULL)
+		return -ENODEV;
+
+	drv = (struct hdmiphy_drv_data *)match->data;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		DRM_ERROR("failed to find phy registers\n");
+		return -ENOENT;
+	}
+
+	hdata->regs = devm_request_and_ioremap(&pdev->dev, res);
+	if (!hdata->regs) {
+		DRM_ERROR("failed to map registers\n");
+		return -ENXIO;
+	}
+
+	hdata->dev = dev;
+	hdata->confs = drv->confs;
+	hdata->nr_confs = drv->count;
+
+	platform_set_drvdata(pdev, hdata);
+	ret = hdmiphy_dt_parse_power_control(hdata);
+	if (ret) {
+		DRM_ERROR("failed to map hdmiphy pow control reg.\n");
+		return ret;
+	}
+
+	return 0;
+}
+
 static int hdmiphy_i2c_device_probe(struct i2c_client *client,
 	const struct i2c_device_id *id)
 {
@@ -538,18 +739,35 @@ struct i2c_driver hdmiphy_i2c_driver = {
 	.command		= NULL,
 };
 
+struct platform_driver hdmiphy_platform_driver = {
+	.driver = {
+		.name	= "exynos-hdmiphy",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(
+				hdmiphy_platform_device_match_types),
+	},
+	.probe		= hdmiphy_platform_device_probe,
+};
+
 int exynos_hdmiphy_driver_register(void)
 {
 	int ret;
 
 	ret = i2c_add_driver(&hdmiphy_i2c_driver);
 	if (ret)
-		return ret;
+		goto err;
+
+	ret = platform_driver_register(&hdmiphy_platform_driver);
+	if (ret)
+		goto err;
 
 	return 0;
+err:
+	return ret;
 }
 
 void exynos_hdmiphy_driver_unregister(void)
 {
 	i2c_del_driver(&hdmiphy_i2c_driver);
+	platform_driver_unregister(&hdmiphy_platform_driver);
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 5/7] exynos/drm: fix ddc i2c device probe failure
  2013-08-30  6:59 [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Rahul Sharma
                   ` (3 preceding siblings ...)
  2013-08-30  6:59 ` [PATCH 4/7] drm/exynos: add support for exynos5420 hdmiphy Rahul Sharma
@ 2013-08-30  6:59 ` Rahul Sharma
  2013-08-30  6:59 ` [PATCH 6/7] ARM: dts: update hdmiphy dt node for exynos5250 Rahul Sharma
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 45+ messages in thread
From: Rahul Sharma @ 2013-08-30  6:59 UTC (permalink / raw)
  To: linux-samsung-soc, dri-devel
  Cc: kgene.kim, sw0312.kim, inki.dae, seanpaul, l.stach, tomasz.figa,
	s.nawrocki, joshi, r.sh.open, Rahul Sharma

Exynos hdmi ddc is a I2C device and if we register hdmi ddc
driver with id_table as NULL, cause failure in probing.

id_table field should not be NULL for i2c_driver registeration.

Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_ddc.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c b/drivers/gpu/drm/exynos/exynos_ddc.c
index 6a8c84e..54ead55 100644
--- a/drivers/gpu/drm/exynos/exynos_ddc.c
+++ b/drivers/gpu/drm/exynos/exynos_ddc.c
@@ -51,12 +51,17 @@ static struct of_device_id hdmiddc_match_types[] = {
 	}
 };
 
+static struct i2c_device_id ddc_idtable[] = {
+	{ },
+};
+
 struct i2c_driver ddc_driver = {
 	.driver = {
 		.name = "exynos-hdmiddc",
 		.owner = THIS_MODULE,
 		.of_match_table = hdmiddc_match_types,
 	},
+	.id_table	= ddc_idtable,
 	.probe		= s5p_ddc_probe,
 	.remove		= s5p_ddc_remove,
 	.command		= NULL,
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 6/7] ARM: dts: update hdmiphy dt node for exynos5250
  2013-08-30  6:59 [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Rahul Sharma
                   ` (4 preceding siblings ...)
  2013-08-30  6:59 ` [PATCH 5/7] exynos/drm: fix ddc i2c device probe failure Rahul Sharma
@ 2013-08-30  6:59 ` Rahul Sharma
  2013-08-30  6:59 ` [PATCH 7/7] ARM: dts: update hdmiphy dt node for exynos5420 Rahul Sharma
  2013-08-30  8:33 ` [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Inki Dae
  7 siblings, 0 replies; 45+ messages in thread
From: Rahul Sharma @ 2013-08-30  6:59 UTC (permalink / raw)
  To: linux-samsung-soc, dri-devel
  Cc: kgene.kim, sw0312.kim, inki.dae, seanpaul, l.stach, tomasz.figa,
	s.nawrocki, joshi, r.sh.open, Rahul Sharma

hdmiphy dt node needs a child node called 'phy-power-control'
which represents the PMU register for power controlling the
hdmiphy.

hdmi driver dt node provides phy property which points to
the hdmiphy dt node.

Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
---
 arch/arm/boot/dts/exynos5250-smdk5250.dts |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 49f18c2..99a83412 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -134,9 +134,15 @@
 		samsung,i2c-sda-delay = <100>;
 		samsung,i2c-max-bus-freq = <66000>;
 
-		hdmiphy@38 {
+		hdmiphy: hdmiphy@38 {
 			compatible = "samsung,exynos4212-hdmiphy";
 			reg = <0x38>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			phy-power-control {
+				reg = <0x10040700 0x04>;
+			};
 		};
 	};
 
@@ -220,6 +226,7 @@
 
 	hdmi {
 		hpd-gpio = <&gpx3 7 0>;
+		phy = <&hdmiphy>;
 	};
 
 	codec@11000000 {
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 7/7] ARM: dts: update hdmiphy dt node for exynos5420
  2013-08-30  6:59 [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Rahul Sharma
                   ` (5 preceding siblings ...)
  2013-08-30  6:59 ` [PATCH 6/7] ARM: dts: update hdmiphy dt node for exynos5250 Rahul Sharma
@ 2013-08-30  6:59 ` Rahul Sharma
  2013-08-30  8:33 ` [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Inki Dae
  7 siblings, 0 replies; 45+ messages in thread
From: Rahul Sharma @ 2013-08-30  6:59 UTC (permalink / raw)
  To: linux-samsung-soc, dri-devel
  Cc: kgene.kim, sw0312.kim, inki.dae, seanpaul, l.stach, tomasz.figa,
	s.nawrocki, joshi, r.sh.open, Rahul Sharma

hdmiphy dt node needs a child node called 'phy-power-control'
which represents the PMU register for power controlling the
hdmiphy.

hdmi driver dt node provides phy property which points to
the hdmiphy dt node.

Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
---
 arch/arm/boot/dts/exynos5420.dtsi |   12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index ed687ac..5262781 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -215,6 +215,18 @@
 		clock-names = "hdmi", "sclk_hdmi", "sclk_pixel",
 			"sclk_hdmiphy", "mout_hdmi";
 		status = "disabled";
+		phy = <&hdmiphy>;
+	};
+
+	hdmiphy: hdmiphy@145D0000 {
+		compatible = "samsung,exynos5420-hdmiphy";
+		reg = <0x145D0000 0x20>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		phy-power-control {
+			reg = <0x10040700 0x04>;
+		};
 	};
 
 	mixer@14450000 {
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* RE: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-08-30  6:59 [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Rahul Sharma
                   ` (6 preceding siblings ...)
  2013-08-30  6:59 ` [PATCH 7/7] ARM: dts: update hdmiphy dt node for exynos5420 Rahul Sharma
@ 2013-08-30  8:33 ` Inki Dae
  2013-08-30  9:06   ` Inki Dae
  2013-08-30 10:05   ` Rahul Sharma
  7 siblings, 2 replies; 45+ messages in thread
From: Inki Dae @ 2013-08-30  8:33 UTC (permalink / raw)
  To: 'Rahul Sharma', linux-samsung-soc, dri-devel
  Cc: kgene.kim, sw0312.kim, seanpaul, l.stach, tomasz.figa,
	s.nawrocki, joshi, r.sh.open

Hi Rahul.

Thanks for your patch set.

I had just quick review to all patch series. And I think we could fully hide
hdmiphy interfaces,
exynos_hdmiphy_enable/disable/check_mode/set_mode/conf_apply, from hdmi
driver.
That may be prototyped like below,

at exynos_hdmi.h

/* Define hdmiphy callbacks. */
struct exynos_hdmiphy_ops {
	void (*enable)(struct device *dev);
	void (*disable)(struct device *dev);
	int (*check_mode)(struct device *dev, struct drm_display_mode
*mode);
	int (*set_mode)(struct device *dev, struct drm_display_mode *mode);
	int (*apply)(struct device *dev);
};


at exynos_hdmi.c

/*
  * Add a new structure for hdmi driver data.
  * type could be HDMI_TYPE13 or HDMI_TYPE14.
  * i2c_hdmiphy could be true or false: true means that current hdmi device
uses i2c
  * based hdmiphy device, otherwise platform device based one.
  */
struct hdmi_drv_data {
	unsigned int type;
	unsigned int i2c_hdmiphy;
};

...

/* Add new members to hdmi context. */
struct hdmi_context {
	...
	struct hdmi_drv_data *drv_data;
	struct hdmiphy_ops *ops;
	...
};


/* Add hdmi device data according Exynos SoC. */
static struct hdmi_drv_data exynos4212_hdmi_drv_data = {
	.type = HDMI_TYPE14,
	.i2c_hdmiphy = true
};

static struct hdmi_drv_data exynos5420_hdmi_drv_data = {
	.type = HDMI_TYPE14,
	.i2c_hdmiphy = false
};


static struct of_device_id hdmi_match_types[] = {
	{
		.compatible = "samsung,exynos4212-hdmi",
		.data		= (void *)&exynos4212_hdmi_drv_data,
	}, {
	...

		.compatible = "samsung,exynos5420-hdmi",
		.data		= (void *)&exynos5420_hdmi_drv_data,
	}, {
	}
};

/* the below example function shows how hdmiphy interfaces can be hided from
hdmi driver. */
static void hdmi_mode_set(...)
{
	...
	hdata->ops->set_mode(hdata->hdmiphy_dev, mode);
}

static int hdmi_get_phy_device(struct hdmi_context *hdata)
{
	struct hdmi_drv_data *data = hdata->drv_data;

	...
	/* Register hdmiphy driver according to i2c_hdmiphy value. */
	ret = exynos_hdmiphy_driver_register(data->i2c_hdmiphy);
	...
	/* Get hdmiphy driver ops according to i2c_hdmiphy value. */
	hdata->ops = exynos_hdmiphy_get_ops(data->i2c_hdmiphy);
	...
}


at exynos_hdmiphy.c

/* Define hdmiphy ops respectively. */
struct exynos_hdmiphy_ops hdmiphy_i2c_ops = {
	.enable = exynos_hdmiphy_i2c_enable,
	.disable = exynos_hdmiphy_i2c_disable,
	...
};

struct exynos_hdmiphy_ops hdmiphy_platdev_ops = {
	.enable = exynos_hdmiphy_platdev_enable,
	.disable = exynos_hdmiphy_platdev_disable,
	...
};

struct exynos_hdmiphy_ops *exynos_hdmiphy_get_ops(unsigned int i2c_hdmiphy)
{
	/* Return hdmiphy ops appropriately according to i2c_hdmiphy. */
	if (i2c_hdmiphy)
		return &hdmiphy_i2c_ops;

	return &hdmiphy_platdev_ops;
}

int exynos_hdmiphy_driver_register(unsigned int i2c_hdmiphy)
{
	...
	/* Register hdmiphy driver appropriately according to i2c_hdmiphy.
*/
	if (i2c_hdmiphy) {
		ret = i2c_add_driver(&hdmiphy_i2c_driver);
		...
	} else {
		ret = platform_driver_register(&hdmiphy_platform_driver);
		...
	}

	return ret;		
}

Thanks,
Inki Dae

> -----Original Message-----
> From: Rahul Sharma [mailto:rahul.sharma@samsung.com]
> Sent: Friday, August 30, 2013 3:59 PM
> To: linux-samsung-soc@vger.kernel.org; dri-devel@lists.freedesktop.org
> Cc: kgene.kim@samsung.com; sw0312.kim@samsung.com; inki.dae@samsung.com;
> seanpaul@chromium.org; l.stach@pengutronix.de; tomasz.figa@gmail.com;
> s.nawrocki@samsung.com; joshi@samsung.com; r.sh.open@gmail.com; Rahul
> Sharma
> Subject: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy
> driver
> 
> Currently, exynos hdmiphy operations and configs are kept
> inside the hdmi driver. Hdmiphy related code is tightly
> coupled with hdmi IP driver.
> 
> This series also removes hdmiphy dummy clock for hdmiphy
> and replace it with Phy PMU Control from the hdmiphy driver.
> 
> At the end, support for exynos5420 hdmiphy is added to the
> hdmiphy driver which is a platform device.
> 
> Drm related paches are based on exynos-drm-next branch at
> git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git
> 
> Arch patches are dependent on
> http://www.mail-archive.com/linux-samsung-
> soc@vger.kernel.org/msg22195.html
> 
> Rahul Sharma (7):
>   drm/exynos: move hdmiphy related code to hdmiphy driver
>   drm/exynos: remove dummy hdmiphy clock
>   drm/exynos: add hdmiphy pmu bit control in hdmiphy driver
>   drm/exynos: add support for exynos5420 hdmiphy
>   exynos/drm: fix ddc i2c device probe failure
>   ARM: dts: update hdmiphy dt node for exynos5250
>   ARM: dts: update hdmiphy dt node for exynos5420
> 
>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
>  .../devicetree/bindings/video/exynos_hdmiphy.txt   |    6 +
>  arch/arm/boot/dts/exynos5250-smdk5250.dts          |    9 +-
>  arch/arm/boot/dts/exynos5420.dtsi                  |   12 +
>  drivers/gpu/drm/exynos/exynos_ddc.c                |    5 +
>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   13 +
>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  353 ++--------
>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  738
> +++++++++++++++++++-
>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 +
>  9 files changed, 868 insertions(+), 305 deletions(-)
>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
> 
> --
> 1.7.10.4

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-08-30  8:33 ` [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Inki Dae
@ 2013-08-30  9:06   ` Inki Dae
  2013-08-30 10:05   ` Rahul Sharma
  1 sibling, 0 replies; 45+ messages in thread
From: Inki Dae @ 2013-08-30  9:06 UTC (permalink / raw)
  To: 'Inki Dae', 'Rahul Sharma', linux-samsung-soc, dri-devel
  Cc: kgene.kim, sw0312.kim, joshi, s.nawrocki

One more thing, you would need to check if other driver can be probed in
probe context. With your patch, exynos_hdmiphy_driver_register() is called
in hdmi_probe() via hdmi_get_phy_device(), and then
platform_driver_reigster() is called via the
exynos_hdmiphy_driver_register(). I remember that was failed.

Thanks,
Inki Dae

> -----Original Message-----
> From: dri-devel-bounces+inki.dae=samsung.com@lists.freedesktop.org
> [mailto:dri-devel-bounces+inki.dae=samsung.com@lists.freedesktop.org] On
> Behalf Of Inki Dae
> Sent: Friday, August 30, 2013 5:33 PM
> To: 'Rahul Sharma'; linux-samsung-soc@vger.kernel.org; dri-
> devel@lists.freedesktop.org
> Cc: kgene.kim@samsung.com; sw0312.kim@samsung.com; joshi@samsung.com;
> s.nawrocki@samsung.com
> Subject: RE: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy
> driver
> 
> Hi Rahul.
> 
> Thanks for your patch set.
> 
> I had just quick review to all patch series. And I think we could fully
> hide
> hdmiphy interfaces,
> exynos_hdmiphy_enable/disable/check_mode/set_mode/conf_apply, from hdmi
> driver.
> That may be prototyped like below,
> 
> at exynos_hdmi.h
> 
> /* Define hdmiphy callbacks. */
> struct exynos_hdmiphy_ops {
> 	void (*enable)(struct device *dev);
> 	void (*disable)(struct device *dev);
> 	int (*check_mode)(struct device *dev, struct drm_display_mode
> *mode);
> 	int (*set_mode)(struct device *dev, struct drm_display_mode *mode);
> 	int (*apply)(struct device *dev);
> };
> 
> 
> at exynos_hdmi.c
> 
> /*
>   * Add a new structure for hdmi driver data.
>   * type could be HDMI_TYPE13 or HDMI_TYPE14.
>   * i2c_hdmiphy could be true or false: true means that current hdmi
> device
> uses i2c
>   * based hdmiphy device, otherwise platform device based one.
>   */
> struct hdmi_drv_data {
> 	unsigned int type;
> 	unsigned int i2c_hdmiphy;
> };
> 
> ...
> 
> /* Add new members to hdmi context. */
> struct hdmi_context {
> 	...
> 	struct hdmi_drv_data *drv_data;
> 	struct hdmiphy_ops *ops;
> 	...
> };
> 
> 
> /* Add hdmi device data according Exynos SoC. */
> static struct hdmi_drv_data exynos4212_hdmi_drv_data = {
> 	.type = HDMI_TYPE14,
> 	.i2c_hdmiphy = true
> };
> 
> static struct hdmi_drv_data exynos5420_hdmi_drv_data = {
> 	.type = HDMI_TYPE14,
> 	.i2c_hdmiphy = false
> };
> 
> 
> static struct of_device_id hdmi_match_types[] = {
> 	{
> 		.compatible = "samsung,exynos4212-hdmi",
> 		.data		= (void *)&exynos4212_hdmi_drv_data,
> 	}, {
> 	...
> 
> 		.compatible = "samsung,exynos5420-hdmi",
> 		.data		= (void *)&exynos5420_hdmi_drv_data,
> 	}, {
> 	}
> };
> 
> /* the below example function shows how hdmiphy interfaces can be hided
> from
> hdmi driver. */
> static void hdmi_mode_set(...)
> {
> 	...
> 	hdata->ops->set_mode(hdata->hdmiphy_dev, mode);
> }
> 
> static int hdmi_get_phy_device(struct hdmi_context *hdata)
> {
> 	struct hdmi_drv_data *data = hdata->drv_data;
> 
> 	...
> 	/* Register hdmiphy driver according to i2c_hdmiphy value. */
> 	ret = exynos_hdmiphy_driver_register(data->i2c_hdmiphy);
> 	...
> 	/* Get hdmiphy driver ops according to i2c_hdmiphy value. */
> 	hdata->ops = exynos_hdmiphy_get_ops(data->i2c_hdmiphy);
> 	...
> }
> 
> 
> at exynos_hdmiphy.c
> 
> /* Define hdmiphy ops respectively. */
> struct exynos_hdmiphy_ops hdmiphy_i2c_ops = {
> 	.enable = exynos_hdmiphy_i2c_enable,
> 	.disable = exynos_hdmiphy_i2c_disable,
> 	...
> };
> 
> struct exynos_hdmiphy_ops hdmiphy_platdev_ops = {
> 	.enable = exynos_hdmiphy_platdev_enable,
> 	.disable = exynos_hdmiphy_platdev_disable,
> 	...
> };
> 
> struct exynos_hdmiphy_ops *exynos_hdmiphy_get_ops(unsigned int
i2c_hdmiphy)
> {
> 	/* Return hdmiphy ops appropriately according to i2c_hdmiphy. */
> 	if (i2c_hdmiphy)
> 		return &hdmiphy_i2c_ops;
> 
> 	return &hdmiphy_platdev_ops;
> }
> 
> int exynos_hdmiphy_driver_register(unsigned int i2c_hdmiphy)
> {
> 	...
> 	/* Register hdmiphy driver appropriately according to i2c_hdmiphy.
> */
> 	if (i2c_hdmiphy) {
> 		ret = i2c_add_driver(&hdmiphy_i2c_driver);
> 		...
> 	} else {
> 		ret = platform_driver_register(&hdmiphy_platform_driver);
> 		...
> 	}
> 
> 	return ret;
> }
> 
> Thanks,
> Inki Dae
> 
> > -----Original Message-----
> > From: Rahul Sharma [mailto:rahul.sharma@samsung.com]
> > Sent: Friday, August 30, 2013 3:59 PM
> > To: linux-samsung-soc@vger.kernel.org; dri-devel@lists.freedesktop.org
> > Cc: kgene.kim@samsung.com; sw0312.kim@samsung.com; inki.dae@samsung.com;
> > seanpaul@chromium.org; l.stach@pengutronix.de; tomasz.figa@gmail.com;
> > s.nawrocki@samsung.com; joshi@samsung.com; r.sh.open@gmail.com; Rahul
> > Sharma
> > Subject: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy
> > driver
> >
> > Currently, exynos hdmiphy operations and configs are kept
> > inside the hdmi driver. Hdmiphy related code is tightly
> > coupled with hdmi IP driver.
> >
> > This series also removes hdmiphy dummy clock for hdmiphy
> > and replace it with Phy PMU Control from the hdmiphy driver.
> >
> > At the end, support for exynos5420 hdmiphy is added to the
> > hdmiphy driver which is a platform device.
> >
> > Drm related paches are based on exynos-drm-next branch at
> > git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git
> >
> > Arch patches are dependent on
> > http://www.mail-archive.com/linux-samsung-
> > soc@vger.kernel.org/msg22195.html
> >
> > Rahul Sharma (7):
> >   drm/exynos: move hdmiphy related code to hdmiphy driver
> >   drm/exynos: remove dummy hdmiphy clock
> >   drm/exynos: add hdmiphy pmu bit control in hdmiphy driver
> >   drm/exynos: add support for exynos5420 hdmiphy
> >   exynos/drm: fix ddc i2c device probe failure
> >   ARM: dts: update hdmiphy dt node for exynos5250
> >   ARM: dts: update hdmiphy dt node for exynos5420
> >
> >  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
> >  .../devicetree/bindings/video/exynos_hdmiphy.txt   |    6 +
> >  arch/arm/boot/dts/exynos5250-smdk5250.dts          |    9 +-
> >  arch/arm/boot/dts/exynos5420.dtsi                  |   12 +
> >  drivers/gpu/drm/exynos/exynos_ddc.c                |    5 +
> >  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   13 +
> >  drivers/gpu/drm/exynos/exynos_hdmi.c               |  353 ++--------
> >  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  738
> > +++++++++++++++++++-
> >  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 +
> >  9 files changed, 868 insertions(+), 305 deletions(-)
> >  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
> >
> > --
> > 1.7.10.4
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-08-30  8:33 ` [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Inki Dae
  2013-08-30  9:06   ` Inki Dae
@ 2013-08-30 10:05   ` Rahul Sharma
  2013-09-02  5:08     ` Inki Dae
  1 sibling, 1 reply; 45+ messages in thread
From: Rahul Sharma @ 2013-08-30 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Rahul Sharma, linux-samsung-soc, dri-devel, Kukjin Kim,
	sw0312.kim, Sean Paul, Lucas Stach, Tomasz Figa,
	Sylwester Nawrocki, sunil joshi

Thanks Mr. Dae,

I have some points for discussion.

On 30 August 2013 14:03, Inki Dae <inki.dae@samsung.com> wrote:
> Hi Rahul.
>
> Thanks for your patch set.
>
> I had just quick review to all patch series. And I think we could fully hide
> hdmiphy interfaces,
> exynos_hdmiphy_enable/disable/check_mode/set_mode/conf_apply, from hdmi
> driver.
> That may be prototyped like below,
>
> at exynos_hdmi.h
>
> /* Define hdmiphy callbacks. */
> struct exynos_hdmiphy_ops {
>         void (*enable)(struct device *dev);
>         void (*disable)(struct device *dev);
>         int (*check_mode)(struct device *dev, struct drm_display_mode
> *mode);
>         int (*set_mode)(struct device *dev, struct drm_display_mode *mode);
>         int (*apply)(struct device *dev);
> };
>

Above looks fine to me. I will hide the ops as you suggested.

>
> at exynos_hdmi.c
>
> /*
>   * Add a new structure for hdmi driver data.
>   * type could be HDMI_TYPE13 or HDMI_TYPE14.
>   * i2c_hdmiphy could be true or false: true means that current hdmi device
> uses i2c
>   * based hdmiphy device, otherwise platform device based one.
>   */
> struct hdmi_drv_data {
>         unsigned int type;
>         unsigned int i2c_hdmiphy;
> };
>
> ...
>
> /* Add new members to hdmi context. */
> struct hdmi_context {
>         ...
>         struct hdmi_drv_data *drv_data;
>         struct hdmiphy_ops *ops;
>         ...
> };
>
>
> /* Add hdmi device data according Exynos SoC. */
> static struct hdmi_drv_data exynos4212_hdmi_drv_data = {
>         .type = HDMI_TYPE14,
>         .i2c_hdmiphy = true
> };
>
> static struct hdmi_drv_data exynos5420_hdmi_drv_data = {
>         .type = HDMI_TYPE14,
>         .i2c_hdmiphy = false
> };
>
>
> static struct of_device_id hdmi_match_types[] = {
>         {
>                 .compatible = "samsung,exynos4212-hdmi",
>                 .data           = (void *)&exynos4212_hdmi_drv_data,
>         }, {
>         ...
>
>                 .compatible = "samsung,exynos5420-hdmi",
>                 .data           = (void *)&exynos5420_hdmi_drv_data,
>         }, {
>         }
> };
>
> /* the below example function shows how hdmiphy interfaces can be hided from
> hdmi driver. */
> static void hdmi_mode_set(...)
> {
>         ...
>         hdata->ops->set_mode(hdata->hdmiphy_dev, mode);

This looks fine.

> }
>
> static int hdmi_get_phy_device(struct hdmi_context *hdata)
> {
>         struct hdmi_drv_data *data = hdata->drv_data;
>
>         ...
>         /* Register hdmiphy driver according to i2c_hdmiphy value. */
>         ret = exynos_hdmiphy_driver_register(data->i2c_hdmiphy);
>         ...
>         /* Get hdmiphy driver ops according to i2c_hdmiphy value. */
>         hdata->ops = exynos_hdmiphy_get_ops(data->i2c_hdmiphy);
>         ...
> }
>
>
> at exynos_hdmiphy.c
>
> /* Define hdmiphy ops respectively. */
> struct exynos_hdmiphy_ops hdmiphy_i2c_ops = {
>         .enable = exynos_hdmiphy_i2c_enable,
>         .disable = exynos_hdmiphy_i2c_disable,
>         ...
> };
>
> struct exynos_hdmiphy_ops hdmiphy_platdev_ops = {
>         .enable = exynos_hdmiphy_platdev_enable,
>         .disable = exynos_hdmiphy_platdev_disable,
>         ...
> };

Actually, Ops for Hdmiphy I2c and platform devices are exactly
same. We don't need 2 sets. Only difference is in static function to
write configuration values to phy. Based on i2c_verify_client(hdata->dev),
we use i2c_master_send or writeb.

>
> struct exynos_hdmiphy_ops *exynos_hdmiphy_get_ops(unsigned int i2c_hdmiphy)
> {
>         /* Return hdmiphy ops appropriately according to i2c_hdmiphy. */
>         if (i2c_hdmiphy)
>                 return &hdmiphy_i2c_ops;
>
>         return &hdmiphy_platdev_ops;
> }

We don't need i2c_hdmiphy flag from the hdmi driver. After probe,
this information is available in hdmiphy driver itself.

>
> int exynos_hdmiphy_driver_register(unsigned int i2c_hdmiphy)
> {
>         ...
>         /* Register hdmiphy driver appropriately according to i2c_hdmiphy.
> */
>         if (i2c_hdmiphy) {
>                 ret = i2c_add_driver(&hdmiphy_i2c_driver);
>                 ...
>         } else {
>                 ret = platform_driver_register(&hdmiphy_platform_driver);
>                 ...
>         }
>

Here i2c_hdmiphy flag helps in avoiding registering both i2c
and platform drivers for phy. But is it a concern that we should
not register 2 drivers on different buses for single hw device. I am
still not clear on this.

Otherwise we do not need to maintain i2c_hdmiphy flag.

Secondly, we always have registration of i2c driver for ddc and
hdmiphy driver in hdmi probe. It works. I have also tested above
series for 5420 and 5250 smdk board. There are no issues.

regards,
Rahul Sharma.

>         return ret;
> }
>
> Thanks,
> Inki Dae
>
>> -----Original Message-----
>> From: Rahul Sharma [mailto:rahul.sharma@samsung.com]
>> Sent: Friday, August 30, 2013 3:59 PM
>> To: linux-samsung-soc@vger.kernel.org; dri-devel@lists.freedesktop.org
>> Cc: kgene.kim@samsung.com; sw0312.kim@samsung.com; inki.dae@samsung.com;
>> seanpaul@chromium.org; l.stach@pengutronix.de; tomasz.figa@gmail.com;
>> s.nawrocki@samsung.com; joshi@samsung.com; r.sh.open@gmail.com; Rahul
>> Sharma
>> Subject: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy
>> driver
>>
>> Currently, exynos hdmiphy operations and configs are kept
>> inside the hdmi driver. Hdmiphy related code is tightly
>> coupled with hdmi IP driver.
>>
>> This series also removes hdmiphy dummy clock for hdmiphy
>> and replace it with Phy PMU Control from the hdmiphy driver.
>>
>> At the end, support for exynos5420 hdmiphy is added to the
>> hdmiphy driver which is a platform device.
>>
>> Drm related paches are based on exynos-drm-next branch at
>> git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git
>>
>> Arch patches are dependent on
>> http://www.mail-archive.com/linux-samsung-
>> soc@vger.kernel.org/msg22195.html
>>
>> Rahul Sharma (7):
>>   drm/exynos: move hdmiphy related code to hdmiphy driver
>>   drm/exynos: remove dummy hdmiphy clock
>>   drm/exynos: add hdmiphy pmu bit control in hdmiphy driver
>>   drm/exynos: add support for exynos5420 hdmiphy
>>   exynos/drm: fix ddc i2c device probe failure
>>   ARM: dts: update hdmiphy dt node for exynos5250
>>   ARM: dts: update hdmiphy dt node for exynos5420
>>
>>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
>>  .../devicetree/bindings/video/exynos_hdmiphy.txt   |    6 +
>>  arch/arm/boot/dts/exynos5250-smdk5250.dts          |    9 +-
>>  arch/arm/boot/dts/exynos5420.dtsi                  |   12 +
>>  drivers/gpu/drm/exynos/exynos_ddc.c                |    5 +
>>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   13 +
>>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  353 ++--------
>>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  738
>> +++++++++++++++++++-
>>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 +
>>  9 files changed, 868 insertions(+), 305 deletions(-)
>>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
>>
>> --
>> 1.7.10.4
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-08-30 10:05   ` Rahul Sharma
@ 2013-09-02  5:08     ` Inki Dae
  2013-09-02  6:28       ` Rahul Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Inki Dae @ 2013-09-02  5:08 UTC (permalink / raw)
  To: 'Rahul Sharma'
  Cc: 'Rahul Sharma', 'linux-samsung-soc',
	dri-devel, 'Kukjin Kim', 'sw0312.kim',
	'Sean Paul', 'Lucas Stach', 'Tomasz Figa',
	'Sylwester Nawrocki', 'sunil joshi'

Hi Rahul,

> -----Original Message-----
> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-soc-
> owner@vger.kernel.org] On Behalf Of Rahul Sharma
> Sent: Friday, August 30, 2013 7:06 PM
> To: Inki Dae
> Cc: Rahul Sharma; linux-samsung-soc; dri-devel@lists.freedesktop.org;
> Kukjin Kim; sw0312.kim; Sean Paul; Lucas Stach; Tomasz Figa; Sylwester
> Nawrocki; sunil joshi
> Subject: Re: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy
> driver
> 
> Thanks Mr. Dae,
> 
> I have some points for discussion.
> 
> On 30 August 2013 14:03, Inki Dae <inki.dae@samsung.com> wrote:
> > Hi Rahul.
> >
> > Thanks for your patch set.
> >
> > I had just quick review to all patch series. And I think we could fully
> hide
> > hdmiphy interfaces,
> > exynos_hdmiphy_enable/disable/check_mode/set_mode/conf_apply, from hdmi
> > driver.
> > That may be prototyped like below,
> >
> > at exynos_hdmi.h
> >
> > /* Define hdmiphy callbacks. */
> > struct exynos_hdmiphy_ops {
> >         void (*enable)(struct device *dev);
> >         void (*disable)(struct device *dev);
> >         int (*check_mode)(struct device *dev, struct drm_display_mode
> > *mode);
> >         int (*set_mode)(struct device *dev, struct drm_display_mode
*mode);
> >         int (*apply)(struct device *dev);
> > };
> >
> 
> Above looks fine to me. I will hide the ops as you suggested.
> 
> >
> > at exynos_hdmi.c
> >
> > /*
> >   * Add a new structure for hdmi driver data.
> >   * type could be HDMI_TYPE13 or HDMI_TYPE14.
> >   * i2c_hdmiphy could be true or false: true means that current hdmi
> device
> > uses i2c
> >   * based hdmiphy device, otherwise platform device based one.
> >   */
> > struct hdmi_drv_data {
> >         unsigned int type;
> >         unsigned int i2c_hdmiphy;
> > };
> >
> > ...
> >
> > /* Add new members to hdmi context. */
> > struct hdmi_context {
> >         ...
> >         struct hdmi_drv_data *drv_data;
> >         struct hdmiphy_ops *ops;
> >         ...
> > };
> >
> >
> > /* Add hdmi device data according Exynos SoC. */
> > static struct hdmi_drv_data exynos4212_hdmi_drv_data = {
> >         .type = HDMI_TYPE14,
> >         .i2c_hdmiphy = true
> > };
> >
> > static struct hdmi_drv_data exynos5420_hdmi_drv_data = {
> >         .type = HDMI_TYPE14,
> >         .i2c_hdmiphy = false
> > };
> >
> >
> > static struct of_device_id hdmi_match_types[] = {
> >         {
> >                 .compatible = "samsung,exynos4212-hdmi",
> >                 .data           = (void *)&exynos4212_hdmi_drv_data,
> >         }, {
> >         ...
> >
> >                 .compatible = "samsung,exynos5420-hdmi",
> >                 .data           = (void *)&exynos5420_hdmi_drv_data,
> >         }, {
> >         }
> > };
> >
> > /* the below example function shows how hdmiphy interfaces can be hided
> from
> > hdmi driver. */
> > static void hdmi_mode_set(...)
> > {
> >         ...
> >         hdata->ops->set_mode(hdata->hdmiphy_dev, mode);
> 
> This looks fine.
> 
> > }
> >
> > static int hdmi_get_phy_device(struct hdmi_context *hdata)
> > {
> >         struct hdmi_drv_data *data = hdata->drv_data;
> >
> >         ...
> >         /* Register hdmiphy driver according to i2c_hdmiphy value. */
> >         ret = exynos_hdmiphy_driver_register(data->i2c_hdmiphy);
> >         ...
> >         /* Get hdmiphy driver ops according to i2c_hdmiphy value. */
> >         hdata->ops = exynos_hdmiphy_get_ops(data->i2c_hdmiphy);
> >         ...
> > }
> >
> >
> > at exynos_hdmiphy.c
> >
> > /* Define hdmiphy ops respectively. */
> > struct exynos_hdmiphy_ops hdmiphy_i2c_ops = {
> >         .enable = exynos_hdmiphy_i2c_enable,
> >         .disable = exynos_hdmiphy_i2c_disable,
> >         ...
> > };
> >
> > struct exynos_hdmiphy_ops hdmiphy_platdev_ops = {
> >         .enable = exynos_hdmiphy_platdev_enable,
> >         .disable = exynos_hdmiphy_platdev_disable,
> >         ...
> > };
> 
> Actually, Ops for Hdmiphy I2c and platform devices are exactly
> same. We don't need 2 sets. Only difference is in static function to
> write configuration values to phy. Based on i2c_verify_client(hdata->dev),
> we use i2c_master_send or writeb.
> 
> >
> > struct exynos_hdmiphy_ops *exynos_hdmiphy_get_ops(unsigned int
> i2c_hdmiphy)
> > {
> >         /* Return hdmiphy ops appropriately according to i2c_hdmiphy. */
> >         if (i2c_hdmiphy)
> >                 return &hdmiphy_i2c_ops;
> >
> >         return &hdmiphy_platdev_ops;
> > }
> 
> We don't need i2c_hdmiphy flag from the hdmi driver. After probe,
> this information is available in hdmiphy driver itself.
> 
> >
> > int exynos_hdmiphy_driver_register(unsigned int i2c_hdmiphy)
> > {
> >         ...
> >         /* Register hdmiphy driver appropriately according to
i2c_hdmiphy.
> > */
> >         if (i2c_hdmiphy) {
> >                 ret = i2c_add_driver(&hdmiphy_i2c_driver);
> >                 ...
> >         } else {
> >                 ret =
platform_driver_register(&hdmiphy_platform_driver);
> >                 ...
> >         }
> >
> 
> Here i2c_hdmiphy flag helps in avoiding registering both i2c
> and platform drivers for phy. But is it a concern that we should
> not register 2 drivers on different buses for single hw device. I am
> still not clear on this.
> 
> Otherwise we do not need to maintain i2c_hdmiphy flag.
> 
> Secondly, we always have registration of i2c driver for ddc and
> hdmiphy driver in hdmi probe. It works. I have also tested above
> series for 5420 and 5250 smdk board. There are no issues.
> 

Can you re-check it? I guess platform_driver_register function would be
failed. Actually, I had faced with same issue at hdmi initial work. And then
only thing we have to discuss  is different buses issue on single hw device
if the above case really works fine.

For this, my opinion is to separate the hdmiphy driver into i2c based and
platform device based drivers; they include same common header file
containing phy configuration data. And it makes hdmi driver call
exynos_hdmiphy_driver_register function in i2c based hdmiphy or platform
device based hdmiphy drivers according to hdmi driver data.

However, we may need to re-design it if the above case is failed.

Thanks,
Inki Dae


> regards,
> Rahul Sharma.
> 
> >         return ret;
> > }
> >
> > Thanks,
> > Inki Dae
> >
> >> -----Original Message-----
> >> From: Rahul Sharma [mailto:rahul.sharma@samsung.com]
> >> Sent: Friday, August 30, 2013 3:59 PM
> >> To: linux-samsung-soc@vger.kernel.org; dri-devel@lists.freedesktop.org
> >> Cc: kgene.kim@samsung.com; sw0312.kim@samsung.com;
inki.dae@samsung.com;
> >> seanpaul@chromium.org; l.stach@pengutronix.de; tomasz.figa@gmail.com;
> >> s.nawrocki@samsung.com; joshi@samsung.com; r.sh.open@gmail.com; Rahul
> >> Sharma
> >> Subject: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy
> >> driver
> >>
> >> Currently, exynos hdmiphy operations and configs are kept
> >> inside the hdmi driver. Hdmiphy related code is tightly
> >> coupled with hdmi IP driver.
> >>
> >> This series also removes hdmiphy dummy clock for hdmiphy
> >> and replace it with Phy PMU Control from the hdmiphy driver.
> >>
> >> At the end, support for exynos5420 hdmiphy is added to the
> >> hdmiphy driver which is a platform device.
> >>
> >> Drm related paches are based on exynos-drm-next branch at
> >> git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git
> >>
> >> Arch patches are dependent on
> >> http://www.mail-archive.com/linux-samsung-
> >> soc@vger.kernel.org/msg22195.html
> >>
> >> Rahul Sharma (7):
> >>   drm/exynos: move hdmiphy related code to hdmiphy driver
> >>   drm/exynos: remove dummy hdmiphy clock
> >>   drm/exynos: add hdmiphy pmu bit control in hdmiphy driver
> >>   drm/exynos: add support for exynos5420 hdmiphy
> >>   exynos/drm: fix ddc i2c device probe failure
> >>   ARM: dts: update hdmiphy dt node for exynos5250
> >>   ARM: dts: update hdmiphy dt node for exynos5420
> >>
> >>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
> >>  .../devicetree/bindings/video/exynos_hdmiphy.txt   |    6 +
> >>  arch/arm/boot/dts/exynos5250-smdk5250.dts          |    9 +-
> >>  arch/arm/boot/dts/exynos5420.dtsi                  |   12 +
> >>  drivers/gpu/drm/exynos/exynos_ddc.c                |    5 +
> >>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   13 +
> >>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  353 ++--------
> >>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  738
> >> +++++++++++++++++++-
> >>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 +
> >>  9 files changed, 868 insertions(+), 305 deletions(-)
> >>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
> >>
> >> --
> >> 1.7.10.4
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-
> soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-02  5:08     ` Inki Dae
@ 2013-09-02  6:28       ` Rahul Sharma
  2013-09-02  7:22         ` Inki Dae
  0 siblings, 1 reply; 45+ messages in thread
From: Rahul Sharma @ 2013-09-02  6:28 UTC (permalink / raw)
  To: Inki Dae
  Cc: Rahul Sharma, linux-samsung-soc, dri-devel, Kukjin Kim,
	sw0312.kim, Sean Paul, Lucas Stach, Tomasz Figa,
	Sylwester Nawrocki, sunil joshi

On 2 September 2013 10:38, Inki Dae <inki.dae@samsung.com> wrote:
> Hi Rahul,
>
>> -----Original Message-----
>> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-soc-
>> owner@vger.kernel.org] On Behalf Of Rahul Sharma
>> Sent: Friday, August 30, 2013 7:06 PM
>> To: Inki Dae
>> Cc: Rahul Sharma; linux-samsung-soc; dri-devel@lists.freedesktop.org;
>> Kukjin Kim; sw0312.kim; Sean Paul; Lucas Stach; Tomasz Figa; Sylwester
>> Nawrocki; sunil joshi
>> Subject: Re: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy
>> driver
>>
>> Thanks Mr. Dae,
>>
>> I have some points for discussion.
>>
>> On 30 August 2013 14:03, Inki Dae <inki.dae@samsung.com> wrote:
>> > Hi Rahul.
>> >
>> > Thanks for your patch set.
>> >
>> > I had just quick review to all patch series. And I think we could fully
>> hide
>> > hdmiphy interfaces,
>> > exynos_hdmiphy_enable/disable/check_mode/set_mode/conf_apply, from hdmi
>> > driver.
>> > That may be prototyped like below,
>> >
>> > at exynos_hdmi.h
>> >
>> > /* Define hdmiphy callbacks. */
>> > struct exynos_hdmiphy_ops {
>> >         void (*enable)(struct device *dev);
>> >         void (*disable)(struct device *dev);
>> >         int (*check_mode)(struct device *dev, struct drm_display_mode
>> > *mode);
>> >         int (*set_mode)(struct device *dev, struct drm_display_mode
> *mode);
>> >         int (*apply)(struct device *dev);
>> > };
>> >
>>
>> Above looks fine to me. I will hide the ops as you suggested.
>>
>> >
>> > at exynos_hdmi.c
>> >
>> > /*
>> >   * Add a new structure for hdmi driver data.
>> >   * type could be HDMI_TYPE13 or HDMI_TYPE14.
>> >   * i2c_hdmiphy could be true or false: true means that current hdmi
>> device
>> > uses i2c
>> >   * based hdmiphy device, otherwise platform device based one.
>> >   */
>> > struct hdmi_drv_data {
>> >         unsigned int type;
>> >         unsigned int i2c_hdmiphy;
>> > };
>> >
>> > ...
>> >
>> > /* Add new members to hdmi context. */
>> > struct hdmi_context {
>> >         ...
>> >         struct hdmi_drv_data *drv_data;
>> >         struct hdmiphy_ops *ops;
>> >         ...
>> > };
>> >
>> >
>> > /* Add hdmi device data according Exynos SoC. */
>> > static struct hdmi_drv_data exynos4212_hdmi_drv_data = {
>> >         .type = HDMI_TYPE14,
>> >         .i2c_hdmiphy = true
>> > };
>> >
>> > static struct hdmi_drv_data exynos5420_hdmi_drv_data = {
>> >         .type = HDMI_TYPE14,
>> >         .i2c_hdmiphy = false
>> > };
>> >
>> >
>> > static struct of_device_id hdmi_match_types[] = {
>> >         {
>> >                 .compatible = "samsung,exynos4212-hdmi",
>> >                 .data           = (void *)&exynos4212_hdmi_drv_data,
>> >         }, {
>> >         ...
>> >
>> >                 .compatible = "samsung,exynos5420-hdmi",
>> >                 .data           = (void *)&exynos5420_hdmi_drv_data,
>> >         }, {
>> >         }
>> > };
>> >
>> > /* the below example function shows how hdmiphy interfaces can be hided
>> from
>> > hdmi driver. */
>> > static void hdmi_mode_set(...)
>> > {
>> >         ...
>> >         hdata->ops->set_mode(hdata->hdmiphy_dev, mode);
>>
>> This looks fine.
>>
>> > }
>> >
>> > static int hdmi_get_phy_device(struct hdmi_context *hdata)
>> > {
>> >         struct hdmi_drv_data *data = hdata->drv_data;
>> >
>> >         ...
>> >         /* Register hdmiphy driver according to i2c_hdmiphy value. */
>> >         ret = exynos_hdmiphy_driver_register(data->i2c_hdmiphy);
>> >         ...
>> >         /* Get hdmiphy driver ops according to i2c_hdmiphy value. */
>> >         hdata->ops = exynos_hdmiphy_get_ops(data->i2c_hdmiphy);
>> >         ...
>> > }
>> >
>> >
>> > at exynos_hdmiphy.c
>> >
>> > /* Define hdmiphy ops respectively. */
>> > struct exynos_hdmiphy_ops hdmiphy_i2c_ops = {
>> >         .enable = exynos_hdmiphy_i2c_enable,
>> >         .disable = exynos_hdmiphy_i2c_disable,
>> >         ...
>> > };
>> >
>> > struct exynos_hdmiphy_ops hdmiphy_platdev_ops = {
>> >         .enable = exynos_hdmiphy_platdev_enable,
>> >         .disable = exynos_hdmiphy_platdev_disable,
>> >         ...
>> > };
>>
>> Actually, Ops for Hdmiphy I2c and platform devices are exactly
>> same. We don't need 2 sets. Only difference is in static function to
>> write configuration values to phy. Based on i2c_verify_client(hdata->dev),
>> we use i2c_master_send or writeb.
>>
>> >
>> > struct exynos_hdmiphy_ops *exynos_hdmiphy_get_ops(unsigned int
>> i2c_hdmiphy)
>> > {
>> >         /* Return hdmiphy ops appropriately according to i2c_hdmiphy. */
>> >         if (i2c_hdmiphy)
>> >                 return &hdmiphy_i2c_ops;
>> >
>> >         return &hdmiphy_platdev_ops;
>> > }
>>
>> We don't need i2c_hdmiphy flag from the hdmi driver. After probe,
>> this information is available in hdmiphy driver itself.
>>
>> >
>> > int exynos_hdmiphy_driver_register(unsigned int i2c_hdmiphy)
>> > {
>> >         ...
>> >         /* Register hdmiphy driver appropriately according to
> i2c_hdmiphy.
>> > */
>> >         if (i2c_hdmiphy) {
>> >                 ret = i2c_add_driver(&hdmiphy_i2c_driver);
>> >                 ...
>> >         } else {
>> >                 ret =
> platform_driver_register(&hdmiphy_platform_driver);
>> >                 ...
>> >         }
>> >
>>
>> Here i2c_hdmiphy flag helps in avoiding registering both i2c
>> and platform drivers for phy. But is it a concern that we should
>> not register 2 drivers on different buses for single hw device. I am
>> still not clear on this.
>>
>> Otherwise we do not need to maintain i2c_hdmiphy flag.
>>
>> Secondly, we always have registration of i2c driver for ddc and
>> hdmiphy driver in hdmi probe. It works. I have also tested above
>> series for 5420 and 5250 smdk board. There are no issues.
>>
>
> Can you re-check it? I guess platform_driver_register function would be
> failed. Actually, I had faced with same issue at hdmi initial work. And then
> only thing we have to discuss  is different buses issue on single hw device
> if the above case really works fine.
>
Mr. dae,

I have re-confirmed. It is working fine. No failure during registering platform
device. Probe hits immediately after registration. I tried 8~9 times.
No failure.
see logs:

# dmesg | grep -i RSH
[    0.895000] [RSH][hdmi_probe][1719] Starting phy registeration
[    0.900000] [RSH][hdmiphy_platform_device_probe Enter][644]
[    0.905000] [RSH][hdmiphy_platform_device_probe Exit Success][683]
[    0.910000] [RSH][exynos_hdmiphy_driver_register][768] Phy
registeration Success.
[    0.915000] [RSH][hdmi_probe][1729] Phy registeration completed.

> For this, my opinion is to separate the hdmiphy driver into i2c based and
> platform device based drivers; they include same common header file
> containing phy configuration data. And it makes hdmi driver call
> exynos_hdmiphy_driver_register function in i2c based hdmiphy or platform
> device based hdmiphy drivers according to hdmi driver data.
>

I am fine with it. We can register hdmiphy-i2c or hdmiphy-platform
driver based on the flag from hdmi driver. But we can still keep both
the drivers in exynos_hdmiphy.c. file and let them share most of the
other callbacks.

regards,
Rahul Sharma.

> However, we may need to re-design it if the above case is failed.
>
> Thanks,
> Inki Dae
>
>
>> regards,
>> Rahul Sharma.
>>
>> >         return ret;
>> > }
>> >
>> > Thanks,
>> > Inki Dae
>> >
>> >> -----Original Message-----
>> >> From: Rahul Sharma [mailto:rahul.sharma@samsung.com]
>> >> Sent: Friday, August 30, 2013 3:59 PM
>> >> To: linux-samsung-soc@vger.kernel.org; dri-devel@lists.freedesktop.org
>> >> Cc: kgene.kim@samsung.com; sw0312.kim@samsung.com;
> inki.dae@samsung.com;
>> >> seanpaul@chromium.org; l.stach@pengutronix.de; tomasz.figa@gmail.com;
>> >> s.nawrocki@samsung.com; joshi@samsung.com; r.sh.open@gmail.com; Rahul
>> >> Sharma
>> >> Subject: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy
>> >> driver
>> >>
>> >> Currently, exynos hdmiphy operations and configs are kept
>> >> inside the hdmi driver. Hdmiphy related code is tightly
>> >> coupled with hdmi IP driver.
>> >>
>> >> This series also removes hdmiphy dummy clock for hdmiphy
>> >> and replace it with Phy PMU Control from the hdmiphy driver.
>> >>
>> >> At the end, support for exynos5420 hdmiphy is added to the
>> >> hdmiphy driver which is a platform device.
>> >>
>> >> Drm related paches are based on exynos-drm-next branch at
>> >> git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git
>> >>
>> >> Arch patches are dependent on
>> >> http://www.mail-archive.com/linux-samsung-
>> >> soc@vger.kernel.org/msg22195.html
>> >>
>> >> Rahul Sharma (7):
>> >>   drm/exynos: move hdmiphy related code to hdmiphy driver
>> >>   drm/exynos: remove dummy hdmiphy clock
>> >>   drm/exynos: add hdmiphy pmu bit control in hdmiphy driver
>> >>   drm/exynos: add support for exynos5420 hdmiphy
>> >>   exynos/drm: fix ddc i2c device probe failure
>> >>   ARM: dts: update hdmiphy dt node for exynos5250
>> >>   ARM: dts: update hdmiphy dt node for exynos5420
>> >>
>> >>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
>> >>  .../devicetree/bindings/video/exynos_hdmiphy.txt   |    6 +
>> >>  arch/arm/boot/dts/exynos5250-smdk5250.dts          |    9 +-
>> >>  arch/arm/boot/dts/exynos5420.dtsi                  |   12 +
>> >>  drivers/gpu/drm/exynos/exynos_ddc.c                |    5 +
>> >>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   13 +
>> >>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  353 ++--------
>> >>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  738
>> >> +++++++++++++++++++-
>> >>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 +
>> >>  9 files changed, 868 insertions(+), 305 deletions(-)
>> >>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
>> >>
>> >> --
>> >> 1.7.10.4
>> >
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-samsung-
>> soc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-02  6:28       ` Rahul Sharma
@ 2013-09-02  7:22         ` Inki Dae
  2013-09-02  9:06           ` Rahul Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Inki Dae @ 2013-09-02  7:22 UTC (permalink / raw)
  To: 'Rahul Sharma'
  Cc: 'Rahul Sharma', 'linux-samsung-soc',
	dri-devel, 'Kukjin Kim', 'sw0312.kim',
	'Sean Paul', 'Lucas Stach', 'Tomasz Figa',
	'Sylwester Nawrocki', 'sunil joshi'



> -----Original Message-----
> From: Rahul Sharma [mailto:r.sh.open@gmail.com]
> Sent: Monday, September 02, 2013 3:28 PM
> To: Inki Dae
> Cc: Rahul Sharma; linux-samsung-soc; dri-devel@lists.freedesktop.org;
> Kukjin Kim; sw0312.kim; Sean Paul; Lucas Stach; Tomasz Figa; Sylwester
> Nawrocki; sunil joshi
> Subject: Re: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy
> driver
> 
> On 2 September 2013 10:38, Inki Dae <inki.dae@samsung.com> wrote:
> > Hi Rahul,
> >
> >> -----Original Message-----
> >> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-
> soc-
> >> owner@vger.kernel.org] On Behalf Of Rahul Sharma
> >> Sent: Friday, August 30, 2013 7:06 PM
> >> To: Inki Dae
> >> Cc: Rahul Sharma; linux-samsung-soc; dri-devel@lists.freedesktop.org;
> >> Kukjin Kim; sw0312.kim; Sean Paul; Lucas Stach; Tomasz Figa; Sylwester
> >> Nawrocki; sunil joshi
> >> Subject: Re: [PATCH 0/7] drm/exynos: move hdmiphy related code to
> hdmiphy
> >> driver
> >>
> >> Thanks Mr. Dae,
> >>
> >> I have some points for discussion.
> >>
> >> On 30 August 2013 14:03, Inki Dae <inki.dae@samsung.com> wrote:
> >> > Hi Rahul.
> >> >
> >> > Thanks for your patch set.
> >> >
> >> > I had just quick review to all patch series. And I think we could
> fully
> >> hide
> >> > hdmiphy interfaces,
> >> > exynos_hdmiphy_enable/disable/check_mode/set_mode/conf_apply, from
> hdmi
> >> > driver.
> >> > That may be prototyped like below,
> >> >
> >> > at exynos_hdmi.h
> >> >
> >> > /* Define hdmiphy callbacks. */
> >> > struct exynos_hdmiphy_ops {
> >> >         void (*enable)(struct device *dev);
> >> >         void (*disable)(struct device *dev);
> >> >         int (*check_mode)(struct device *dev, struct drm_display_mode
> >> > *mode);
> >> >         int (*set_mode)(struct device *dev, struct drm_display_mode
> > *mode);
> >> >         int (*apply)(struct device *dev);
> >> > };
> >> >
> >>
> >> Above looks fine to me. I will hide the ops as you suggested.
> >>
> >> >
> >> > at exynos_hdmi.c
> >> >
> >> > /*
> >> >   * Add a new structure for hdmi driver data.
> >> >   * type could be HDMI_TYPE13 or HDMI_TYPE14.
> >> >   * i2c_hdmiphy could be true or false: true means that current hdmi
> >> device
> >> > uses i2c
> >> >   * based hdmiphy device, otherwise platform device based one.
> >> >   */
> >> > struct hdmi_drv_data {
> >> >         unsigned int type;
> >> >         unsigned int i2c_hdmiphy;
> >> > };
> >> >
> >> > ...
> >> >
> >> > /* Add new members to hdmi context. */
> >> > struct hdmi_context {
> >> >         ...
> >> >         struct hdmi_drv_data *drv_data;
> >> >         struct hdmiphy_ops *ops;
> >> >         ...
> >> > };
> >> >
> >> >
> >> > /* Add hdmi device data according Exynos SoC. */
> >> > static struct hdmi_drv_data exynos4212_hdmi_drv_data = {
> >> >         .type = HDMI_TYPE14,
> >> >         .i2c_hdmiphy = true
> >> > };
> >> >
> >> > static struct hdmi_drv_data exynos5420_hdmi_drv_data = {
> >> >         .type = HDMI_TYPE14,
> >> >         .i2c_hdmiphy = false
> >> > };
> >> >
> >> >
> >> > static struct of_device_id hdmi_match_types[] = {
> >> >         {
> >> >                 .compatible = "samsung,exynos4212-hdmi",
> >> >                 .data           = (void *)&exynos4212_hdmi_drv_data,
> >> >         }, {
> >> >         ...
> >> >
> >> >                 .compatible = "samsung,exynos5420-hdmi",
> >> >                 .data           = (void *)&exynos5420_hdmi_drv_data,
> >> >         }, {
> >> >         }
> >> > };
> >> >
> >> > /* the below example function shows how hdmiphy interfaces can be
> hided
> >> from
> >> > hdmi driver. */
> >> > static void hdmi_mode_set(...)
> >> > {
> >> >         ...
> >> >         hdata->ops->set_mode(hdata->hdmiphy_dev, mode);
> >>
> >> This looks fine.
> >>
> >> > }
> >> >
> >> > static int hdmi_get_phy_device(struct hdmi_context *hdata)
> >> > {
> >> >         struct hdmi_drv_data *data = hdata->drv_data;
> >> >
> >> >         ...
> >> >         /* Register hdmiphy driver according to i2c_hdmiphy value. */
> >> >         ret = exynos_hdmiphy_driver_register(data->i2c_hdmiphy);
> >> >         ...
> >> >         /* Get hdmiphy driver ops according to i2c_hdmiphy value. */
> >> >         hdata->ops = exynos_hdmiphy_get_ops(data->i2c_hdmiphy);
> >> >         ...
> >> > }
> >> >
> >> >
> >> > at exynos_hdmiphy.c
> >> >
> >> > /* Define hdmiphy ops respectively. */
> >> > struct exynos_hdmiphy_ops hdmiphy_i2c_ops = {
> >> >         .enable = exynos_hdmiphy_i2c_enable,
> >> >         .disable = exynos_hdmiphy_i2c_disable,
> >> >         ...
> >> > };
> >> >
> >> > struct exynos_hdmiphy_ops hdmiphy_platdev_ops = {
> >> >         .enable = exynos_hdmiphy_platdev_enable,
> >> >         .disable = exynos_hdmiphy_platdev_disable,
> >> >         ...
> >> > };
> >>
> >> Actually, Ops for Hdmiphy I2c and platform devices are exactly
> >> same. We don't need 2 sets. Only difference is in static function to
> >> write configuration values to phy. Based on i2c_verify_client(hdata-
> >dev),
> >> we use i2c_master_send or writeb.
> >>
> >> >
> >> > struct exynos_hdmiphy_ops *exynos_hdmiphy_get_ops(unsigned int
> >> i2c_hdmiphy)
> >> > {
> >> >         /* Return hdmiphy ops appropriately according to i2c_hdmiphy.
> */
> >> >         if (i2c_hdmiphy)
> >> >                 return &hdmiphy_i2c_ops;
> >> >
> >> >         return &hdmiphy_platdev_ops;
> >> > }
> >>
> >> We don't need i2c_hdmiphy flag from the hdmi driver. After probe,
> >> this information is available in hdmiphy driver itself.
> >>
> >> >
> >> > int exynos_hdmiphy_driver_register(unsigned int i2c_hdmiphy)
> >> > {
> >> >         ...
> >> >         /* Register hdmiphy driver appropriately according to
> > i2c_hdmiphy.
> >> > */
> >> >         if (i2c_hdmiphy) {
> >> >                 ret = i2c_add_driver(&hdmiphy_i2c_driver);
> >> >                 ...
> >> >         } else {
> >> >                 ret =
> > platform_driver_register(&hdmiphy_platform_driver);
> >> >                 ...
> >> >         }
> >> >
> >>
> >> Here i2c_hdmiphy flag helps in avoiding registering both i2c
> >> and platform drivers for phy. But is it a concern that we should
> >> not register 2 drivers on different buses for single hw device. I am
> >> still not clear on this.
> >>
> >> Otherwise we do not need to maintain i2c_hdmiphy flag.
> >>
> >> Secondly, we always have registration of i2c driver for ddc and
> >> hdmiphy driver in hdmi probe. It works. I have also tested above
> >> series for 5420 and 5250 smdk board. There are no issues.
> >>
> >
> > Can you re-check it? I guess platform_driver_register function would be
> > failed. Actually, I had faced with same issue at hdmi initial work. And
> then
> > only thing we have to discuss  is different buses issue on single hw
> device
> > if the above case really works fine.
> >
> Mr. dae,
> 
> I have re-confirmed. It is working fine. No failure during registering
> platform
> device. Probe hits immediately after registration. I tried 8~9 times.
> No failure.
> see logs:
> 
> # dmesg | grep -i RSH
> [    0.895000] [RSH][hdmi_probe][1719] Starting phy registeration
> [    0.900000] [RSH][hdmiphy_platform_device_probe Enter][644]
> [    0.905000] [RSH][hdmiphy_platform_device_probe Exit Success][683]
> [    0.910000] [RSH][exynos_hdmiphy_driver_register][768] Phy
> registeration Success.
> [    0.915000] [RSH][hdmi_probe][1729] Phy registeration completed.
> 

Great. I will also re-check it.

> > For this, my opinion is to separate the hdmiphy driver into i2c based
> and
> > platform device based drivers; they include same common header file
> > containing phy configuration data. And it makes hdmi driver call
> > exynos_hdmiphy_driver_register function in i2c based hdmiphy or platform
> > device based hdmiphy drivers according to hdmi driver data.
> >
> 
> I am fine with it. We can register hdmiphy-i2c or hdmiphy-platform
> driver based on the flag from hdmi driver. But we can still keep both
> the drivers in exynos_hdmiphy.c. file and let them share most of the
> other callbacks.
> 

Is there any mainline driver that keeps two bus drivers; i2c and platform
device, in one file? I'm not sure that this is a good way. So it seems good
to keep two hdmiphy drivers: One is based on i2c bus, and other is based on
platform device. Anyway, we should keep different type's drivers because
Exynos SoC has different type's hdmiphy IP; based on i2c or memory mapped
IO.

Thanks,
Inki Dae

> regards,
> Rahul Sharma.
> 
> > However, we may need to re-design it if the above case is failed.
> >
> > Thanks,
> > Inki Dae
> >
> >
> >> regards,
> >> Rahul Sharma.
> >>
> >> >         return ret;
> >> > }
> >> >
> >> > Thanks,
> >> > Inki Dae
> >> >
> >> >> -----Original Message-----
> >> >> From: Rahul Sharma [mailto:rahul.sharma@samsung.com]
> >> >> Sent: Friday, August 30, 2013 3:59 PM
> >> >> To: linux-samsung-soc@vger.kernel.org; dri-
> devel@lists.freedesktop.org
> >> >> Cc: kgene.kim@samsung.com; sw0312.kim@samsung.com;
> > inki.dae@samsung.com;
> >> >> seanpaul@chromium.org; l.stach@pengutronix.de;
tomasz.figa@gmail.com;
> >> >> s.nawrocki@samsung.com; joshi@samsung.com; r.sh.open@gmail.com;
> Rahul
> >> >> Sharma
> >> >> Subject: [PATCH 0/7] drm/exynos: move hdmiphy related code to
> hdmiphy
> >> >> driver
> >> >>
> >> >> Currently, exynos hdmiphy operations and configs are kept
> >> >> inside the hdmi driver. Hdmiphy related code is tightly
> >> >> coupled with hdmi IP driver.
> >> >>
> >> >> This series also removes hdmiphy dummy clock for hdmiphy
> >> >> and replace it with Phy PMU Control from the hdmiphy driver.
> >> >>
> >> >> At the end, support for exynos5420 hdmiphy is added to the
> >> >> hdmiphy driver which is a platform device.
> >> >>
> >> >> Drm related paches are based on exynos-drm-next branch at
> >> >> git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git
> >> >>
> >> >> Arch patches are dependent on
> >> >> http://www.mail-archive.com/linux-samsung-
> >> >> soc@vger.kernel.org/msg22195.html
> >> >>
> >> >> Rahul Sharma (7):
> >> >>   drm/exynos: move hdmiphy related code to hdmiphy driver
> >> >>   drm/exynos: remove dummy hdmiphy clock
> >> >>   drm/exynos: add hdmiphy pmu bit control in hdmiphy driver
> >> >>   drm/exynos: add support for exynos5420 hdmiphy
> >> >>   exynos/drm: fix ddc i2c device probe failure
> >> >>   ARM: dts: update hdmiphy dt node for exynos5250
> >> >>   ARM: dts: update hdmiphy dt node for exynos5420
> >> >>
> >> >>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
> >> >>  .../devicetree/bindings/video/exynos_hdmiphy.txt   |    6 +
> >> >>  arch/arm/boot/dts/exynos5250-smdk5250.dts          |    9 +-
> >> >>  arch/arm/boot/dts/exynos5420.dtsi                  |   12 +
> >> >>  drivers/gpu/drm/exynos/exynos_ddc.c                |    5 +
> >> >>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   13 +
> >> >>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  353
++--------
> >> >>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  738
> >> >> +++++++++++++++++++-
> >> >>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 +
> >> >>  9 files changed, 868 insertions(+), 305 deletions(-)
> >> >>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
> >> >>
> >> >> --
> >> >> 1.7.10.4
> >> >
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-
> samsung-
> >> soc" in
> >> the body of a message to majordomo@vger.kernel.org
> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-02  7:22         ` Inki Dae
@ 2013-09-02  9:06           ` Rahul Sharma
  2013-09-02 10:06             ` Inki Dae
  0 siblings, 1 reply; 45+ messages in thread
From: Rahul Sharma @ 2013-09-02  9:06 UTC (permalink / raw)
  To: Inki Dae
  Cc: Rahul Sharma, linux-samsung-soc, dri-devel, Kukjin Kim,
	sw0312.kim, Sean Paul, Lucas Stach, Tomasz Figa,
	Sylwester Nawrocki, sunil joshi

On 2 September 2013 12:52, Inki Dae <inki.dae@samsung.com> wrote:
>
>
>> -----Original Message-----
>> From: Rahul Sharma [mailto:r.sh.open@gmail.com]
>> Sent: Monday, September 02, 2013 3:28 PM
>> To: Inki Dae
>> Cc: Rahul Sharma; linux-samsung-soc; dri-devel@lists.freedesktop.org;
>> Kukjin Kim; sw0312.kim; Sean Paul; Lucas Stach; Tomasz Figa; Sylwester
>> Nawrocki; sunil joshi
>> Subject: Re: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy
>> driver
>>
>> On 2 September 2013 10:38, Inki Dae <inki.dae@samsung.com> wrote:
>> > Hi Rahul,
>> >
>> >> -----Original Message-----
>> >> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-
>> soc-
>> >> owner@vger.kernel.org] On Behalf Of Rahul Sharma
>> >> Sent: Friday, August 30, 2013 7:06 PM
>> >> To: Inki Dae
>> >> Cc: Rahul Sharma; linux-samsung-soc; dri-devel@lists.freedesktop.org;
>> >> Kukjin Kim; sw0312.kim; Sean Paul; Lucas Stach; Tomasz Figa; Sylwester
>> >> Nawrocki; sunil joshi
>> >> Subject: Re: [PATCH 0/7] drm/exynos: move hdmiphy related code to
>> hdmiphy
>> >> driver
>> >>
>> >> Thanks Mr. Dae,
>> >>
>> >> I have some points for discussion.
>> >>
>> >> On 30 August 2013 14:03, Inki Dae <inki.dae@samsung.com> wrote:
>> >> > Hi Rahul.
>> >> >
>> >> > Thanks for your patch set.
>> >> >
>> >> > I had just quick review to all patch series. And I think we could
>> fully
>> >> hide
>> >> > hdmiphy interfaces,
>> >> > exynos_hdmiphy_enable/disable/check_mode/set_mode/conf_apply, from
>> hdmi
>> >> > driver.
>> >> > That may be prototyped like below,
>> >> >
>> >> > at exynos_hdmi.h
>> >> >
>> >> > /* Define hdmiphy callbacks. */
>> >> > struct exynos_hdmiphy_ops {
>> >> >         void (*enable)(struct device *dev);
>> >> >         void (*disable)(struct device *dev);
>> >> >         int (*check_mode)(struct device *dev, struct drm_display_mode
>> >> > *mode);
>> >> >         int (*set_mode)(struct device *dev, struct drm_display_mode
>> > *mode);
>> >> >         int (*apply)(struct device *dev);
>> >> > };
>> >> >
>> >>
>> >> Above looks fine to me. I will hide the ops as you suggested.
>> >>
>> >> >
>> >> > at exynos_hdmi.c
>> >> >
>> >> > /*
>> >> >   * Add a new structure for hdmi driver data.
>> >> >   * type could be HDMI_TYPE13 or HDMI_TYPE14.
>> >> >   * i2c_hdmiphy could be true or false: true means that current hdmi
>> >> device
>> >> > uses i2c
>> >> >   * based hdmiphy device, otherwise platform device based one.
>> >> >   */
>> >> > struct hdmi_drv_data {
>> >> >         unsigned int type;
>> >> >         unsigned int i2c_hdmiphy;
>> >> > };
>> >> >
>> >> > ...
>> >> >
>> >> > /* Add new members to hdmi context. */
>> >> > struct hdmi_context {
>> >> >         ...
>> >> >         struct hdmi_drv_data *drv_data;
>> >> >         struct hdmiphy_ops *ops;
>> >> >         ...
>> >> > };
>> >> >
>> >> >
>> >> > /* Add hdmi device data according Exynos SoC. */
>> >> > static struct hdmi_drv_data exynos4212_hdmi_drv_data = {
>> >> >         .type = HDMI_TYPE14,
>> >> >         .i2c_hdmiphy = true
>> >> > };
>> >> >
>> >> > static struct hdmi_drv_data exynos5420_hdmi_drv_data = {
>> >> >         .type = HDMI_TYPE14,
>> >> >         .i2c_hdmiphy = false
>> >> > };
>> >> >
>> >> >
>> >> > static struct of_device_id hdmi_match_types[] = {
>> >> >         {
>> >> >                 .compatible = "samsung,exynos4212-hdmi",
>> >> >                 .data           = (void *)&exynos4212_hdmi_drv_data,
>> >> >         }, {
>> >> >         ...
>> >> >
>> >> >                 .compatible = "samsung,exynos5420-hdmi",
>> >> >                 .data           = (void *)&exynos5420_hdmi_drv_data,
>> >> >         }, {
>> >> >         }
>> >> > };
>> >> >
>> >> > /* the below example function shows how hdmiphy interfaces can be
>> hided
>> >> from
>> >> > hdmi driver. */
>> >> > static void hdmi_mode_set(...)
>> >> > {
>> >> >         ...
>> >> >         hdata->ops->set_mode(hdata->hdmiphy_dev, mode);
>> >>
>> >> This looks fine.
>> >>
>> >> > }
>> >> >
>> >> > static int hdmi_get_phy_device(struct hdmi_context *hdata)
>> >> > {
>> >> >         struct hdmi_drv_data *data = hdata->drv_data;
>> >> >
>> >> >         ...
>> >> >         /* Register hdmiphy driver according to i2c_hdmiphy value. */
>> >> >         ret = exynos_hdmiphy_driver_register(data->i2c_hdmiphy);
>> >> >         ...
>> >> >         /* Get hdmiphy driver ops according to i2c_hdmiphy value. */
>> >> >         hdata->ops = exynos_hdmiphy_get_ops(data->i2c_hdmiphy);
>> >> >         ...
>> >> > }
>> >> >
>> >> >
>> >> > at exynos_hdmiphy.c
>> >> >
>> >> > /* Define hdmiphy ops respectively. */
>> >> > struct exynos_hdmiphy_ops hdmiphy_i2c_ops = {
>> >> >         .enable = exynos_hdmiphy_i2c_enable,
>> >> >         .disable = exynos_hdmiphy_i2c_disable,
>> >> >         ...
>> >> > };
>> >> >
>> >> > struct exynos_hdmiphy_ops hdmiphy_platdev_ops = {
>> >> >         .enable = exynos_hdmiphy_platdev_enable,
>> >> >         .disable = exynos_hdmiphy_platdev_disable,
>> >> >         ...
>> >> > };
>> >>
>> >> Actually, Ops for Hdmiphy I2c and platform devices are exactly
>> >> same. We don't need 2 sets. Only difference is in static function to
>> >> write configuration values to phy. Based on i2c_verify_client(hdata-
>> >dev),
>> >> we use i2c_master_send or writeb.
>> >>
>> >> >
>> >> > struct exynos_hdmiphy_ops *exynos_hdmiphy_get_ops(unsigned int
>> >> i2c_hdmiphy)
>> >> > {
>> >> >         /* Return hdmiphy ops appropriately according to i2c_hdmiphy.
>> */
>> >> >         if (i2c_hdmiphy)
>> >> >                 return &hdmiphy_i2c_ops;
>> >> >
>> >> >         return &hdmiphy_platdev_ops;
>> >> > }
>> >>
>> >> We don't need i2c_hdmiphy flag from the hdmi driver. After probe,
>> >> this information is available in hdmiphy driver itself.
>> >>
>> >> >
>> >> > int exynos_hdmiphy_driver_register(unsigned int i2c_hdmiphy)
>> >> > {
>> >> >         ...
>> >> >         /* Register hdmiphy driver appropriately according to
>> > i2c_hdmiphy.
>> >> > */
>> >> >         if (i2c_hdmiphy) {
>> >> >                 ret = i2c_add_driver(&hdmiphy_i2c_driver);
>> >> >                 ...
>> >> >         } else {
>> >> >                 ret =
>> > platform_driver_register(&hdmiphy_platform_driver);
>> >> >                 ...
>> >> >         }
>> >> >
>> >>
>> >> Here i2c_hdmiphy flag helps in avoiding registering both i2c
>> >> and platform drivers for phy. But is it a concern that we should
>> >> not register 2 drivers on different buses for single hw device. I am
>> >> still not clear on this.
>> >>
>> >> Otherwise we do not need to maintain i2c_hdmiphy flag.
>> >>
>> >> Secondly, we always have registration of i2c driver for ddc and
>> >> hdmiphy driver in hdmi probe. It works. I have also tested above
>> >> series for 5420 and 5250 smdk board. There are no issues.
>> >>
>> >
>> > Can you re-check it? I guess platform_driver_register function would be
>> > failed. Actually, I had faced with same issue at hdmi initial work. And
>> then
>> > only thing we have to discuss  is different buses issue on single hw
>> device
>> > if the above case really works fine.
>> >
>> Mr. dae,
>>
>> I have re-confirmed. It is working fine. No failure during registering
>> platform
>> device. Probe hits immediately after registration. I tried 8~9 times.
>> No failure.
>> see logs:
>>
>> # dmesg | grep -i RSH
>> [    0.895000] [RSH][hdmi_probe][1719] Starting phy registeration
>> [    0.900000] [RSH][hdmiphy_platform_device_probe Enter][644]
>> [    0.905000] [RSH][hdmiphy_platform_device_probe Exit Success][683]
>> [    0.910000] [RSH][exynos_hdmiphy_driver_register][768] Phy
>> registeration Success.
>> [    0.915000] [RSH][hdmi_probe][1729] Phy registeration completed.
>>
>
> Great. I will also re-check it.
>
>> > For this, my opinion is to separate the hdmiphy driver into i2c based
>> and
>> > platform device based drivers; they include same common header file
>> > containing phy configuration data. And it makes hdmi driver call
>> > exynos_hdmiphy_driver_register function in i2c based hdmiphy or platform
>> > device based hdmiphy drivers according to hdmi driver data.
>> >
>>
>> I am fine with it. We can register hdmiphy-i2c or hdmiphy-platform
>> driver based on the flag from hdmi driver. But we can still keep both
>> the drivers in exynos_hdmiphy.c. file and let them share most of the
>> other callbacks.
>>
>
> Is there any mainline driver that keeps two bus drivers; i2c and platform
> device, in one file? I'm not sure that this is a good way. So it seems good

I haven't come across any such mainline driver. I always have this doubt.
If it is not fitting properly, I will implement 2 different drivers in 2 files
(exynos_hdmiphy_i2c.c and exynos_hdmiphy_platform.c).

Regards,
Rahul Sharma.

> to keep two hdmiphy drivers: One is based on i2c bus, and other is based on
> platform device. Anyway, we should keep different type's drivers because
> Exynos SoC has different type's hdmiphy IP; based on i2c or memory mapped
> IO.
>
> Thanks,
> Inki Dae
>
>> regards,
>> Rahul Sharma.
>>
>> > However, we may need to re-design it if the above case is failed.
>> >
>> > Thanks,
>> > Inki Dae
>> >
>> >
>> >> regards,
>> >> Rahul Sharma.
>> >>
>> >> >         return ret;
>> >> > }
>> >> >
>> >> > Thanks,
>> >> > Inki Dae
>> >> >
>> >> >> -----Original Message-----
>> >> >> From: Rahul Sharma [mailto:rahul.sharma@samsung.com]
>> >> >> Sent: Friday, August 30, 2013 3:59 PM
>> >> >> To: linux-samsung-soc@vger.kernel.org; dri-
>> devel@lists.freedesktop.org
>> >> >> Cc: kgene.kim@samsung.com; sw0312.kim@samsung.com;
>> > inki.dae@samsung.com;
>> >> >> seanpaul@chromium.org; l.stach@pengutronix.de;
> tomasz.figa@gmail.com;
>> >> >> s.nawrocki@samsung.com; joshi@samsung.com; r.sh.open@gmail.com;
>> Rahul
>> >> >> Sharma
>> >> >> Subject: [PATCH 0/7] drm/exynos: move hdmiphy related code to
>> hdmiphy
>> >> >> driver
>> >> >>
>> >> >> Currently, exynos hdmiphy operations and configs are kept
>> >> >> inside the hdmi driver. Hdmiphy related code is tightly
>> >> >> coupled with hdmi IP driver.
>> >> >>
>> >> >> This series also removes hdmiphy dummy clock for hdmiphy
>> >> >> and replace it with Phy PMU Control from the hdmiphy driver.
>> >> >>
>> >> >> At the end, support for exynos5420 hdmiphy is added to the
>> >> >> hdmiphy driver which is a platform device.
>> >> >>
>> >> >> Drm related paches are based on exynos-drm-next branch at
>> >> >> git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git
>> >> >>
>> >> >> Arch patches are dependent on
>> >> >> http://www.mail-archive.com/linux-samsung-
>> >> >> soc@vger.kernel.org/msg22195.html
>> >> >>
>> >> >> Rahul Sharma (7):
>> >> >>   drm/exynos: move hdmiphy related code to hdmiphy driver
>> >> >>   drm/exynos: remove dummy hdmiphy clock
>> >> >>   drm/exynos: add hdmiphy pmu bit control in hdmiphy driver
>> >> >>   drm/exynos: add support for exynos5420 hdmiphy
>> >> >>   exynos/drm: fix ddc i2c device probe failure
>> >> >>   ARM: dts: update hdmiphy dt node for exynos5250
>> >> >>   ARM: dts: update hdmiphy dt node for exynos5420
>> >> >>
>> >> >>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
>> >> >>  .../devicetree/bindings/video/exynos_hdmiphy.txt   |    6 +
>> >> >>  arch/arm/boot/dts/exynos5250-smdk5250.dts          |    9 +-
>> >> >>  arch/arm/boot/dts/exynos5420.dtsi                  |   12 +
>> >> >>  drivers/gpu/drm/exynos/exynos_ddc.c                |    5 +
>> >> >>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   13 +
>> >> >>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  353
> ++--------
>> >> >>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  738
>> >> >> +++++++++++++++++++-
>> >> >>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 +
>> >> >>  9 files changed, 868 insertions(+), 305 deletions(-)
>> >> >>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
>> >> >>
>> >> >> --
>> >> >> 1.7.10.4
>> >> >
>> >> --
>> >> To unsubscribe from this list: send the line "unsubscribe linux-
>> samsung-
>> >> soc" in
>> >> the body of a message to majordomo@vger.kernel.org
>> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> >
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-02  9:06           ` Rahul Sharma
@ 2013-09-02 10:06             ` Inki Dae
  0 siblings, 0 replies; 45+ messages in thread
From: Inki Dae @ 2013-09-02 10:06 UTC (permalink / raw)
  To: 'Rahul Sharma'
  Cc: 'Rahul Sharma', 'linux-samsung-soc',
	dri-devel, 'Kukjin Kim', 'sw0312.kim',
	'Sean Paul', 'Lucas Stach', 'Tomasz Figa',
	'Sylwester Nawrocki', 'sunil joshi'



> -----Original Message-----
> From: Rahul Sharma [mailto:r.sh.open@gmail.com]
> Sent: Monday, September 02, 2013 6:06 PM
> To: Inki Dae
> Cc: Rahul Sharma; linux-samsung-soc; dri-devel@lists.freedesktop.org;
> Kukjin Kim; sw0312.kim; Sean Paul; Lucas Stach; Tomasz Figa; Sylwester
> Nawrocki; sunil joshi
> Subject: Re: [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy
> driver
> 
> On 2 September 2013 12:52, Inki Dae <inki.dae@samsung.com> wrote:
> >
> >
> >> -----Original Message-----
> >> From: Rahul Sharma [mailto:r.sh.open@gmail.com]
> >> Sent: Monday, September 02, 2013 3:28 PM
> >> To: Inki Dae
> >> Cc: Rahul Sharma; linux-samsung-soc; dri-devel@lists.freedesktop.org;
> >> Kukjin Kim; sw0312.kim; Sean Paul; Lucas Stach; Tomasz Figa; Sylwester
> >> Nawrocki; sunil joshi
> >> Subject: Re: [PATCH 0/7] drm/exynos: move hdmiphy related code to
> hdmiphy
> >> driver
> >>
> >> On 2 September 2013 10:38, Inki Dae <inki.dae@samsung.com> wrote:
> >> > Hi Rahul,
> >> >
> >> >> -----Original Message-----
> >> >> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-
> >> soc-
> >> >> owner@vger.kernel.org] On Behalf Of Rahul Sharma
> >> >> Sent: Friday, August 30, 2013 7:06 PM
> >> >> To: Inki Dae
> >> >> Cc: Rahul Sharma; linux-samsung-soc;
dri-devel@lists.freedesktop.org;
> >> >> Kukjin Kim; sw0312.kim; Sean Paul; Lucas Stach; Tomasz Figa;
> Sylwester
> >> >> Nawrocki; sunil joshi
> >> >> Subject: Re: [PATCH 0/7] drm/exynos: move hdmiphy related code to
> >> hdmiphy
> >> >> driver
> >> >>
> >> >> Thanks Mr. Dae,
> >> >>
> >> >> I have some points for discussion.
> >> >>
> >> >> On 30 August 2013 14:03, Inki Dae <inki.dae@samsung.com> wrote:
> >> >> > Hi Rahul.
> >> >> >
> >> >> > Thanks for your patch set.
> >> >> >
> >> >> > I had just quick review to all patch series. And I think we could
> >> fully
> >> >> hide
> >> >> > hdmiphy interfaces,
> >> >> > exynos_hdmiphy_enable/disable/check_mode/set_mode/conf_apply, from
> >> hdmi
> >> >> > driver.
> >> >> > That may be prototyped like below,
> >> >> >
> >> >> > at exynos_hdmi.h
> >> >> >
> >> >> > /* Define hdmiphy callbacks. */
> >> >> > struct exynos_hdmiphy_ops {
> >> >> >         void (*enable)(struct device *dev);
> >> >> >         void (*disable)(struct device *dev);
> >> >> >         int (*check_mode)(struct device *dev, struct
> drm_display_mode
> >> >> > *mode);
> >> >> >         int (*set_mode)(struct device *dev, struct
drm_display_mode
> >> > *mode);
> >> >> >         int (*apply)(struct device *dev);
> >> >> > };
> >> >> >
> >> >>
> >> >> Above looks fine to me. I will hide the ops as you suggested.
> >> >>
> >> >> >
> >> >> > at exynos_hdmi.c
> >> >> >
> >> >> > /*
> >> >> >   * Add a new structure for hdmi driver data.
> >> >> >   * type could be HDMI_TYPE13 or HDMI_TYPE14.
> >> >> >   * i2c_hdmiphy could be true or false: true means that current
> hdmi
> >> >> device
> >> >> > uses i2c
> >> >> >   * based hdmiphy device, otherwise platform device based one.
> >> >> >   */
> >> >> > struct hdmi_drv_data {
> >> >> >         unsigned int type;
> >> >> >         unsigned int i2c_hdmiphy;
> >> >> > };
> >> >> >
> >> >> > ...
> >> >> >
> >> >> > /* Add new members to hdmi context. */
> >> >> > struct hdmi_context {
> >> >> >         ...
> >> >> >         struct hdmi_drv_data *drv_data;
> >> >> >         struct hdmiphy_ops *ops;
> >> >> >         ...
> >> >> > };
> >> >> >
> >> >> >
> >> >> > /* Add hdmi device data according Exynos SoC. */
> >> >> > static struct hdmi_drv_data exynos4212_hdmi_drv_data = {
> >> >> >         .type = HDMI_TYPE14,
> >> >> >         .i2c_hdmiphy = true
> >> >> > };
> >> >> >
> >> >> > static struct hdmi_drv_data exynos5420_hdmi_drv_data = {
> >> >> >         .type = HDMI_TYPE14,
> >> >> >         .i2c_hdmiphy = false
> >> >> > };
> >> >> >
> >> >> >
> >> >> > static struct of_device_id hdmi_match_types[] = {
> >> >> >         {
> >> >> >                 .compatible = "samsung,exynos4212-hdmi",
> >> >> >                 .data           = (void
*)&exynos4212_hdmi_drv_data,
> >> >> >         }, {
> >> >> >         ...
> >> >> >
> >> >> >                 .compatible = "samsung,exynos5420-hdmi",
> >> >> >                 .data           = (void
*)&exynos5420_hdmi_drv_data,
> >> >> >         }, {
> >> >> >         }
> >> >> > };
> >> >> >
> >> >> > /* the below example function shows how hdmiphy interfaces can be
> >> hided
> >> >> from
> >> >> > hdmi driver. */
> >> >> > static void hdmi_mode_set(...)
> >> >> > {
> >> >> >         ...
> >> >> >         hdata->ops->set_mode(hdata->hdmiphy_dev, mode);
> >> >>
> >> >> This looks fine.
> >> >>
> >> >> > }
> >> >> >
> >> >> > static int hdmi_get_phy_device(struct hdmi_context *hdata)
> >> >> > {
> >> >> >         struct hdmi_drv_data *data = hdata->drv_data;
> >> >> >
> >> >> >         ...
> >> >> >         /* Register hdmiphy driver according to i2c_hdmiphy value.
> */
> >> >> >         ret = exynos_hdmiphy_driver_register(data->i2c_hdmiphy);
> >> >> >         ...
> >> >> >         /* Get hdmiphy driver ops according to i2c_hdmiphy value.
*/
> >> >> >         hdata->ops = exynos_hdmiphy_get_ops(data->i2c_hdmiphy);
> >> >> >         ...
> >> >> > }
> >> >> >
> >> >> >
> >> >> > at exynos_hdmiphy.c
> >> >> >
> >> >> > /* Define hdmiphy ops respectively. */
> >> >> > struct exynos_hdmiphy_ops hdmiphy_i2c_ops = {
> >> >> >         .enable = exynos_hdmiphy_i2c_enable,
> >> >> >         .disable = exynos_hdmiphy_i2c_disable,
> >> >> >         ...
> >> >> > };
> >> >> >
> >> >> > struct exynos_hdmiphy_ops hdmiphy_platdev_ops = {
> >> >> >         .enable = exynos_hdmiphy_platdev_enable,
> >> >> >         .disable = exynos_hdmiphy_platdev_disable,
> >> >> >         ...
> >> >> > };
> >> >>
> >> >> Actually, Ops for Hdmiphy I2c and platform devices are exactly
> >> >> same. We don't need 2 sets. Only difference is in static function to
> >> >> write configuration values to phy. Based on i2c_verify_client(hdata-
> >> >dev),
> >> >> we use i2c_master_send or writeb.
> >> >>
> >> >> >
> >> >> > struct exynos_hdmiphy_ops *exynos_hdmiphy_get_ops(unsigned int
> >> >> i2c_hdmiphy)
> >> >> > {
> >> >> >         /* Return hdmiphy ops appropriately according to
i2c_hdmiphy.
> >> */
> >> >> >         if (i2c_hdmiphy)
> >> >> >                 return &hdmiphy_i2c_ops;
> >> >> >
> >> >> >         return &hdmiphy_platdev_ops;
> >> >> > }
> >> >>
> >> >> We don't need i2c_hdmiphy flag from the hdmi driver. After probe,
> >> >> this information is available in hdmiphy driver itself.
> >> >>
> >> >> >
> >> >> > int exynos_hdmiphy_driver_register(unsigned int i2c_hdmiphy)
> >> >> > {
> >> >> >         ...
> >> >> >         /* Register hdmiphy driver appropriately according to
> >> > i2c_hdmiphy.
> >> >> > */
> >> >> >         if (i2c_hdmiphy) {
> >> >> >                 ret = i2c_add_driver(&hdmiphy_i2c_driver);
> >> >> >                 ...
> >> >> >         } else {
> >> >> >                 ret =
> >> > platform_driver_register(&hdmiphy_platform_driver);
> >> >> >                 ...
> >> >> >         }
> >> >> >
> >> >>
> >> >> Here i2c_hdmiphy flag helps in avoiding registering both i2c
> >> >> and platform drivers for phy. But is it a concern that we should
> >> >> not register 2 drivers on different buses for single hw device. I am
> >> >> still not clear on this.
> >> >>
> >> >> Otherwise we do not need to maintain i2c_hdmiphy flag.
> >> >>
> >> >> Secondly, we always have registration of i2c driver for ddc and
> >> >> hdmiphy driver in hdmi probe. It works. I have also tested above
> >> >> series for 5420 and 5250 smdk board. There are no issues.
> >> >>
> >> >
> >> > Can you re-check it? I guess platform_driver_register function would
> be
> >> > failed. Actually, I had faced with same issue at hdmi initial work.
> And
> >> then
> >> > only thing we have to discuss  is different buses issue on single hw
> >> device
> >> > if the above case really works fine.
> >> >
> >> Mr. dae,
> >>
> >> I have re-confirmed. It is working fine. No failure during registering
> >> platform
> >> device. Probe hits immediately after registration. I tried 8~9 times.
> >> No failure.
> >> see logs:
> >>
> >> # dmesg | grep -i RSH
> >> [    0.895000] [RSH][hdmi_probe][1719] Starting phy registeration
> >> [    0.900000] [RSH][hdmiphy_platform_device_probe Enter][644]
> >> [    0.905000] [RSH][hdmiphy_platform_device_probe Exit Success][683]
> >> [    0.910000] [RSH][exynos_hdmiphy_driver_register][768] Phy
> >> registeration Success.
> >> [    0.915000] [RSH][hdmi_probe][1729] Phy registeration completed.
> >>
> >
> > Great. I will also re-check it.
> >


Works fine. :) It seems that some patch to avoid duplicate probe was merged
to mainline.
For this, someone had posed it like below but this patch hasn't been merged
to mainline.
 https://lists.ozlabs.org/pipermail/devicetree-discuss/2012-July/017011.html

So it seems that mainline has other solution to avoid that issue. Is there
anyone to give me more detail for this?

> >> > For this, my opinion is to separate the hdmiphy driver into i2c based
> >> and
> >> > platform device based drivers; they include same common header file
> >> > containing phy configuration data. And it makes hdmi driver call
> >> > exynos_hdmiphy_driver_register function in i2c based hdmiphy or
> platform
> >> > device based hdmiphy drivers according to hdmi driver data.
> >> >
> >>
> >> I am fine with it. We can register hdmiphy-i2c or hdmiphy-platform
> >> driver based on the flag from hdmi driver. But we can still keep both
> >> the drivers in exynos_hdmiphy.c. file and let them share most of the
> >> other callbacks.
> >>
> >
> > Is there any mainline driver that keeps two bus drivers; i2c and
> platform
> > device, in one file? I'm not sure that this is a good way. So it seems
> good
> 
> I haven't come across any such mainline driver. I always have this doubt.
> If it is not fitting properly, I will implement 2 different drivers in 2
> files
> (exynos_hdmiphy_i2c.c and exynos_hdmiphy_platform.c).
> 

Let's do it if there is no other opinion. :)

Thanks,
Inki Dae

> Regards,
> Rahul Sharma.
> 
> > to keep two hdmiphy drivers: One is based on i2c bus, and other is based
> on
> > platform device. Anyway, we should keep different type's drivers because
> > Exynos SoC has different type's hdmiphy IP; based on i2c or memory
> mapped
> > IO.
> >
> > Thanks,
> > Inki Dae
> >
> >> regards,
> >> Rahul Sharma.
> >>
> >> > However, we may need to re-design it if the above case is failed.
> >> >
> >> > Thanks,
> >> > Inki Dae
> >> >
> >> >
> >> >> regards,
> >> >> Rahul Sharma.
> >> >>
> >> >> >         return ret;
> >> >> > }
> >> >> >
> >> >> > Thanks,
> >> >> > Inki Dae
> >> >> >
> >> >> >> -----Original Message-----
> >> >> >> From: Rahul Sharma [mailto:rahul.sharma@samsung.com]
> >> >> >> Sent: Friday, August 30, 2013 3:59 PM
> >> >> >> To: linux-samsung-soc@vger.kernel.org; dri-
> >> devel@lists.freedesktop.org
> >> >> >> Cc: kgene.kim@samsung.com; sw0312.kim@samsung.com;
> >> > inki.dae@samsung.com;
> >> >> >> seanpaul@chromium.org; l.stach@pengutronix.de;
> > tomasz.figa@gmail.com;
> >> >> >> s.nawrocki@samsung.com; joshi@samsung.com; r.sh.open@gmail.com;
> >> Rahul
> >> >> >> Sharma
> >> >> >> Subject: [PATCH 0/7] drm/exynos: move hdmiphy related code to
> >> hdmiphy
> >> >> >> driver
> >> >> >>
> >> >> >> Currently, exynos hdmiphy operations and configs are kept
> >> >> >> inside the hdmi driver. Hdmiphy related code is tightly
> >> >> >> coupled with hdmi IP driver.
> >> >> >>
> >> >> >> This series also removes hdmiphy dummy clock for hdmiphy
> >> >> >> and replace it with Phy PMU Control from the hdmiphy driver.
> >> >> >>
> >> >> >> At the end, support for exynos5420 hdmiphy is added to the
> >> >> >> hdmiphy driver which is a platform device.
> >> >> >>
> >> >> >> Drm related paches are based on exynos-drm-next branch at
> >> >> >> git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-
> exynos.git
> >> >> >>
> >> >> >> Arch patches are dependent on
> >> >> >> http://www.mail-archive.com/linux-samsung-
> >> >> >> soc@vger.kernel.org/msg22195.html
> >> >> >>
> >> >> >> Rahul Sharma (7):
> >> >> >>   drm/exynos: move hdmiphy related code to hdmiphy driver
> >> >> >>   drm/exynos: remove dummy hdmiphy clock
> >> >> >>   drm/exynos: add hdmiphy pmu bit control in hdmiphy driver
> >> >> >>   drm/exynos: add support for exynos5420 hdmiphy
> >> >> >>   exynos/drm: fix ddc i2c device probe failure
> >> >> >>   ARM: dts: update hdmiphy dt node for exynos5250
> >> >> >>   ARM: dts: update hdmiphy dt node for exynos5420
> >> >> >>
> >> >> >>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
> >> >> >>  .../devicetree/bindings/video/exynos_hdmiphy.txt   |    6 +
> >> >> >>  arch/arm/boot/dts/exynos5250-smdk5250.dts          |    9 +-
> >> >> >>  arch/arm/boot/dts/exynos5420.dtsi                  |   12 +
> >> >> >>  drivers/gpu/drm/exynos/exynos_ddc.c                |    5 +
> >> >> >>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   13 +
> >> >> >>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  353
> > ++--------
> >> >> >>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  738
> >> >> >> +++++++++++++++++++-
> >> >> >>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 +
> >> >> >>  9 files changed, 868 insertions(+), 305 deletions(-)
> >> >> >>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
> >> >> >>
> >> >> >> --
> >> >> >> 1.7.10.4
> >> >> >
> >> >> --
> >> >> To unsubscribe from this list: send the line "unsubscribe linux-
> >> samsung-
> >> >> soc" in
> >> >> the body of a message to majordomo@vger.kernel.org
> >> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >> >
> >

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-08-30  6:59 ` [PATCH 1/7] " Rahul Sharma
@ 2013-09-03 14:45   ` Sean Paul
  2013-09-04  5:47     ` Rahul Sharma
  2013-09-30 10:50   ` Tushar Behera
  1 sibling, 1 reply; 45+ messages in thread
From: Sean Paul @ 2013-09-03 14:45 UTC (permalink / raw)
  To: Rahul Sharma
  Cc: linux-samsung-soc, dri-devel, kgene.kim, sw0312.kim, InKi Dae,
	l.stach, Tomasz Figa, s.nawrocki, sunil joshi, r.sh.open

A few comments.

On Fri, Aug 30, 2013 at 2:59 AM, Rahul Sharma <rahul.sharma@samsung.com> wrote:
> Exynos hdmiphy operations and configs are kept inside
> the hdmi driver. Hdmiphy related code is tightly coupled
> with hdmi IP driver.
>
> This patche moves hdmiphy related code to hdmiphy driver.

s/patche/patch

> It will help in cleanly supporting the hdmiphy variations
> in further SoCs.
>
> Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
> ---
>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   11 +
>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  343 +++------------
>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  438 +++++++++++++++++++-
>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 ++
>  5 files changed, 533 insertions(+), 296 deletions(-)
>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
>
> diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
> index 50decf8..240eca5 100644
> --- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
> +++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
> @@ -25,6 +25,7 @@ Required properties:
>                 sclk_pixel.
>  - clock-names: aliases as per driver requirements for above clock IDs:
>         "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi".
> +- phy: it points to hdmiphy dt node.
>  Example:
>
>         hdmi {
> @@ -32,4 +33,5 @@ Example:
>                 reg = <0x14530000 0x100000>;
>                 interrupts = <0 95 0>;
>                 hpd-gpio = <&gpx3 7 1>;
> +               phy = <&hdmiphy>;
>         };
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> index 724cab1..1c839f8 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> @@ -64,4 +64,15 @@ void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx);
>  void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx);
>  void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
>  void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
> +
> +int exynos_hdmiphy_driver_register(void);
> +void exynos_hdmiphy_driver_unregister(void);
> +
> +void exynos_hdmiphy_enable(struct device *dev);
> +void exynos_hdmiphy_disable(struct device *dev);
> +int exynos_hdmiphy_check_mode(struct device *dev,
> +                               struct drm_display_mode *mode);
> +int exynos_hdmiphy_set_mode(struct device *dev,
> +                               struct drm_display_mode *mode);
> +int exynos_hdmiphy_conf_apply(struct device *dev);
>  #endif
> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
> index f67ffca..3af4e4c 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> @@ -34,6 +34,8 @@
>  #include <linux/io.h>
>  #include <linux/of.h>
>  #include <linux/of_gpio.h>
> +#include <linux/of_i2c.h>
> +#include <linux/of_platform.h>
>
>  #include <drm/exynos_drm.h>
>
> @@ -172,7 +174,6 @@ struct hdmi_v14_conf {
>  };
>
>  struct hdmi_conf_regs {
> -       int pixel_clock;
>         int cea_video_id;
>         union {
>                 struct hdmi_v13_conf v13_conf;
> @@ -193,9 +194,9 @@ struct hdmi_context {
>         int                             irq;
>
>         struct i2c_client               *ddc_port;
> -       struct i2c_client               *hdmiphy_port;
> +       struct device                   *hdmiphy_dev;
>
> -       /* current hdmiphy conf regs */
> +       /* current hdmi ip configuration registers. */
>         struct hdmi_conf_regs           mode_conf;
>
>         struct hdmi_resources           res;
> @@ -205,180 +206,6 @@ struct hdmi_context {
>         enum hdmi_type                  type;
>  };
>
> -struct hdmiphy_config {
> -       int pixel_clock;
> -       u8 conf[32];
> -};
> -
> -/* list of phy config settings */
> -static const struct hdmiphy_config hdmiphy_v13_configs[] = {
> -       {
> -               .pixel_clock = 27000000,
> -               .conf = {
> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
> -               },
> -       },
> -       {
> -               .pixel_clock = 27027000,
> -               .conf = {
> -                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
> -               },
> -       },
> -       {
> -               .pixel_clock = 74176000,
> -               .conf = {
> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
> -                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> -                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
> -               },
> -       },
> -       {
> -               .pixel_clock = 74250000,
> -               .conf = {
> -                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
> -                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
> -                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
> -               },
> -       },
> -       {
> -               .pixel_clock = 148500000,
> -               .conf = {
> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
> -                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
> -                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
> -               },
> -       },
> -};
> -
> -static const struct hdmiphy_config hdmiphy_v14_configs[] = {
> -       {
> -               .pixel_clock = 25200000,
> -               .conf = {
> -                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
> -                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> -               },
> -       },
> -       {
> -               .pixel_clock = 27000000,
> -               .conf = {
> -                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
> -                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> -                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> -               },
> -       },
> -       {
> -               .pixel_clock = 27027000,
> -               .conf = {
> -                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
> -                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
> -               },
> -       },
> -       {
> -               .pixel_clock = 36000000,
> -               .conf = {
> -                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> -               },
> -       },
> -       {
> -               .pixel_clock = 40000000,
> -               .conf = {
> -                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
> -                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> -               },
> -       },
> -       {
> -               .pixel_clock = 65000000,
> -               .conf = {
> -                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
> -                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> -               },
> -       },
> -       {
> -               .pixel_clock = 74176000,
> -               .conf = {
> -                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
> -                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> -                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> -               },
> -       },
> -       {
> -               .pixel_clock = 74250000,
> -               .conf = {
> -                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
> -               },
> -       },
> -       {
> -               .pixel_clock = 83500000,
> -               .conf = {
> -                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
> -                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> -               },
> -       },
> -       {
> -               .pixel_clock = 106500000,
> -               .conf = {
> -                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
> -                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> -               },
> -       },
> -       {
> -               .pixel_clock = 108000000,
> -               .conf = {
> -                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
> -               },
> -       },
> -       {
> -               .pixel_clock = 146250000,
> -               .conf = {
> -                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
> -                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
> -               },
> -       },
> -       {
> -               .pixel_clock = 148500000,
> -               .conf = {
> -                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> -                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
> -               },
> -       },
> -};
> -
>  struct hdmi_infoframe {
>         enum HDMI_PACKET_TYPE type;
>         u8 ver;
> @@ -769,28 +596,6 @@ static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector)
>         return raw_edid;
>  }
>
> -static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
> -{
> -       const struct hdmiphy_config *confs;
> -       int count, i;
> -
> -       if (hdata->type == HDMI_TYPE13) {
> -               confs = hdmiphy_v13_configs;
> -               count = ARRAY_SIZE(hdmiphy_v13_configs);
> -       } else if (hdata->type == HDMI_TYPE14) {
> -               confs = hdmiphy_v14_configs;
> -               count = ARRAY_SIZE(hdmiphy_v14_configs);
> -       } else
> -               return -EINVAL;
> -
> -       for (i = 0; i < count; i++)
> -               if (confs[i].pixel_clock == pixel_clock)
> -                       return i;
> -
> -       DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
> -       return -EINVAL;
> -}
> -
>  static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
>  {
>         struct hdmi_context *hdata = ctx;
> @@ -801,7 +606,7 @@ static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
>                 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
>                 false, mode->clock * 1000);
>
> -       ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
> +       ret = exynos_hdmiphy_check_mode(hdata->hdmiphy_dev, mode);
>         if (ret < 0)
>                 return ret;
>         return 0;
> @@ -1302,19 +1107,13 @@ static void hdmi_mode_apply(struct hdmi_context *hdata)
>
>  static void hdmiphy_conf_reset(struct hdmi_context *hdata)
>  {
> -       u8 buffer[2];
>         u32 reg;
>
>         clk_disable_unprepare(hdata->res.sclk_hdmi);
>         clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
>         clk_prepare_enable(hdata->res.sclk_hdmi);
>
> -       /* operation mode */
> -       buffer[0] = 0x1f;
> -       buffer[1] = 0x00;
> -
> -       if (hdata->hdmiphy_port)
> -               i2c_master_send(hdata->hdmiphy_port, buffer, 2);
> +       exynos_hdmiphy_disable(hdata->hdmiphy_dev);
>
>         if (hdata->type == HDMI_TYPE13)
>                 reg = HDMI_V13_PHY_RSTOUT;
> @@ -1342,66 +1141,12 @@ static void hdmiphy_poweroff(struct hdmi_context *hdata)
>                         HDMI_PHY_POWER_OFF_EN);
>  }
>
> -static void hdmiphy_conf_apply(struct hdmi_context *hdata)
> -{
> -       const u8 *hdmiphy_data;
> -       u8 buffer[32];
> -       u8 operation[2];
> -       u8 read_buffer[32] = {0, };
> -       int ret;
> -       int i;
> -
> -       if (!hdata->hdmiphy_port) {
> -               DRM_ERROR("hdmiphy is not attached\n");
> -               return;
> -       }
> -
> -       /* pixel clock */
> -       i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
> -       if (i < 0) {
> -               DRM_ERROR("failed to find hdmiphy conf\n");
> -               return;
> -       }
> -
> -       if (hdata->type == HDMI_TYPE13)
> -               hdmiphy_data = hdmiphy_v13_configs[i].conf;
> -       else
> -               hdmiphy_data = hdmiphy_v14_configs[i].conf;
> -
> -       memcpy(buffer, hdmiphy_data, 32);
> -       ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
> -       if (ret != 32) {
> -               DRM_ERROR("failed to configure HDMIPHY via I2C\n");
> -               return;
> -       }
> -
> -       usleep_range(10000, 12000);
> -
> -       /* operation mode */
> -       operation[0] = 0x1f;
> -       operation[1] = 0x80;
> -
> -       ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
> -       if (ret != 2) {
> -               DRM_ERROR("failed to enable hdmiphy\n");
> -               return;
> -       }
> -
> -       ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
> -       if (ret < 0) {
> -               DRM_ERROR("failed to read hdmiphy config\n");
> -               return;
> -       }
> -
> -       for (i = 0; i < ret; i++)
> -               DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
> -                       "recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
> -}
> -
>  static void hdmi_conf_apply(struct hdmi_context *hdata)
>  {
>         hdmiphy_conf_reset(hdata);
> -       hdmiphy_conf_apply(hdata);
> +       exynos_hdmiphy_conf_apply(hdata->hdmiphy_dev);
> +       usleep_range(10000, 12000);

This delay seems like something that should be in the phy driver,
instead of the hdmi driver (since it seems conceivable that certain
phys might not need a delay or might need a longer delay).

> +       exynos_hdmiphy_enable(hdata->hdmiphy_dev);
>
>         mutex_lock(&hdata->hdmi_mutex);
>         hdmi_conf_reset(hdata);
> @@ -1434,7 +1179,6 @@ static void hdmi_v13_mode_set(struct hdmi_context *hdata,
>
>         hdata->mode_conf.cea_video_id =
>                 drm_match_cea_mode((struct drm_display_mode *)m);
> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
>
>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
>         hdmi_set_reg(core->h_v_line, 3, (m->htotal << 12) | m->vtotal);
> @@ -1530,7 +1274,6 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
>
>         hdata->mode_conf.cea_video_id =
>                 drm_match_cea_mode((struct drm_display_mode *)m);
> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
>
>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
>         hdmi_set_reg(core->v_line, 2, m->vtotal);
> @@ -1646,6 +1389,8 @@ static void hdmi_mode_set(void *ctx, struct drm_display_mode *mode)
>                 hdmi_v13_mode_set(hdata, mode);
>         else
>                 hdmi_v14_mode_set(hdata, mode);
> +
> +       exynos_hdmiphy_set_mode(hdata->hdmiphy_dev, mode);

Why set_mode when everything else is mode_set?

>  }
>
>  static void hdmi_get_max_resol(void *ctx, unsigned int *width,
> @@ -1824,7 +1569,7 @@ fail:
>         return -ENODEV;
>  }
>
> -static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
> +static struct i2c_client *hdmi_ddc;
>
>  void hdmi_attach_ddc_client(struct i2c_client *ddc)
>  {
> @@ -1832,12 +1577,6 @@ void hdmi_attach_ddc_client(struct i2c_client *ddc)
>                 hdmi_ddc = ddc;
>  }
>
> -void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
> -{
> -       if (hdmiphy)
> -               hdmi_hdmiphy = hdmiphy;
> -}
> -
>  static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
>                                         (struct device *dev)
>  {
> @@ -1862,6 +1601,50 @@ err_data:
>         return NULL;
>  }
>
> +static int hdmi_get_phy_device(struct hdmi_context *hdata)

"get" is not the proper verb here, "initialize" would be more
appropriate (IMO, of course).

> +{
> +       struct device_node *np;
> +       struct i2c_client *client;
> +       struct platform_device *pdev;
> +       int ret;
> +
> +       /* register hdmiphy driver */
> +       ret = exynos_hdmiphy_driver_register();
> +       if (ret) {
> +               DRM_ERROR("failed to register hdmiphy driver\n");

Printing ret would be useful here.

> +               goto err;
> +       }
> +
> +       np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
> +       if (!np) {
> +               DRM_ERROR("Could not find 'phy' property\n");
> +               ret = -ENOENT;
> +               goto err;
> +       }
> +
> +       /* find hdmi phy on i2c bus */
> +       client = of_find_i2c_device_by_node(np);
> +       if (client) {
> +               hdata->hdmiphy_dev = &client->dev;
> +               ret = 0;
> +               goto exit;
> +       }
> +
> +       /* find hdmi phy on platform bus */
> +       pdev = of_find_device_by_node(np);
> +       if (pdev) {
> +               hdata->hdmiphy_dev = &pdev->dev;
> +               ret = 0;
> +               goto exit;
> +       }
> +
> +exit:
> +       /* able to find hdmiphy on platform/i2c bus */
> +err:

Probably just easier to have one "exit" or "out" label that just returns ret.

> +       of_node_put(np);
> +       return ret;
> +}
> +
>  static struct of_device_id hdmi_match_types[] = {
>         {
>                 .compatible = "samsung,exynos5-hdmi",
> @@ -1939,15 +1722,13 @@ static int hdmi_probe(struct platform_device *pdev)
>
>         hdata->ddc_port = hdmi_ddc;
>
> -       /* hdmiphy i2c driver */
> -       if (i2c_add_driver(&hdmiphy_driver)) {
> -               DRM_ERROR("failed to register hdmiphy i2c driver\n");
> +       ret = hdmi_get_phy_device(hdata);
> +       if (ret) {
> +               DRM_ERROR("failed to get hdmiphy device\n");

Printing ret would be useful.


>                 ret = -ENOENT;

Why change the return value here?

>                 goto err_ddc;
>         }
>
> -       hdata->hdmiphy_port = hdmi_hdmiphy;
> -
>         hdata->irq = gpio_to_irq(hdata->hpd_gpio);
>         if (hdata->irq < 0) {
>                 DRM_ERROR("failed to get GPIO irq\n");
> @@ -1977,7 +1758,7 @@ static int hdmi_probe(struct platform_device *pdev)
>         return 0;
>
>  err_hdmiphy:
> -       i2c_del_driver(&hdmiphy_driver);
> +       exynos_hdmiphy_driver_unregister();
>  err_ddc:
>         i2c_del_driver(&ddc_driver);
>         return ret;
> @@ -1989,8 +1770,8 @@ static int hdmi_remove(struct platform_device *pdev)
>
>         pm_runtime_disable(dev);
>
> -       /* hdmiphy i2c driver */
> -       i2c_del_driver(&hdmiphy_driver);
> +       /* hdmiphy driver */
> +       exynos_hdmiphy_driver_unregister();
>         /* DDC i2c driver */
>         i2c_del_driver(&ddc_driver);
>
> diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> index 59abb14..82daa42 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> @@ -15,51 +15,459 @@
>
>  #include <linux/kernel.h>
>  #include <linux/i2c.h>
> -#include <linux/of.h>
> +#include <linux/module.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/clk.h>
>
>  #include "exynos_drm_drv.h"
>  #include "exynos_hdmi.h"
> +#include "exynos_drm_hdmi.h"
> +#include "regs-hdmiphy.h"
>
> +#define HDMIPHY_REG_COUNT      (32)

This probably belongs in regs-hdmiphy.h instead of here. Also remove the ()

>
> -static int hdmiphy_probe(struct i2c_client *client,
> -       const struct i2c_device_id *id)
> +struct hdmiphy_context {
> +       struct device           *dev;
> +       struct hdmiphy_config   *current_conf;
> +
> +       struct hdmiphy_config   *confs;
> +       unsigned int            nr_confs;
> +};
> +
> +struct hdmiphy_config {
> +       int pixel_clock;
> +       u8 conf[HDMIPHY_REG_COUNT];
> +};
> +
> +struct hdmiphy_drv_data {
> +       struct hdmiphy_config *confs;
> +       unsigned int count;
> +};
> +
> +/* list of all required phy config settings */
> +static struct hdmiphy_config hdmiphy_4212_configs[] = {
> +       {
> +               .pixel_clock = 25200000,
> +               .conf = {
> +                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
> +                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 27000000,
> +               .conf = {
> +                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
> +                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> +                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 27027000,
> +               .conf = {
> +                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
> +                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
> +               },
> +       },
> +       {
> +               .pixel_clock = 36000000,
> +               .conf = {
> +                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 40000000,
> +               .conf = {
> +                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
> +                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 65000000,
> +               .conf = {
> +                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
> +                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 74176000,
> +               .conf = {
> +                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
> +                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> +                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 74250000,
> +               .conf = {
> +                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
> +               },
> +       },
> +       {
> +               .pixel_clock = 83500000,
> +               .conf = {
> +                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
> +                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 106500000,
> +               .conf = {
> +                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
> +                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 108000000,
> +               .conf = {
> +                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 146250000,
> +               .conf = {
> +                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
> +                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 148500000,
> +               .conf = {
> +                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> +                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
> +               },
> +       },
> +};
> +
> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
> +       {
> +               .pixel_clock = 27000000,
> +               .conf = {
> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
> +               },
> +       },
> +       {
> +               .pixel_clock = 27027000,
> +               .conf = {
> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
> +               },
> +       },
> +       {
> +               .pixel_clock = 74176000,
> +               .conf = {
> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
> +               },
> +       },
> +       {
> +               .pixel_clock = 74250000,
> +               .conf = {
> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
> +               },
> +       },
> +       {
> +               .pixel_clock = 148500000,
> +               .conf = {
> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
> +               },
> +       },
> +};
> +

Are you aware of the effort to move these to dt? Since these are
board-specific values, it seems incorrect to apply them universally.
Shirish has uploaded a patch to the chromium review site to push these
into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
you can work that into your patch set?


> +static struct hdmiphy_config *hdmiphy_find_conf(struct hdmiphy_context *hdata,
> +                       const struct drm_display_mode *mode)
> +{
> +       int i;
> +
> +       for (i = 0; i < hdata->nr_confs; i++)
> +               if (hdata->confs[i].pixel_clock == (mode->clock * 1000))
> +                       return &hdata->confs[i];
> +
> +       return NULL;
> +}
> +
> +static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata,
> +                       u32 reg_offset, u8 value)
> +{
> +       if (reg_offset >= HDMIPHY_REG_COUNT)
> +               return -EINVAL;
> +
> +       if (i2c_verify_client(hdata->dev)) {

Is this necessary?

> +               u8 buffer[2];
> +               int ret;
> +
> +               buffer[0] = reg_offset;
> +               buffer[1] = value;
> +
> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
> +                               buffer, 2);
> +               if (ret == 2)
> +                       return 0;
> +               return ret;
> +       } else {
> +               return -EINVAL;
> +       }
> +}
> +
> +static int hdmiphy_reg_write_buf(struct hdmiphy_context *hdata,
> +                       u32 reg_offset, const u8 *buf, u32 len)
> +{
> +       if ((reg_offset + len) > HDMIPHY_REG_COUNT)
> +               return -EINVAL;
> +
> +       if (i2c_verify_client(hdata->dev)) {

Is this necessary?


> +               int ret;
> +
> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
> +                               buf, len);

Does this actually work? You don't seem to be using reg_offset anywhere.

> +               if (ret == len)
> +                       return 0;
> +               return ret;
> +       } else {
> +               return -EINVAL;
> +       }
> +}
> +
> +int exynos_hdmiphy_check_mode(struct device *dev,
> +                       struct drm_display_mode *mode)
>  {
> -       hdmi_attach_hdmiphy_client(client);
> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> +       const struct hdmiphy_config *conf;
> +
> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);

Maybe you can merge this debug message with the one below.

>
> -       dev_info(&client->adapter->dev, "attached s5p_hdmiphy "
> -               "into i2c adapter successfully\n");
> +       if (!hdata) {
> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> +               return -EINVAL;
> +       }

Can this happen? I think the phy driver registration should be
synchronous with the hdmi driver registration. As such, it shouldn't
be possible to get a check_mode callback until it's all set up.

>
> +       DRM_DEBUG("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
> +               mode->hdisplay, mode->vdisplay,
> +               mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE)
> +               ? true : false, mode->clock * 1000);
> +
> +       conf = hdmiphy_find_conf(hdata, mode);
> +       if (!conf) {
> +               DRM_DEBUG("Display Mode is not supported.\n");
> +               return -EINVAL;
> +       }
>         return 0;
>  }
>
> -static int hdmiphy_remove(struct i2c_client *client)
> +int exynos_hdmiphy_set_mode(struct device *dev,
> +                       struct drm_display_mode *mode)
>  {
> -       dev_info(&client->adapter->dev, "detached s5p_hdmiphy "
> -               "from i2c adapter successfully\n");
> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> +
> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> +
> +       hdata->current_conf = hdmiphy_find_conf(hdata, mode);
> +
> +       if (!hdata) {
> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> +               return -EINVAL;
> +       }

I really hope this check isn't necessary, since you've already
dereferenced it 2 lines up :) See my comment above, I don't think you
can ever hit this.

>
> +       if (!hdata->current_conf) {
> +               DRM_ERROR("Display Mode is not supported.\n");
> +               return -EINVAL;
> +       }
>         return 0;
>  }
>
> -static struct of_device_id hdmiphy_match_types[] = {
> +void exynos_hdmiphy_enable(struct device *dev)
> +{
> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> +       int ret;
> +
> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> +
> +       if (!hdata) {
> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> +               return;
> +       }

Same comment as above.

> +
> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
> +                       HDMIPHY_MODE_EN);
> +       if (ret < 0) {
> +               DRM_ERROR("failed to disable hdmiphy.\n");
> +               return;
> +       }
> +}
> +
> +void exynos_hdmiphy_disable(struct device *dev)
> +{
> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> +       int ret;
> +
> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> +
> +       if (!hdata) {
> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> +               return;
> +       }
> +
> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, 0);
> +       if (ret < 0) {
> +               DRM_ERROR("failed to enable hdmiphy.\n");

If you're not going to return the error code, at least print it here.

> +               return;
> +       }
> +}
> +
> +int exynos_hdmiphy_conf_apply(struct device *dev)
> +{
> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> +       const u8 *hdmiphy_data;
> +       int ret;
> +
> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> +
> +       if (!hdata) {
> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> +               return -EINVAL;
> +       }
> +
> +       /* pixel clock */

I don't understand this comment.

> +       if (hdata->current_conf)
> +               hdmiphy_data = hdata->current_conf->conf;
> +       else
> +               return -EINVAL;
> +
> +       ret = hdmiphy_reg_write_buf(hdata, 0, hdmiphy_data,
> +                       HDMIPHY_REG_COUNT);

I think the only reason this works is b/c you're writing to register offset 0.

> +       if (ret) {
> +               DRM_ERROR("failed to configure hdmiphy.\n");
> +               return -EINVAL;

Why don't you return ret?

> +       }
> +       return 0;
> +}
> +
> +static struct hdmiphy_drv_data exynos4212_hdmiphy_drv_data = {
> +       .confs = hdmiphy_4212_configs,
> +       .count = ARRAY_SIZE(hdmiphy_4212_configs)
> +};
> +
> +static struct hdmiphy_drv_data exynos4210_hdmiphy_drv_data = {
> +       .confs = hdmiphy_4210_configs,
> +       .count = ARRAY_SIZE(hdmiphy_4210_configs)
> +};
> +
> +static struct of_device_id hdmiphy_i2c_device_match_types[] = {
>         {
>                 .compatible = "samsung,exynos5-hdmiphy",
> +               .data   = &exynos4212_hdmiphy_drv_data,
>         }, {
>                 .compatible = "samsung,exynos4210-hdmiphy",
> +               .data   = &exynos4210_hdmiphy_drv_data,
>         }, {
>                 .compatible = "samsung,exynos4212-hdmiphy",
> +               .data   = &exynos4212_hdmiphy_drv_data,
>         }, {
>                 /* end node */
>         }
>  };
>
> -struct i2c_driver hdmiphy_driver = {
> +static int hdmiphy_i2c_device_probe(struct i2c_client *client,
> +       const struct i2c_device_id *id)
> +{
> +       struct device *dev = &client->dev;
> +       struct hdmiphy_context *hdata;
> +       struct hdmiphy_drv_data *drv;
> +       const struct of_device_id *match;
> +
> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> +
> +       hdata = devm_kzalloc(dev, sizeof(*hdata), GFP_KERNEL);
> +       if (!hdata) {
> +               DRM_ERROR("failed to allocate hdmiphy context.\n");
> +               return -ENOMEM;
> +       }
> +
> +       match = of_match_node(of_match_ptr(
> +               hdmiphy_i2c_device_match_types),
> +               dev->of_node);
> +
> +       if (match == NULL)
> +               return -ENODEV;
> +
> +       drv = (struct hdmiphy_drv_data *)match->data;
> +
> +       hdata->dev = dev;
> +       hdata->confs = drv->confs;
> +       hdata->nr_confs = drv->count;
> +
> +       i2c_set_clientdata(client, hdata);
> +
> +       return 0;
> +}
> +
> +static const struct i2c_device_id hdmiphy_id[] = {
> +       { },
> +};
> +
> +struct i2c_driver hdmiphy_i2c_driver = {
>         .driver = {
>                 .name   = "exynos-hdmiphy",
>                 .owner  = THIS_MODULE,
> -               .of_match_table = hdmiphy_match_types,
> +               .of_match_table = of_match_ptr(
> +                               hdmiphy_i2c_device_match_types),
>         },
> -       .probe          = hdmiphy_probe,
> -       .remove         = hdmiphy_remove,
> +       .id_table               = hdmiphy_id,
> +       .probe          = hdmiphy_i2c_device_probe,
>         .command                = NULL,
>  };
> -EXPORT_SYMBOL(hdmiphy_driver);
> +
> +int exynos_hdmiphy_driver_register(void)
> +{
> +       int ret;
> +
> +       ret = i2c_add_driver(&hdmiphy_i2c_driver);
> +       if (ret)
> +               return ret;
> +
> +       return 0;
> +}
> +
> +void exynos_hdmiphy_driver_unregister(void)
> +{
> +       i2c_del_driver(&hdmiphy_i2c_driver);
> +}
> diff --git a/drivers/gpu/drm/exynos/regs-hdmiphy.h b/drivers/gpu/drm/exynos/regs-hdmiphy.h
> new file mode 100644
> index 0000000..d3f9d87
> --- /dev/null
> +++ b/drivers/gpu/drm/exynos/regs-hdmiphy.h
> @@ -0,0 +1,35 @@
> +/*
> + *
> + *  regs-hdmiphy.h
> + *
> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> + * http://www.samsung.com/
> + *
> + * HDMI-PHY register header file for Samsung HDMI driver
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#ifndef SAMSUNG_REGS_HDMIPHY_H
> +#define SAMSUNG_REGS_HDMIPHY_H
> +
> +/*
> + * Register part
> +*/
> +#define HDMIPHY_MODE_SET_DONE  (0x1f)
> +
> +/*
> + * Bit definition part
> + */
> +
> +/* HDMIPHY_MODE_SET_DONE */
> +#define HDMIPHY_MODE_EN                (1 << 7)
> +
> +/* hdmiphy pmu control bits */
> +#define PMU_HDMI_PHY_CONTROL_MASK      (1 << 0)
> +#define PMU_HDMI_PHY_ENABLE            (1)
> +#define PMU_HDMI_PHY_DISABLE           (0)


You don't need the () around simple values

> +
> +#endif /* SAMSUNG_REGS_HDMIPHY_H */
> --
> 1.7.10.4
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 2/7] drm/exynos: remove dummy hdmiphy clock
  2013-08-30  6:59 ` [PATCH 2/7] drm/exynos: remove dummy hdmiphy clock Rahul Sharma
@ 2013-09-03 15:58   ` Sean Paul
  0 siblings, 0 replies; 45+ messages in thread
From: Sean Paul @ 2013-09-03 15:58 UTC (permalink / raw)
  To: Rahul Sharma
  Cc: linux-samsung-soc, dri-devel, kgene.kim, sw0312.kim, InKi Dae,
	l.stach, Tomasz Figa, s.nawrocki, sunil joshi, r.sh.open

On Fri, Aug 30, 2013 at 2:59 AM, Rahul Sharma <rahul.sharma@samsung.com> wrote:
> hdmiphy is a dummy clock which actually controls the PMU bit
> to enable/disbale hdmiphy (before CCF). This clock is cleaned

s/disbale/disable/

> from the hdmi driver.
>
> Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_hdmi.c |    8 --------
>  1 file changed, 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
> index 3af4e4c..cd1d921 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> @@ -84,7 +84,6 @@ struct hdmi_resources {
>         struct clk                      *sclk_hdmi;
>         struct clk                      *sclk_pixel;
>         struct clk                      *sclk_hdmiphy;
> -       struct clk                      *hdmiphy;
>         struct clk                      *mout_hdmi;
>         struct regulator_bulk_data      *regul_bulk;
>         int                             regul_count;
> @@ -1431,7 +1430,6 @@ static void hdmi_poweron(struct hdmi_context *hdata)
>         if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
>                 DRM_DEBUG_KMS("failed to enable regulator bulk\n");
>
> -       clk_prepare_enable(res->hdmiphy);
>         clk_prepare_enable(res->hdmi);
>         clk_prepare_enable(res->sclk_hdmi);
>
> @@ -1456,7 +1454,6 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
>
>         clk_disable_unprepare(res->sclk_hdmi);
>         clk_disable_unprepare(res->hdmi);
> -       clk_disable_unprepare(res->hdmiphy);
>         regulator_bulk_disable(res->regul_count, res->regul_bulk);
>
>         mutex_lock(&hdata->hdmi_mutex);
> @@ -1549,11 +1546,6 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
>                 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
>                 goto fail;
>         }
> -       res->hdmiphy = devm_clk_get(dev, "hdmiphy");
> -       if (IS_ERR(res->hdmiphy)) {
> -               DRM_ERROR("failed to get clock 'hdmiphy'\n");
> -               goto fail;
> -       }
>         res->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
>         if (IS_ERR(res->mout_hdmi)) {
>                 DRM_ERROR("failed to get clock 'mout_hdmi'\n");
> --
> 1.7.10.4
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 3/7] drm/exynos: add hdmiphy pmu bit control in hdmiphy driver
  2013-08-30  6:59 ` [PATCH 3/7] drm/exynos: add hdmiphy pmu bit control in hdmiphy driver Rahul Sharma
@ 2013-09-03 16:10   ` Sean Paul
  0 siblings, 0 replies; 45+ messages in thread
From: Sean Paul @ 2013-09-03 16:10 UTC (permalink / raw)
  To: Rahul Sharma
  Cc: linux-samsung-soc, dri-devel, kgene.kim, sw0312.kim, InKi Dae,
	l.stach, Tomasz Figa, s.nawrocki, sunil joshi, r.sh.open

On Fri, Aug 30, 2013 at 2:59 AM, Rahul Sharma <rahul.sharma@samsung.com> wrote:
> Before hdmiphy operation like config, start etc, hdmiphy
> bit in PMU block should be enabled. Earlier this happens
> in hdmi drvier through a dummy "hdmiphy" clock.

s/drvier/driver/

>
> Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
> ---
>  .../devicetree/bindings/video/exynos_hdmiphy.txt   |    6 ++
>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |    2 +
>  drivers/gpu/drm/exynos/exynos_hdmi.c               |    2 +
>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |   82 ++++++++++++++++++++
>  4 files changed, 92 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt b/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt
> index 162f641..f6bf096 100644
> --- a/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt
> +++ b/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt
> @@ -6,10 +6,16 @@ Required properties:
>         2) "samsung,exynos4210-hdmiphy".
>         3) "samsung,exynos4212-hdmiphy".
>  - reg: I2C address of the hdmiphy device.
> +- phy-power-control: this child node represents phy power control
> +       register which is inside the pmu block (power management unit).

Should you include devicetree-discuss on this?

>
>  Example:
>
>         hdmiphy {
>                 compatible = "samsung,exynos4210-hdmiphy";
>                 reg = <0x38>;
> +
> +               phy-power-control {
> +                               reg = <0x10040700 0x04>;
> +               };
>         };
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> index 1c839f8..9a14f96 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> @@ -68,6 +68,8 @@ void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
>  int exynos_hdmiphy_driver_register(void);
>  void exynos_hdmiphy_driver_unregister(void);
>
> +void exynos_hdmiphy_poweron(struct device *dev);
> +void exynos_hdmiphy_poweroff(struct device *dev);
>  void exynos_hdmiphy_enable(struct device *dev);
>  void exynos_hdmiphy_disable(struct device *dev);
>  int exynos_hdmiphy_check_mode(struct device *dev,
> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
> index cd1d921..a6234fc 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> @@ -1131,6 +1131,7 @@ static void hdmiphy_poweron(struct hdmi_context *hdata)
>         if (hdata->type == HDMI_TYPE14)
>                 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0,
>                         HDMI_PHY_POWER_OFF_EN);
> +       exynos_hdmiphy_poweron(hdata->hdmiphy_dev);
>  }
>
>  static void hdmiphy_poweroff(struct hdmi_context *hdata)
> @@ -1138,6 +1139,7 @@ static void hdmiphy_poweroff(struct hdmi_context *hdata)
>         if (hdata->type == HDMI_TYPE14)
>                 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0,
>                         HDMI_PHY_POWER_OFF_EN);
> +       exynos_hdmiphy_poweroff(hdata->hdmiphy_dev);

Shouldn't the phy power off before HDMI?

>  }
>
>  static void hdmi_conf_apply(struct hdmi_context *hdata)
> diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> index 82daa42..b1b8a0f 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> @@ -30,6 +30,9 @@ struct hdmiphy_context {
>         struct device           *dev;
>         struct hdmiphy_config   *current_conf;
>
> +       /* hdmiphy resources */
> +       void __iomem            *phy_pow_ctrl_reg;
> +
>         struct hdmiphy_config   *confs;
>         unsigned int            nr_confs;
>  };
> @@ -225,6 +228,49 @@ static struct hdmiphy_config *hdmiphy_find_conf(struct hdmiphy_context *hdata,
>         return NULL;
>  }
>
> +static int hdmiphy_dt_parse_power_control(struct hdmiphy_context *hdata)
> +{
> +       struct device_node *phy_pow_ctrl_node;
> +       u32 buf[2];
> +       int ret = 0;
> +
> +       phy_pow_ctrl_node = of_get_child_by_name(hdata->dev->of_node,
> +                       "phy-power-control");
> +       if (!phy_pow_ctrl_node) {
> +               DRM_ERROR("Failed to find phy power control node\n");
> +               ret = -ENODEV;
> +               goto fail;

You can just return -ENODEV here.

> +       }
> +
> +       /* reg property holds two informations: addr of pmu register, size */
> +       if (of_property_read_u32_array(phy_pow_ctrl_node, "reg",
> +                       (u32 *)&buf, 2)) {

Maybe I'm missing something, but this looks bad. I think this should be:

of_property_read_u32_array(phy_pow_ctrl_node, "reg", buf, ARRAY_SIZE(buf))

ie: dereferencing buf won't do what you expect it to.

> +               DRM_ERROR("faild to get phy power control reg\n");
> +               ret = -EINVAL;
> +               goto fail;
> +       }
> +
> +       hdata->phy_pow_ctrl_reg = devm_ioremap(hdata->dev, buf[0], buf[1]);
> +       if (!hdata->phy_pow_ctrl_reg) {
> +               DRM_ERROR("failed to ioremap phy pmu reg\n");
> +               ret = -ENOMEM;
> +               goto fail;
> +       }
> +
> +fail:

fail seems like the wrong thing to call this, since it's run on
success too :) Maybe "out" would be more appropriate.

> +       of_node_put(phy_pow_ctrl_node);
> +       return ret;
> +}
> +
> +static inline void hdmiphy_pow_ctrl_reg_writemask(
> +                       struct hdmiphy_context *hdata,
> +                       u32 value, u32 mask)
> +{
> +       u32 old = readl(hdata->phy_pow_ctrl_reg);
> +       value = (value & mask) | (old & ~mask);
> +       writel(value, hdata->phy_pow_ctrl_reg);
> +}
> +
>  static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata,
>                         u32 reg_offset, u8 value)
>  {
> @@ -353,6 +399,36 @@ void exynos_hdmiphy_disable(struct device *dev)
>         }
>  }
>
> +void exynos_hdmiphy_poweron(struct device *dev)
> +{
> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> +
> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> +
> +       if (!hdata) {
> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> +               return;
> +       }

Same comment as the other review. I wonder if you really need this check

> +
> +       hdmiphy_pow_ctrl_reg_writemask(hdata, PMU_HDMI_PHY_ENABLE,
> +               PMU_HDMI_PHY_CONTROL_MASK);
> +}
> +
> +void exynos_hdmiphy_poweroff(struct device *dev)
> +{
> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> +
> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> +
> +       if (!hdata) {
> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> +               return;
> +       }
> +
> +       hdmiphy_pow_ctrl_reg_writemask(hdata, PMU_HDMI_PHY_DISABLE,
> +               PMU_HDMI_PHY_CONTROL_MASK);
> +}
> +
>  int exynos_hdmiphy_conf_apply(struct device *dev)
>  {
>         struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> @@ -413,6 +489,7 @@ static int hdmiphy_i2c_device_probe(struct i2c_client *client,
>         struct hdmiphy_context *hdata;
>         struct hdmiphy_drv_data *drv;
>         const struct of_device_id *match;
> +       int ret;
>
>         DRM_DEBUG_KMS("[%d]\n", __LINE__);
>
> @@ -436,6 +513,11 @@ static int hdmiphy_i2c_device_probe(struct i2c_client *client,
>         hdata->nr_confs = drv->count;
>
>         i2c_set_clientdata(client, hdata);
> +       ret = hdmiphy_dt_parse_power_control(hdata);
> +       if (ret) {
> +               DRM_ERROR("failed to map hdmiphy pow control reg.\n");
> +               return ret;
> +       }
>
>         return 0;
>  }
> --
> 1.7.10.4
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 4/7] drm/exynos: add support for exynos5420 hdmiphy
  2013-08-30  6:59 ` [PATCH 4/7] drm/exynos: add support for exynos5420 hdmiphy Rahul Sharma
@ 2013-09-03 16:15   ` Sean Paul
  0 siblings, 0 replies; 45+ messages in thread
From: Sean Paul @ 2013-09-03 16:15 UTC (permalink / raw)
  To: Rahul Sharma
  Cc: linux-samsung-soc, dri-devel, kgene.kim, sw0312.kim, InKi Dae,
	l.stach, Tomasz Figa, s.nawrocki, sunil joshi, r.sh.open

On Fri, Aug 30, 2013 at 2:59 AM, Rahul Sharma <rahul.sharma@samsung.com> wrote:
> Exynos5420 hdmiphy device is a platform device, unlike
> predecessor SoCs where it used to be a I2C device. This
> support is added to the hdmiphy driver.
>

Stuffing a platform driver in the same place as your i2c driver seems
weird. I think you should split them up.

> Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_hdmiphy.c |  224 ++++++++++++++++++++++++++++++-
>  1 file changed, 221 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> index b1b8a0f..33e89d9 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> @@ -32,6 +32,7 @@ struct hdmiphy_context {
>
>         /* hdmiphy resources */
>         void __iomem            *phy_pow_ctrl_reg;
> +       void __iomem            *regs;
>
>         struct hdmiphy_config   *confs;
>         unsigned int            nr_confs;
> @@ -48,6 +49,135 @@ struct hdmiphy_drv_data {
>  };
>
>  /* list of all required phy config settings */
> +static struct hdmiphy_config hdmiphy_5420_configs[] = {
> +       {
> +               .pixel_clock = 25200000,
> +               .conf = {
> +                       0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
> +                       0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 27000000,
> +               .conf = {
> +                       0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
> +                       0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 27027000,
> +               .conf = {
> +                       0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
> +                       0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 36000000,
> +               .conf = {
> +                       0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
> +                       0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 40000000,
> +               .conf = {
> +                       0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
> +                       0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 65000000,
> +               .conf = {
> +                       0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
> +                       0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 71000000,
> +               .conf = {
> +                       0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
> +                       0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 74176000,
> +               .conf = {
> +                       0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
> +                       0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 74250000,
> +               .conf = {
> +                       0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0xC8,
> +                       0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 83500000,
> +               .conf = {
> +                       0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
> +                       0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 106500000,
> +               .conf = {
> +                       0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
> +                       0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 108000000,
> +               .conf = {
> +                       0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
> +                       0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 146250000,
> +               .conf = {
> +                       0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
> +                       0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +       {
> +               .pixel_clock = 148500000,
> +               .conf = {
> +                       0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0xC8,
> +                       0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
> +                       0x66, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
> +                       0x54, 0x4B, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
> +               },
> +       },
> +};

Same comment here about these being board-specific. It would be nice
to come to consensus about putting this stuff in dt before moving too
far forward.

> +
>  static struct hdmiphy_config hdmiphy_4212_configs[] = {
>         {
>                 .pixel_clock = 25200000,
> @@ -290,7 +420,8 @@ static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata,
>                         return 0;
>                 return ret;
>         } else {
> -               return -EINVAL;
> +               writeb(value, hdata->regs + (reg_offset<<2));
> +               return 0;
>         }
>  }
>
> @@ -309,7 +440,11 @@ static int hdmiphy_reg_write_buf(struct hdmiphy_context *hdata,
>                         return 0;
>                 return ret;
>         } else {
> -               return -EINVAL;
> +               int i;
> +               for (i = 0; i < len; i++)
> +                       writeb(buf[i], hdata->regs +
> +                               ((reg_offset + i)<<2));
> +               return 0;
>         }
>  }
>
> @@ -457,6 +592,11 @@ int exynos_hdmiphy_conf_apply(struct device *dev)
>         return 0;
>  }
>
> +static struct hdmiphy_drv_data exynos5420_hdmiphy_drv_data = {
> +       .confs = hdmiphy_5420_configs,
> +       .count = ARRAY_SIZE(hdmiphy_5420_configs)
> +};
> +
>  static struct hdmiphy_drv_data exynos4212_hdmiphy_drv_data = {
>         .confs = hdmiphy_4212_configs,
>         .count = ARRAY_SIZE(hdmiphy_4212_configs)
> @@ -482,6 +622,67 @@ static struct of_device_id hdmiphy_i2c_device_match_types[] = {
>         }
>  };
>
> +static struct of_device_id hdmiphy_platform_device_match_types[] = {
> +       {
> +               .compatible = "samsung,exynos5420-hdmiphy",
> +               .data   = &exynos5420_hdmiphy_drv_data,
> +       }, {
> +               /* end node */
> +       }
> +};
> +
> +static int hdmiphy_platform_device_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct hdmiphy_context *hdata;
> +       struct hdmiphy_drv_data *drv;
> +       struct resource *res;
> +       const struct of_device_id *match;
> +       int ret;
> +
> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> +
> +       hdata = devm_kzalloc(dev, sizeof(*hdata), GFP_KERNEL);
> +       if (!hdata) {
> +               DRM_ERROR("failed to allocate hdmiphy context.\n");
> +               return -ENOMEM;
> +       }
> +
> +       match = of_match_node(of_match_ptr(
> +               hdmiphy_platform_device_match_types),
> +               dev->of_node);
> +
> +       if (match == NULL)

if (!match) should do the trick

> +               return -ENODEV;
> +
> +       drv = (struct hdmiphy_drv_data *)match->data;
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!res) {
> +               DRM_ERROR("failed to find phy registers\n");
> +               return -ENOENT;
> +       }
> +
> +       hdata->regs = devm_request_and_ioremap(&pdev->dev, res);
> +       if (!hdata->regs) {
> +               DRM_ERROR("failed to map registers\n");
> +               return -ENXIO;
> +       }
> +
> +       hdata->dev = dev;
> +       hdata->confs = drv->confs;
> +       hdata->nr_confs = drv->count;
> +
> +       platform_set_drvdata(pdev, hdata);
> +       ret = hdmiphy_dt_parse_power_control(hdata);
> +       if (ret) {
> +               DRM_ERROR("failed to map hdmiphy pow control reg.\n");
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
>  static int hdmiphy_i2c_device_probe(struct i2c_client *client,
>         const struct i2c_device_id *id)
>  {
> @@ -538,18 +739,35 @@ struct i2c_driver hdmiphy_i2c_driver = {
>         .command                = NULL,
>  };
>
> +struct platform_driver hdmiphy_platform_driver = {
> +       .driver = {
> +               .name   = "exynos-hdmiphy",
> +               .owner  = THIS_MODULE,
> +               .of_match_table = of_match_ptr(
> +                               hdmiphy_platform_device_match_types),
> +       },
> +       .probe          = hdmiphy_platform_device_probe,
> +};
> +
>  int exynos_hdmiphy_driver_register(void)
>  {
>         int ret;
>
>         ret = i2c_add_driver(&hdmiphy_i2c_driver);
>         if (ret)
> -               return ret;
> +               goto err;
> +
> +       ret = platform_driver_register(&hdmiphy_platform_driver);
> +       if (ret)
> +               goto err;
>
>         return 0;
> +err:
> +       return ret;
>  }
>
>  void exynos_hdmiphy_driver_unregister(void)
>  {
>         i2c_del_driver(&hdmiphy_i2c_driver);
> +       platform_driver_unregister(&hdmiphy_platform_driver);
>  }
> --
> 1.7.10.4
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-03 14:45   ` Sean Paul
@ 2013-09-04  5:47     ` Rahul Sharma
  2013-09-04  7:37       ` Inki Dae
  2013-09-04 14:33       ` Sean Paul
  0 siblings, 2 replies; 45+ messages in thread
From: Rahul Sharma @ 2013-09-04  5:47 UTC (permalink / raw)
  To: Sean Paul
  Cc: Rahul Sharma, linux-samsung-soc, dri-devel, kgene.kim,
	sw0312.kim, InKi Dae, Lucas Stach, Tomasz Figa,
	Sylwester Nawrocki, sunil joshi, shirish

Thanks Sean,

On 3 September 2013 20:15, Sean Paul <seanpaul@chromium.org> wrote:
> A few comments.
>
> On Fri, Aug 30, 2013 at 2:59 AM, Rahul Sharma <rahul.sharma@samsung.com> wrote:
>> Exynos hdmiphy operations and configs are kept inside
>> the hdmi driver. Hdmiphy related code is tightly coupled
>> with hdmi IP driver.
>>
>> This patche moves hdmiphy related code to hdmiphy driver.
>
> s/patche/patch
>
ok.
>> It will help in cleanly supporting the hdmiphy variations
>> in further SoCs.
>>
>> Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
>> ---
>>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
>>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   11 +
>>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  343 +++------------
>>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  438 +++++++++++++++++++-
>>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 ++
>>  5 files changed, 533 insertions(+), 296 deletions(-)
>>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
>>
>> diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> index 50decf8..240eca5 100644
>> --- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> +++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> @@ -25,6 +25,7 @@ Required properties:
>>                 sclk_pixel.
>>  - clock-names: aliases as per driver requirements for above clock IDs:
>>         "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi".
>> +- phy: it points to hdmiphy dt node.
>>  Example:
>>
>>         hdmi {
>> @@ -32,4 +33,5 @@ Example:
>>                 reg = <0x14530000 0x100000>;
>>                 interrupts = <0 95 0>;
>>                 hpd-gpio = <&gpx3 7 1>;
>> +               phy = <&hdmiphy>;
>>         };
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>> index 724cab1..1c839f8 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>> @@ -64,4 +64,15 @@ void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx);
>>  void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx);
>>  void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
>>  void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
>> +
>> +int exynos_hdmiphy_driver_register(void);
>> +void exynos_hdmiphy_driver_unregister(void);
>> +
>> +void exynos_hdmiphy_enable(struct device *dev);
>> +void exynos_hdmiphy_disable(struct device *dev);
>> +int exynos_hdmiphy_check_mode(struct device *dev,
>> +                               struct drm_display_mode *mode);
>> +int exynos_hdmiphy_set_mode(struct device *dev,
>> +                               struct drm_display_mode *mode);
>> +int exynos_hdmiphy_conf_apply(struct device *dev);
>>  #endif
>> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
>> index f67ffca..3af4e4c 100644
>> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
>> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
>> @@ -34,6 +34,8 @@
>>  #include <linux/io.h>
>>  #include <linux/of.h>
>>  #include <linux/of_gpio.h>
>> +#include <linux/of_i2c.h>
>> +#include <linux/of_platform.h>
>>
>>  #include <drm/exynos_drm.h>
>>
>> @@ -172,7 +174,6 @@ struct hdmi_v14_conf {
>>  };
>>
>>  struct hdmi_conf_regs {
>> -       int pixel_clock;
>>         int cea_video_id;
>>         union {
>>                 struct hdmi_v13_conf v13_conf;
>> @@ -193,9 +194,9 @@ struct hdmi_context {
>>         int                             irq;
>>
>>         struct i2c_client               *ddc_port;
>> -       struct i2c_client               *hdmiphy_port;
>> +       struct device                   *hdmiphy_dev;
>>
>> -       /* current hdmiphy conf regs */
>> +       /* current hdmi ip configuration registers. */
>>         struct hdmi_conf_regs           mode_conf;
>>
>>         struct hdmi_resources           res;
>> @@ -205,180 +206,6 @@ struct hdmi_context {
>>         enum hdmi_type                  type;
>>  };
>>
>> -struct hdmiphy_config {
>> -       int pixel_clock;
>> -       u8 conf[32];
>> -};
>> -
>> -/* list of phy config settings */
>> -static const struct hdmiphy_config hdmiphy_v13_configs[] = {
>> -       {
>> -               .pixel_clock = 27000000,
>> -               .conf = {
>> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
>> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 27027000,
>> -               .conf = {
>> -                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
>> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 74176000,
>> -               .conf = {
>> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
>> -                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
>> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> -                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 74250000,
>> -               .conf = {
>> -                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
>> -                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
>> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
>> -                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 148500000,
>> -               .conf = {
>> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
>> -                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
>> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> -                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
>> -               },
>> -       },
>> -};
>> -
>> -static const struct hdmiphy_config hdmiphy_v14_configs[] = {
>> -       {
>> -               .pixel_clock = 25200000,
>> -               .conf = {
>> -                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
>> -                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 27000000,
>> -               .conf = {
>> -                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
>> -                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 27027000,
>> -               .conf = {
>> -                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
>> -                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 36000000,
>> -               .conf = {
>> -                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
>> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 40000000,
>> -               .conf = {
>> -                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
>> -                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 65000000,
>> -               .conf = {
>> -                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
>> -                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 74176000,
>> -               .conf = {
>> -                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
>> -                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 74250000,
>> -               .conf = {
>> -                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
>> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 83500000,
>> -               .conf = {
>> -                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
>> -                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 106500000,
>> -               .conf = {
>> -                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
>> -                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 108000000,
>> -               .conf = {
>> -                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
>> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 146250000,
>> -               .conf = {
>> -                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
>> -                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
>> -               },
>> -       },
>> -       {
>> -               .pixel_clock = 148500000,
>> -               .conf = {
>> -                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
>> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> -                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
>> -               },
>> -       },
>> -};
>> -
>>  struct hdmi_infoframe {
>>         enum HDMI_PACKET_TYPE type;
>>         u8 ver;
>> @@ -769,28 +596,6 @@ static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector)
>>         return raw_edid;
>>  }
>>
>> -static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
>> -{
>> -       const struct hdmiphy_config *confs;
>> -       int count, i;
>> -
>> -       if (hdata->type == HDMI_TYPE13) {
>> -               confs = hdmiphy_v13_configs;
>> -               count = ARRAY_SIZE(hdmiphy_v13_configs);
>> -       } else if (hdata->type == HDMI_TYPE14) {
>> -               confs = hdmiphy_v14_configs;
>> -               count = ARRAY_SIZE(hdmiphy_v14_configs);
>> -       } else
>> -               return -EINVAL;
>> -
>> -       for (i = 0; i < count; i++)
>> -               if (confs[i].pixel_clock == pixel_clock)
>> -                       return i;
>> -
>> -       DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
>> -       return -EINVAL;
>> -}
>> -
>>  static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
>>  {
>>         struct hdmi_context *hdata = ctx;
>> @@ -801,7 +606,7 @@ static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
>>                 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
>>                 false, mode->clock * 1000);
>>
>> -       ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
>> +       ret = exynos_hdmiphy_check_mode(hdata->hdmiphy_dev, mode);
>>         if (ret < 0)
>>                 return ret;
>>         return 0;
>> @@ -1302,19 +1107,13 @@ static void hdmi_mode_apply(struct hdmi_context *hdata)
>>
>>  static void hdmiphy_conf_reset(struct hdmi_context *hdata)
>>  {
>> -       u8 buffer[2];
>>         u32 reg;
>>
>>         clk_disable_unprepare(hdata->res.sclk_hdmi);
>>         clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
>>         clk_prepare_enable(hdata->res.sclk_hdmi);
>>
>> -       /* operation mode */
>> -       buffer[0] = 0x1f;
>> -       buffer[1] = 0x00;
>> -
>> -       if (hdata->hdmiphy_port)
>> -               i2c_master_send(hdata->hdmiphy_port, buffer, 2);
>> +       exynos_hdmiphy_disable(hdata->hdmiphy_dev);
>>
>>         if (hdata->type == HDMI_TYPE13)
>>                 reg = HDMI_V13_PHY_RSTOUT;
>> @@ -1342,66 +1141,12 @@ static void hdmiphy_poweroff(struct hdmi_context *hdata)
>>                         HDMI_PHY_POWER_OFF_EN);
>>  }
>>
>> -static void hdmiphy_conf_apply(struct hdmi_context *hdata)
>> -{
>> -       const u8 *hdmiphy_data;
>> -       u8 buffer[32];
>> -       u8 operation[2];
>> -       u8 read_buffer[32] = {0, };
>> -       int ret;
>> -       int i;
>> -
>> -       if (!hdata->hdmiphy_port) {
>> -               DRM_ERROR("hdmiphy is not attached\n");
>> -               return;
>> -       }
>> -
>> -       /* pixel clock */
>> -       i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
>> -       if (i < 0) {
>> -               DRM_ERROR("failed to find hdmiphy conf\n");
>> -               return;
>> -       }
>> -
>> -       if (hdata->type == HDMI_TYPE13)
>> -               hdmiphy_data = hdmiphy_v13_configs[i].conf;
>> -       else
>> -               hdmiphy_data = hdmiphy_v14_configs[i].conf;
>> -
>> -       memcpy(buffer, hdmiphy_data, 32);
>> -       ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
>> -       if (ret != 32) {
>> -               DRM_ERROR("failed to configure HDMIPHY via I2C\n");
>> -               return;
>> -       }
>> -
>> -       usleep_range(10000, 12000);
>> -
>> -       /* operation mode */
>> -       operation[0] = 0x1f;
>> -       operation[1] = 0x80;
>> -
>> -       ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
>> -       if (ret != 2) {
>> -               DRM_ERROR("failed to enable hdmiphy\n");
>> -               return;
>> -       }
>> -
>> -       ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
>> -       if (ret < 0) {
>> -               DRM_ERROR("failed to read hdmiphy config\n");
>> -               return;
>> -       }
>> -
>> -       for (i = 0; i < ret; i++)
>> -               DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
>> -                       "recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
>> -}
>> -
>>  static void hdmi_conf_apply(struct hdmi_context *hdata)
>>  {
>>         hdmiphy_conf_reset(hdata);
>> -       hdmiphy_conf_apply(hdata);
>> +       exynos_hdmiphy_conf_apply(hdata->hdmiphy_dev);
>> +       usleep_range(10000, 12000);
>
> This delay seems like something that should be in the phy driver,
> instead of the hdmi driver (since it seems conceivable that certain
> phys might not need a delay or might need a longer delay).
>

ok. I will move it there.

>> +       exynos_hdmiphy_enable(hdata->hdmiphy_dev);
>>
>>         mutex_lock(&hdata->hdmi_mutex);
>>         hdmi_conf_reset(hdata);
>> @@ -1434,7 +1179,6 @@ static void hdmi_v13_mode_set(struct hdmi_context *hdata,
>>
>>         hdata->mode_conf.cea_video_id =
>>                 drm_match_cea_mode((struct drm_display_mode *)m);
>> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
>>
>>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
>>         hdmi_set_reg(core->h_v_line, 3, (m->htotal << 12) | m->vtotal);
>> @@ -1530,7 +1274,6 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
>>
>>         hdata->mode_conf.cea_video_id =
>>                 drm_match_cea_mode((struct drm_display_mode *)m);
>> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
>>
>>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
>>         hdmi_set_reg(core->v_line, 2, m->vtotal);
>> @@ -1646,6 +1389,8 @@ static void hdmi_mode_set(void *ctx, struct drm_display_mode *mode)
>>                 hdmi_v13_mode_set(hdata, mode);
>>         else
>>                 hdmi_v14_mode_set(hdata, mode);
>> +
>> +       exynos_hdmiphy_set_mode(hdata->hdmiphy_dev, mode);
>
> Why set_mode when everything else is mode_set?
>

I will change it to mode_set.

>>  }
>>
>>  static void hdmi_get_max_resol(void *ctx, unsigned int *width,
>> @@ -1824,7 +1569,7 @@ fail:
>>         return -ENODEV;
>>  }
>>
>> -static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
>> +static struct i2c_client *hdmi_ddc;
>>
>>  void hdmi_attach_ddc_client(struct i2c_client *ddc)
>>  {
>> @@ -1832,12 +1577,6 @@ void hdmi_attach_ddc_client(struct i2c_client *ddc)
>>                 hdmi_ddc = ddc;
>>  }
>>
>> -void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
>> -{
>> -       if (hdmiphy)
>> -               hdmi_hdmiphy = hdmiphy;
>> -}
>> -
>>  static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
>>                                         (struct device *dev)
>>  {
>> @@ -1862,6 +1601,50 @@ err_data:
>>         return NULL;
>>  }
>>
>> +static int hdmi_get_phy_device(struct hdmi_context *hdata)
>
> "get" is not the proper verb here, "initialize" would be more
> appropriate (IMO, of course).
>

But we don't initialise the phy here. It is just to get the
hdmiphy dev* through dt.

>> +{
>> +       struct device_node *np;
>> +       struct i2c_client *client;
>> +       struct platform_device *pdev;
>> +       int ret;
>> +
>> +       /* register hdmiphy driver */
>> +       ret = exynos_hdmiphy_driver_register();
>> +       if (ret) {
>> +               DRM_ERROR("failed to register hdmiphy driver\n");
>
> Printing ret would be useful here.

ok.
>
>> +               goto err;
>> +       }
>> +
>> +       np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
>> +       if (!np) {
>> +               DRM_ERROR("Could not find 'phy' property\n");
>> +               ret = -ENOENT;
>> +               goto err;
>> +       }
>> +
>> +       /* find hdmi phy on i2c bus */
>> +       client = of_find_i2c_device_by_node(np);
>> +       if (client) {
>> +               hdata->hdmiphy_dev = &client->dev;
>> +               ret = 0;
>> +               goto exit;
>> +       }
>> +
>> +       /* find hdmi phy on platform bus */
>> +       pdev = of_find_device_by_node(np);
>> +       if (pdev) {
>> +               hdata->hdmiphy_dev = &pdev->dev;
>> +               ret = 0;
>> +               goto exit;
>> +       }
>> +
>> +exit:
>> +       /* able to find hdmiphy on platform/i2c bus */
>> +err:
>
> Probably just easier to have one "exit" or "out" label that just returns ret.

ok.
>
>> +       of_node_put(np);
>> +       return ret;
>> +}
>> +
>>  static struct of_device_id hdmi_match_types[] = {
>>         {
>>                 .compatible = "samsung,exynos5-hdmi",
>> @@ -1939,15 +1722,13 @@ static int hdmi_probe(struct platform_device *pdev)
>>
>>         hdata->ddc_port = hdmi_ddc;
>>
>> -       /* hdmiphy i2c driver */
>> -       if (i2c_add_driver(&hdmiphy_driver)) {
>> -               DRM_ERROR("failed to register hdmiphy i2c driver\n");
>> +       ret = hdmi_get_phy_device(hdata);
>> +       if (ret) {
>> +               DRM_ERROR("failed to get hdmiphy device\n");
>
> Printing ret would be useful.
>
>
>>                 ret = -ENOENT;
>
> Why change the return value here?
>
Yea. Correct. I shouldn't. I will change this.

>>                 goto err_ddc;
>>         }
>>
>> -       hdata->hdmiphy_port = hdmi_hdmiphy;
>> -
>>         hdata->irq = gpio_to_irq(hdata->hpd_gpio);
>>         if (hdata->irq < 0) {
>>                 DRM_ERROR("failed to get GPIO irq\n");
>> @@ -1977,7 +1758,7 @@ static int hdmi_probe(struct platform_device *pdev)
>>         return 0;
>>
>>  err_hdmiphy:
>> -       i2c_del_driver(&hdmiphy_driver);
>> +       exynos_hdmiphy_driver_unregister();
>>  err_ddc:
>>         i2c_del_driver(&ddc_driver);
>>         return ret;
>> @@ -1989,8 +1770,8 @@ static int hdmi_remove(struct platform_device *pdev)
>>
>>         pm_runtime_disable(dev);
>>
>> -       /* hdmiphy i2c driver */
>> -       i2c_del_driver(&hdmiphy_driver);
>> +       /* hdmiphy driver */
>> +       exynos_hdmiphy_driver_unregister();
>>         /* DDC i2c driver */
>>         i2c_del_driver(&ddc_driver);
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>> index 59abb14..82daa42 100644
>> --- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>> +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>> @@ -15,51 +15,459 @@
>>
>>  #include <linux/kernel.h>
>>  #include <linux/i2c.h>
>> -#include <linux/of.h>
>> +#include <linux/module.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/clk.h>
>>
>>  #include "exynos_drm_drv.h"
>>  #include "exynos_hdmi.h"
>> +#include "exynos_drm_hdmi.h"
>> +#include "regs-hdmiphy.h"
>>
>> +#define HDMIPHY_REG_COUNT      (32)
>
> This probably belongs in regs-hdmiphy.h instead of here. Also remove the ()
>

Ok. I will move it there.

>>
>> -static int hdmiphy_probe(struct i2c_client *client,
>> -       const struct i2c_device_id *id)
>> +struct hdmiphy_context {
>> +       struct device           *dev;
>> +       struct hdmiphy_config   *current_conf;
>> +
>> +       struct hdmiphy_config   *confs;
>> +       unsigned int            nr_confs;
>> +};
>> +
>> +struct hdmiphy_config {
>> +       int pixel_clock;
>> +       u8 conf[HDMIPHY_REG_COUNT];
>> +};
>> +
>> +struct hdmiphy_drv_data {
>> +       struct hdmiphy_config *confs;
>> +       unsigned int count;
>> +};
>> +
>> +/* list of all required phy config settings */
>> +static struct hdmiphy_config hdmiphy_4212_configs[] = {
>> +       {
>> +               .pixel_clock = 25200000,
>> +               .conf = {
>> +                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
>> +                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 27000000,
>> +               .conf = {
>> +                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
>> +                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 27027000,
>> +               .conf = {
>> +                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
>> +                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 36000000,
>> +               .conf = {
>> +                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
>> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 40000000,
>> +               .conf = {
>> +                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
>> +                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 65000000,
>> +               .conf = {
>> +                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
>> +                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 74176000,
>> +               .conf = {
>> +                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
>> +                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 74250000,
>> +               .conf = {
>> +                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
>> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 83500000,
>> +               .conf = {
>> +                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
>> +                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 106500000,
>> +               .conf = {
>> +                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
>> +                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 108000000,
>> +               .conf = {
>> +                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
>> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 146250000,
>> +               .conf = {
>> +                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
>> +                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 148500000,
>> +               .conf = {
>> +                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
>> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> +                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
>> +               },
>> +       },
>> +};
>> +
>> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
>> +       {
>> +               .pixel_clock = 27000000,
>> +               .conf = {
>> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
>> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 27027000,
>> +               .conf = {
>> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
>> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 74176000,
>> +               .conf = {
>> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
>> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
>> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 74250000,
>> +               .conf = {
>> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
>> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
>> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
>> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
>> +               },
>> +       },
>> +       {
>> +               .pixel_clock = 148500000,
>> +               .conf = {
>> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
>> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
>> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
>> +               },
>> +       },
>> +};
>> +
>
> Are you aware of the effort to move these to dt? Since these are
> board-specific values, it seems incorrect to apply them universally.
> Shirish has uploaded a patch to the chromium review site to push these
> into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
> you can work that into your patch set?
>

I have gone through these patches. I am adding Shirish here for further
discussion on these changes. he can explain better.

>
>> +static struct hdmiphy_config *hdmiphy_find_conf(struct hdmiphy_context *hdata,
>> +                       const struct drm_display_mode *mode)
>> +{
>> +       int i;
>> +
>> +       for (i = 0; i < hdata->nr_confs; i++)
>> +               if (hdata->confs[i].pixel_clock == (mode->clock * 1000))
>> +                       return &hdata->confs[i];
>> +
>> +       return NULL;
>> +}
>> +
>> +static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata,
>> +                       u32 reg_offset, u8 value)
>> +{
>> +       if (reg_offset >= HDMIPHY_REG_COUNT)
>> +               return -EINVAL;
>> +
>> +       if (i2c_verify_client(hdata->dev)) {
>
> Is this necessary?

Based on this check, I was deciding that given dev is i2c or
platform device. But now when we agreed to split drivers to
phy and plf driver, I will remove this.

>
>> +               u8 buffer[2];
>> +               int ret;
>> +
>> +               buffer[0] = reg_offset;
>> +               buffer[1] = value;
>> +
>> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
>> +                               buffer, 2);
>> +               if (ret == 2)
>> +                       return 0;
>> +               return ret;
>> +       } else {
>> +               return -EINVAL;
>> +       }
>> +}
>> +
>> +static int hdmiphy_reg_write_buf(struct hdmiphy_context *hdata,
>> +                       u32 reg_offset, const u8 *buf, u32 len)
>> +{
>> +       if ((reg_offset + len) > HDMIPHY_REG_COUNT)
>> +               return -EINVAL;
>> +
>> +       if (i2c_verify_client(hdata->dev)) {
>
> Is this necessary?
>
>
>> +               int ret;
>> +
>> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
>> +                               buf, len);
>
> Does this actually work? You don't seem to be using reg_offset anywhere.
>

reg_offset is not required here. I should remove this. This
procedure is to write the complete buf starting from 0.
hdmiphy_reg_writeb is supposed to be used for writing
value from some offset.

>> +               if (ret == len)
>> +                       return 0;
>> +               return ret;
>> +       } else {
>> +               return -EINVAL;
>> +       }
>> +}
>> +
>> +int exynos_hdmiphy_check_mode(struct device *dev,
>> +                       struct drm_display_mode *mode)
>>  {
>> -       hdmi_attach_hdmiphy_client(client);
>> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> +       const struct hdmiphy_config *conf;
>> +
>> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>
> Maybe you can merge this debug message with the one below.
>

ok.

>>
>> -       dev_info(&client->adapter->dev, "attached s5p_hdmiphy "
>> -               "into i2c adapter successfully\n");
>> +       if (!hdata) {
>> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> +               return -EINVAL;
>> +       }
>
> Can this happen? I think the phy driver registration should be
> synchronous with the hdmi driver registration. As such, it shouldn't
> be possible to get a check_mode callback until it's all set up.
>

I will confirm on this.

>>
>> +       DRM_DEBUG("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
>> +               mode->hdisplay, mode->vdisplay,
>> +               mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE)
>> +               ? true : false, mode->clock * 1000);
>> +
>> +       conf = hdmiphy_find_conf(hdata, mode);
>> +       if (!conf) {
>> +               DRM_DEBUG("Display Mode is not supported.\n");
>> +               return -EINVAL;
>> +       }
>>         return 0;
>>  }
>>
>> -static int hdmiphy_remove(struct i2c_client *client)
>> +int exynos_hdmiphy_set_mode(struct device *dev,
>> +                       struct drm_display_mode *mode)
>>  {
>> -       dev_info(&client->adapter->dev, "detached s5p_hdmiphy "
>> -               "from i2c adapter successfully\n");
>> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> +
>> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> +
>> +       hdata->current_conf = hdmiphy_find_conf(hdata, mode);
>> +
>> +       if (!hdata) {
>> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> +               return -EINVAL;
>> +       }
>
> I really hope this check isn't necessary, since you've already
> dereferenced it 2 lines up :) See my comment above, I don't think you
> can ever hit this.
>
>>
>> +       if (!hdata->current_conf) {
>> +               DRM_ERROR("Display Mode is not supported.\n");
>> +               return -EINVAL;
>> +       }
>>         return 0;
>>  }
>>
>> -static struct of_device_id hdmiphy_match_types[] = {
>> +void exynos_hdmiphy_enable(struct device *dev)
>> +{
>> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> +       int ret;
>> +
>> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> +
>> +       if (!hdata) {
>> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> +               return;
>> +       }
>
> Same comment as above.
>
>> +
>> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
>> +                       HDMIPHY_MODE_EN);
>> +       if (ret < 0) {
>> +               DRM_ERROR("failed to disable hdmiphy.\n");
>> +               return;
>> +       }
>> +}
>> +
>> +void exynos_hdmiphy_disable(struct device *dev)
>> +{
>> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> +       int ret;
>> +
>> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> +
>> +       if (!hdata) {
>> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> +               return;
>> +       }
>> +
>> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, 0);
>> +       if (ret < 0) {
>> +               DRM_ERROR("failed to enable hdmiphy.\n");
>
> If you're not going to return the error code, at least print it here.
>

ok.

>> +               return;
>> +       }
>> +}
>> +
>> +int exynos_hdmiphy_conf_apply(struct device *dev)
>> +{
>> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> +       const u8 *hdmiphy_data;
>> +       int ret;
>> +
>> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> +
>> +       if (!hdata) {
>> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> +               return -EINVAL;
>> +       }
>> +
>> +       /* pixel clock */
>
> I don't understand this comment.
>

I will remove this.

>> +       if (hdata->current_conf)
>> +               hdmiphy_data = hdata->current_conf->conf;
>> +       else
>> +               return -EINVAL;
>> +
>> +       ret = hdmiphy_reg_write_buf(hdata, 0, hdmiphy_data,
>> +                       HDMIPHY_REG_COUNT);
>
> I think the only reason this works is b/c you're writing to register offset 0.
>
>> +       if (ret) {
>> +               DRM_ERROR("failed to configure hdmiphy.\n");
>> +               return -EINVAL;
>
> Why don't you return ret?
>

ok.

>> +       }
>> +       return 0;
>> +}
>> +
>> +static struct hdmiphy_drv_data exynos4212_hdmiphy_drv_data = {
>> +       .confs = hdmiphy_4212_configs,
>> +       .count = ARRAY_SIZE(hdmiphy_4212_configs)
>> +};
>> +
>> +static struct hdmiphy_drv_data exynos4210_hdmiphy_drv_data = {
>> +       .confs = hdmiphy_4210_configs,
>> +       .count = ARRAY_SIZE(hdmiphy_4210_configs)
>> +};
>> +
>> +static struct of_device_id hdmiphy_i2c_device_match_types[] = {
>>         {
>>                 .compatible = "samsung,exynos5-hdmiphy",
>> +               .data   = &exynos4212_hdmiphy_drv_data,
>>         }, {
>>                 .compatible = "samsung,exynos4210-hdmiphy",
>> +               .data   = &exynos4210_hdmiphy_drv_data,
>>         }, {
>>                 .compatible = "samsung,exynos4212-hdmiphy",
>> +               .data   = &exynos4212_hdmiphy_drv_data,
>>         }, {
>>                 /* end node */
>>         }
>>  };
>>
>> -struct i2c_driver hdmiphy_driver = {
>> +static int hdmiphy_i2c_device_probe(struct i2c_client *client,
>> +       const struct i2c_device_id *id)
>> +{
>> +       struct device *dev = &client->dev;
>> +       struct hdmiphy_context *hdata;
>> +       struct hdmiphy_drv_data *drv;
>> +       const struct of_device_id *match;
>> +
>> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> +
>> +       hdata = devm_kzalloc(dev, sizeof(*hdata), GFP_KERNEL);
>> +       if (!hdata) {
>> +               DRM_ERROR("failed to allocate hdmiphy context.\n");
>> +               return -ENOMEM;
>> +       }
>> +
>> +       match = of_match_node(of_match_ptr(
>> +               hdmiphy_i2c_device_match_types),
>> +               dev->of_node);
>> +
>> +       if (match == NULL)
>> +               return -ENODEV;
>> +
>> +       drv = (struct hdmiphy_drv_data *)match->data;
>> +
>> +       hdata->dev = dev;
>> +       hdata->confs = drv->confs;
>> +       hdata->nr_confs = drv->count;
>> +
>> +       i2c_set_clientdata(client, hdata);
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct i2c_device_id hdmiphy_id[] = {
>> +       { },
>> +};
>> +
>> +struct i2c_driver hdmiphy_i2c_driver = {
>>         .driver = {
>>                 .name   = "exynos-hdmiphy",
>>                 .owner  = THIS_MODULE,
>> -               .of_match_table = hdmiphy_match_types,
>> +               .of_match_table = of_match_ptr(
>> +                               hdmiphy_i2c_device_match_types),
>>         },
>> -       .probe          = hdmiphy_probe,
>> -       .remove         = hdmiphy_remove,
>> +       .id_table               = hdmiphy_id,
>> +       .probe          = hdmiphy_i2c_device_probe,
>>         .command                = NULL,
>>  };
>> -EXPORT_SYMBOL(hdmiphy_driver);
>> +
>> +int exynos_hdmiphy_driver_register(void)
>> +{
>> +       int ret;
>> +
>> +       ret = i2c_add_driver(&hdmiphy_i2c_driver);
>> +       if (ret)
>> +               return ret;
>> +
>> +       return 0;
>> +}
>> +
>> +void exynos_hdmiphy_driver_unregister(void)
>> +{
>> +       i2c_del_driver(&hdmiphy_i2c_driver);
>> +}
>> diff --git a/drivers/gpu/drm/exynos/regs-hdmiphy.h b/drivers/gpu/drm/exynos/regs-hdmiphy.h
>> new file mode 100644
>> index 0000000..d3f9d87
>> --- /dev/null
>> +++ b/drivers/gpu/drm/exynos/regs-hdmiphy.h
>> @@ -0,0 +1,35 @@
>> +/*
>> + *
>> + *  regs-hdmiphy.h
>> + *
>> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
>> + * http://www.samsung.com/
>> + *
>> + * HDMI-PHY register header file for Samsung HDMI driver
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> +*/
>> +
>> +#ifndef SAMSUNG_REGS_HDMIPHY_H
>> +#define SAMSUNG_REGS_HDMIPHY_H
>> +
>> +/*
>> + * Register part
>> +*/
>> +#define HDMIPHY_MODE_SET_DONE  (0x1f)
>> +
>> +/*
>> + * Bit definition part
>> + */
>> +
>> +/* HDMIPHY_MODE_SET_DONE */
>> +#define HDMIPHY_MODE_EN                (1 << 7)
>> +
>> +/* hdmiphy pmu control bits */
>> +#define PMU_HDMI_PHY_CONTROL_MASK      (1 << 0)
>> +#define PMU_HDMI_PHY_ENABLE            (1)
>> +#define PMU_HDMI_PHY_DISABLE           (0)
>
>
> You don't need the () around simple values
>

ok.

We also discussed previously to keep independent i2c and
platform phy drivers in exynos_hdmiphy_i2c.c and
exynos_hdmiphy_platform.c respectively, which will duplicate
the code to some extent.

Second point is to implement exynos_i2c_hdmiphy_get_ops()
and exynos_platform_hdmiphy_get_ops() to get access to all
callbacks. This will limit the exposure of phy callbacks to the
phy controller.

Please share your views on this.

Regards,
Rahul Sharma.

>> +
>> +#endif /* SAMSUNG_REGS_HDMIPHY_H */
>> --
>> 1.7.10.4
>>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-04  5:47     ` Rahul Sharma
@ 2013-09-04  7:37       ` Inki Dae
  2013-09-04 14:51         ` Sean Paul
  2013-09-04 14:33       ` Sean Paul
  1 sibling, 1 reply; 45+ messages in thread
From: Inki Dae @ 2013-09-04  7:37 UTC (permalink / raw)
  To: 'Rahul Sharma', 'Sean Paul'
  Cc: 'Rahul Sharma', 'linux-samsung-soc',
	'dri-devel', 'kgene.kim', 'sw0312.kim',
	'Lucas Stach', 'Tomasz Figa',
	'Sylwester Nawrocki', 'sunil joshi',
	shirish



> -----Original Message-----
> From: Rahul Sharma [mailto:r.sh.open@gmail.com]
> Sent: Wednesday, September 04, 2013 2:48 PM
> To: Sean Paul
> Cc: Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim; sw0312.kim;
> InKi Dae; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
> shirish@chromium.org
> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
> driver
> 
> Thanks Sean,
> 
> On 3 September 2013 20:15, Sean Paul <seanpaul@chromium.org> wrote:
> > A few comments.
> >
> > On Fri, Aug 30, 2013 at 2:59 AM, Rahul Sharma <rahul.sharma@samsung.com>
> wrote:
> >> Exynos hdmiphy operations and configs are kept inside
> >> the hdmi driver. Hdmiphy related code is tightly coupled
> >> with hdmi IP driver.
> >>
> >> This patche moves hdmiphy related code to hdmiphy driver.
> >
> > s/patche/patch
> >
> ok.
> >> It will help in cleanly supporting the hdmiphy variations
> >> in further SoCs.
> >>
> >> Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
> >> ---
> >>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
> >>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   11 +
> >>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  343
+++------------
> >>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  438
> +++++++++++++++++++-
> >>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 ++
> >>  5 files changed, 533 insertions(+), 296 deletions(-)
> >>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
> >>
> >> diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
> b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
> >> index 50decf8..240eca5 100644
> >> --- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
> >> +++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
> >> @@ -25,6 +25,7 @@ Required properties:
> >>                 sclk_pixel.
> >>  - clock-names: aliases as per driver requirements for above clock IDs:
> >>         "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and
"mout_hdmi".
> >> +- phy: it points to hdmiphy dt node.
> >>  Example:
> >>
> >>         hdmi {
> >> @@ -32,4 +33,5 @@ Example:
> >>                 reg = <0x14530000 0x100000>;
> >>                 interrupts = <0 95 0>;
> >>                 hpd-gpio = <&gpx3 7 1>;
> >> +               phy = <&hdmiphy>;
> >>         };
> >> diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> >> index 724cab1..1c839f8 100644
> >> --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> >> +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> >> @@ -64,4 +64,15 @@ void exynos_hdmi_drv_attach(struct
> exynos_drm_hdmi_context *ctx);
> >>  void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx);
> >>  void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
> >>  void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
> >> +
> >> +int exynos_hdmiphy_driver_register(void);
> >> +void exynos_hdmiphy_driver_unregister(void);
> >> +
> >> +void exynos_hdmiphy_enable(struct device *dev);
> >> +void exynos_hdmiphy_disable(struct device *dev);
> >> +int exynos_hdmiphy_check_mode(struct device *dev,
> >> +                               struct drm_display_mode *mode);
> >> +int exynos_hdmiphy_set_mode(struct device *dev,
> >> +                               struct drm_display_mode *mode);
> >> +int exynos_hdmiphy_conf_apply(struct device *dev);
> >>  #endif
> >> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c
> b/drivers/gpu/drm/exynos/exynos_hdmi.c
> >> index f67ffca..3af4e4c 100644
> >> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> >> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> >> @@ -34,6 +34,8 @@
> >>  #include <linux/io.h>
> >>  #include <linux/of.h>
> >>  #include <linux/of_gpio.h>
> >> +#include <linux/of_i2c.h>
> >> +#include <linux/of_platform.h>
> >>
> >>  #include <drm/exynos_drm.h>
> >>
> >> @@ -172,7 +174,6 @@ struct hdmi_v14_conf {
> >>  };
> >>
> >>  struct hdmi_conf_regs {
> >> -       int pixel_clock;
> >>         int cea_video_id;
> >>         union {
> >>                 struct hdmi_v13_conf v13_conf;
> >> @@ -193,9 +194,9 @@ struct hdmi_context {
> >>         int                             irq;
> >>
> >>         struct i2c_client               *ddc_port;
> >> -       struct i2c_client               *hdmiphy_port;
> >> +       struct device                   *hdmiphy_dev;
> >>
> >> -       /* current hdmiphy conf regs */
> >> +       /* current hdmi ip configuration registers. */
> >>         struct hdmi_conf_regs           mode_conf;
> >>
> >>         struct hdmi_resources           res;
> >> @@ -205,180 +206,6 @@ struct hdmi_context {
> >>         enum hdmi_type                  type;
> >>  };
> >>
> >> -struct hdmiphy_config {
> >> -       int pixel_clock;
> >> -       u8 conf[32];
> >> -};
> >> -
> >> -/* list of phy config settings */
> >> -static const struct hdmiphy_config hdmiphy_v13_configs[] = {
> >> -       {
> >> -               .pixel_clock = 27000000,
> >> -               .conf = {
> >> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
> >> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
> >> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> >> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 27027000,
> >> -               .conf = {
> >> -                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
> >> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
> >> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> >> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 74176000,
> >> -               .conf = {
> >> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
> >> -                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
> >> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> >> -                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 74250000,
> >> -               .conf = {
> >> -                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
> >> -                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
> >> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
> >> -                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 148500000,
> >> -               .conf = {
> >> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
> >> -                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
> >> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
> >> -                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
> >> -               },
> >> -       },
> >> -};
> >> -
> >> -static const struct hdmiphy_config hdmiphy_v14_configs[] = {
> >> -       {
> >> -               .pixel_clock = 25200000,
> >> -               .conf = {
> >> -                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
> >> -                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 27000000,
> >> -               .conf = {
> >> -                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
> >> -                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 27027000,
> >> -               .conf = {
> >> -                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
> >> -                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 36000000,
> >> -               .conf = {
> >> -                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
> >> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 40000000,
> >> -               .conf = {
> >> -                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
> >> -                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 65000000,
> >> -               .conf = {
> >> -                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
> >> -                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 74176000,
> >> -               .conf = {
> >> -                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
> >> -                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 74250000,
> >> -               .conf = {
> >> -                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
> >> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 83500000,
> >> -               .conf = {
> >> -                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
> >> -                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 106500000,
> >> -               .conf = {
> >> -                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
> >> -                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 108000000,
> >> -               .conf = {
> >> -                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
> >> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 146250000,
> >> -               .conf = {
> >> -                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
> >> -                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
> >> -               },
> >> -       },
> >> -       {
> >> -               .pixel_clock = 148500000,
> >> -               .conf = {
> >> -                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
> >> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> >> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> -                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
> >> -               },
> >> -       },
> >> -};
> >> -
> >>  struct hdmi_infoframe {
> >>         enum HDMI_PACKET_TYPE type;
> >>         u8 ver;
> >> @@ -769,28 +596,6 @@ static struct edid *hdmi_get_edid(void *ctx,
> struct drm_connector *connector)
> >>         return raw_edid;
> >>  }
> >>
> >> -static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32
> pixel_clock)
> >> -{
> >> -       const struct hdmiphy_config *confs;
> >> -       int count, i;
> >> -
> >> -       if (hdata->type == HDMI_TYPE13) {
> >> -               confs = hdmiphy_v13_configs;
> >> -               count = ARRAY_SIZE(hdmiphy_v13_configs);
> >> -       } else if (hdata->type == HDMI_TYPE14) {
> >> -               confs = hdmiphy_v14_configs;
> >> -               count = ARRAY_SIZE(hdmiphy_v14_configs);
> >> -       } else
> >> -               return -EINVAL;
> >> -
> >> -       for (i = 0; i < count; i++)
> >> -               if (confs[i].pixel_clock == pixel_clock)
> >> -                       return i;
> >> -
> >> -       DRM_DEBUG_KMS("Could not find phy config for %d\n",
pixel_clock);
> >> -       return -EINVAL;
> >> -}
> >> -
> >>  static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
> >>  {
> >>         struct hdmi_context *hdata = ctx;
> >> @@ -801,7 +606,7 @@ static int hdmi_check_mode(void *ctx, struct
> drm_display_mode *mode)
> >>                 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
> >>                 false, mode->clock * 1000);
> >>
> >> -       ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
> >> +       ret = exynos_hdmiphy_check_mode(hdata->hdmiphy_dev, mode);
> >>         if (ret < 0)
> >>                 return ret;
> >>         return 0;
> >> @@ -1302,19 +1107,13 @@ static void hdmi_mode_apply(struct hdmi_context
> *hdata)
> >>
> >>  static void hdmiphy_conf_reset(struct hdmi_context *hdata)
> >>  {
> >> -       u8 buffer[2];
> >>         u32 reg;
> >>
> >>         clk_disable_unprepare(hdata->res.sclk_hdmi);
> >>         clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
> >>         clk_prepare_enable(hdata->res.sclk_hdmi);
> >>
> >> -       /* operation mode */
> >> -       buffer[0] = 0x1f;
> >> -       buffer[1] = 0x00;
> >> -
> >> -       if (hdata->hdmiphy_port)
> >> -               i2c_master_send(hdata->hdmiphy_port, buffer, 2);
> >> +       exynos_hdmiphy_disable(hdata->hdmiphy_dev);
> >>
> >>         if (hdata->type == HDMI_TYPE13)
> >>                 reg = HDMI_V13_PHY_RSTOUT;
> >> @@ -1342,66 +1141,12 @@ static void hdmiphy_poweroff(struct
> hdmi_context *hdata)
> >>                         HDMI_PHY_POWER_OFF_EN);
> >>  }
> >>
> >> -static void hdmiphy_conf_apply(struct hdmi_context *hdata)
> >> -{
> >> -       const u8 *hdmiphy_data;
> >> -       u8 buffer[32];
> >> -       u8 operation[2];
> >> -       u8 read_buffer[32] = {0, };
> >> -       int ret;
> >> -       int i;
> >> -
> >> -       if (!hdata->hdmiphy_port) {
> >> -               DRM_ERROR("hdmiphy is not attached\n");
> >> -               return;
> >> -       }
> >> -
> >> -       /* pixel clock */
> >> -       i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
> >> -       if (i < 0) {
> >> -               DRM_ERROR("failed to find hdmiphy conf\n");
> >> -               return;
> >> -       }
> >> -
> >> -       if (hdata->type == HDMI_TYPE13)
> >> -               hdmiphy_data = hdmiphy_v13_configs[i].conf;
> >> -       else
> >> -               hdmiphy_data = hdmiphy_v14_configs[i].conf;
> >> -
> >> -       memcpy(buffer, hdmiphy_data, 32);
> >> -       ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
> >> -       if (ret != 32) {
> >> -               DRM_ERROR("failed to configure HDMIPHY via I2C\n");
> >> -               return;
> >> -       }
> >> -
> >> -       usleep_range(10000, 12000);
> >> -
> >> -       /* operation mode */
> >> -       operation[0] = 0x1f;
> >> -       operation[1] = 0x80;
> >> -
> >> -       ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
> >> -       if (ret != 2) {
> >> -               DRM_ERROR("failed to enable hdmiphy\n");
> >> -               return;
> >> -       }
> >> -
> >> -       ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
> >> -       if (ret < 0) {
> >> -               DRM_ERROR("failed to read hdmiphy config\n");
> >> -               return;
> >> -       }
> >> -
> >> -       for (i = 0; i < ret; i++)
> >> -               DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
> >> -                       "recv [0x%02x]\n", i, buffer[i],
read_buffer[i]);
> >> -}
> >> -
> >>  static void hdmi_conf_apply(struct hdmi_context *hdata)
> >>  {
> >>         hdmiphy_conf_reset(hdata);
> >> -       hdmiphy_conf_apply(hdata);
> >> +       exynos_hdmiphy_conf_apply(hdata->hdmiphy_dev);
> >> +       usleep_range(10000, 12000);
> >
> > This delay seems like something that should be in the phy driver,
> > instead of the hdmi driver (since it seems conceivable that certain
> > phys might not need a delay or might need a longer delay).
> >
> 
> ok. I will move it there.
> 
> >> +       exynos_hdmiphy_enable(hdata->hdmiphy_dev);
> >>
> >>         mutex_lock(&hdata->hdmi_mutex);
> >>         hdmi_conf_reset(hdata);
> >> @@ -1434,7 +1179,6 @@ static void hdmi_v13_mode_set(struct hdmi_context
> *hdata,
> >>
> >>         hdata->mode_conf.cea_video_id =
> >>                 drm_match_cea_mode((struct drm_display_mode *)m);
> >> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
> >>
> >>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
> >>         hdmi_set_reg(core->h_v_line, 3, (m->htotal << 12) | m->vtotal);
> >> @@ -1530,7 +1274,6 @@ static void hdmi_v14_mode_set(struct hdmi_context
> *hdata,
> >>
> >>         hdata->mode_conf.cea_video_id =
> >>                 drm_match_cea_mode((struct drm_display_mode *)m);
> >> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
> >>
> >>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
> >>         hdmi_set_reg(core->v_line, 2, m->vtotal);
> >> @@ -1646,6 +1389,8 @@ static void hdmi_mode_set(void *ctx, struct
> drm_display_mode *mode)
> >>                 hdmi_v13_mode_set(hdata, mode);
> >>         else
> >>                 hdmi_v14_mode_set(hdata, mode);
> >> +
> >> +       exynos_hdmiphy_set_mode(hdata->hdmiphy_dev, mode);
> >
> > Why set_mode when everything else is mode_set?
> >
> 
> I will change it to mode_set.
> 
> >>  }
> >>
> >>  static void hdmi_get_max_resol(void *ctx, unsigned int *width,
> >> @@ -1824,7 +1569,7 @@ fail:
> >>         return -ENODEV;
> >>  }
> >>
> >> -static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
> >> +static struct i2c_client *hdmi_ddc;
> >>
> >>  void hdmi_attach_ddc_client(struct i2c_client *ddc)
> >>  {
> >> @@ -1832,12 +1577,6 @@ void hdmi_attach_ddc_client(struct i2c_client
> *ddc)
> >>                 hdmi_ddc = ddc;
> >>  }
> >>
> >> -void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
> >> -{
> >> -       if (hdmiphy)
> >> -               hdmi_hdmiphy = hdmiphy;
> >> -}
> >> -
> >>  static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
> >>                                         (struct device *dev)
> >>  {
> >> @@ -1862,6 +1601,50 @@ err_data:
> >>         return NULL;
> >>  }
> >>
> >> +static int hdmi_get_phy_device(struct hdmi_context *hdata)
> >
> > "get" is not the proper verb here, "initialize" would be more
> > appropriate (IMO, of course).
> >
> 
> But we don't initialise the phy here. It is just to get the
> hdmiphy dev* through dt.
> 
> >> +{
> >> +       struct device_node *np;
> >> +       struct i2c_client *client;
> >> +       struct platform_device *pdev;
> >> +       int ret;
> >> +
> >> +       /* register hdmiphy driver */
> >> +       ret = exynos_hdmiphy_driver_register();
> >> +       if (ret) {
> >> +               DRM_ERROR("failed to register hdmiphy driver\n");
> >
> > Printing ret would be useful here.
> 
> ok.
> >
> >> +               goto err;
> >> +       }
> >> +
> >> +       np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
> >> +       if (!np) {
> >> +               DRM_ERROR("Could not find 'phy' property\n");
> >> +               ret = -ENOENT;
> >> +               goto err;
> >> +       }
> >> +
> >> +       /* find hdmi phy on i2c bus */
> >> +       client = of_find_i2c_device_by_node(np);
> >> +       if (client) {
> >> +               hdata->hdmiphy_dev = &client->dev;
> >> +               ret = 0;
> >> +               goto exit;
> >> +       }
> >> +
> >> +       /* find hdmi phy on platform bus */
> >> +       pdev = of_find_device_by_node(np);
> >> +       if (pdev) {
> >> +               hdata->hdmiphy_dev = &pdev->dev;
> >> +               ret = 0;
> >> +               goto exit;
> >> +       }
> >> +
> >> +exit:
> >> +       /* able to find hdmiphy on platform/i2c bus */
> >> +err:
> >
> > Probably just easier to have one "exit" or "out" label that just returns
> ret.
> 
> ok.
> >
> >> +       of_node_put(np);
> >> +       return ret;
> >> +}
> >> +
> >>  static struct of_device_id hdmi_match_types[] = {
> >>         {
> >>                 .compatible = "samsung,exynos5-hdmi",
> >> @@ -1939,15 +1722,13 @@ static int hdmi_probe(struct platform_device
> *pdev)
> >>
> >>         hdata->ddc_port = hdmi_ddc;
> >>
> >> -       /* hdmiphy i2c driver */
> >> -       if (i2c_add_driver(&hdmiphy_driver)) {
> >> -               DRM_ERROR("failed to register hdmiphy i2c driver\n");
> >> +       ret = hdmi_get_phy_device(hdata);
> >> +       if (ret) {
> >> +               DRM_ERROR("failed to get hdmiphy device\n");
> >
> > Printing ret would be useful.
> >
> >
> >>                 ret = -ENOENT;
> >
> > Why change the return value here?
> >
> Yea. Correct. I shouldn't. I will change this.
> 
> >>                 goto err_ddc;
> >>         }
> >>
> >> -       hdata->hdmiphy_port = hdmi_hdmiphy;
> >> -
> >>         hdata->irq = gpio_to_irq(hdata->hpd_gpio);
> >>         if (hdata->irq < 0) {
> >>                 DRM_ERROR("failed to get GPIO irq\n");
> >> @@ -1977,7 +1758,7 @@ static int hdmi_probe(struct platform_device
> *pdev)
> >>         return 0;
> >>
> >>  err_hdmiphy:
> >> -       i2c_del_driver(&hdmiphy_driver);
> >> +       exynos_hdmiphy_driver_unregister();
> >>  err_ddc:
> >>         i2c_del_driver(&ddc_driver);
> >>         return ret;
> >> @@ -1989,8 +1770,8 @@ static int hdmi_remove(struct platform_device
> *pdev)
> >>
> >>         pm_runtime_disable(dev);
> >>
> >> -       /* hdmiphy i2c driver */
> >> -       i2c_del_driver(&hdmiphy_driver);
> >> +       /* hdmiphy driver */
> >> +       exynos_hdmiphy_driver_unregister();
> >>         /* DDC i2c driver */
> >>         i2c_del_driver(&ddc_driver);
> >>
> >> diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> >> index 59abb14..82daa42 100644
> >> --- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> >> +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> >> @@ -15,51 +15,459 @@
> >>
> >>  #include <linux/kernel.h>
> >>  #include <linux/i2c.h>
> >> -#include <linux/of.h>
> >> +#include <linux/module.h>
> >> +#include <linux/pm_runtime.h>
> >> +#include <linux/clk.h>
> >>
> >>  #include "exynos_drm_drv.h"
> >>  #include "exynos_hdmi.h"
> >> +#include "exynos_drm_hdmi.h"
> >> +#include "regs-hdmiphy.h"
> >>
> >> +#define HDMIPHY_REG_COUNT      (32)
> >
> > This probably belongs in regs-hdmiphy.h instead of here. Also remove the
> ()
> >
> 
> Ok. I will move it there.
> 
> >>
> >> -static int hdmiphy_probe(struct i2c_client *client,
> >> -       const struct i2c_device_id *id)
> >> +struct hdmiphy_context {
> >> +       struct device           *dev;
> >> +       struct hdmiphy_config   *current_conf;
> >> +
> >> +       struct hdmiphy_config   *confs;
> >> +       unsigned int            nr_confs;
> >> +};
> >> +
> >> +struct hdmiphy_config {
> >> +       int pixel_clock;
> >> +       u8 conf[HDMIPHY_REG_COUNT];
> >> +};
> >> +
> >> +struct hdmiphy_drv_data {
> >> +       struct hdmiphy_config *confs;
> >> +       unsigned int count;
> >> +};
> >> +
> >> +/* list of all required phy config settings */
> >> +static struct hdmiphy_config hdmiphy_4212_configs[] = {
> >> +       {
> >> +               .pixel_clock = 25200000,
> >> +               .conf = {
> >> +                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
> >> +                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 27000000,
> >> +               .conf = {
> >> +                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
> >> +                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 27027000,
> >> +               .conf = {
> >> +                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
> >> +                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 36000000,
> >> +               .conf = {
> >> +                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
> >> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 40000000,
> >> +               .conf = {
> >> +                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
> >> +                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 65000000,
> >> +               .conf = {
> >> +                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
> >> +                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 74176000,
> >> +               .conf = {
> >> +                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
> >> +                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 74250000,
> >> +               .conf = {
> >> +                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
> >> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 83500000,
> >> +               .conf = {
> >> +                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
> >> +                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 106500000,
> >> +               .conf = {
> >> +                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
> >> +                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 108000000,
> >> +               .conf = {
> >> +                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
> >> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 146250000,
> >> +               .conf = {
> >> +                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
> >> +                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 148500000,
> >> +               .conf = {
> >> +                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
> >> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
> >> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
> >> +                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
> >> +               },
> >> +       },
> >> +};
> >> +
> >> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
> >> +       {
> >> +               .pixel_clock = 27000000,
> >> +               .conf = {
> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 27027000,
> >> +               .conf = {
> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 74176000,
> >> +               .conf = {
> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 74250000,
> >> +               .conf = {
> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
> >> +               },
> >> +       },
> >> +       {
> >> +               .pixel_clock = 148500000,
> >> +               .conf = {
> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
> >> +               },
> >> +       },
> >> +};
> >> +
> >
> > Are you aware of the effort to move these to dt? Since these are
> > board-specific values, it seems incorrect to apply them universally.
> > Shirish has uploaded a patch to the chromium review site to push these
> > into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
> > you can work that into your patch set?
> >

Are these really board-specific values? I think they are SoC-specific
values, and it's better to define them in the driver. For this, I gave
already comments to Shirish why these constraints should be placed in
driver. For more detail, you can also refer to the below link,
	
http://www.mail-archive.com/devicetree-discuss@lists.ozlabs.org/msg36691.htm
l

Thanks,
Inki Dae

> 
> I have gone through these patches. I am adding Shirish here for further
> discussion on these changes. he can explain better.
> 
> >
> >> +static struct hdmiphy_config *hdmiphy_find_conf(struct hdmiphy_context
> *hdata,
> >> +                       const struct drm_display_mode *mode)
> >> +{
> >> +       int i;
> >> +
> >> +       for (i = 0; i < hdata->nr_confs; i++)
> >> +               if (hdata->confs[i].pixel_clock == (mode->clock *
1000))
> >> +                       return &hdata->confs[i];
> >> +
> >> +       return NULL;
> >> +}
> >> +
> >> +static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata,
> >> +                       u32 reg_offset, u8 value)
> >> +{
> >> +       if (reg_offset >= HDMIPHY_REG_COUNT)
> >> +               return -EINVAL;
> >> +
> >> +       if (i2c_verify_client(hdata->dev)) {
> >
> > Is this necessary?
> 
> Based on this check, I was deciding that given dev is i2c or
> platform device. But now when we agreed to split drivers to
> phy and plf driver, I will remove this.
> 
> >
> >> +               u8 buffer[2];
> >> +               int ret;
> >> +
> >> +               buffer[0] = reg_offset;
> >> +               buffer[1] = value;
> >> +
> >> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
> >> +                               buffer, 2);
> >> +               if (ret == 2)
> >> +                       return 0;
> >> +               return ret;
> >> +       } else {
> >> +               return -EINVAL;
> >> +       }
> >> +}
> >> +
> >> +static int hdmiphy_reg_write_buf(struct hdmiphy_context *hdata,
> >> +                       u32 reg_offset, const u8 *buf, u32 len)
> >> +{
> >> +       if ((reg_offset + len) > HDMIPHY_REG_COUNT)
> >> +               return -EINVAL;
> >> +
> >> +       if (i2c_verify_client(hdata->dev)) {
> >
> > Is this necessary?
> >
> >
> >> +               int ret;
> >> +
> >> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
> >> +                               buf, len);
> >
> > Does this actually work? You don't seem to be using reg_offset anywhere.
> >
> 
> reg_offset is not required here. I should remove this. This
> procedure is to write the complete buf starting from 0.
> hdmiphy_reg_writeb is supposed to be used for writing
> value from some offset.
> 
> >> +               if (ret == len)
> >> +                       return 0;
> >> +               return ret;
> >> +       } else {
> >> +               return -EINVAL;
> >> +       }
> >> +}
> >> +
> >> +int exynos_hdmiphy_check_mode(struct device *dev,
> >> +                       struct drm_display_mode *mode)
> >>  {
> >> -       hdmi_attach_hdmiphy_client(client);
> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> >> +       const struct hdmiphy_config *conf;
> >> +
> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> >
> > Maybe you can merge this debug message with the one below.
> >
> 
> ok.
> 
> >>
> >> -       dev_info(&client->adapter->dev, "attached s5p_hdmiphy "
> >> -               "into i2c adapter successfully\n");
> >> +       if (!hdata) {
> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> >> +               return -EINVAL;
> >> +       }
> >
> > Can this happen? I think the phy driver registration should be
> > synchronous with the hdmi driver registration. As such, it shouldn't
> > be possible to get a check_mode callback until it's all set up.
> >
> 
> I will confirm on this.
> 
> >>
> >> +       DRM_DEBUG("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
> >> +               mode->hdisplay, mode->vdisplay,
> >> +               mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE)
> >> +               ? true : false, mode->clock * 1000);
> >> +
> >> +       conf = hdmiphy_find_conf(hdata, mode);
> >> +       if (!conf) {
> >> +               DRM_DEBUG("Display Mode is not supported.\n");
> >> +               return -EINVAL;
> >> +       }
> >>         return 0;
> >>  }
> >>
> >> -static int hdmiphy_remove(struct i2c_client *client)
> >> +int exynos_hdmiphy_set_mode(struct device *dev,
> >> +                       struct drm_display_mode *mode)
> >>  {
> >> -       dev_info(&client->adapter->dev, "detached s5p_hdmiphy "
> >> -               "from i2c adapter successfully\n");
> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> >> +
> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> >> +
> >> +       hdata->current_conf = hdmiphy_find_conf(hdata, mode);
> >> +
> >> +       if (!hdata) {
> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> >> +               return -EINVAL;
> >> +       }
> >
> > I really hope this check isn't necessary, since you've already
> > dereferenced it 2 lines up :) See my comment above, I don't think you
> > can ever hit this.
> >
> >>
> >> +       if (!hdata->current_conf) {
> >> +               DRM_ERROR("Display Mode is not supported.\n");
> >> +               return -EINVAL;
> >> +       }
> >>         return 0;
> >>  }
> >>
> >> -static struct of_device_id hdmiphy_match_types[] = {
> >> +void exynos_hdmiphy_enable(struct device *dev)
> >> +{
> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> >> +       int ret;
> >> +
> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> >> +
> >> +       if (!hdata) {
> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> >> +               return;
> >> +       }
> >
> > Same comment as above.
> >
> >> +
> >> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
> >> +                       HDMIPHY_MODE_EN);
> >> +       if (ret < 0) {
> >> +               DRM_ERROR("failed to disable hdmiphy.\n");
> >> +               return;
> >> +       }
> >> +}
> >> +
> >> +void exynos_hdmiphy_disable(struct device *dev)
> >> +{
> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> >> +       int ret;
> >> +
> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> >> +
> >> +       if (!hdata) {
> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> >> +               return;
> >> +       }
> >> +
> >> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, 0);
> >> +       if (ret < 0) {
> >> +               DRM_ERROR("failed to enable hdmiphy.\n");
> >
> > If you're not going to return the error code, at least print it here.
> >
> 
> ok.
> 
> >> +               return;
> >> +       }
> >> +}
> >> +
> >> +int exynos_hdmiphy_conf_apply(struct device *dev)
> >> +{
> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> >> +       const u8 *hdmiphy_data;
> >> +       int ret;
> >> +
> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> >> +
> >> +       if (!hdata) {
> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> >> +               return -EINVAL;
> >> +       }
> >> +
> >> +       /* pixel clock */
> >
> > I don't understand this comment.
> >
> 
> I will remove this.
> 
> >> +       if (hdata->current_conf)
> >> +               hdmiphy_data = hdata->current_conf->conf;
> >> +       else
> >> +               return -EINVAL;
> >> +
> >> +       ret = hdmiphy_reg_write_buf(hdata, 0, hdmiphy_data,
> >> +                       HDMIPHY_REG_COUNT);
> >
> > I think the only reason this works is b/c you're writing to register
> offset 0.
> >
> >> +       if (ret) {
> >> +               DRM_ERROR("failed to configure hdmiphy.\n");
> >> +               return -EINVAL;
> >
> > Why don't you return ret?
> >
> 
> ok.
> 
> >> +       }
> >> +       return 0;
> >> +}
> >> +
> >> +static struct hdmiphy_drv_data exynos4212_hdmiphy_drv_data = {
> >> +       .confs = hdmiphy_4212_configs,
> >> +       .count = ARRAY_SIZE(hdmiphy_4212_configs)
> >> +};
> >> +
> >> +static struct hdmiphy_drv_data exynos4210_hdmiphy_drv_data = {
> >> +       .confs = hdmiphy_4210_configs,
> >> +       .count = ARRAY_SIZE(hdmiphy_4210_configs)
> >> +};
> >> +
> >> +static struct of_device_id hdmiphy_i2c_device_match_types[] = {
> >>         {
> >>                 .compatible = "samsung,exynos5-hdmiphy",
> >> +               .data   = &exynos4212_hdmiphy_drv_data,
> >>         }, {
> >>                 .compatible = "samsung,exynos4210-hdmiphy",
> >> +               .data   = &exynos4210_hdmiphy_drv_data,
> >>         }, {
> >>                 .compatible = "samsung,exynos4212-hdmiphy",
> >> +               .data   = &exynos4212_hdmiphy_drv_data,
> >>         }, {
> >>                 /* end node */
> >>         }
> >>  };
> >>
> >> -struct i2c_driver hdmiphy_driver = {
> >> +static int hdmiphy_i2c_device_probe(struct i2c_client *client,
> >> +       const struct i2c_device_id *id)
> >> +{
> >> +       struct device *dev = &client->dev;
> >> +       struct hdmiphy_context *hdata;
> >> +       struct hdmiphy_drv_data *drv;
> >> +       const struct of_device_id *match;
> >> +
> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> >> +
> >> +       hdata = devm_kzalloc(dev, sizeof(*hdata), GFP_KERNEL);
> >> +       if (!hdata) {
> >> +               DRM_ERROR("failed to allocate hdmiphy context.\n");
> >> +               return -ENOMEM;
> >> +       }
> >> +
> >> +       match = of_match_node(of_match_ptr(
> >> +               hdmiphy_i2c_device_match_types),
> >> +               dev->of_node);
> >> +
> >> +       if (match == NULL)
> >> +               return -ENODEV;
> >> +
> >> +       drv = (struct hdmiphy_drv_data *)match->data;
> >> +
> >> +       hdata->dev = dev;
> >> +       hdata->confs = drv->confs;
> >> +       hdata->nr_confs = drv->count;
> >> +
> >> +       i2c_set_clientdata(client, hdata);
> >> +
> >> +       return 0;
> >> +}
> >> +
> >> +static const struct i2c_device_id hdmiphy_id[] = {
> >> +       { },
> >> +};
> >> +
> >> +struct i2c_driver hdmiphy_i2c_driver = {
> >>         .driver = {
> >>                 .name   = "exynos-hdmiphy",
> >>                 .owner  = THIS_MODULE,
> >> -               .of_match_table = hdmiphy_match_types,
> >> +               .of_match_table = of_match_ptr(
> >> +                               hdmiphy_i2c_device_match_types),
> >>         },
> >> -       .probe          = hdmiphy_probe,
> >> -       .remove         = hdmiphy_remove,
> >> +       .id_table               = hdmiphy_id,
> >> +       .probe          = hdmiphy_i2c_device_probe,
> >>         .command                = NULL,
> >>  };
> >> -EXPORT_SYMBOL(hdmiphy_driver);
> >> +
> >> +int exynos_hdmiphy_driver_register(void)
> >> +{
> >> +       int ret;
> >> +
> >> +       ret = i2c_add_driver(&hdmiphy_i2c_driver);
> >> +       if (ret)
> >> +               return ret;
> >> +
> >> +       return 0;
> >> +}
> >> +
> >> +void exynos_hdmiphy_driver_unregister(void)
> >> +{
> >> +       i2c_del_driver(&hdmiphy_i2c_driver);
> >> +}
> >> diff --git a/drivers/gpu/drm/exynos/regs-hdmiphy.h
> b/drivers/gpu/drm/exynos/regs-hdmiphy.h
> >> new file mode 100644
> >> index 0000000..d3f9d87
> >> --- /dev/null
> >> +++ b/drivers/gpu/drm/exynos/regs-hdmiphy.h
> >> @@ -0,0 +1,35 @@
> >> +/*
> >> + *
> >> + *  regs-hdmiphy.h
> >> + *
> >> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> >> + * http://www.samsung.com/
> >> + *
> >> + * HDMI-PHY register header file for Samsung HDMI driver
> >> + *
> >> + * This program is free software; you can redistribute it and/or
> modify
> >> + * it under the terms of the GNU General Public License version 2 as
> >> + * published by the Free Software Foundation.
> >> +*/
> >> +
> >> +#ifndef SAMSUNG_REGS_HDMIPHY_H
> >> +#define SAMSUNG_REGS_HDMIPHY_H
> >> +
> >> +/*
> >> + * Register part
> >> +*/
> >> +#define HDMIPHY_MODE_SET_DONE  (0x1f)
> >> +
> >> +/*
> >> + * Bit definition part
> >> + */
> >> +
> >> +/* HDMIPHY_MODE_SET_DONE */
> >> +#define HDMIPHY_MODE_EN                (1 << 7)
> >> +
> >> +/* hdmiphy pmu control bits */
> >> +#define PMU_HDMI_PHY_CONTROL_MASK      (1 << 0)
> >> +#define PMU_HDMI_PHY_ENABLE            (1)
> >> +#define PMU_HDMI_PHY_DISABLE           (0)
> >
> >
> > You don't need the () around simple values
> >
> 
> ok.
> 
> We also discussed previously to keep independent i2c and
> platform phy drivers in exynos_hdmiphy_i2c.c and
> exynos_hdmiphy_platform.c respectively, which will duplicate
> the code to some extent.
> 
> Second point is to implement exynos_i2c_hdmiphy_get_ops()
> and exynos_platform_hdmiphy_get_ops() to get access to all
> callbacks. This will limit the exposure of phy callbacks to the
> phy controller.
> 
> Please share your views on this.
> 
> Regards,
> Rahul Sharma.
> 
> >> +
> >> +#endif /* SAMSUNG_REGS_HDMIPHY_H */
> >> --
> >> 1.7.10.4
> >>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-04  5:47     ` Rahul Sharma
  2013-09-04  7:37       ` Inki Dae
@ 2013-09-04 14:33       ` Sean Paul
  1 sibling, 0 replies; 45+ messages in thread
From: Sean Paul @ 2013-09-04 14:33 UTC (permalink / raw)
  To: Rahul Sharma
  Cc: Rahul Sharma, linux-samsung-soc, dri-devel, kgene.kim,
	sw0312.kim, InKi Dae, Lucas Stach, Tomasz Figa,
	Sylwester Nawrocki, sunil joshi, Shirish S

On Wed, Sep 4, 2013 at 1:47 AM, Rahul Sharma <r.sh.open@gmail.com> wrote:
> Thanks Sean,
>
> On 3 September 2013 20:15, Sean Paul <seanpaul@chromium.org> wrote:
>> A few comments.
>>
>> On Fri, Aug 30, 2013 at 2:59 AM, Rahul Sharma <rahul.sharma@samsung.com> wrote:
>>> Exynos hdmiphy operations and configs are kept inside
>>> the hdmi driver. Hdmiphy related code is tightly coupled
>>> with hdmi IP driver.
>>>
>>> This patche moves hdmiphy related code to hdmiphy driver.
>>
>> s/patche/patch
>>
> ok.
>>> It will help in cleanly supporting the hdmiphy variations
>>> in further SoCs.
>>>
>>> Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
>>> ---
>>>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
>>>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   11 +
>>>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  343 +++------------
>>>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  438 +++++++++++++++++++-
>>>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 ++
>>>  5 files changed, 533 insertions(+), 296 deletions(-)
>>>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
>>>
>>> diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>>> index 50decf8..240eca5 100644
>>> --- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>>> +++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>>> @@ -25,6 +25,7 @@ Required properties:
>>>                 sclk_pixel.
>>>  - clock-names: aliases as per driver requirements for above clock IDs:
>>>         "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi".
>>> +- phy: it points to hdmiphy dt node.
>>>  Example:
>>>
>>>         hdmi {
>>> @@ -32,4 +33,5 @@ Example:
>>>                 reg = <0x14530000 0x100000>;
>>>                 interrupts = <0 95 0>;
>>>                 hpd-gpio = <&gpx3 7 1>;
>>> +               phy = <&hdmiphy>;
>>>         };
>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>>> index 724cab1..1c839f8 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>>> @@ -64,4 +64,15 @@ void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx);
>>>  void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx);
>>>  void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
>>>  void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
>>> +
>>> +int exynos_hdmiphy_driver_register(void);
>>> +void exynos_hdmiphy_driver_unregister(void);
>>> +
>>> +void exynos_hdmiphy_enable(struct device *dev);
>>> +void exynos_hdmiphy_disable(struct device *dev);
>>> +int exynos_hdmiphy_check_mode(struct device *dev,
>>> +                               struct drm_display_mode *mode);
>>> +int exynos_hdmiphy_set_mode(struct device *dev,
>>> +                               struct drm_display_mode *mode);
>>> +int exynos_hdmiphy_conf_apply(struct device *dev);
>>>  #endif
>>> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
>>> index f67ffca..3af4e4c 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
>>> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
>>> @@ -34,6 +34,8 @@
>>>  #include <linux/io.h>
>>>  #include <linux/of.h>
>>>  #include <linux/of_gpio.h>
>>> +#include <linux/of_i2c.h>
>>> +#include <linux/of_platform.h>
>>>
>>>  #include <drm/exynos_drm.h>
>>>
>>> @@ -172,7 +174,6 @@ struct hdmi_v14_conf {
>>>  };
>>>
>>>  struct hdmi_conf_regs {
>>> -       int pixel_clock;
>>>         int cea_video_id;
>>>         union {
>>>                 struct hdmi_v13_conf v13_conf;
>>> @@ -193,9 +194,9 @@ struct hdmi_context {
>>>         int                             irq;
>>>
>>>         struct i2c_client               *ddc_port;
>>> -       struct i2c_client               *hdmiphy_port;
>>> +       struct device                   *hdmiphy_dev;
>>>
>>> -       /* current hdmiphy conf regs */
>>> +       /* current hdmi ip configuration registers. */
>>>         struct hdmi_conf_regs           mode_conf;
>>>
>>>         struct hdmi_resources           res;
>>> @@ -205,180 +206,6 @@ struct hdmi_context {
>>>         enum hdmi_type                  type;
>>>  };
>>>
>>> -struct hdmiphy_config {
>>> -       int pixel_clock;
>>> -       u8 conf[32];
>>> -};
>>> -
>>> -/* list of phy config settings */
>>> -static const struct hdmiphy_config hdmiphy_v13_configs[] = {
>>> -       {
>>> -               .pixel_clock = 27000000,
>>> -               .conf = {
>>> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
>>> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>>> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>>> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 27027000,
>>> -               .conf = {
>>> -                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
>>> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>>> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>>> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 74176000,
>>> -               .conf = {
>>> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
>>> -                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
>>> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>>> -                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 74250000,
>>> -               .conf = {
>>> -                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
>>> -                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
>>> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
>>> -                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 148500000,
>>> -               .conf = {
>>> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
>>> -                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
>>> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
>>> -                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
>>> -               },
>>> -       },
>>> -};
>>> -
>>> -static const struct hdmiphy_config hdmiphy_v14_configs[] = {
>>> -       {
>>> -               .pixel_clock = 25200000,
>>> -               .conf = {
>>> -                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
>>> -                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 27000000,
>>> -               .conf = {
>>> -                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
>>> -                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 27027000,
>>> -               .conf = {
>>> -                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
>>> -                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 36000000,
>>> -               .conf = {
>>> -                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
>>> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 40000000,
>>> -               .conf = {
>>> -                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
>>> -                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 65000000,
>>> -               .conf = {
>>> -                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
>>> -                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 74176000,
>>> -               .conf = {
>>> -                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
>>> -                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 74250000,
>>> -               .conf = {
>>> -                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
>>> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 83500000,
>>> -               .conf = {
>>> -                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
>>> -                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 106500000,
>>> -               .conf = {
>>> -                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
>>> -                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 108000000,
>>> -               .conf = {
>>> -                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
>>> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 146250000,
>>> -               .conf = {
>>> -                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
>>> -                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
>>> -               },
>>> -       },
>>> -       {
>>> -               .pixel_clock = 148500000,
>>> -               .conf = {
>>> -                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
>>> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>>> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> -                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
>>> -               },
>>> -       },
>>> -};
>>> -
>>>  struct hdmi_infoframe {
>>>         enum HDMI_PACKET_TYPE type;
>>>         u8 ver;
>>> @@ -769,28 +596,6 @@ static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector)
>>>         return raw_edid;
>>>  }
>>>
>>> -static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
>>> -{
>>> -       const struct hdmiphy_config *confs;
>>> -       int count, i;
>>> -
>>> -       if (hdata->type == HDMI_TYPE13) {
>>> -               confs = hdmiphy_v13_configs;
>>> -               count = ARRAY_SIZE(hdmiphy_v13_configs);
>>> -       } else if (hdata->type == HDMI_TYPE14) {
>>> -               confs = hdmiphy_v14_configs;
>>> -               count = ARRAY_SIZE(hdmiphy_v14_configs);
>>> -       } else
>>> -               return -EINVAL;
>>> -
>>> -       for (i = 0; i < count; i++)
>>> -               if (confs[i].pixel_clock == pixel_clock)
>>> -                       return i;
>>> -
>>> -       DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
>>> -       return -EINVAL;
>>> -}
>>> -
>>>  static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
>>>  {
>>>         struct hdmi_context *hdata = ctx;
>>> @@ -801,7 +606,7 @@ static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
>>>                 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
>>>                 false, mode->clock * 1000);
>>>
>>> -       ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
>>> +       ret = exynos_hdmiphy_check_mode(hdata->hdmiphy_dev, mode);
>>>         if (ret < 0)
>>>                 return ret;
>>>         return 0;
>>> @@ -1302,19 +1107,13 @@ static void hdmi_mode_apply(struct hdmi_context *hdata)
>>>
>>>  static void hdmiphy_conf_reset(struct hdmi_context *hdata)
>>>  {
>>> -       u8 buffer[2];
>>>         u32 reg;
>>>
>>>         clk_disable_unprepare(hdata->res.sclk_hdmi);
>>>         clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
>>>         clk_prepare_enable(hdata->res.sclk_hdmi);
>>>
>>> -       /* operation mode */
>>> -       buffer[0] = 0x1f;
>>> -       buffer[1] = 0x00;
>>> -
>>> -       if (hdata->hdmiphy_port)
>>> -               i2c_master_send(hdata->hdmiphy_port, buffer, 2);
>>> +       exynos_hdmiphy_disable(hdata->hdmiphy_dev);
>>>
>>>         if (hdata->type == HDMI_TYPE13)
>>>                 reg = HDMI_V13_PHY_RSTOUT;
>>> @@ -1342,66 +1141,12 @@ static void hdmiphy_poweroff(struct hdmi_context *hdata)
>>>                         HDMI_PHY_POWER_OFF_EN);
>>>  }
>>>
>>> -static void hdmiphy_conf_apply(struct hdmi_context *hdata)
>>> -{
>>> -       const u8 *hdmiphy_data;
>>> -       u8 buffer[32];
>>> -       u8 operation[2];
>>> -       u8 read_buffer[32] = {0, };
>>> -       int ret;
>>> -       int i;
>>> -
>>> -       if (!hdata->hdmiphy_port) {
>>> -               DRM_ERROR("hdmiphy is not attached\n");
>>> -               return;
>>> -       }
>>> -
>>> -       /* pixel clock */
>>> -       i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
>>> -       if (i < 0) {
>>> -               DRM_ERROR("failed to find hdmiphy conf\n");
>>> -               return;
>>> -       }
>>> -
>>> -       if (hdata->type == HDMI_TYPE13)
>>> -               hdmiphy_data = hdmiphy_v13_configs[i].conf;
>>> -       else
>>> -               hdmiphy_data = hdmiphy_v14_configs[i].conf;
>>> -
>>> -       memcpy(buffer, hdmiphy_data, 32);
>>> -       ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
>>> -       if (ret != 32) {
>>> -               DRM_ERROR("failed to configure HDMIPHY via I2C\n");
>>> -               return;
>>> -       }
>>> -
>>> -       usleep_range(10000, 12000);
>>> -
>>> -       /* operation mode */
>>> -       operation[0] = 0x1f;
>>> -       operation[1] = 0x80;
>>> -
>>> -       ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
>>> -       if (ret != 2) {
>>> -               DRM_ERROR("failed to enable hdmiphy\n");
>>> -               return;
>>> -       }
>>> -
>>> -       ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
>>> -       if (ret < 0) {
>>> -               DRM_ERROR("failed to read hdmiphy config\n");
>>> -               return;
>>> -       }
>>> -
>>> -       for (i = 0; i < ret; i++)
>>> -               DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
>>> -                       "recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
>>> -}
>>> -
>>>  static void hdmi_conf_apply(struct hdmi_context *hdata)
>>>  {
>>>         hdmiphy_conf_reset(hdata);
>>> -       hdmiphy_conf_apply(hdata);
>>> +       exynos_hdmiphy_conf_apply(hdata->hdmiphy_dev);
>>> +       usleep_range(10000, 12000);
>>
>> This delay seems like something that should be in the phy driver,
>> instead of the hdmi driver (since it seems conceivable that certain
>> phys might not need a delay or might need a longer delay).
>>
>
> ok. I will move it there.
>
>>> +       exynos_hdmiphy_enable(hdata->hdmiphy_dev);
>>>
>>>         mutex_lock(&hdata->hdmi_mutex);
>>>         hdmi_conf_reset(hdata);
>>> @@ -1434,7 +1179,6 @@ static void hdmi_v13_mode_set(struct hdmi_context *hdata,
>>>
>>>         hdata->mode_conf.cea_video_id =
>>>                 drm_match_cea_mode((struct drm_display_mode *)m);
>>> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
>>>
>>>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
>>>         hdmi_set_reg(core->h_v_line, 3, (m->htotal << 12) | m->vtotal);
>>> @@ -1530,7 +1274,6 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
>>>
>>>         hdata->mode_conf.cea_video_id =
>>>                 drm_match_cea_mode((struct drm_display_mode *)m);
>>> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
>>>
>>>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
>>>         hdmi_set_reg(core->v_line, 2, m->vtotal);
>>> @@ -1646,6 +1389,8 @@ static void hdmi_mode_set(void *ctx, struct drm_display_mode *mode)
>>>                 hdmi_v13_mode_set(hdata, mode);
>>>         else
>>>                 hdmi_v14_mode_set(hdata, mode);
>>> +
>>> +       exynos_hdmiphy_set_mode(hdata->hdmiphy_dev, mode);
>>
>> Why set_mode when everything else is mode_set?
>>
>
> I will change it to mode_set.
>
>>>  }
>>>
>>>  static void hdmi_get_max_resol(void *ctx, unsigned int *width,
>>> @@ -1824,7 +1569,7 @@ fail:
>>>         return -ENODEV;
>>>  }
>>>
>>> -static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
>>> +static struct i2c_client *hdmi_ddc;
>>>
>>>  void hdmi_attach_ddc_client(struct i2c_client *ddc)
>>>  {
>>> @@ -1832,12 +1577,6 @@ void hdmi_attach_ddc_client(struct i2c_client *ddc)
>>>                 hdmi_ddc = ddc;
>>>  }
>>>
>>> -void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
>>> -{
>>> -       if (hdmiphy)
>>> -               hdmi_hdmiphy = hdmiphy;
>>> -}
>>> -
>>>  static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
>>>                                         (struct device *dev)
>>>  {
>>> @@ -1862,6 +1601,50 @@ err_data:
>>>         return NULL;
>>>  }
>>>
>>> +static int hdmi_get_phy_device(struct hdmi_context *hdata)
>>
>> "get" is not the proper verb here, "initialize" would be more
>> appropriate (IMO, of course).
>>
>
> But we don't initialise the phy here. It is just to get the
> hdmiphy dev* through dt.
>

OK, sure. Maybe hdmi_register_phy_device then, since you're doing more
than just getting it from dt.

>>> +{
>>> +       struct device_node *np;
>>> +       struct i2c_client *client;
>>> +       struct platform_device *pdev;
>>> +       int ret;
>>> +
>>> +       /* register hdmiphy driver */
>>> +       ret = exynos_hdmiphy_driver_register();
>>> +       if (ret) {
>>> +               DRM_ERROR("failed to register hdmiphy driver\n");
>>
>> Printing ret would be useful here.
>
> ok.
>>
>>> +               goto err;
>>> +       }
>>> +
>>> +       np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
>>> +       if (!np) {
>>> +               DRM_ERROR("Could not find 'phy' property\n");
>>> +               ret = -ENOENT;
>>> +               goto err;
>>> +       }
>>> +
>>> +       /* find hdmi phy on i2c bus */
>>> +       client = of_find_i2c_device_by_node(np);
>>> +       if (client) {
>>> +               hdata->hdmiphy_dev = &client->dev;
>>> +               ret = 0;
>>> +               goto exit;
>>> +       }
>>> +
>>> +       /* find hdmi phy on platform bus */
>>> +       pdev = of_find_device_by_node(np);
>>> +       if (pdev) {
>>> +               hdata->hdmiphy_dev = &pdev->dev;
>>> +               ret = 0;
>>> +               goto exit;
>>> +       }
>>> +
>>> +exit:
>>> +       /* able to find hdmiphy on platform/i2c bus */
>>> +err:
>>
>> Probably just easier to have one "exit" or "out" label that just returns ret.
>
> ok.
>>
>>> +       of_node_put(np);
>>> +       return ret;
>>> +}
>>> +
>>>  static struct of_device_id hdmi_match_types[] = {
>>>         {
>>>                 .compatible = "samsung,exynos5-hdmi",
>>> @@ -1939,15 +1722,13 @@ static int hdmi_probe(struct platform_device *pdev)
>>>
>>>         hdata->ddc_port = hdmi_ddc;
>>>
>>> -       /* hdmiphy i2c driver */
>>> -       if (i2c_add_driver(&hdmiphy_driver)) {
>>> -               DRM_ERROR("failed to register hdmiphy i2c driver\n");
>>> +       ret = hdmi_get_phy_device(hdata);
>>> +       if (ret) {
>>> +               DRM_ERROR("failed to get hdmiphy device\n");
>>
>> Printing ret would be useful.
>>
>>
>>>                 ret = -ENOENT;
>>
>> Why change the return value here?
>>
> Yea. Correct. I shouldn't. I will change this.
>
>>>                 goto err_ddc;
>>>         }
>>>
>>> -       hdata->hdmiphy_port = hdmi_hdmiphy;
>>> -
>>>         hdata->irq = gpio_to_irq(hdata->hpd_gpio);
>>>         if (hdata->irq < 0) {
>>>                 DRM_ERROR("failed to get GPIO irq\n");
>>> @@ -1977,7 +1758,7 @@ static int hdmi_probe(struct platform_device *pdev)
>>>         return 0;
>>>
>>>  err_hdmiphy:
>>> -       i2c_del_driver(&hdmiphy_driver);
>>> +       exynos_hdmiphy_driver_unregister();
>>>  err_ddc:
>>>         i2c_del_driver(&ddc_driver);
>>>         return ret;
>>> @@ -1989,8 +1770,8 @@ static int hdmi_remove(struct platform_device *pdev)
>>>
>>>         pm_runtime_disable(dev);
>>>
>>> -       /* hdmiphy i2c driver */
>>> -       i2c_del_driver(&hdmiphy_driver);
>>> +       /* hdmiphy driver */
>>> +       exynos_hdmiphy_driver_unregister();
>>>         /* DDC i2c driver */
>>>         i2c_del_driver(&ddc_driver);
>>>
>>> diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>>> index 59abb14..82daa42 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>>> +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>>> @@ -15,51 +15,459 @@
>>>
>>>  #include <linux/kernel.h>
>>>  #include <linux/i2c.h>
>>> -#include <linux/of.h>
>>> +#include <linux/module.h>
>>> +#include <linux/pm_runtime.h>
>>> +#include <linux/clk.h>
>>>
>>>  #include "exynos_drm_drv.h"
>>>  #include "exynos_hdmi.h"
>>> +#include "exynos_drm_hdmi.h"
>>> +#include "regs-hdmiphy.h"
>>>
>>> +#define HDMIPHY_REG_COUNT      (32)
>>
>> This probably belongs in regs-hdmiphy.h instead of here. Also remove the ()
>>
>
> Ok. I will move it there.
>
>>>
>>> -static int hdmiphy_probe(struct i2c_client *client,
>>> -       const struct i2c_device_id *id)
>>> +struct hdmiphy_context {
>>> +       struct device           *dev;
>>> +       struct hdmiphy_config   *current_conf;
>>> +
>>> +       struct hdmiphy_config   *confs;
>>> +       unsigned int            nr_confs;
>>> +};
>>> +
>>> +struct hdmiphy_config {
>>> +       int pixel_clock;
>>> +       u8 conf[HDMIPHY_REG_COUNT];
>>> +};
>>> +
>>> +struct hdmiphy_drv_data {
>>> +       struct hdmiphy_config *confs;
>>> +       unsigned int count;
>>> +};
>>> +
>>> +/* list of all required phy config settings */
>>> +static struct hdmiphy_config hdmiphy_4212_configs[] = {
>>> +       {
>>> +               .pixel_clock = 25200000,
>>> +               .conf = {
>>> +                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
>>> +                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 27000000,
>>> +               .conf = {
>>> +                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
>>> +                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 27027000,
>>> +               .conf = {
>>> +                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
>>> +                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 36000000,
>>> +               .conf = {
>>> +                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
>>> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 40000000,
>>> +               .conf = {
>>> +                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
>>> +                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 65000000,
>>> +               .conf = {
>>> +                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
>>> +                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 74176000,
>>> +               .conf = {
>>> +                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
>>> +                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 74250000,
>>> +               .conf = {
>>> +                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
>>> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 83500000,
>>> +               .conf = {
>>> +                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
>>> +                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 106500000,
>>> +               .conf = {
>>> +                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
>>> +                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 108000000,
>>> +               .conf = {
>>> +                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
>>> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 146250000,
>>> +               .conf = {
>>> +                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
>>> +                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 148500000,
>>> +               .conf = {
>>> +                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
>>> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>>> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>>> +                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
>>> +               },
>>> +       },
>>> +};
>>> +
>>> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
>>> +       {
>>> +               .pixel_clock = 27000000,
>>> +               .conf = {
>>> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
>>> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>>> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>>> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 27027000,
>>> +               .conf = {
>>> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
>>> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>>> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>>> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 74176000,
>>> +               .conf = {
>>> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
>>> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
>>> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>>> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 74250000,
>>> +               .conf = {
>>> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
>>> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
>>> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
>>> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
>>> +               },
>>> +       },
>>> +       {
>>> +               .pixel_clock = 148500000,
>>> +               .conf = {
>>> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
>>> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
>>> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
>>> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
>>> +               },
>>> +       },
>>> +};
>>> +
>>
>> Are you aware of the effort to move these to dt? Since these are
>> board-specific values, it seems incorrect to apply them universally.
>> Shirish has uploaded a patch to the chromium review site to push these
>> into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
>> you can work that into your patch set?
>>
>
> I have gone through these patches. I am adding Shirish here for further
> discussion on these changes. he can explain better.
>
>>
>>> +static struct hdmiphy_config *hdmiphy_find_conf(struct hdmiphy_context *hdata,
>>> +                       const struct drm_display_mode *mode)
>>> +{
>>> +       int i;
>>> +
>>> +       for (i = 0; i < hdata->nr_confs; i++)
>>> +               if (hdata->confs[i].pixel_clock == (mode->clock * 1000))
>>> +                       return &hdata->confs[i];
>>> +
>>> +       return NULL;
>>> +}
>>> +
>>> +static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata,
>>> +                       u32 reg_offset, u8 value)
>>> +{
>>> +       if (reg_offset >= HDMIPHY_REG_COUNT)
>>> +               return -EINVAL;
>>> +
>>> +       if (i2c_verify_client(hdata->dev)) {
>>
>> Is this necessary?
>
> Based on this check, I was deciding that given dev is i2c or
> platform device. But now when we agreed to split drivers to
> phy and plf driver, I will remove this.
>
>>
>>> +               u8 buffer[2];
>>> +               int ret;
>>> +
>>> +               buffer[0] = reg_offset;
>>> +               buffer[1] = value;
>>> +
>>> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
>>> +                               buffer, 2);
>>> +               if (ret == 2)
>>> +                       return 0;
>>> +               return ret;
>>> +       } else {
>>> +               return -EINVAL;
>>> +       }
>>> +}
>>> +
>>> +static int hdmiphy_reg_write_buf(struct hdmiphy_context *hdata,
>>> +                       u32 reg_offset, const u8 *buf, u32 len)
>>> +{
>>> +       if ((reg_offset + len) > HDMIPHY_REG_COUNT)
>>> +               return -EINVAL;
>>> +
>>> +       if (i2c_verify_client(hdata->dev)) {
>>
>> Is this necessary?
>>
>>
>>> +               int ret;
>>> +
>>> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
>>> +                               buf, len);
>>
>> Does this actually work? You don't seem to be using reg_offset anywhere.
>>
>
> reg_offset is not required here. I should remove this. This
> procedure is to write the complete buf starting from 0.
> hdmiphy_reg_writeb is supposed to be used for writing
> value from some offset.
>

The only way this works is if the first byte in buf is the register
offset, is this why each conf blob starts with 0x1? That seems a bit
error prone.

IMO, you should be using reg_offset instead of encoding the register
address in the blob.

>>> +               if (ret == len)
>>> +                       return 0;
>>> +               return ret;
>>> +       } else {
>>> +               return -EINVAL;
>>> +       }
>>> +}
>>> +
>>> +int exynos_hdmiphy_check_mode(struct device *dev,
>>> +                       struct drm_display_mode *mode)
>>>  {
>>> -       hdmi_attach_hdmiphy_client(client);
>>> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>>> +       const struct hdmiphy_config *conf;
>>> +
>>> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>>
>> Maybe you can merge this debug message with the one below.
>>
>
> ok.
>
>>>
>>> -       dev_info(&client->adapter->dev, "attached s5p_hdmiphy "
>>> -               "into i2c adapter successfully\n");
>>> +       if (!hdata) {
>>> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>>> +               return -EINVAL;
>>> +       }
>>
>> Can this happen? I think the phy driver registration should be
>> synchronous with the hdmi driver registration. As such, it shouldn't
>> be possible to get a check_mode callback until it's all set up.
>>
>
> I will confirm on this.
>
>>>
>>> +       DRM_DEBUG("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
>>> +               mode->hdisplay, mode->vdisplay,
>>> +               mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE)
>>> +               ? true : false, mode->clock * 1000);
>>> +
>>> +       conf = hdmiphy_find_conf(hdata, mode);
>>> +       if (!conf) {
>>> +               DRM_DEBUG("Display Mode is not supported.\n");
>>> +               return -EINVAL;
>>> +       }
>>>         return 0;
>>>  }
>>>
>>> -static int hdmiphy_remove(struct i2c_client *client)
>>> +int exynos_hdmiphy_set_mode(struct device *dev,
>>> +                       struct drm_display_mode *mode)
>>>  {
>>> -       dev_info(&client->adapter->dev, "detached s5p_hdmiphy "
>>> -               "from i2c adapter successfully\n");
>>> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>>> +
>>> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>>> +
>>> +       hdata->current_conf = hdmiphy_find_conf(hdata, mode);
>>> +
>>> +       if (!hdata) {
>>> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>>> +               return -EINVAL;
>>> +       }
>>
>> I really hope this check isn't necessary, since you've already
>> dereferenced it 2 lines up :) See my comment above, I don't think you
>> can ever hit this.
>>
>>>
>>> +       if (!hdata->current_conf) {
>>> +               DRM_ERROR("Display Mode is not supported.\n");
>>> +               return -EINVAL;
>>> +       }
>>>         return 0;
>>>  }
>>>
>>> -static struct of_device_id hdmiphy_match_types[] = {
>>> +void exynos_hdmiphy_enable(struct device *dev)
>>> +{
>>> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>>> +       int ret;
>>> +
>>> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>>> +
>>> +       if (!hdata) {
>>> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>>> +               return;
>>> +       }
>>
>> Same comment as above.
>>
>>> +
>>> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
>>> +                       HDMIPHY_MODE_EN);
>>> +       if (ret < 0) {
>>> +               DRM_ERROR("failed to disable hdmiphy.\n");
>>> +               return;
>>> +       }
>>> +}
>>> +
>>> +void exynos_hdmiphy_disable(struct device *dev)
>>> +{
>>> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>>> +       int ret;
>>> +
>>> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>>> +
>>> +       if (!hdata) {
>>> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>>> +               return;
>>> +       }
>>> +
>>> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, 0);
>>> +       if (ret < 0) {
>>> +               DRM_ERROR("failed to enable hdmiphy.\n");
>>
>> If you're not going to return the error code, at least print it here.
>>
>
> ok.
>
>>> +               return;
>>> +       }
>>> +}
>>> +
>>> +int exynos_hdmiphy_conf_apply(struct device *dev)
>>> +{
>>> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>>> +       const u8 *hdmiphy_data;
>>> +       int ret;
>>> +
>>> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>>> +
>>> +       if (!hdata) {
>>> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>>> +               return -EINVAL;
>>> +       }
>>> +
>>> +       /* pixel clock */
>>
>> I don't understand this comment.
>>
>
> I will remove this.
>
>>> +       if (hdata->current_conf)
>>> +               hdmiphy_data = hdata->current_conf->conf;
>>> +       else
>>> +               return -EINVAL;
>>> +
>>> +       ret = hdmiphy_reg_write_buf(hdata, 0, hdmiphy_data,
>>> +                       HDMIPHY_REG_COUNT);
>>
>> I think the only reason this works is b/c you're writing to register offset 0.
>>
>>> +       if (ret) {
>>> +               DRM_ERROR("failed to configure hdmiphy.\n");
>>> +               return -EINVAL;
>>
>> Why don't you return ret?
>>
>
> ok.
>
>>> +       }
>>> +       return 0;
>>> +}
>>> +
>>> +static struct hdmiphy_drv_data exynos4212_hdmiphy_drv_data = {
>>> +       .confs = hdmiphy_4212_configs,
>>> +       .count = ARRAY_SIZE(hdmiphy_4212_configs)
>>> +};
>>> +
>>> +static struct hdmiphy_drv_data exynos4210_hdmiphy_drv_data = {
>>> +       .confs = hdmiphy_4210_configs,
>>> +       .count = ARRAY_SIZE(hdmiphy_4210_configs)
>>> +};
>>> +
>>> +static struct of_device_id hdmiphy_i2c_device_match_types[] = {
>>>         {
>>>                 .compatible = "samsung,exynos5-hdmiphy",
>>> +               .data   = &exynos4212_hdmiphy_drv_data,
>>>         }, {
>>>                 .compatible = "samsung,exynos4210-hdmiphy",
>>> +               .data   = &exynos4210_hdmiphy_drv_data,
>>>         }, {
>>>                 .compatible = "samsung,exynos4212-hdmiphy",
>>> +               .data   = &exynos4212_hdmiphy_drv_data,
>>>         }, {
>>>                 /* end node */
>>>         }
>>>  };
>>>
>>> -struct i2c_driver hdmiphy_driver = {
>>> +static int hdmiphy_i2c_device_probe(struct i2c_client *client,
>>> +       const struct i2c_device_id *id)
>>> +{
>>> +       struct device *dev = &client->dev;
>>> +       struct hdmiphy_context *hdata;
>>> +       struct hdmiphy_drv_data *drv;
>>> +       const struct of_device_id *match;
>>> +
>>> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>>> +
>>> +       hdata = devm_kzalloc(dev, sizeof(*hdata), GFP_KERNEL);
>>> +       if (!hdata) {
>>> +               DRM_ERROR("failed to allocate hdmiphy context.\n");
>>> +               return -ENOMEM;
>>> +       }
>>> +
>>> +       match = of_match_node(of_match_ptr(
>>> +               hdmiphy_i2c_device_match_types),
>>> +               dev->of_node);
>>> +
>>> +       if (match == NULL)
>>> +               return -ENODEV;
>>> +
>>> +       drv = (struct hdmiphy_drv_data *)match->data;
>>> +
>>> +       hdata->dev = dev;
>>> +       hdata->confs = drv->confs;
>>> +       hdata->nr_confs = drv->count;
>>> +
>>> +       i2c_set_clientdata(client, hdata);
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +static const struct i2c_device_id hdmiphy_id[] = {
>>> +       { },
>>> +};
>>> +
>>> +struct i2c_driver hdmiphy_i2c_driver = {
>>>         .driver = {
>>>                 .name   = "exynos-hdmiphy",
>>>                 .owner  = THIS_MODULE,
>>> -               .of_match_table = hdmiphy_match_types,
>>> +               .of_match_table = of_match_ptr(
>>> +                               hdmiphy_i2c_device_match_types),
>>>         },
>>> -       .probe          = hdmiphy_probe,
>>> -       .remove         = hdmiphy_remove,
>>> +       .id_table               = hdmiphy_id,
>>> +       .probe          = hdmiphy_i2c_device_probe,
>>>         .command                = NULL,
>>>  };
>>> -EXPORT_SYMBOL(hdmiphy_driver);
>>> +
>>> +int exynos_hdmiphy_driver_register(void)
>>> +{
>>> +       int ret;
>>> +
>>> +       ret = i2c_add_driver(&hdmiphy_i2c_driver);
>>> +       if (ret)
>>> +               return ret;
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +void exynos_hdmiphy_driver_unregister(void)
>>> +{
>>> +       i2c_del_driver(&hdmiphy_i2c_driver);
>>> +}
>>> diff --git a/drivers/gpu/drm/exynos/regs-hdmiphy.h b/drivers/gpu/drm/exynos/regs-hdmiphy.h
>>> new file mode 100644
>>> index 0000000..d3f9d87
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/exynos/regs-hdmiphy.h
>>> @@ -0,0 +1,35 @@
>>> +/*
>>> + *
>>> + *  regs-hdmiphy.h
>>> + *
>>> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
>>> + * http://www.samsung.com/
>>> + *
>>> + * HDMI-PHY register header file for Samsung HDMI driver
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License version 2 as
>>> + * published by the Free Software Foundation.
>>> +*/
>>> +
>>> +#ifndef SAMSUNG_REGS_HDMIPHY_H
>>> +#define SAMSUNG_REGS_HDMIPHY_H
>>> +
>>> +/*
>>> + * Register part
>>> +*/
>>> +#define HDMIPHY_MODE_SET_DONE  (0x1f)
>>> +
>>> +/*
>>> + * Bit definition part
>>> + */
>>> +
>>> +/* HDMIPHY_MODE_SET_DONE */
>>> +#define HDMIPHY_MODE_EN                (1 << 7)
>>> +
>>> +/* hdmiphy pmu control bits */
>>> +#define PMU_HDMI_PHY_CONTROL_MASK      (1 << 0)
>>> +#define PMU_HDMI_PHY_ENABLE            (1)
>>> +#define PMU_HDMI_PHY_DISABLE           (0)
>>
>>
>> You don't need the () around simple values
>>
>
> ok.
>
> We also discussed previously to keep independent i2c and
> platform phy drivers in exynos_hdmiphy_i2c.c and
> exynos_hdmiphy_platform.c respectively, which will duplicate
> the code to some extent.
>
> Second point is to implement exynos_i2c_hdmiphy_get_ops()
> and exynos_platform_hdmiphy_get_ops() to get access to all
> callbacks. This will limit the exposure of phy callbacks to the
> phy controller.
>
> Please share your views on this.
>

Yeah, this is a bit tricky, tbh. I think if you're duplicating a bunch
of code, it would be better to keep exynos_hdmiphy.c as a phy helper
library. However most of the code here revolves around writing the
blob to the phy, so I don't think the duplication will be too bad.

It might be worth trying to trim the amount of code down as well. For
instance, you could remove check_mode in favor of just calling
find_conf from the hdmi driver.

Sean

> Regards,
> Rahul Sharma.
>
>>> +
>>> +#endif /* SAMSUNG_REGS_HDMIPHY_H */
>>> --
>>> 1.7.10.4
>>>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-04  7:37       ` Inki Dae
@ 2013-09-04 14:51         ` Sean Paul
  2013-09-05  4:16           ` Inki Dae
  0 siblings, 1 reply; 45+ messages in thread
From: Sean Paul @ 2013-09-04 14:51 UTC (permalink / raw)
  To: Inki Dae
  Cc: Rahul Sharma, Rahul Sharma, linux-samsung-soc, dri-devel,
	kgene.kim, sw0312.kim, Lucas Stach, Tomasz Figa,
	Sylwester Nawrocki, sunil joshi, Shirish S

On Wed, Sep 4, 2013 at 3:37 AM, Inki Dae <inki.dae@samsung.com> wrote:
>
>
>> -----Original Message-----
>> From: Rahul Sharma [mailto:r.sh.open@gmail.com]
>> Sent: Wednesday, September 04, 2013 2:48 PM
>> To: Sean Paul
>> Cc: Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim; sw0312.kim;
>> InKi Dae; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
>> shirish@chromium.org
>> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
>> driver
>>
>> Thanks Sean,
>>
>> On 3 September 2013 20:15, Sean Paul <seanpaul@chromium.org> wrote:
>> > A few comments.
>> >
>> > On Fri, Aug 30, 2013 at 2:59 AM, Rahul Sharma <rahul.sharma@samsung.com>
>> wrote:
>> >> Exynos hdmiphy operations and configs are kept inside
>> >> the hdmi driver. Hdmiphy related code is tightly coupled
>> >> with hdmi IP driver.
>> >>
>> >> This patche moves hdmiphy related code to hdmiphy driver.
>> >
>> > s/patche/patch
>> >
>> ok.
>> >> It will help in cleanly supporting the hdmiphy variations
>> >> in further SoCs.
>> >>
>> >> Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
>> >> ---
>> >>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
>> >>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   11 +
>> >>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  343
> +++------------
>> >>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  438
>> +++++++++++++++++++-
>> >>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 ++
>> >>  5 files changed, 533 insertions(+), 296 deletions(-)
>> >>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
>> >>
>> >> diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> >> index 50decf8..240eca5 100644
>> >> --- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> >> +++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> >> @@ -25,6 +25,7 @@ Required properties:
>> >>                 sclk_pixel.
>> >>  - clock-names: aliases as per driver requirements for above clock IDs:
>> >>         "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and
> "mout_hdmi".
>> >> +- phy: it points to hdmiphy dt node.
>> >>  Example:
>> >>
>> >>         hdmi {
>> >> @@ -32,4 +33,5 @@ Example:
>> >>                 reg = <0x14530000 0x100000>;
>> >>                 interrupts = <0 95 0>;
>> >>                 hpd-gpio = <&gpx3 7 1>;
>> >> +               phy = <&hdmiphy>;
>> >>         };
>> >> diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>> b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>> >> index 724cab1..1c839f8 100644
>> >> --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>> >> +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>> >> @@ -64,4 +64,15 @@ void exynos_hdmi_drv_attach(struct
>> exynos_drm_hdmi_context *ctx);
>> >>  void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx);
>> >>  void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
>> >>  void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
>> >> +
>> >> +int exynos_hdmiphy_driver_register(void);
>> >> +void exynos_hdmiphy_driver_unregister(void);
>> >> +
>> >> +void exynos_hdmiphy_enable(struct device *dev);
>> >> +void exynos_hdmiphy_disable(struct device *dev);
>> >> +int exynos_hdmiphy_check_mode(struct device *dev,
>> >> +                               struct drm_display_mode *mode);
>> >> +int exynos_hdmiphy_set_mode(struct device *dev,
>> >> +                               struct drm_display_mode *mode);
>> >> +int exynos_hdmiphy_conf_apply(struct device *dev);
>> >>  #endif
>> >> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c
>> b/drivers/gpu/drm/exynos/exynos_hdmi.c
>> >> index f67ffca..3af4e4c 100644
>> >> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
>> >> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
>> >> @@ -34,6 +34,8 @@
>> >>  #include <linux/io.h>
>> >>  #include <linux/of.h>
>> >>  #include <linux/of_gpio.h>
>> >> +#include <linux/of_i2c.h>
>> >> +#include <linux/of_platform.h>
>> >>
>> >>  #include <drm/exynos_drm.h>
>> >>
>> >> @@ -172,7 +174,6 @@ struct hdmi_v14_conf {
>> >>  };
>> >>
>> >>  struct hdmi_conf_regs {
>> >> -       int pixel_clock;
>> >>         int cea_video_id;
>> >>         union {
>> >>                 struct hdmi_v13_conf v13_conf;
>> >> @@ -193,9 +194,9 @@ struct hdmi_context {
>> >>         int                             irq;
>> >>
>> >>         struct i2c_client               *ddc_port;
>> >> -       struct i2c_client               *hdmiphy_port;
>> >> +       struct device                   *hdmiphy_dev;
>> >>
>> >> -       /* current hdmiphy conf regs */
>> >> +       /* current hdmi ip configuration registers. */
>> >>         struct hdmi_conf_regs           mode_conf;
>> >>
>> >>         struct hdmi_resources           res;
>> >> @@ -205,180 +206,6 @@ struct hdmi_context {
>> >>         enum hdmi_type                  type;
>> >>  };
>> >>
>> >> -struct hdmiphy_config {
>> >> -       int pixel_clock;
>> >> -       u8 conf[32];
>> >> -};
>> >> -
>> >> -/* list of phy config settings */
>> >> -static const struct hdmiphy_config hdmiphy_v13_configs[] = {
>> >> -       {
>> >> -               .pixel_clock = 27000000,
>> >> -               .conf = {
>> >> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
>> >> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>> >> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> >> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 27027000,
>> >> -               .conf = {
>> >> -                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
>> >> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>> >> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> >> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 74176000,
>> >> -               .conf = {
>> >> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
>> >> -                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
>> >> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> >> -                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 74250000,
>> >> -               .conf = {
>> >> -                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
>> >> -                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
>> >> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
>> >> -                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 148500000,
>> >> -               .conf = {
>> >> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
>> >> -                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
>> >> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> >> -                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
>> >> -               },
>> >> -       },
>> >> -};
>> >> -
>> >> -static const struct hdmiphy_config hdmiphy_v14_configs[] = {
>> >> -       {
>> >> -               .pixel_clock = 25200000,
>> >> -               .conf = {
>> >> -                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
>> >> -                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 27000000,
>> >> -               .conf = {
>> >> -                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
>> >> -                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 27027000,
>> >> -               .conf = {
>> >> -                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
>> >> -                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 36000000,
>> >> -               .conf = {
>> >> -                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
>> >> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 40000000,
>> >> -               .conf = {
>> >> -                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
>> >> -                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 65000000,
>> >> -               .conf = {
>> >> -                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
>> >> -                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 74176000,
>> >> -               .conf = {
>> >> -                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
>> >> -                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 74250000,
>> >> -               .conf = {
>> >> -                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
>> >> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 83500000,
>> >> -               .conf = {
>> >> -                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
>> >> -                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 106500000,
>> >> -               .conf = {
>> >> -                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
>> >> -                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 108000000,
>> >> -               .conf = {
>> >> -                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
>> >> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 146250000,
>> >> -               .conf = {
>> >> -                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
>> >> -                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
>> >> -               },
>> >> -       },
>> >> -       {
>> >> -               .pixel_clock = 148500000,
>> >> -               .conf = {
>> >> -                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
>> >> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> >> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> -                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
>> >> -               },
>> >> -       },
>> >> -};
>> >> -
>> >>  struct hdmi_infoframe {
>> >>         enum HDMI_PACKET_TYPE type;
>> >>         u8 ver;
>> >> @@ -769,28 +596,6 @@ static struct edid *hdmi_get_edid(void *ctx,
>> struct drm_connector *connector)
>> >>         return raw_edid;
>> >>  }
>> >>
>> >> -static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32
>> pixel_clock)
>> >> -{
>> >> -       const struct hdmiphy_config *confs;
>> >> -       int count, i;
>> >> -
>> >> -       if (hdata->type == HDMI_TYPE13) {
>> >> -               confs = hdmiphy_v13_configs;
>> >> -               count = ARRAY_SIZE(hdmiphy_v13_configs);
>> >> -       } else if (hdata->type == HDMI_TYPE14) {
>> >> -               confs = hdmiphy_v14_configs;
>> >> -               count = ARRAY_SIZE(hdmiphy_v14_configs);
>> >> -       } else
>> >> -               return -EINVAL;
>> >> -
>> >> -       for (i = 0; i < count; i++)
>> >> -               if (confs[i].pixel_clock == pixel_clock)
>> >> -                       return i;
>> >> -
>> >> -       DRM_DEBUG_KMS("Could not find phy config for %d\n",
> pixel_clock);
>> >> -       return -EINVAL;
>> >> -}
>> >> -
>> >>  static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
>> >>  {
>> >>         struct hdmi_context *hdata = ctx;
>> >> @@ -801,7 +606,7 @@ static int hdmi_check_mode(void *ctx, struct
>> drm_display_mode *mode)
>> >>                 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
>> >>                 false, mode->clock * 1000);
>> >>
>> >> -       ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
>> >> +       ret = exynos_hdmiphy_check_mode(hdata->hdmiphy_dev, mode);
>> >>         if (ret < 0)
>> >>                 return ret;
>> >>         return 0;
>> >> @@ -1302,19 +1107,13 @@ static void hdmi_mode_apply(struct hdmi_context
>> *hdata)
>> >>
>> >>  static void hdmiphy_conf_reset(struct hdmi_context *hdata)
>> >>  {
>> >> -       u8 buffer[2];
>> >>         u32 reg;
>> >>
>> >>         clk_disable_unprepare(hdata->res.sclk_hdmi);
>> >>         clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
>> >>         clk_prepare_enable(hdata->res.sclk_hdmi);
>> >>
>> >> -       /* operation mode */
>> >> -       buffer[0] = 0x1f;
>> >> -       buffer[1] = 0x00;
>> >> -
>> >> -       if (hdata->hdmiphy_port)
>> >> -               i2c_master_send(hdata->hdmiphy_port, buffer, 2);
>> >> +       exynos_hdmiphy_disable(hdata->hdmiphy_dev);
>> >>
>> >>         if (hdata->type == HDMI_TYPE13)
>> >>                 reg = HDMI_V13_PHY_RSTOUT;
>> >> @@ -1342,66 +1141,12 @@ static void hdmiphy_poweroff(struct
>> hdmi_context *hdata)
>> >>                         HDMI_PHY_POWER_OFF_EN);
>> >>  }
>> >>
>> >> -static void hdmiphy_conf_apply(struct hdmi_context *hdata)
>> >> -{
>> >> -       const u8 *hdmiphy_data;
>> >> -       u8 buffer[32];
>> >> -       u8 operation[2];
>> >> -       u8 read_buffer[32] = {0, };
>> >> -       int ret;
>> >> -       int i;
>> >> -
>> >> -       if (!hdata->hdmiphy_port) {
>> >> -               DRM_ERROR("hdmiphy is not attached\n");
>> >> -               return;
>> >> -       }
>> >> -
>> >> -       /* pixel clock */
>> >> -       i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
>> >> -       if (i < 0) {
>> >> -               DRM_ERROR("failed to find hdmiphy conf\n");
>> >> -               return;
>> >> -       }
>> >> -
>> >> -       if (hdata->type == HDMI_TYPE13)
>> >> -               hdmiphy_data = hdmiphy_v13_configs[i].conf;
>> >> -       else
>> >> -               hdmiphy_data = hdmiphy_v14_configs[i].conf;
>> >> -
>> >> -       memcpy(buffer, hdmiphy_data, 32);
>> >> -       ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
>> >> -       if (ret != 32) {
>> >> -               DRM_ERROR("failed to configure HDMIPHY via I2C\n");
>> >> -               return;
>> >> -       }
>> >> -
>> >> -       usleep_range(10000, 12000);
>> >> -
>> >> -       /* operation mode */
>> >> -       operation[0] = 0x1f;
>> >> -       operation[1] = 0x80;
>> >> -
>> >> -       ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
>> >> -       if (ret != 2) {
>> >> -               DRM_ERROR("failed to enable hdmiphy\n");
>> >> -               return;
>> >> -       }
>> >> -
>> >> -       ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
>> >> -       if (ret < 0) {
>> >> -               DRM_ERROR("failed to read hdmiphy config\n");
>> >> -               return;
>> >> -       }
>> >> -
>> >> -       for (i = 0; i < ret; i++)
>> >> -               DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
>> >> -                       "recv [0x%02x]\n", i, buffer[i],
> read_buffer[i]);
>> >> -}
>> >> -
>> >>  static void hdmi_conf_apply(struct hdmi_context *hdata)
>> >>  {
>> >>         hdmiphy_conf_reset(hdata);
>> >> -       hdmiphy_conf_apply(hdata);
>> >> +       exynos_hdmiphy_conf_apply(hdata->hdmiphy_dev);
>> >> +       usleep_range(10000, 12000);
>> >
>> > This delay seems like something that should be in the phy driver,
>> > instead of the hdmi driver (since it seems conceivable that certain
>> > phys might not need a delay or might need a longer delay).
>> >
>>
>> ok. I will move it there.
>>
>> >> +       exynos_hdmiphy_enable(hdata->hdmiphy_dev);
>> >>
>> >>         mutex_lock(&hdata->hdmi_mutex);
>> >>         hdmi_conf_reset(hdata);
>> >> @@ -1434,7 +1179,6 @@ static void hdmi_v13_mode_set(struct hdmi_context
>> *hdata,
>> >>
>> >>         hdata->mode_conf.cea_video_id =
>> >>                 drm_match_cea_mode((struct drm_display_mode *)m);
>> >> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
>> >>
>> >>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
>> >>         hdmi_set_reg(core->h_v_line, 3, (m->htotal << 12) | m->vtotal);
>> >> @@ -1530,7 +1274,6 @@ static void hdmi_v14_mode_set(struct hdmi_context
>> *hdata,
>> >>
>> >>         hdata->mode_conf.cea_video_id =
>> >>                 drm_match_cea_mode((struct drm_display_mode *)m);
>> >> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
>> >>
>> >>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
>> >>         hdmi_set_reg(core->v_line, 2, m->vtotal);
>> >> @@ -1646,6 +1389,8 @@ static void hdmi_mode_set(void *ctx, struct
>> drm_display_mode *mode)
>> >>                 hdmi_v13_mode_set(hdata, mode);
>> >>         else
>> >>                 hdmi_v14_mode_set(hdata, mode);
>> >> +
>> >> +       exynos_hdmiphy_set_mode(hdata->hdmiphy_dev, mode);
>> >
>> > Why set_mode when everything else is mode_set?
>> >
>>
>> I will change it to mode_set.
>>
>> >>  }
>> >>
>> >>  static void hdmi_get_max_resol(void *ctx, unsigned int *width,
>> >> @@ -1824,7 +1569,7 @@ fail:
>> >>         return -ENODEV;
>> >>  }
>> >>
>> >> -static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
>> >> +static struct i2c_client *hdmi_ddc;
>> >>
>> >>  void hdmi_attach_ddc_client(struct i2c_client *ddc)
>> >>  {
>> >> @@ -1832,12 +1577,6 @@ void hdmi_attach_ddc_client(struct i2c_client
>> *ddc)
>> >>                 hdmi_ddc = ddc;
>> >>  }
>> >>
>> >> -void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
>> >> -{
>> >> -       if (hdmiphy)
>> >> -               hdmi_hdmiphy = hdmiphy;
>> >> -}
>> >> -
>> >>  static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
>> >>                                         (struct device *dev)
>> >>  {
>> >> @@ -1862,6 +1601,50 @@ err_data:
>> >>         return NULL;
>> >>  }
>> >>
>> >> +static int hdmi_get_phy_device(struct hdmi_context *hdata)
>> >
>> > "get" is not the proper verb here, "initialize" would be more
>> > appropriate (IMO, of course).
>> >
>>
>> But we don't initialise the phy here. It is just to get the
>> hdmiphy dev* through dt.
>>
>> >> +{
>> >> +       struct device_node *np;
>> >> +       struct i2c_client *client;
>> >> +       struct platform_device *pdev;
>> >> +       int ret;
>> >> +
>> >> +       /* register hdmiphy driver */
>> >> +       ret = exynos_hdmiphy_driver_register();
>> >> +       if (ret) {
>> >> +               DRM_ERROR("failed to register hdmiphy driver\n");
>> >
>> > Printing ret would be useful here.
>>
>> ok.
>> >
>> >> +               goto err;
>> >> +       }
>> >> +
>> >> +       np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
>> >> +       if (!np) {
>> >> +               DRM_ERROR("Could not find 'phy' property\n");
>> >> +               ret = -ENOENT;
>> >> +               goto err;
>> >> +       }
>> >> +
>> >> +       /* find hdmi phy on i2c bus */
>> >> +       client = of_find_i2c_device_by_node(np);
>> >> +       if (client) {
>> >> +               hdata->hdmiphy_dev = &client->dev;
>> >> +               ret = 0;
>> >> +               goto exit;
>> >> +       }
>> >> +
>> >> +       /* find hdmi phy on platform bus */
>> >> +       pdev = of_find_device_by_node(np);
>> >> +       if (pdev) {
>> >> +               hdata->hdmiphy_dev = &pdev->dev;
>> >> +               ret = 0;
>> >> +               goto exit;
>> >> +       }
>> >> +
>> >> +exit:
>> >> +       /* able to find hdmiphy on platform/i2c bus */
>> >> +err:
>> >
>> > Probably just easier to have one "exit" or "out" label that just returns
>> ret.
>>
>> ok.
>> >
>> >> +       of_node_put(np);
>> >> +       return ret;
>> >> +}
>> >> +
>> >>  static struct of_device_id hdmi_match_types[] = {
>> >>         {
>> >>                 .compatible = "samsung,exynos5-hdmi",
>> >> @@ -1939,15 +1722,13 @@ static int hdmi_probe(struct platform_device
>> *pdev)
>> >>
>> >>         hdata->ddc_port = hdmi_ddc;
>> >>
>> >> -       /* hdmiphy i2c driver */
>> >> -       if (i2c_add_driver(&hdmiphy_driver)) {
>> >> -               DRM_ERROR("failed to register hdmiphy i2c driver\n");
>> >> +       ret = hdmi_get_phy_device(hdata);
>> >> +       if (ret) {
>> >> +               DRM_ERROR("failed to get hdmiphy device\n");
>> >
>> > Printing ret would be useful.
>> >
>> >
>> >>                 ret = -ENOENT;
>> >
>> > Why change the return value here?
>> >
>> Yea. Correct. I shouldn't. I will change this.
>>
>> >>                 goto err_ddc;
>> >>         }
>> >>
>> >> -       hdata->hdmiphy_port = hdmi_hdmiphy;
>> >> -
>> >>         hdata->irq = gpio_to_irq(hdata->hpd_gpio);
>> >>         if (hdata->irq < 0) {
>> >>                 DRM_ERROR("failed to get GPIO irq\n");
>> >> @@ -1977,7 +1758,7 @@ static int hdmi_probe(struct platform_device
>> *pdev)
>> >>         return 0;
>> >>
>> >>  err_hdmiphy:
>> >> -       i2c_del_driver(&hdmiphy_driver);
>> >> +       exynos_hdmiphy_driver_unregister();
>> >>  err_ddc:
>> >>         i2c_del_driver(&ddc_driver);
>> >>         return ret;
>> >> @@ -1989,8 +1770,8 @@ static int hdmi_remove(struct platform_device
>> *pdev)
>> >>
>> >>         pm_runtime_disable(dev);
>> >>
>> >> -       /* hdmiphy i2c driver */
>> >> -       i2c_del_driver(&hdmiphy_driver);
>> >> +       /* hdmiphy driver */
>> >> +       exynos_hdmiphy_driver_unregister();
>> >>         /* DDC i2c driver */
>> >>         i2c_del_driver(&ddc_driver);
>> >>
>> >> diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>> b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>> >> index 59abb14..82daa42 100644
>> >> --- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>> >> +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>> >> @@ -15,51 +15,459 @@
>> >>
>> >>  #include <linux/kernel.h>
>> >>  #include <linux/i2c.h>
>> >> -#include <linux/of.h>
>> >> +#include <linux/module.h>
>> >> +#include <linux/pm_runtime.h>
>> >> +#include <linux/clk.h>
>> >>
>> >>  #include "exynos_drm_drv.h"
>> >>  #include "exynos_hdmi.h"
>> >> +#include "exynos_drm_hdmi.h"
>> >> +#include "regs-hdmiphy.h"
>> >>
>> >> +#define HDMIPHY_REG_COUNT      (32)
>> >
>> > This probably belongs in regs-hdmiphy.h instead of here. Also remove the
>> ()
>> >
>>
>> Ok. I will move it there.
>>
>> >>
>> >> -static int hdmiphy_probe(struct i2c_client *client,
>> >> -       const struct i2c_device_id *id)
>> >> +struct hdmiphy_context {
>> >> +       struct device           *dev;
>> >> +       struct hdmiphy_config   *current_conf;
>> >> +
>> >> +       struct hdmiphy_config   *confs;
>> >> +       unsigned int            nr_confs;
>> >> +};
>> >> +
>> >> +struct hdmiphy_config {
>> >> +       int pixel_clock;
>> >> +       u8 conf[HDMIPHY_REG_COUNT];
>> >> +};
>> >> +
>> >> +struct hdmiphy_drv_data {
>> >> +       struct hdmiphy_config *confs;
>> >> +       unsigned int count;
>> >> +};
>> >> +
>> >> +/* list of all required phy config settings */
>> >> +static struct hdmiphy_config hdmiphy_4212_configs[] = {
>> >> +       {
>> >> +               .pixel_clock = 25200000,
>> >> +               .conf = {
>> >> +                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
>> >> +                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 27000000,
>> >> +               .conf = {
>> >> +                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
>> >> +                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 27027000,
>> >> +               .conf = {
>> >> +                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
>> >> +                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 36000000,
>> >> +               .conf = {
>> >> +                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
>> >> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 40000000,
>> >> +               .conf = {
>> >> +                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
>> >> +                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 65000000,
>> >> +               .conf = {
>> >> +                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
>> >> +                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 74176000,
>> >> +               .conf = {
>> >> +                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
>> >> +                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 74250000,
>> >> +               .conf = {
>> >> +                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
>> >> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 83500000,
>> >> +               .conf = {
>> >> +                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
>> >> +                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 106500000,
>> >> +               .conf = {
>> >> +                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
>> >> +                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 108000000,
>> >> +               .conf = {
>> >> +                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
>> >> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 146250000,
>> >> +               .conf = {
>> >> +                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
>> >> +                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 148500000,
>> >> +               .conf = {
>> >> +                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
>> >> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
>> >> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
>> >> +                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
>> >> +               },
>> >> +       },
>> >> +};
>> >> +
>> >> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
>> >> +       {
>> >> +               .pixel_clock = 27000000,
>> >> +               .conf = {
>> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
>> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 27027000,
>> >> +               .conf = {
>> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
>> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 74176000,
>> >> +               .conf = {
>> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
>> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
>> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 74250000,
>> >> +               .conf = {
>> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
>> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
>> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
>> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
>> >> +               },
>> >> +       },
>> >> +       {
>> >> +               .pixel_clock = 148500000,
>> >> +               .conf = {
>> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
>> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
>> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
>> >> +               },
>> >> +       },
>> >> +};
>> >> +
>> >
>> > Are you aware of the effort to move these to dt? Since these are
>> > board-specific values, it seems incorrect to apply them universally.
>> > Shirish has uploaded a patch to the chromium review site to push these
>> > into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
>> > you can work that into your patch set?
>> >
>
> Are these really board-specific values?

According to your hardware people:

"If the signal pattern doesn't change for new board, the phy setting
is same as the current board. But if changed, you need to confirm with
measurement of signals, because it may vary slightly by resistance of
board pattern"

That indicates to me that we might need to tweak these on a per-board basis.

In the 5420 datasheet, there are a few register descriptions available
for the phy. 0x145D0004 is CLK_SEL which seems like it would be
board-specific, same with TX_* registers.

Sean



> I think they are SoC-specific
> values, and it's better to define them in the driver. For this, I gave
> already comments to Shirish why these constraints should be placed in
> driver. For more detail, you can also refer to the below link,
>
> http://www.mail-archive.com/devicetree-discuss@lists.ozlabs.org/msg36691.htm
> l
>
> Thanks,
> Inki Dae
>
>>
>> I have gone through these patches. I am adding Shirish here for further
>> discussion on these changes. he can explain better.
>>
>> >
>> >> +static struct hdmiphy_config *hdmiphy_find_conf(struct hdmiphy_context
>> *hdata,
>> >> +                       const struct drm_display_mode *mode)
>> >> +{
>> >> +       int i;
>> >> +
>> >> +       for (i = 0; i < hdata->nr_confs; i++)
>> >> +               if (hdata->confs[i].pixel_clock == (mode->clock *
> 1000))
>> >> +                       return &hdata->confs[i];
>> >> +
>> >> +       return NULL;
>> >> +}
>> >> +
>> >> +static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata,
>> >> +                       u32 reg_offset, u8 value)
>> >> +{
>> >> +       if (reg_offset >= HDMIPHY_REG_COUNT)
>> >> +               return -EINVAL;
>> >> +
>> >> +       if (i2c_verify_client(hdata->dev)) {
>> >
>> > Is this necessary?
>>
>> Based on this check, I was deciding that given dev is i2c or
>> platform device. But now when we agreed to split drivers to
>> phy and plf driver, I will remove this.
>>
>> >
>> >> +               u8 buffer[2];
>> >> +               int ret;
>> >> +
>> >> +               buffer[0] = reg_offset;
>> >> +               buffer[1] = value;
>> >> +
>> >> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
>> >> +                               buffer, 2);
>> >> +               if (ret == 2)
>> >> +                       return 0;
>> >> +               return ret;
>> >> +       } else {
>> >> +               return -EINVAL;
>> >> +       }
>> >> +}
>> >> +
>> >> +static int hdmiphy_reg_write_buf(struct hdmiphy_context *hdata,
>> >> +                       u32 reg_offset, const u8 *buf, u32 len)
>> >> +{
>> >> +       if ((reg_offset + len) > HDMIPHY_REG_COUNT)
>> >> +               return -EINVAL;
>> >> +
>> >> +       if (i2c_verify_client(hdata->dev)) {
>> >
>> > Is this necessary?
>> >
>> >
>> >> +               int ret;
>> >> +
>> >> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
>> >> +                               buf, len);
>> >
>> > Does this actually work? You don't seem to be using reg_offset anywhere.
>> >
>>
>> reg_offset is not required here. I should remove this. This
>> procedure is to write the complete buf starting from 0.
>> hdmiphy_reg_writeb is supposed to be used for writing
>> value from some offset.
>>
>> >> +               if (ret == len)
>> >> +                       return 0;
>> >> +               return ret;
>> >> +       } else {
>> >> +               return -EINVAL;
>> >> +       }
>> >> +}
>> >> +
>> >> +int exynos_hdmiphy_check_mode(struct device *dev,
>> >> +                       struct drm_display_mode *mode)
>> >>  {
>> >> -       hdmi_attach_hdmiphy_client(client);
>> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> >> +       const struct hdmiphy_config *conf;
>> >> +
>> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> >
>> > Maybe you can merge this debug message with the one below.
>> >
>>
>> ok.
>>
>> >>
>> >> -       dev_info(&client->adapter->dev, "attached s5p_hdmiphy "
>> >> -               "into i2c adapter successfully\n");
>> >> +       if (!hdata) {
>> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> >> +               return -EINVAL;
>> >> +       }
>> >
>> > Can this happen? I think the phy driver registration should be
>> > synchronous with the hdmi driver registration. As such, it shouldn't
>> > be possible to get a check_mode callback until it's all set up.
>> >
>>
>> I will confirm on this.
>>
>> >>
>> >> +       DRM_DEBUG("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
>> >> +               mode->hdisplay, mode->vdisplay,
>> >> +               mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE)
>> >> +               ? true : false, mode->clock * 1000);
>> >> +
>> >> +       conf = hdmiphy_find_conf(hdata, mode);
>> >> +       if (!conf) {
>> >> +               DRM_DEBUG("Display Mode is not supported.\n");
>> >> +               return -EINVAL;
>> >> +       }
>> >>         return 0;
>> >>  }
>> >>
>> >> -static int hdmiphy_remove(struct i2c_client *client)
>> >> +int exynos_hdmiphy_set_mode(struct device *dev,
>> >> +                       struct drm_display_mode *mode)
>> >>  {
>> >> -       dev_info(&client->adapter->dev, "detached s5p_hdmiphy "
>> >> -               "from i2c adapter successfully\n");
>> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> >> +
>> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> >> +
>> >> +       hdata->current_conf = hdmiphy_find_conf(hdata, mode);
>> >> +
>> >> +       if (!hdata) {
>> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> >> +               return -EINVAL;
>> >> +       }
>> >
>> > I really hope this check isn't necessary, since you've already
>> > dereferenced it 2 lines up :) See my comment above, I don't think you
>> > can ever hit this.
>> >
>> >>
>> >> +       if (!hdata->current_conf) {
>> >> +               DRM_ERROR("Display Mode is not supported.\n");
>> >> +               return -EINVAL;
>> >> +       }
>> >>         return 0;
>> >>  }
>> >>
>> >> -static struct of_device_id hdmiphy_match_types[] = {
>> >> +void exynos_hdmiphy_enable(struct device *dev)
>> >> +{
>> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> >> +       int ret;
>> >> +
>> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> >> +
>> >> +       if (!hdata) {
>> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> >> +               return;
>> >> +       }
>> >
>> > Same comment as above.
>> >
>> >> +
>> >> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
>> >> +                       HDMIPHY_MODE_EN);
>> >> +       if (ret < 0) {
>> >> +               DRM_ERROR("failed to disable hdmiphy.\n");
>> >> +               return;
>> >> +       }
>> >> +}
>> >> +
>> >> +void exynos_hdmiphy_disable(struct device *dev)
>> >> +{
>> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> >> +       int ret;
>> >> +
>> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> >> +
>> >> +       if (!hdata) {
>> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> >> +               return;
>> >> +       }
>> >> +
>> >> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, 0);
>> >> +       if (ret < 0) {
>> >> +               DRM_ERROR("failed to enable hdmiphy.\n");
>> >
>> > If you're not going to return the error code, at least print it here.
>> >
>>
>> ok.
>>
>> >> +               return;
>> >> +       }
>> >> +}
>> >> +
>> >> +int exynos_hdmiphy_conf_apply(struct device *dev)
>> >> +{
>> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> >> +       const u8 *hdmiphy_data;
>> >> +       int ret;
>> >> +
>> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> >> +
>> >> +       if (!hdata) {
>> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> >> +               return -EINVAL;
>> >> +       }
>> >> +
>> >> +       /* pixel clock */
>> >
>> > I don't understand this comment.
>> >
>>
>> I will remove this.
>>
>> >> +       if (hdata->current_conf)
>> >> +               hdmiphy_data = hdata->current_conf->conf;
>> >> +       else
>> >> +               return -EINVAL;
>> >> +
>> >> +       ret = hdmiphy_reg_write_buf(hdata, 0, hdmiphy_data,
>> >> +                       HDMIPHY_REG_COUNT);
>> >
>> > I think the only reason this works is b/c you're writing to register
>> offset 0.
>> >
>> >> +       if (ret) {
>> >> +               DRM_ERROR("failed to configure hdmiphy.\n");
>> >> +               return -EINVAL;
>> >
>> > Why don't you return ret?
>> >
>>
>> ok.
>>
>> >> +       }
>> >> +       return 0;
>> >> +}
>> >> +
>> >> +static struct hdmiphy_drv_data exynos4212_hdmiphy_drv_data = {
>> >> +       .confs = hdmiphy_4212_configs,
>> >> +       .count = ARRAY_SIZE(hdmiphy_4212_configs)
>> >> +};
>> >> +
>> >> +static struct hdmiphy_drv_data exynos4210_hdmiphy_drv_data = {
>> >> +       .confs = hdmiphy_4210_configs,
>> >> +       .count = ARRAY_SIZE(hdmiphy_4210_configs)
>> >> +};
>> >> +
>> >> +static struct of_device_id hdmiphy_i2c_device_match_types[] = {
>> >>         {
>> >>                 .compatible = "samsung,exynos5-hdmiphy",
>> >> +               .data   = &exynos4212_hdmiphy_drv_data,
>> >>         }, {
>> >>                 .compatible = "samsung,exynos4210-hdmiphy",
>> >> +               .data   = &exynos4210_hdmiphy_drv_data,
>> >>         }, {
>> >>                 .compatible = "samsung,exynos4212-hdmiphy",
>> >> +               .data   = &exynos4212_hdmiphy_drv_data,
>> >>         }, {
>> >>                 /* end node */
>> >>         }
>> >>  };
>> >>
>> >> -struct i2c_driver hdmiphy_driver = {
>> >> +static int hdmiphy_i2c_device_probe(struct i2c_client *client,
>> >> +       const struct i2c_device_id *id)
>> >> +{
>> >> +       struct device *dev = &client->dev;
>> >> +       struct hdmiphy_context *hdata;
>> >> +       struct hdmiphy_drv_data *drv;
>> >> +       const struct of_device_id *match;
>> >> +
>> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> >> +
>> >> +       hdata = devm_kzalloc(dev, sizeof(*hdata), GFP_KERNEL);
>> >> +       if (!hdata) {
>> >> +               DRM_ERROR("failed to allocate hdmiphy context.\n");
>> >> +               return -ENOMEM;
>> >> +       }
>> >> +
>> >> +       match = of_match_node(of_match_ptr(
>> >> +               hdmiphy_i2c_device_match_types),
>> >> +               dev->of_node);
>> >> +
>> >> +       if (match == NULL)
>> >> +               return -ENODEV;
>> >> +
>> >> +       drv = (struct hdmiphy_drv_data *)match->data;
>> >> +
>> >> +       hdata->dev = dev;
>> >> +       hdata->confs = drv->confs;
>> >> +       hdata->nr_confs = drv->count;
>> >> +
>> >> +       i2c_set_clientdata(client, hdata);
>> >> +
>> >> +       return 0;
>> >> +}
>> >> +
>> >> +static const struct i2c_device_id hdmiphy_id[] = {
>> >> +       { },
>> >> +};
>> >> +
>> >> +struct i2c_driver hdmiphy_i2c_driver = {
>> >>         .driver = {
>> >>                 .name   = "exynos-hdmiphy",
>> >>                 .owner  = THIS_MODULE,
>> >> -               .of_match_table = hdmiphy_match_types,
>> >> +               .of_match_table = of_match_ptr(
>> >> +                               hdmiphy_i2c_device_match_types),
>> >>         },
>> >> -       .probe          = hdmiphy_probe,
>> >> -       .remove         = hdmiphy_remove,
>> >> +       .id_table               = hdmiphy_id,
>> >> +       .probe          = hdmiphy_i2c_device_probe,
>> >>         .command                = NULL,
>> >>  };
>> >> -EXPORT_SYMBOL(hdmiphy_driver);
>> >> +
>> >> +int exynos_hdmiphy_driver_register(void)
>> >> +{
>> >> +       int ret;
>> >> +
>> >> +       ret = i2c_add_driver(&hdmiphy_i2c_driver);
>> >> +       if (ret)
>> >> +               return ret;
>> >> +
>> >> +       return 0;
>> >> +}
>> >> +
>> >> +void exynos_hdmiphy_driver_unregister(void)
>> >> +{
>> >> +       i2c_del_driver(&hdmiphy_i2c_driver);
>> >> +}
>> >> diff --git a/drivers/gpu/drm/exynos/regs-hdmiphy.h
>> b/drivers/gpu/drm/exynos/regs-hdmiphy.h
>> >> new file mode 100644
>> >> index 0000000..d3f9d87
>> >> --- /dev/null
>> >> +++ b/drivers/gpu/drm/exynos/regs-hdmiphy.h
>> >> @@ -0,0 +1,35 @@
>> >> +/*
>> >> + *
>> >> + *  regs-hdmiphy.h
>> >> + *
>> >> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
>> >> + * http://www.samsung.com/
>> >> + *
>> >> + * HDMI-PHY register header file for Samsung HDMI driver
>> >> + *
>> >> + * This program is free software; you can redistribute it and/or
>> modify
>> >> + * it under the terms of the GNU General Public License version 2 as
>> >> + * published by the Free Software Foundation.
>> >> +*/
>> >> +
>> >> +#ifndef SAMSUNG_REGS_HDMIPHY_H
>> >> +#define SAMSUNG_REGS_HDMIPHY_H
>> >> +
>> >> +/*
>> >> + * Register part
>> >> +*/
>> >> +#define HDMIPHY_MODE_SET_DONE  (0x1f)
>> >> +
>> >> +/*
>> >> + * Bit definition part
>> >> + */
>> >> +
>> >> +/* HDMIPHY_MODE_SET_DONE */
>> >> +#define HDMIPHY_MODE_EN                (1 << 7)
>> >> +
>> >> +/* hdmiphy pmu control bits */
>> >> +#define PMU_HDMI_PHY_CONTROL_MASK      (1 << 0)
>> >> +#define PMU_HDMI_PHY_ENABLE            (1)
>> >> +#define PMU_HDMI_PHY_DISABLE           (0)
>> >
>> >
>> > You don't need the () around simple values
>> >
>>
>> ok.
>>
>> We also discussed previously to keep independent i2c and
>> platform phy drivers in exynos_hdmiphy_i2c.c and
>> exynos_hdmiphy_platform.c respectively, which will duplicate
>> the code to some extent.
>>
>> Second point is to implement exynos_i2c_hdmiphy_get_ops()
>> and exynos_platform_hdmiphy_get_ops() to get access to all
>> callbacks. This will limit the exposure of phy callbacks to the
>> phy controller.
>>
>> Please share your views on this.
>>
>> Regards,
>> Rahul Sharma.
>>
>> >> +
>> >> +#endif /* SAMSUNG_REGS_HDMIPHY_H */
>> >> --
>> >> 1.7.10.4
>> >>
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-04 14:51         ` Sean Paul
@ 2013-09-05  4:16           ` Inki Dae
  2013-09-05  4:43             ` Rahul Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Inki Dae @ 2013-09-05  4:16 UTC (permalink / raw)
  To: 'Sean Paul'
  Cc: 'Rahul Sharma', 'Rahul Sharma',
	'linux-samsung-soc', 'dri-devel',
	'kgene.kim', 'sw0312.kim', 'Lucas Stach',
	'Tomasz Figa', 'Sylwester Nawrocki',
	'sunil joshi', 'Shirish S'



> -----Original Message-----
> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-soc-
> owner@vger.kernel.org] On Behalf Of Sean Paul
> Sent: Wednesday, September 04, 2013 11:52 PM
> To: Inki Dae
> Cc: Rahul Sharma; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
> Shirish S
> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
> driver
> 
> On Wed, Sep 4, 2013 at 3:37 AM, Inki Dae <inki.dae@samsung.com> wrote:
> >
> >
> >> -----Original Message-----
> >> From: Rahul Sharma [mailto:r.sh.open@gmail.com]
> >> Sent: Wednesday, September 04, 2013 2:48 PM
> >> To: Sean Paul
> >> Cc: Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim; sw0312.kim;
> >> InKi Dae; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
> >> shirish@chromium.org
> >> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
> hdmiphy
> >> driver
> >>
> >> Thanks Sean,
> >>
> >> On 3 September 2013 20:15, Sean Paul <seanpaul@chromium.org> wrote:
> >> > A few comments.
> >> >
> >> > On Fri, Aug 30, 2013 at 2:59 AM, Rahul Sharma
> <rahul.sharma@samsung.com>
> >> wrote:
> >> >> Exynos hdmiphy operations and configs are kept inside
> >> >> the hdmi driver. Hdmiphy related code is tightly coupled
> >> >> with hdmi IP driver.
> >> >>
> >> >> This patche moves hdmiphy related code to hdmiphy driver.
> >> >
> >> > s/patche/patch
> >> >
> >> ok.
> >> >> It will help in cleanly supporting the hdmiphy variations
> >> >> in further SoCs.
> >> >>
> >> >> Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
> >> >> ---
> >> >>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
> >> >>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   11 +
> >> >>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  343
> > +++------------
> >> >>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  438
> >> +++++++++++++++++++-
> >> >>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 ++
> >> >>  5 files changed, 533 insertions(+), 296 deletions(-)
> >> >>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
> >> >>
> >> >> diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
> >> b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
> >> >> index 50decf8..240eca5 100644
> >> >> --- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
> >> >> +++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
> >> >> @@ -25,6 +25,7 @@ Required properties:
> >> >>                 sclk_pixel.
> >> >>  - clock-names: aliases as per driver requirements for above clock
> IDs:
> >> >>         "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and
> > "mout_hdmi".
> >> >> +- phy: it points to hdmiphy dt node.
> >> >>  Example:
> >> >>
> >> >>         hdmi {
> >> >> @@ -32,4 +33,5 @@ Example:
> >> >>                 reg = <0x14530000 0x100000>;
> >> >>                 interrupts = <0 95 0>;
> >> >>                 hpd-gpio = <&gpx3 7 1>;
> >> >> +               phy = <&hdmiphy>;
> >> >>         };
> >> >> diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> >> b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> >> >> index 724cab1..1c839f8 100644
> >> >> --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> >> >> +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> >> >> @@ -64,4 +64,15 @@ void exynos_hdmi_drv_attach(struct
> >> exynos_drm_hdmi_context *ctx);
> >> >>  void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx);
> >> >>  void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
> >> >>  void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
> >> >> +
> >> >> +int exynos_hdmiphy_driver_register(void);
> >> >> +void exynos_hdmiphy_driver_unregister(void);
> >> >> +
> >> >> +void exynos_hdmiphy_enable(struct device *dev);
> >> >> +void exynos_hdmiphy_disable(struct device *dev);
> >> >> +int exynos_hdmiphy_check_mode(struct device *dev,
> >> >> +                               struct drm_display_mode *mode);
> >> >> +int exynos_hdmiphy_set_mode(struct device *dev,
> >> >> +                               struct drm_display_mode *mode);
> >> >> +int exynos_hdmiphy_conf_apply(struct device *dev);
> >> >>  #endif
> >> >> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c
> >> b/drivers/gpu/drm/exynos/exynos_hdmi.c
> >> >> index f67ffca..3af4e4c 100644
> >> >> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> >> >> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> >> >> @@ -34,6 +34,8 @@
> >> >>  #include <linux/io.h>
> >> >>  #include <linux/of.h>
> >> >>  #include <linux/of_gpio.h>
> >> >> +#include <linux/of_i2c.h>
> >> >> +#include <linux/of_platform.h>
> >> >>
> >> >>  #include <drm/exynos_drm.h>
> >> >>
> >> >> @@ -172,7 +174,6 @@ struct hdmi_v14_conf {
> >> >>  };
> >> >>
> >> >>  struct hdmi_conf_regs {
> >> >> -       int pixel_clock;
> >> >>         int cea_video_id;
> >> >>         union {
> >> >>                 struct hdmi_v13_conf v13_conf;
> >> >> @@ -193,9 +194,9 @@ struct hdmi_context {
> >> >>         int                             irq;
> >> >>
> >> >>         struct i2c_client               *ddc_port;
> >> >> -       struct i2c_client               *hdmiphy_port;
> >> >> +       struct device                   *hdmiphy_dev;
> >> >>
> >> >> -       /* current hdmiphy conf regs */
> >> >> +       /* current hdmi ip configuration registers. */
> >> >>         struct hdmi_conf_regs           mode_conf;
> >> >>
> >> >>         struct hdmi_resources           res;
> >> >> @@ -205,180 +206,6 @@ struct hdmi_context {
> >> >>         enum hdmi_type                  type;
> >> >>  };
> >> >>
> >> >> -struct hdmiphy_config {
> >> >> -       int pixel_clock;
> >> >> -       u8 conf[32];
> >> >> -};
> >> >> -
> >> >> -/* list of phy config settings */
> >> >> -static const struct hdmiphy_config hdmiphy_v13_configs[] = {
> >> >> -       {
> >> >> -               .pixel_clock = 27000000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30,
0x40,
> >> >> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
0x87,
> >> >> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
0xE0,
> >> >> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
0x00,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 27027000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09,
0x64,
> >> >> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
0x87,
> >> >> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
0xE0,
> >> >> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
0x00,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 74176000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef,
0x5B,
> >> >> -                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54,
0xb9,
> >> >> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
0xE0,
> >> >> -                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00,
0x00,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 74250000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8,
0x40,
> >> >> -                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54,
0xba,
> >> >> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10,
0xe0,
> >> >> -                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00,
0x00,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 148500000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8,
0x40,
> >> >> -                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54,
0xba,
> >> >> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10,
0xE0,
> >> >> -                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00,
0x00,
> >> >> -               },
> >> >> -       },
> >> >> -};
> >> >> -
> >> >> -static const struct hdmiphy_config hdmiphy_v14_configs[] = {
> >> >> -       {
> >> >> -               .pixel_clock = 25200000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00,
0x08,
> >> >> -                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01,
0x80,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 27000000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc,
0x20,
> >> >> -                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01,
0x80,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 27027000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12,
0x08,
> >> >> -                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01,
0x00,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 36000000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00,
0x08,
> >> >> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01,
0x80,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 40000000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00,
0x08,
> >> >> -                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01,
0x80,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 65000000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a,
0x08,
> >> >> -                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01,
0x80,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 74176000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde,
0x08,
> >> >> -                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01,
0x80,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 74250000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8,
0x08,
> >> >> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01,
0x00,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 83500000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb,
0x08,
> >> >> -                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01,
0x80,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 106500000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09,
0x08,
> >> >> -                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01,
0x80,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 108000000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00,
0x08,
> >> >> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01,
0x80,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 146250000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd,
0x08,
> >> >> -                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01,
0x80,
> >> >> -               },
> >> >> -       },
> >> >> -       {
> >> >> -               .pixel_clock = 148500000,
> >> >> -               .conf = {
> >> >> -                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8,
0x08,
> >> >> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac,
0x80,
> >> >> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> -                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01,
0x00,
> >> >> -               },
> >> >> -       },
> >> >> -};
> >> >> -
> >> >>  struct hdmi_infoframe {
> >> >>         enum HDMI_PACKET_TYPE type;
> >> >>         u8 ver;
> >> >> @@ -769,28 +596,6 @@ static struct edid *hdmi_get_edid(void *ctx,
> >> struct drm_connector *connector)
> >> >>         return raw_edid;
> >> >>  }
> >> >>
> >> >> -static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32
> >> pixel_clock)
> >> >> -{
> >> >> -       const struct hdmiphy_config *confs;
> >> >> -       int count, i;
> >> >> -
> >> >> -       if (hdata->type == HDMI_TYPE13) {
> >> >> -               confs = hdmiphy_v13_configs;
> >> >> -               count = ARRAY_SIZE(hdmiphy_v13_configs);
> >> >> -       } else if (hdata->type == HDMI_TYPE14) {
> >> >> -               confs = hdmiphy_v14_configs;
> >> >> -               count = ARRAY_SIZE(hdmiphy_v14_configs);
> >> >> -       } else
> >> >> -               return -EINVAL;
> >> >> -
> >> >> -       for (i = 0; i < count; i++)
> >> >> -               if (confs[i].pixel_clock == pixel_clock)
> >> >> -                       return i;
> >> >> -
> >> >> -       DRM_DEBUG_KMS("Could not find phy config for %d\n",
> > pixel_clock);
> >> >> -       return -EINVAL;
> >> >> -}
> >> >> -
> >> >>  static int hdmi_check_mode(void *ctx, struct drm_display_mode
*mode)
> >> >>  {
> >> >>         struct hdmi_context *hdata = ctx;
> >> >> @@ -801,7 +606,7 @@ static int hdmi_check_mode(void *ctx, struct
> >> drm_display_mode *mode)
> >> >>                 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
> >> >>                 false, mode->clock * 1000);
> >> >>
> >> >> -       ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
> >> >> +       ret = exynos_hdmiphy_check_mode(hdata->hdmiphy_dev, mode);
> >> >>         if (ret < 0)
> >> >>                 return ret;
> >> >>         return 0;
> >> >> @@ -1302,19 +1107,13 @@ static void hdmi_mode_apply(struct
> hdmi_context
> >> *hdata)
> >> >>
> >> >>  static void hdmiphy_conf_reset(struct hdmi_context *hdata)
> >> >>  {
> >> >> -       u8 buffer[2];
> >> >>         u32 reg;
> >> >>
> >> >>         clk_disable_unprepare(hdata->res.sclk_hdmi);
> >> >>         clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
> >> >>         clk_prepare_enable(hdata->res.sclk_hdmi);
> >> >>
> >> >> -       /* operation mode */
> >> >> -       buffer[0] = 0x1f;
> >> >> -       buffer[1] = 0x00;
> >> >> -
> >> >> -       if (hdata->hdmiphy_port)
> >> >> -               i2c_master_send(hdata->hdmiphy_port, buffer, 2);
> >> >> +       exynos_hdmiphy_disable(hdata->hdmiphy_dev);
> >> >>
> >> >>         if (hdata->type == HDMI_TYPE13)
> >> >>                 reg = HDMI_V13_PHY_RSTOUT;
> >> >> @@ -1342,66 +1141,12 @@ static void hdmiphy_poweroff(struct
> >> hdmi_context *hdata)
> >> >>                         HDMI_PHY_POWER_OFF_EN);
> >> >>  }
> >> >>
> >> >> -static void hdmiphy_conf_apply(struct hdmi_context *hdata)
> >> >> -{
> >> >> -       const u8 *hdmiphy_data;
> >> >> -       u8 buffer[32];
> >> >> -       u8 operation[2];
> >> >> -       u8 read_buffer[32] = {0, };
> >> >> -       int ret;
> >> >> -       int i;
> >> >> -
> >> >> -       if (!hdata->hdmiphy_port) {
> >> >> -               DRM_ERROR("hdmiphy is not attached\n");
> >> >> -               return;
> >> >> -       }
> >> >> -
> >> >> -       /* pixel clock */
> >> >> -       i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
> >> >> -       if (i < 0) {
> >> >> -               DRM_ERROR("failed to find hdmiphy conf\n");
> >> >> -               return;
> >> >> -       }
> >> >> -
> >> >> -       if (hdata->type == HDMI_TYPE13)
> >> >> -               hdmiphy_data = hdmiphy_v13_configs[i].conf;
> >> >> -       else
> >> >> -               hdmiphy_data = hdmiphy_v14_configs[i].conf;
> >> >> -
> >> >> -       memcpy(buffer, hdmiphy_data, 32);
> >> >> -       ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
> >> >> -       if (ret != 32) {
> >> >> -               DRM_ERROR("failed to configure HDMIPHY via I2C\n");
> >> >> -               return;
> >> >> -       }
> >> >> -
> >> >> -       usleep_range(10000, 12000);
> >> >> -
> >> >> -       /* operation mode */
> >> >> -       operation[0] = 0x1f;
> >> >> -       operation[1] = 0x80;
> >> >> -
> >> >> -       ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
> >> >> -       if (ret != 2) {
> >> >> -               DRM_ERROR("failed to enable hdmiphy\n");
> >> >> -               return;
> >> >> -       }
> >> >> -
> >> >> -       ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
> >> >> -       if (ret < 0) {
> >> >> -               DRM_ERROR("failed to read hdmiphy config\n");
> >> >> -               return;
> >> >> -       }
> >> >> -
> >> >> -       for (i = 0; i < ret; i++)
> >> >> -               DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
> >> >> -                       "recv [0x%02x]\n", i, buffer[i],
> > read_buffer[i]);
> >> >> -}
> >> >> -
> >> >>  static void hdmi_conf_apply(struct hdmi_context *hdata)
> >> >>  {
> >> >>         hdmiphy_conf_reset(hdata);
> >> >> -       hdmiphy_conf_apply(hdata);
> >> >> +       exynos_hdmiphy_conf_apply(hdata->hdmiphy_dev);
> >> >> +       usleep_range(10000, 12000);
> >> >
> >> > This delay seems like something that should be in the phy driver,
> >> > instead of the hdmi driver (since it seems conceivable that certain
> >> > phys might not need a delay or might need a longer delay).
> >> >
> >>
> >> ok. I will move it there.
> >>
> >> >> +       exynos_hdmiphy_enable(hdata->hdmiphy_dev);
> >> >>
> >> >>         mutex_lock(&hdata->hdmi_mutex);
> >> >>         hdmi_conf_reset(hdata);
> >> >> @@ -1434,7 +1179,6 @@ static void hdmi_v13_mode_set(struct
> hdmi_context
> >> *hdata,
> >> >>
> >> >>         hdata->mode_conf.cea_video_id =
> >> >>                 drm_match_cea_mode((struct drm_display_mode *)m);
> >> >> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
> >> >>
> >> >>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
> >> >>         hdmi_set_reg(core->h_v_line, 3, (m->htotal << 12) |
m->vtotal);
> >> >> @@ -1530,7 +1274,6 @@ static void hdmi_v14_mode_set(struct
> hdmi_context
> >> *hdata,
> >> >>
> >> >>         hdata->mode_conf.cea_video_id =
> >> >>                 drm_match_cea_mode((struct drm_display_mode *)m);
> >> >> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
> >> >>
> >> >>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
> >> >>         hdmi_set_reg(core->v_line, 2, m->vtotal);
> >> >> @@ -1646,6 +1389,8 @@ static void hdmi_mode_set(void *ctx, struct
> >> drm_display_mode *mode)
> >> >>                 hdmi_v13_mode_set(hdata, mode);
> >> >>         else
> >> >>                 hdmi_v14_mode_set(hdata, mode);
> >> >> +
> >> >> +       exynos_hdmiphy_set_mode(hdata->hdmiphy_dev, mode);
> >> >
> >> > Why set_mode when everything else is mode_set?
> >> >
> >>
> >> I will change it to mode_set.
> >>
> >> >>  }
> >> >>
> >> >>  static void hdmi_get_max_resol(void *ctx, unsigned int *width,
> >> >> @@ -1824,7 +1569,7 @@ fail:
> >> >>         return -ENODEV;
> >> >>  }
> >> >>
> >> >> -static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
> >> >> +static struct i2c_client *hdmi_ddc;
> >> >>
> >> >>  void hdmi_attach_ddc_client(struct i2c_client *ddc)
> >> >>  {
> >> >> @@ -1832,12 +1577,6 @@ void hdmi_attach_ddc_client(struct i2c_client
> >> *ddc)
> >> >>                 hdmi_ddc = ddc;
> >> >>  }
> >> >>
> >> >> -void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
> >> >> -{
> >> >> -       if (hdmiphy)
> >> >> -               hdmi_hdmiphy = hdmiphy;
> >> >> -}
> >> >> -
> >> >>  static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
> >> >>                                         (struct device *dev)
> >> >>  {
> >> >> @@ -1862,6 +1601,50 @@ err_data:
> >> >>         return NULL;
> >> >>  }
> >> >>
> >> >> +static int hdmi_get_phy_device(struct hdmi_context *hdata)
> >> >
> >> > "get" is not the proper verb here, "initialize" would be more
> >> > appropriate (IMO, of course).
> >> >
> >>
> >> But we don't initialise the phy here. It is just to get the
> >> hdmiphy dev* through dt.
> >>
> >> >> +{
> >> >> +       struct device_node *np;
> >> >> +       struct i2c_client *client;
> >> >> +       struct platform_device *pdev;
> >> >> +       int ret;
> >> >> +
> >> >> +       /* register hdmiphy driver */
> >> >> +       ret = exynos_hdmiphy_driver_register();
> >> >> +       if (ret) {
> >> >> +               DRM_ERROR("failed to register hdmiphy driver\n");
> >> >
> >> > Printing ret would be useful here.
> >>
> >> ok.
> >> >
> >> >> +               goto err;
> >> >> +       }
> >> >> +
> >> >> +       np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
> >> >> +       if (!np) {
> >> >> +               DRM_ERROR("Could not find 'phy' property\n");
> >> >> +               ret = -ENOENT;
> >> >> +               goto err;
> >> >> +       }
> >> >> +
> >> >> +       /* find hdmi phy on i2c bus */
> >> >> +       client = of_find_i2c_device_by_node(np);
> >> >> +       if (client) {
> >> >> +               hdata->hdmiphy_dev = &client->dev;
> >> >> +               ret = 0;
> >> >> +               goto exit;
> >> >> +       }
> >> >> +
> >> >> +       /* find hdmi phy on platform bus */
> >> >> +       pdev = of_find_device_by_node(np);
> >> >> +       if (pdev) {
> >> >> +               hdata->hdmiphy_dev = &pdev->dev;
> >> >> +               ret = 0;
> >> >> +               goto exit;
> >> >> +       }
> >> >> +
> >> >> +exit:
> >> >> +       /* able to find hdmiphy on platform/i2c bus */
> >> >> +err:
> >> >
> >> > Probably just easier to have one "exit" or "out" label that just
> returns
> >> ret.
> >>
> >> ok.
> >> >
> >> >> +       of_node_put(np);
> >> >> +       return ret;
> >> >> +}
> >> >> +
> >> >>  static struct of_device_id hdmi_match_types[] = {
> >> >>         {
> >> >>                 .compatible = "samsung,exynos5-hdmi",
> >> >> @@ -1939,15 +1722,13 @@ static int hdmi_probe(struct platform_device
> >> *pdev)
> >> >>
> >> >>         hdata->ddc_port = hdmi_ddc;
> >> >>
> >> >> -       /* hdmiphy i2c driver */
> >> >> -       if (i2c_add_driver(&hdmiphy_driver)) {
> >> >> -               DRM_ERROR("failed to register hdmiphy i2c
driver\n");
> >> >> +       ret = hdmi_get_phy_device(hdata);
> >> >> +       if (ret) {
> >> >> +               DRM_ERROR("failed to get hdmiphy device\n");
> >> >
> >> > Printing ret would be useful.
> >> >
> >> >
> >> >>                 ret = -ENOENT;
> >> >
> >> > Why change the return value here?
> >> >
> >> Yea. Correct. I shouldn't. I will change this.
> >>
> >> >>                 goto err_ddc;
> >> >>         }
> >> >>
> >> >> -       hdata->hdmiphy_port = hdmi_hdmiphy;
> >> >> -
> >> >>         hdata->irq = gpio_to_irq(hdata->hpd_gpio);
> >> >>         if (hdata->irq < 0) {
> >> >>                 DRM_ERROR("failed to get GPIO irq\n");
> >> >> @@ -1977,7 +1758,7 @@ static int hdmi_probe(struct platform_device
> >> *pdev)
> >> >>         return 0;
> >> >>
> >> >>  err_hdmiphy:
> >> >> -       i2c_del_driver(&hdmiphy_driver);
> >> >> +       exynos_hdmiphy_driver_unregister();
> >> >>  err_ddc:
> >> >>         i2c_del_driver(&ddc_driver);
> >> >>         return ret;
> >> >> @@ -1989,8 +1770,8 @@ static int hdmi_remove(struct platform_device
> >> *pdev)
> >> >>
> >> >>         pm_runtime_disable(dev);
> >> >>
> >> >> -       /* hdmiphy i2c driver */
> >> >> -       i2c_del_driver(&hdmiphy_driver);
> >> >> +       /* hdmiphy driver */
> >> >> +       exynos_hdmiphy_driver_unregister();
> >> >>         /* DDC i2c driver */
> >> >>         i2c_del_driver(&ddc_driver);
> >> >>
> >> >> diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> >> b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> >> >> index 59abb14..82daa42 100644
> >> >> --- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> >> >> +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
> >> >> @@ -15,51 +15,459 @@
> >> >>
> >> >>  #include <linux/kernel.h>
> >> >>  #include <linux/i2c.h>
> >> >> -#include <linux/of.h>
> >> >> +#include <linux/module.h>
> >> >> +#include <linux/pm_runtime.h>
> >> >> +#include <linux/clk.h>
> >> >>
> >> >>  #include "exynos_drm_drv.h"
> >> >>  #include "exynos_hdmi.h"
> >> >> +#include "exynos_drm_hdmi.h"
> >> >> +#include "regs-hdmiphy.h"
> >> >>
> >> >> +#define HDMIPHY_REG_COUNT      (32)
> >> >
> >> > This probably belongs in regs-hdmiphy.h instead of here. Also remove
> the
> >> ()
> >> >
> >>
> >> Ok. I will move it there.
> >>
> >> >>
> >> >> -static int hdmiphy_probe(struct i2c_client *client,
> >> >> -       const struct i2c_device_id *id)
> >> >> +struct hdmiphy_context {
> >> >> +       struct device           *dev;
> >> >> +       struct hdmiphy_config   *current_conf;
> >> >> +
> >> >> +       struct hdmiphy_config   *confs;
> >> >> +       unsigned int            nr_confs;
> >> >> +};
> >> >> +
> >> >> +struct hdmiphy_config {
> >> >> +       int pixel_clock;
> >> >> +       u8 conf[HDMIPHY_REG_COUNT];
> >> >> +};
> >> >> +
> >> >> +struct hdmiphy_drv_data {
> >> >> +       struct hdmiphy_config *confs;
> >> >> +       unsigned int count;
> >> >> +};
> >> >> +
> >> >> +/* list of all required phy config settings */
> >> >> +static struct hdmiphy_config hdmiphy_4212_configs[] = {
> >> >> +       {
> >> >> +               .pixel_clock = 25200000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00,
0x08,
> >> >> +                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01,
0x80,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 27000000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc,
0x20,
> >> >> +                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01,
0x80,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 27027000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12,
0x08,
> >> >> +                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01,
0x00,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 36000000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00,
0x08,
> >> >> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01,
0x80,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 40000000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00,
0x08,
> >> >> +                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01,
0x80,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 65000000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a,
0x08,
> >> >> +                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01,
0x80,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 74176000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde,
0x08,
> >> >> +                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01,
0x80,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 74250000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8,
0x08,
> >> >> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01,
0x00,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 83500000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb,
0x08,
> >> >> +                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01,
0x80,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 106500000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09,
0x08,
> >> >> +                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01,
0x80,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 108000000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00,
0x08,
> >> >> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01,
0x80,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 146250000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd,
0x08,
> >> >> +                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01,
0x80,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 148500000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8,
0x08,
> >> >> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac,
0x80,
> >> >> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
0x86,
> >> >> +                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01,
0x00,
> >> >> +               },
> >> >> +       },
> >> >> +};
> >> >> +
> >> >> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
> >> >> +       {
> >> >> +               .pixel_clock = 27000000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30,
0x40,
> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
0x87,
> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
0xE0,
> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
0x00,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 27027000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09,
0x64,
> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
0x87,
> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
0xE0,
> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
0x00,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 74176000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef,
0x5B,
> >> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54,
0xb9,
> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
0xE0,
> >> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00,
0x00,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 74250000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8,
0x40,
> >> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54,
0xba,
> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10,
0xe0,
> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00,
0x00,
> >> >> +               },
> >> >> +       },
> >> >> +       {
> >> >> +               .pixel_clock = 148500000,
> >> >> +               .conf = {
> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8,
0x40,
> >> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54,
0xba,
> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10,
0xE0,
> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00,
0x00,
> >> >> +               },
> >> >> +       },
> >> >> +};
> >> >> +
> >> >
> >> > Are you aware of the effort to move these to dt? Since these are
> >> > board-specific values, it seems incorrect to apply them universally.
> >> > Shirish has uploaded a patch to the chromium review site to push
> these
> >> > into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
> >> > you can work that into your patch set?
> >> >
> >
> > Are these really board-specific values?
> 
> According to your hardware people:
> 
> "If the signal pattern doesn't change for new board, the phy setting
> is same as the current board. But if changed, you need to confirm with
> measurement of signals, because it may vary slightly by resistance of
> board pattern"
> 

Right. it seems that the phy configuration should be adjusted according to
PCB environment: OSC clock rate, 24MHz or 27MHz, could be decided by PCB
even though most PCBs use 27MHz.

> That indicates to me that we might need to tweak these on a per-board
> basis.
> 
> In the 5420 datasheet, there are a few register descriptions available
> for the phy. 0x145D0004 is CLK_SEL which seems like it would be
> board-specific, same with TX_* registers.
> 

And we can select HDMI Tx PHY internal PLL input clock by setting CLK_SEL.
Ok, Shirish's patch set is reasonable to me. However, that patch set should
be rebased on top of Rahul's patch set. Shirish and Rahul, please re-post
your patch set after discussing how to rebase these patch set.

Thanks,
Inki Dae

> Sean
> 
> 
> 
> > I think they are SoC-specific
> > values, and it's better to define them in the driver. For this, I gave
> > already comments to Shirish why these constraints should be placed in
> > driver. For more detail, you can also refer to the below link,
> >
> > http://www.mail-archive.com/devicetree-
> discuss@lists.ozlabs.org/msg36691.htm
> > l
> >
> > Thanks,
> > Inki Dae
> >
> >>
> >> I have gone through these patches. I am adding Shirish here for further
> >> discussion on these changes. he can explain better.
> >>
> >> >
> >> >> +static struct hdmiphy_config *hdmiphy_find_conf(struct
> hdmiphy_context
> >> *hdata,
> >> >> +                       const struct drm_display_mode *mode)
> >> >> +{
> >> >> +       int i;
> >> >> +
> >> >> +       for (i = 0; i < hdata->nr_confs; i++)
> >> >> +               if (hdata->confs[i].pixel_clock == (mode->clock *
> > 1000))
> >> >> +                       return &hdata->confs[i];
> >> >> +
> >> >> +       return NULL;
> >> >> +}
> >> >> +
> >> >> +static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata,
> >> >> +                       u32 reg_offset, u8 value)
> >> >> +{
> >> >> +       if (reg_offset >= HDMIPHY_REG_COUNT)
> >> >> +               return -EINVAL;
> >> >> +
> >> >> +       if (i2c_verify_client(hdata->dev)) {
> >> >
> >> > Is this necessary?
> >>
> >> Based on this check, I was deciding that given dev is i2c or
> >> platform device. But now when we agreed to split drivers to
> >> phy and plf driver, I will remove this.
> >>
> >> >
> >> >> +               u8 buffer[2];
> >> >> +               int ret;
> >> >> +
> >> >> +               buffer[0] = reg_offset;
> >> >> +               buffer[1] = value;
> >> >> +
> >> >> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
> >> >> +                               buffer, 2);
> >> >> +               if (ret == 2)
> >> >> +                       return 0;
> >> >> +               return ret;
> >> >> +       } else {
> >> >> +               return -EINVAL;
> >> >> +       }
> >> >> +}
> >> >> +
> >> >> +static int hdmiphy_reg_write_buf(struct hdmiphy_context *hdata,
> >> >> +                       u32 reg_offset, const u8 *buf, u32 len)
> >> >> +{
> >> >> +       if ((reg_offset + len) > HDMIPHY_REG_COUNT)
> >> >> +               return -EINVAL;
> >> >> +
> >> >> +       if (i2c_verify_client(hdata->dev)) {
> >> >
> >> > Is this necessary?
> >> >
> >> >
> >> >> +               int ret;
> >> >> +
> >> >> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
> >> >> +                               buf, len);
> >> >
> >> > Does this actually work? You don't seem to be using reg_offset
> anywhere.
> >> >
> >>
> >> reg_offset is not required here. I should remove this. This
> >> procedure is to write the complete buf starting from 0.
> >> hdmiphy_reg_writeb is supposed to be used for writing
> >> value from some offset.
> >>
> >> >> +               if (ret == len)
> >> >> +                       return 0;
> >> >> +               return ret;
> >> >> +       } else {
> >> >> +               return -EINVAL;
> >> >> +       }
> >> >> +}
> >> >> +
> >> >> +int exynos_hdmiphy_check_mode(struct device *dev,
> >> >> +                       struct drm_display_mode *mode)
> >> >>  {
> >> >> -       hdmi_attach_hdmiphy_client(client);
> >> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> >> >> +       const struct hdmiphy_config *conf;
> >> >> +
> >> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> >> >
> >> > Maybe you can merge this debug message with the one below.
> >> >
> >>
> >> ok.
> >>
> >> >>
> >> >> -       dev_info(&client->adapter->dev, "attached s5p_hdmiphy "
> >> >> -               "into i2c adapter successfully\n");
> >> >> +       if (!hdata) {
> >> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> >> >> +               return -EINVAL;
> >> >> +       }
> >> >
> >> > Can this happen? I think the phy driver registration should be
> >> > synchronous with the hdmi driver registration. As such, it shouldn't
> >> > be possible to get a check_mode callback until it's all set up.
> >> >
> >>
> >> I will confirm on this.
> >>
> >> >>
> >> >> +       DRM_DEBUG("xres=%d, yres=%d, refresh=%d, intl=%d
clock=%d\n",
> >> >> +               mode->hdisplay, mode->vdisplay,
> >> >> +               mode->vrefresh, (mode->flags &
DRM_MODE_FLAG_INTERLACE)
> >> >> +               ? true : false, mode->clock * 1000);
> >> >> +
> >> >> +       conf = hdmiphy_find_conf(hdata, mode);
> >> >> +       if (!conf) {
> >> >> +               DRM_DEBUG("Display Mode is not supported.\n");
> >> >> +               return -EINVAL;
> >> >> +       }
> >> >>         return 0;
> >> >>  }
> >> >>
> >> >> -static int hdmiphy_remove(struct i2c_client *client)
> >> >> +int exynos_hdmiphy_set_mode(struct device *dev,
> >> >> +                       struct drm_display_mode *mode)
> >> >>  {
> >> >> -       dev_info(&client->adapter->dev, "detached s5p_hdmiphy "
> >> >> -               "from i2c adapter successfully\n");
> >> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> >> >> +
> >> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> >> >> +
> >> >> +       hdata->current_conf = hdmiphy_find_conf(hdata, mode);
> >> >> +
> >> >> +       if (!hdata) {
> >> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> >> >> +               return -EINVAL;
> >> >> +       }
> >> >
> >> > I really hope this check isn't necessary, since you've already
> >> > dereferenced it 2 lines up :) See my comment above, I don't think you
> >> > can ever hit this.
> >> >
> >> >>
> >> >> +       if (!hdata->current_conf) {
> >> >> +               DRM_ERROR("Display Mode is not supported.\n");
> >> >> +               return -EINVAL;
> >> >> +       }
> >> >>         return 0;
> >> >>  }
> >> >>
> >> >> -static struct of_device_id hdmiphy_match_types[] = {
> >> >> +void exynos_hdmiphy_enable(struct device *dev)
> >> >> +{
> >> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> >> >> +       int ret;
> >> >> +
> >> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> >> >> +
> >> >> +       if (!hdata) {
> >> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> >> >> +               return;
> >> >> +       }
> >> >
> >> > Same comment as above.
> >> >
> >> >> +
> >> >> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
> >> >> +                       HDMIPHY_MODE_EN);
> >> >> +       if (ret < 0) {
> >> >> +               DRM_ERROR("failed to disable hdmiphy.\n");
> >> >> +               return;
> >> >> +       }
> >> >> +}
> >> >> +
> >> >> +void exynos_hdmiphy_disable(struct device *dev)
> >> >> +{
> >> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> >> >> +       int ret;
> >> >> +
> >> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> >> >> +
> >> >> +       if (!hdata) {
> >> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> >> >> +               return;
> >> >> +       }
> >> >> +
> >> >> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, 0);
> >> >> +       if (ret < 0) {
> >> >> +               DRM_ERROR("failed to enable hdmiphy.\n");
> >> >
> >> > If you're not going to return the error code, at least print it here.
> >> >
> >>
> >> ok.
> >>
> >> >> +               return;
> >> >> +       }
> >> >> +}
> >> >> +
> >> >> +int exynos_hdmiphy_conf_apply(struct device *dev)
> >> >> +{
> >> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
> >> >> +       const u8 *hdmiphy_data;
> >> >> +       int ret;
> >> >> +
> >> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> >> >> +
> >> >> +       if (!hdata) {
> >> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
> >> >> +               return -EINVAL;
> >> >> +       }
> >> >> +
> >> >> +       /* pixel clock */
> >> >
> >> > I don't understand this comment.
> >> >
> >>
> >> I will remove this.
> >>
> >> >> +       if (hdata->current_conf)
> >> >> +               hdmiphy_data = hdata->current_conf->conf;
> >> >> +       else
> >> >> +               return -EINVAL;
> >> >> +
> >> >> +       ret = hdmiphy_reg_write_buf(hdata, 0, hdmiphy_data,
> >> >> +                       HDMIPHY_REG_COUNT);
> >> >
> >> > I think the only reason this works is b/c you're writing to register
> >> offset 0.
> >> >
> >> >> +       if (ret) {
> >> >> +               DRM_ERROR("failed to configure hdmiphy.\n");
> >> >> +               return -EINVAL;
> >> >
> >> > Why don't you return ret?
> >> >
> >>
> >> ok.
> >>
> >> >> +       }
> >> >> +       return 0;
> >> >> +}
> >> >> +
> >> >> +static struct hdmiphy_drv_data exynos4212_hdmiphy_drv_data = {
> >> >> +       .confs = hdmiphy_4212_configs,
> >> >> +       .count = ARRAY_SIZE(hdmiphy_4212_configs)
> >> >> +};
> >> >> +
> >> >> +static struct hdmiphy_drv_data exynos4210_hdmiphy_drv_data = {
> >> >> +       .confs = hdmiphy_4210_configs,
> >> >> +       .count = ARRAY_SIZE(hdmiphy_4210_configs)
> >> >> +};
> >> >> +
> >> >> +static struct of_device_id hdmiphy_i2c_device_match_types[] = {
> >> >>         {
> >> >>                 .compatible = "samsung,exynos5-hdmiphy",
> >> >> +               .data   = &exynos4212_hdmiphy_drv_data,
> >> >>         }, {
> >> >>                 .compatible = "samsung,exynos4210-hdmiphy",
> >> >> +               .data   = &exynos4210_hdmiphy_drv_data,
> >> >>         }, {
> >> >>                 .compatible = "samsung,exynos4212-hdmiphy",
> >> >> +               .data   = &exynos4212_hdmiphy_drv_data,
> >> >>         }, {
> >> >>                 /* end node */
> >> >>         }
> >> >>  };
> >> >>
> >> >> -struct i2c_driver hdmiphy_driver = {
> >> >> +static int hdmiphy_i2c_device_probe(struct i2c_client *client,
> >> >> +       const struct i2c_device_id *id)
> >> >> +{
> >> >> +       struct device *dev = &client->dev;
> >> >> +       struct hdmiphy_context *hdata;
> >> >> +       struct hdmiphy_drv_data *drv;
> >> >> +       const struct of_device_id *match;
> >> >> +
> >> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
> >> >> +
> >> >> +       hdata = devm_kzalloc(dev, sizeof(*hdata), GFP_KERNEL);
> >> >> +       if (!hdata) {
> >> >> +               DRM_ERROR("failed to allocate hdmiphy context.\n");
> >> >> +               return -ENOMEM;
> >> >> +       }
> >> >> +
> >> >> +       match = of_match_node(of_match_ptr(
> >> >> +               hdmiphy_i2c_device_match_types),
> >> >> +               dev->of_node);
> >> >> +
> >> >> +       if (match == NULL)
> >> >> +               return -ENODEV;
> >> >> +
> >> >> +       drv = (struct hdmiphy_drv_data *)match->data;
> >> >> +
> >> >> +       hdata->dev = dev;
> >> >> +       hdata->confs = drv->confs;
> >> >> +       hdata->nr_confs = drv->count;
> >> >> +
> >> >> +       i2c_set_clientdata(client, hdata);
> >> >> +
> >> >> +       return 0;
> >> >> +}
> >> >> +
> >> >> +static const struct i2c_device_id hdmiphy_id[] = {
> >> >> +       { },
> >> >> +};
> >> >> +
> >> >> +struct i2c_driver hdmiphy_i2c_driver = {
> >> >>         .driver = {
> >> >>                 .name   = "exynos-hdmiphy",
> >> >>                 .owner  = THIS_MODULE,
> >> >> -               .of_match_table = hdmiphy_match_types,
> >> >> +               .of_match_table = of_match_ptr(
> >> >> +                               hdmiphy_i2c_device_match_types),
> >> >>         },
> >> >> -       .probe          = hdmiphy_probe,
> >> >> -       .remove         = hdmiphy_remove,
> >> >> +       .id_table               = hdmiphy_id,
> >> >> +       .probe          = hdmiphy_i2c_device_probe,
> >> >>         .command                = NULL,
> >> >>  };
> >> >> -EXPORT_SYMBOL(hdmiphy_driver);
> >> >> +
> >> >> +int exynos_hdmiphy_driver_register(void)
> >> >> +{
> >> >> +       int ret;
> >> >> +
> >> >> +       ret = i2c_add_driver(&hdmiphy_i2c_driver);
> >> >> +       if (ret)
> >> >> +               return ret;
> >> >> +
> >> >> +       return 0;
> >> >> +}
> >> >> +
> >> >> +void exynos_hdmiphy_driver_unregister(void)
> >> >> +{
> >> >> +       i2c_del_driver(&hdmiphy_i2c_driver);
> >> >> +}
> >> >> diff --git a/drivers/gpu/drm/exynos/regs-hdmiphy.h
> >> b/drivers/gpu/drm/exynos/regs-hdmiphy.h
> >> >> new file mode 100644
> >> >> index 0000000..d3f9d87
> >> >> --- /dev/null
> >> >> +++ b/drivers/gpu/drm/exynos/regs-hdmiphy.h
> >> >> @@ -0,0 +1,35 @@
> >> >> +/*
> >> >> + *
> >> >> + *  regs-hdmiphy.h
> >> >> + *
> >> >> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> >> >> + * http://www.samsung.com/
> >> >> + *
> >> >> + * HDMI-PHY register header file for Samsung HDMI driver
> >> >> + *
> >> >> + * This program is free software; you can redistribute it and/or
> >> modify
> >> >> + * it under the terms of the GNU General Public License version 2
> as
> >> >> + * published by the Free Software Foundation.
> >> >> +*/
> >> >> +
> >> >> +#ifndef SAMSUNG_REGS_HDMIPHY_H
> >> >> +#define SAMSUNG_REGS_HDMIPHY_H
> >> >> +
> >> >> +/*
> >> >> + * Register part
> >> >> +*/
> >> >> +#define HDMIPHY_MODE_SET_DONE  (0x1f)
> >> >> +
> >> >> +/*
> >> >> + * Bit definition part
> >> >> + */
> >> >> +
> >> >> +/* HDMIPHY_MODE_SET_DONE */
> >> >> +#define HDMIPHY_MODE_EN                (1 << 7)
> >> >> +
> >> >> +/* hdmiphy pmu control bits */
> >> >> +#define PMU_HDMI_PHY_CONTROL_MASK      (1 << 0)
> >> >> +#define PMU_HDMI_PHY_ENABLE            (1)
> >> >> +#define PMU_HDMI_PHY_DISABLE           (0)
> >> >
> >> >
> >> > You don't need the () around simple values
> >> >
> >>
> >> ok.
> >>
> >> We also discussed previously to keep independent i2c and
> >> platform phy drivers in exynos_hdmiphy_i2c.c and
> >> exynos_hdmiphy_platform.c respectively, which will duplicate
> >> the code to some extent.
> >>
> >> Second point is to implement exynos_i2c_hdmiphy_get_ops()
> >> and exynos_platform_hdmiphy_get_ops() to get access to all
> >> callbacks. This will limit the exposure of phy callbacks to the
> >> phy controller.
> >>
> >> Please share your views on this.
> >>
> >> Regards,
> >> Rahul Sharma.
> >>
> >> >> +
> >> >> +#endif /* SAMSUNG_REGS_HDMIPHY_H */
> >> >> --
> >> >> 1.7.10.4
> >> >>
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-
> soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-05  4:16           ` Inki Dae
@ 2013-09-05  4:43             ` Rahul Sharma
  2013-09-05  5:22               ` Inki Dae
  0 siblings, 1 reply; 45+ messages in thread
From: Rahul Sharma @ 2013-09-05  4:43 UTC (permalink / raw)
  To: Inki Dae
  Cc: Sean Paul, Rahul Sharma, linux-samsung-soc, dri-devel, kgene.kim,
	sw0312.kim, Lucas Stach, Tomasz Figa, Sylwester Nawrocki,
	sunil joshi, Shirish S

On 5 September 2013 09:46, Inki Dae <inki.dae@samsung.com> wrote:
>
>
>> -----Original Message-----
>> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-soc-
>> owner@vger.kernel.org] On Behalf Of Sean Paul
>> Sent: Wednesday, September 04, 2013 11:52 PM
>> To: Inki Dae
>> Cc: Rahul Sharma; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
>> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
>> Shirish S
>> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
>> driver
>>
>> On Wed, Sep 4, 2013 at 3:37 AM, Inki Dae <inki.dae@samsung.com> wrote:
>> >
>> >
>> >> -----Original Message-----
>> >> From: Rahul Sharma [mailto:r.sh.open@gmail.com]
>> >> Sent: Wednesday, September 04, 2013 2:48 PM
>> >> To: Sean Paul
>> >> Cc: Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim; sw0312.kim;
>> >> InKi Dae; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
>> >> shirish@chromium.org
>> >> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
>> hdmiphy
>> >> driver
>> >>
>> >> Thanks Sean,
>> >>
>> >> On 3 September 2013 20:15, Sean Paul <seanpaul@chromium.org> wrote:
>> >> > A few comments.
>> >> >
>> >> > On Fri, Aug 30, 2013 at 2:59 AM, Rahul Sharma
>> <rahul.sharma@samsung.com>
>> >> wrote:
>> >> >> Exynos hdmiphy operations and configs are kept inside
>> >> >> the hdmi driver. Hdmiphy related code is tightly coupled
>> >> >> with hdmi IP driver.
>> >> >>
>> >> >> This patche moves hdmiphy related code to hdmiphy driver.
>> >> >
>> >> > s/patche/patch
>> >> >
>> >> ok.
>> >> >> It will help in cleanly supporting the hdmiphy variations
>> >> >> in further SoCs.
>> >> >>
>> >> >> Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
>> >> >> ---
>> >> >>  .../devicetree/bindings/video/exynos_hdmi.txt      |    2 +
>> >> >>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h           |   11 +
>> >> >>  drivers/gpu/drm/exynos/exynos_hdmi.c               |  343
>> > +++------------
>> >> >>  drivers/gpu/drm/exynos/exynos_hdmiphy.c            |  438
>> >> +++++++++++++++++++-
>> >> >>  drivers/gpu/drm/exynos/regs-hdmiphy.h              |   35 ++
>> >> >>  5 files changed, 533 insertions(+), 296 deletions(-)
>> >> >>  create mode 100644 drivers/gpu/drm/exynos/regs-hdmiphy.h
>> >> >>
>> >> >> diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> >> b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> >> >> index 50decf8..240eca5 100644
>> >> >> --- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> >> >> +++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
>> >> >> @@ -25,6 +25,7 @@ Required properties:
>> >> >>                 sclk_pixel.
>> >> >>  - clock-names: aliases as per driver requirements for above clock
>> IDs:
>> >> >>         "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and
>> > "mout_hdmi".
>> >> >> +- phy: it points to hdmiphy dt node.
>> >> >>  Example:
>> >> >>
>> >> >>         hdmi {
>> >> >> @@ -32,4 +33,5 @@ Example:
>> >> >>                 reg = <0x14530000 0x100000>;
>> >> >>                 interrupts = <0 95 0>;
>> >> >>                 hpd-gpio = <&gpx3 7 1>;
>> >> >> +               phy = <&hdmiphy>;
>> >> >>         };
>> >> >> diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>> >> b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>> >> >> index 724cab1..1c839f8 100644
>> >> >> --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>> >> >> +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
>> >> >> @@ -64,4 +64,15 @@ void exynos_hdmi_drv_attach(struct
>> >> exynos_drm_hdmi_context *ctx);
>> >> >>  void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx);
>> >> >>  void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
>> >> >>  void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
>> >> >> +
>> >> >> +int exynos_hdmiphy_driver_register(void);
>> >> >> +void exynos_hdmiphy_driver_unregister(void);
>> >> >> +
>> >> >> +void exynos_hdmiphy_enable(struct device *dev);
>> >> >> +void exynos_hdmiphy_disable(struct device *dev);
>> >> >> +int exynos_hdmiphy_check_mode(struct device *dev,
>> >> >> +                               struct drm_display_mode *mode);
>> >> >> +int exynos_hdmiphy_set_mode(struct device *dev,
>> >> >> +                               struct drm_display_mode *mode);
>> >> >> +int exynos_hdmiphy_conf_apply(struct device *dev);
>> >> >>  #endif
>> >> >> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c
>> >> b/drivers/gpu/drm/exynos/exynos_hdmi.c
>> >> >> index f67ffca..3af4e4c 100644
>> >> >> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
>> >> >> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
>> >> >> @@ -34,6 +34,8 @@
>> >> >>  #include <linux/io.h>
>> >> >>  #include <linux/of.h>
>> >> >>  #include <linux/of_gpio.h>
>> >> >> +#include <linux/of_i2c.h>
>> >> >> +#include <linux/of_platform.h>
>> >> >>
>> >> >>  #include <drm/exynos_drm.h>
>> >> >>
>> >> >> @@ -172,7 +174,6 @@ struct hdmi_v14_conf {
>> >> >>  };
>> >> >>
>> >> >>  struct hdmi_conf_regs {
>> >> >> -       int pixel_clock;
>> >> >>         int cea_video_id;
>> >> >>         union {
>> >> >>                 struct hdmi_v13_conf v13_conf;
>> >> >> @@ -193,9 +194,9 @@ struct hdmi_context {
>> >> >>         int                             irq;
>> >> >>
>> >> >>         struct i2c_client               *ddc_port;
>> >> >> -       struct i2c_client               *hdmiphy_port;
>> >> >> +       struct device                   *hdmiphy_dev;
>> >> >>
>> >> >> -       /* current hdmiphy conf regs */
>> >> >> +       /* current hdmi ip configuration registers. */
>> >> >>         struct hdmi_conf_regs           mode_conf;
>> >> >>
>> >> >>         struct hdmi_resources           res;
>> >> >> @@ -205,180 +206,6 @@ struct hdmi_context {
>> >> >>         enum hdmi_type                  type;
>> >> >>  };
>> >> >>
>> >> >> -struct hdmiphy_config {
>> >> >> -       int pixel_clock;
>> >> >> -       u8 conf[32];
>> >> >> -};
>> >> >> -
>> >> >> -/* list of phy config settings */
>> >> >> -static const struct hdmiphy_config hdmiphy_v13_configs[] = {
>> >> >> -       {
>> >> >> -               .pixel_clock = 27000000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30,
> 0x40,
>> >> >> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
> 0x87,
>> >> >> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
> 0xE0,
>> >> >> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
> 0x00,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 27027000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09,
> 0x64,
>> >> >> -                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
> 0x87,
>> >> >> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
> 0xE0,
>> >> >> -                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
> 0x00,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 74176000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef,
> 0x5B,
>> >> >> -                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54,
> 0xb9,
>> >> >> -                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
> 0xE0,
>> >> >> -                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00,
> 0x00,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 74250000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8,
> 0x40,
>> >> >> -                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54,
> 0xba,
>> >> >> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10,
> 0xe0,
>> >> >> -                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00,
> 0x00,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 148500000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8,
> 0x40,
>> >> >> -                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54,
> 0xba,
>> >> >> -                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10,
> 0xE0,
>> >> >> -                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00,
> 0x00,
>> >> >> -               },
>> >> >> -       },
>> >> >> -};
>> >> >> -
>> >> >> -static const struct hdmiphy_config hdmiphy_v14_configs[] = {
>> >> >> -       {
>> >> >> -               .pixel_clock = 25200000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00,
> 0x08,
>> >> >> -                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 27000000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc,
> 0x20,
>> >> >> -                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 27027000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12,
> 0x08,
>> >> >> -                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01,
> 0x00,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 36000000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00,
> 0x08,
>> >> >> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 40000000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00,
> 0x08,
>> >> >> -                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 65000000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a,
> 0x08,
>> >> >> -                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 74176000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde,
> 0x08,
>> >> >> -                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 74250000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8,
> 0x08,
>> >> >> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01,
> 0x00,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 83500000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb,
> 0x08,
>> >> >> -                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 106500000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09,
> 0x08,
>> >> >> -                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 108000000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00,
> 0x08,
>> >> >> -                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 146250000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd,
> 0x08,
>> >> >> -                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> -               },
>> >> >> -       },
>> >> >> -       {
>> >> >> -               .pixel_clock = 148500000,
>> >> >> -               .conf = {
>> >> >> -                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8,
> 0x08,
>> >> >> -                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> -                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> -                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01,
> 0x00,
>> >> >> -               },
>> >> >> -       },
>> >> >> -};
>> >> >> -
>> >> >>  struct hdmi_infoframe {
>> >> >>         enum HDMI_PACKET_TYPE type;
>> >> >>         u8 ver;
>> >> >> @@ -769,28 +596,6 @@ static struct edid *hdmi_get_edid(void *ctx,
>> >> struct drm_connector *connector)
>> >> >>         return raw_edid;
>> >> >>  }
>> >> >>
>> >> >> -static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32
>> >> pixel_clock)
>> >> >> -{
>> >> >> -       const struct hdmiphy_config *confs;
>> >> >> -       int count, i;
>> >> >> -
>> >> >> -       if (hdata->type == HDMI_TYPE13) {
>> >> >> -               confs = hdmiphy_v13_configs;
>> >> >> -               count = ARRAY_SIZE(hdmiphy_v13_configs);
>> >> >> -       } else if (hdata->type == HDMI_TYPE14) {
>> >> >> -               confs = hdmiphy_v14_configs;
>> >> >> -               count = ARRAY_SIZE(hdmiphy_v14_configs);
>> >> >> -       } else
>> >> >> -               return -EINVAL;
>> >> >> -
>> >> >> -       for (i = 0; i < count; i++)
>> >> >> -               if (confs[i].pixel_clock == pixel_clock)
>> >> >> -                       return i;
>> >> >> -
>> >> >> -       DRM_DEBUG_KMS("Could not find phy config for %d\n",
>> > pixel_clock);
>> >> >> -       return -EINVAL;
>> >> >> -}
>> >> >> -
>> >> >>  static int hdmi_check_mode(void *ctx, struct drm_display_mode
> *mode)
>> >> >>  {
>> >> >>         struct hdmi_context *hdata = ctx;
>> >> >> @@ -801,7 +606,7 @@ static int hdmi_check_mode(void *ctx, struct
>> >> drm_display_mode *mode)
>> >> >>                 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
>> >> >>                 false, mode->clock * 1000);
>> >> >>
>> >> >> -       ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
>> >> >> +       ret = exynos_hdmiphy_check_mode(hdata->hdmiphy_dev, mode);
>> >> >>         if (ret < 0)
>> >> >>                 return ret;
>> >> >>         return 0;
>> >> >> @@ -1302,19 +1107,13 @@ static void hdmi_mode_apply(struct
>> hdmi_context
>> >> *hdata)
>> >> >>
>> >> >>  static void hdmiphy_conf_reset(struct hdmi_context *hdata)
>> >> >>  {
>> >> >> -       u8 buffer[2];
>> >> >>         u32 reg;
>> >> >>
>> >> >>         clk_disable_unprepare(hdata->res.sclk_hdmi);
>> >> >>         clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
>> >> >>         clk_prepare_enable(hdata->res.sclk_hdmi);
>> >> >>
>> >> >> -       /* operation mode */
>> >> >> -       buffer[0] = 0x1f;
>> >> >> -       buffer[1] = 0x00;
>> >> >> -
>> >> >> -       if (hdata->hdmiphy_port)
>> >> >> -               i2c_master_send(hdata->hdmiphy_port, buffer, 2);
>> >> >> +       exynos_hdmiphy_disable(hdata->hdmiphy_dev);
>> >> >>
>> >> >>         if (hdata->type == HDMI_TYPE13)
>> >> >>                 reg = HDMI_V13_PHY_RSTOUT;
>> >> >> @@ -1342,66 +1141,12 @@ static void hdmiphy_poweroff(struct
>> >> hdmi_context *hdata)
>> >> >>                         HDMI_PHY_POWER_OFF_EN);
>> >> >>  }
>> >> >>
>> >> >> -static void hdmiphy_conf_apply(struct hdmi_context *hdata)
>> >> >> -{
>> >> >> -       const u8 *hdmiphy_data;
>> >> >> -       u8 buffer[32];
>> >> >> -       u8 operation[2];
>> >> >> -       u8 read_buffer[32] = {0, };
>> >> >> -       int ret;
>> >> >> -       int i;
>> >> >> -
>> >> >> -       if (!hdata->hdmiphy_port) {
>> >> >> -               DRM_ERROR("hdmiphy is not attached\n");
>> >> >> -               return;
>> >> >> -       }
>> >> >> -
>> >> >> -       /* pixel clock */
>> >> >> -       i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
>> >> >> -       if (i < 0) {
>> >> >> -               DRM_ERROR("failed to find hdmiphy conf\n");
>> >> >> -               return;
>> >> >> -       }
>> >> >> -
>> >> >> -       if (hdata->type == HDMI_TYPE13)
>> >> >> -               hdmiphy_data = hdmiphy_v13_configs[i].conf;
>> >> >> -       else
>> >> >> -               hdmiphy_data = hdmiphy_v14_configs[i].conf;
>> >> >> -
>> >> >> -       memcpy(buffer, hdmiphy_data, 32);
>> >> >> -       ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
>> >> >> -       if (ret != 32) {
>> >> >> -               DRM_ERROR("failed to configure HDMIPHY via I2C\n");
>> >> >> -               return;
>> >> >> -       }
>> >> >> -
>> >> >> -       usleep_range(10000, 12000);
>> >> >> -
>> >> >> -       /* operation mode */
>> >> >> -       operation[0] = 0x1f;
>> >> >> -       operation[1] = 0x80;
>> >> >> -
>> >> >> -       ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
>> >> >> -       if (ret != 2) {
>> >> >> -               DRM_ERROR("failed to enable hdmiphy\n");
>> >> >> -               return;
>> >> >> -       }
>> >> >> -
>> >> >> -       ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
>> >> >> -       if (ret < 0) {
>> >> >> -               DRM_ERROR("failed to read hdmiphy config\n");
>> >> >> -               return;
>> >> >> -       }
>> >> >> -
>> >> >> -       for (i = 0; i < ret; i++)
>> >> >> -               DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
>> >> >> -                       "recv [0x%02x]\n", i, buffer[i],
>> > read_buffer[i]);
>> >> >> -}
>> >> >> -
>> >> >>  static void hdmi_conf_apply(struct hdmi_context *hdata)
>> >> >>  {
>> >> >>         hdmiphy_conf_reset(hdata);
>> >> >> -       hdmiphy_conf_apply(hdata);
>> >> >> +       exynos_hdmiphy_conf_apply(hdata->hdmiphy_dev);
>> >> >> +       usleep_range(10000, 12000);
>> >> >
>> >> > This delay seems like something that should be in the phy driver,
>> >> > instead of the hdmi driver (since it seems conceivable that certain
>> >> > phys might not need a delay or might need a longer delay).
>> >> >
>> >>
>> >> ok. I will move it there.
>> >>
>> >> >> +       exynos_hdmiphy_enable(hdata->hdmiphy_dev);
>> >> >>
>> >> >>         mutex_lock(&hdata->hdmi_mutex);
>> >> >>         hdmi_conf_reset(hdata);
>> >> >> @@ -1434,7 +1179,6 @@ static void hdmi_v13_mode_set(struct
>> hdmi_context
>> >> *hdata,
>> >> >>
>> >> >>         hdata->mode_conf.cea_video_id =
>> >> >>                 drm_match_cea_mode((struct drm_display_mode *)m);
>> >> >> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
>> >> >>
>> >> >>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
>> >> >>         hdmi_set_reg(core->h_v_line, 3, (m->htotal << 12) |
> m->vtotal);
>> >> >> @@ -1530,7 +1274,6 @@ static void hdmi_v14_mode_set(struct
>> hdmi_context
>> >> *hdata,
>> >> >>
>> >> >>         hdata->mode_conf.cea_video_id =
>> >> >>                 drm_match_cea_mode((struct drm_display_mode *)m);
>> >> >> -       hdata->mode_conf.pixel_clock = m->clock * 1000;
>> >> >>
>> >> >>         hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
>> >> >>         hdmi_set_reg(core->v_line, 2, m->vtotal);
>> >> >> @@ -1646,6 +1389,8 @@ static void hdmi_mode_set(void *ctx, struct
>> >> drm_display_mode *mode)
>> >> >>                 hdmi_v13_mode_set(hdata, mode);
>> >> >>         else
>> >> >>                 hdmi_v14_mode_set(hdata, mode);
>> >> >> +
>> >> >> +       exynos_hdmiphy_set_mode(hdata->hdmiphy_dev, mode);
>> >> >
>> >> > Why set_mode when everything else is mode_set?
>> >> >
>> >>
>> >> I will change it to mode_set.
>> >>
>> >> >>  }
>> >> >>
>> >> >>  static void hdmi_get_max_resol(void *ctx, unsigned int *width,
>> >> >> @@ -1824,7 +1569,7 @@ fail:
>> >> >>         return -ENODEV;
>> >> >>  }
>> >> >>
>> >> >> -static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
>> >> >> +static struct i2c_client *hdmi_ddc;
>> >> >>
>> >> >>  void hdmi_attach_ddc_client(struct i2c_client *ddc)
>> >> >>  {
>> >> >> @@ -1832,12 +1577,6 @@ void hdmi_attach_ddc_client(struct i2c_client
>> >> *ddc)
>> >> >>                 hdmi_ddc = ddc;
>> >> >>  }
>> >> >>
>> >> >> -void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
>> >> >> -{
>> >> >> -       if (hdmiphy)
>> >> >> -               hdmi_hdmiphy = hdmiphy;
>> >> >> -}
>> >> >> -
>> >> >>  static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
>> >> >>                                         (struct device *dev)
>> >> >>  {
>> >> >> @@ -1862,6 +1601,50 @@ err_data:
>> >> >>         return NULL;
>> >> >>  }
>> >> >>
>> >> >> +static int hdmi_get_phy_device(struct hdmi_context *hdata)
>> >> >
>> >> > "get" is not the proper verb here, "initialize" would be more
>> >> > appropriate (IMO, of course).
>> >> >
>> >>
>> >> But we don't initialise the phy here. It is just to get the
>> >> hdmiphy dev* through dt.
>> >>
>> >> >> +{
>> >> >> +       struct device_node *np;
>> >> >> +       struct i2c_client *client;
>> >> >> +       struct platform_device *pdev;
>> >> >> +       int ret;
>> >> >> +
>> >> >> +       /* register hdmiphy driver */
>> >> >> +       ret = exynos_hdmiphy_driver_register();
>> >> >> +       if (ret) {
>> >> >> +               DRM_ERROR("failed to register hdmiphy driver\n");
>> >> >
>> >> > Printing ret would be useful here.
>> >>
>> >> ok.
>> >> >
>> >> >> +               goto err;
>> >> >> +       }
>> >> >> +
>> >> >> +       np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
>> >> >> +       if (!np) {
>> >> >> +               DRM_ERROR("Could not find 'phy' property\n");
>> >> >> +               ret = -ENOENT;
>> >> >> +               goto err;
>> >> >> +       }
>> >> >> +
>> >> >> +       /* find hdmi phy on i2c bus */
>> >> >> +       client = of_find_i2c_device_by_node(np);
>> >> >> +       if (client) {
>> >> >> +               hdata->hdmiphy_dev = &client->dev;
>> >> >> +               ret = 0;
>> >> >> +               goto exit;
>> >> >> +       }
>> >> >> +
>> >> >> +       /* find hdmi phy on platform bus */
>> >> >> +       pdev = of_find_device_by_node(np);
>> >> >> +       if (pdev) {
>> >> >> +               hdata->hdmiphy_dev = &pdev->dev;
>> >> >> +               ret = 0;
>> >> >> +               goto exit;
>> >> >> +       }
>> >> >> +
>> >> >> +exit:
>> >> >> +       /* able to find hdmiphy on platform/i2c bus */
>> >> >> +err:
>> >> >
>> >> > Probably just easier to have one "exit" or "out" label that just
>> returns
>> >> ret.
>> >>
>> >> ok.
>> >> >
>> >> >> +       of_node_put(np);
>> >> >> +       return ret;
>> >> >> +}
>> >> >> +
>> >> >>  static struct of_device_id hdmi_match_types[] = {
>> >> >>         {
>> >> >>                 .compatible = "samsung,exynos5-hdmi",
>> >> >> @@ -1939,15 +1722,13 @@ static int hdmi_probe(struct platform_device
>> >> *pdev)
>> >> >>
>> >> >>         hdata->ddc_port = hdmi_ddc;
>> >> >>
>> >> >> -       /* hdmiphy i2c driver */
>> >> >> -       if (i2c_add_driver(&hdmiphy_driver)) {
>> >> >> -               DRM_ERROR("failed to register hdmiphy i2c
> driver\n");
>> >> >> +       ret = hdmi_get_phy_device(hdata);
>> >> >> +       if (ret) {
>> >> >> +               DRM_ERROR("failed to get hdmiphy device\n");
>> >> >
>> >> > Printing ret would be useful.
>> >> >
>> >> >
>> >> >>                 ret = -ENOENT;
>> >> >
>> >> > Why change the return value here?
>> >> >
>> >> Yea. Correct. I shouldn't. I will change this.
>> >>
>> >> >>                 goto err_ddc;
>> >> >>         }
>> >> >>
>> >> >> -       hdata->hdmiphy_port = hdmi_hdmiphy;
>> >> >> -
>> >> >>         hdata->irq = gpio_to_irq(hdata->hpd_gpio);
>> >> >>         if (hdata->irq < 0) {
>> >> >>                 DRM_ERROR("failed to get GPIO irq\n");
>> >> >> @@ -1977,7 +1758,7 @@ static int hdmi_probe(struct platform_device
>> >> *pdev)
>> >> >>         return 0;
>> >> >>
>> >> >>  err_hdmiphy:
>> >> >> -       i2c_del_driver(&hdmiphy_driver);
>> >> >> +       exynos_hdmiphy_driver_unregister();
>> >> >>  err_ddc:
>> >> >>         i2c_del_driver(&ddc_driver);
>> >> >>         return ret;
>> >> >> @@ -1989,8 +1770,8 @@ static int hdmi_remove(struct platform_device
>> >> *pdev)
>> >> >>
>> >> >>         pm_runtime_disable(dev);
>> >> >>
>> >> >> -       /* hdmiphy i2c driver */
>> >> >> -       i2c_del_driver(&hdmiphy_driver);
>> >> >> +       /* hdmiphy driver */
>> >> >> +       exynos_hdmiphy_driver_unregister();
>> >> >>         /* DDC i2c driver */
>> >> >>         i2c_del_driver(&ddc_driver);
>> >> >>
>> >> >> diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>> >> b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>> >> >> index 59abb14..82daa42 100644
>> >> >> --- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>> >> >> +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
>> >> >> @@ -15,51 +15,459 @@
>> >> >>
>> >> >>  #include <linux/kernel.h>
>> >> >>  #include <linux/i2c.h>
>> >> >> -#include <linux/of.h>
>> >> >> +#include <linux/module.h>
>> >> >> +#include <linux/pm_runtime.h>
>> >> >> +#include <linux/clk.h>
>> >> >>
>> >> >>  #include "exynos_drm_drv.h"
>> >> >>  #include "exynos_hdmi.h"
>> >> >> +#include "exynos_drm_hdmi.h"
>> >> >> +#include "regs-hdmiphy.h"
>> >> >>
>> >> >> +#define HDMIPHY_REG_COUNT      (32)
>> >> >
>> >> > This probably belongs in regs-hdmiphy.h instead of here. Also remove
>> the
>> >> ()
>> >> >
>> >>
>> >> Ok. I will move it there.
>> >>
>> >> >>
>> >> >> -static int hdmiphy_probe(struct i2c_client *client,
>> >> >> -       const struct i2c_device_id *id)
>> >> >> +struct hdmiphy_context {
>> >> >> +       struct device           *dev;
>> >> >> +       struct hdmiphy_config   *current_conf;
>> >> >> +
>> >> >> +       struct hdmiphy_config   *confs;
>> >> >> +       unsigned int            nr_confs;
>> >> >> +};
>> >> >> +
>> >> >> +struct hdmiphy_config {
>> >> >> +       int pixel_clock;
>> >> >> +       u8 conf[HDMIPHY_REG_COUNT];
>> >> >> +};
>> >> >> +
>> >> >> +struct hdmiphy_drv_data {
>> >> >> +       struct hdmiphy_config *confs;
>> >> >> +       unsigned int count;
>> >> >> +};
>> >> >> +
>> >> >> +/* list of all required phy config settings */
>> >> >> +static struct hdmiphy_config hdmiphy_4212_configs[] = {
>> >> >> +       {
>> >> >> +               .pixel_clock = 25200000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00,
> 0x08,
>> >> >> +                       0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 27000000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc,
> 0x20,
>> >> >> +                       0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 27027000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12,
> 0x08,
>> >> >> +                       0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01,
> 0x00,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 36000000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00,
> 0x08,
>> >> >> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 40000000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00,
> 0x08,
>> >> >> +                       0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 65000000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a,
> 0x08,
>> >> >> +                       0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 74176000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde,
> 0x08,
>> >> >> +                       0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 74250000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8,
> 0x08,
>> >> >> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01,
> 0x00,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 83500000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb,
> 0x08,
>> >> >> +                       0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 106500000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09,
> 0x08,
>> >> >> +                       0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 108000000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00,
> 0x08,
>> >> >> +                       0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 146250000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd,
> 0x08,
>> >> >> +                       0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01,
> 0x80,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 148500000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8,
> 0x08,
>> >> >> +                       0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac,
> 0x80,
>> >> >> +                       0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44,
> 0x86,
>> >> >> +                       0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01,
> 0x00,
>> >> >> +               },
>> >> >> +       },
>> >> >> +};
>> >> >> +
>> >> >> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
>> >> >> +       {
>> >> >> +               .pixel_clock = 27000000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30,
> 0x40,
>> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
> 0x87,
>> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
> 0xE0,
>> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
> 0x00,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 27027000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09,
> 0x64,
>> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
> 0x87,
>> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
> 0xE0,
>> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
> 0x00,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 74176000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef,
> 0x5B,
>> >> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54,
> 0xb9,
>> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
> 0xE0,
>> >> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00,
> 0x00,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 74250000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8,
> 0x40,
>> >> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54,
> 0xba,
>> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10,
> 0xe0,
>> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00,
> 0x00,
>> >> >> +               },
>> >> >> +       },
>> >> >> +       {
>> >> >> +               .pixel_clock = 148500000,
>> >> >> +               .conf = {
>> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8,
> 0x40,
>> >> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54,
> 0xba,
>> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10,
> 0xE0,
>> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00,
> 0x00,
>> >> >> +               },
>> >> >> +       },
>> >> >> +};
>> >> >> +
>> >> >
>> >> > Are you aware of the effort to move these to dt? Since these are
>> >> > board-specific values, it seems incorrect to apply them universally.
>> >> > Shirish has uploaded a patch to the chromium review site to push
>> these
>> >> > into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
>> >> > you can work that into your patch set?
>> >> >
>> >
>> > Are these really board-specific values?
>>
>> According to your hardware people:
>>
>> "If the signal pattern doesn't change for new board, the phy setting
>> is same as the current board. But if changed, you need to confirm with
>> measurement of signals, because it may vary slightly by resistance of
>> board pattern"
>>
>
> Right. it seems that the phy configuration should be adjusted according to
> PCB environment: OSC clock rate, 24MHz or 27MHz, could be decided by PCB
> even though most PCBs use 27MHz.
>
>> That indicates to me that we might need to tweak these on a per-board
>> basis.
>>
>> In the 5420 datasheet, there are a few register descriptions available
>> for the phy. 0x145D0004 is CLK_SEL which seems like it would be
>> board-specific, same with TX_* registers.
>>
>
> And we can select HDMI Tx PHY internal PLL input clock by setting CLK_SEL.
> Ok, Shirish's patch set is reasonable to me. However, that patch set should
> be rebased on top of Rahul's patch set. Shirish and Rahul, please re-post
> your patch set after discussing how to rebase these patch set.
>
> Thanks,
> Inki Dae
>

In that case, we need to test the phy confs for all the exynos boards,
supported in
mainline. Probably needs a analyser as well to precisely compare the deviation.
Shirish patch is only for 5420 Peach board. Else, to start with we can mark
phyconf as optional property which overrides the default Phy Confs for
given SoC.

regards,
Rahul Sharma.

>> Sean
>>
>>
>>
>> > I think they are SoC-specific
>> > values, and it's better to define them in the driver. For this, I gave
>> > already comments to Shirish why these constraints should be placed in
>> > driver. For more detail, you can also refer to the below link,
>> >
>> > http://www.mail-archive.com/devicetree-
>> discuss@lists.ozlabs.org/msg36691.htm
>> > l
>> >
>> > Thanks,
>> > Inki Dae
>> >
>> >>
>> >> I have gone through these patches. I am adding Shirish here for further
>> >> discussion on these changes. he can explain better.
>> >>
>> >> >
>> >> >> +static struct hdmiphy_config *hdmiphy_find_conf(struct
>> hdmiphy_context
>> >> *hdata,
>> >> >> +                       const struct drm_display_mode *mode)
>> >> >> +{
>> >> >> +       int i;
>> >> >> +
>> >> >> +       for (i = 0; i < hdata->nr_confs; i++)
>> >> >> +               if (hdata->confs[i].pixel_clock == (mode->clock *
>> > 1000))
>> >> >> +                       return &hdata->confs[i];
>> >> >> +
>> >> >> +       return NULL;
>> >> >> +}
>> >> >> +
>> >> >> +static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata,
>> >> >> +                       u32 reg_offset, u8 value)
>> >> >> +{
>> >> >> +       if (reg_offset >= HDMIPHY_REG_COUNT)
>> >> >> +               return -EINVAL;
>> >> >> +
>> >> >> +       if (i2c_verify_client(hdata->dev)) {
>> >> >
>> >> > Is this necessary?
>> >>
>> >> Based on this check, I was deciding that given dev is i2c or
>> >> platform device. But now when we agreed to split drivers to
>> >> phy and plf driver, I will remove this.
>> >>
>> >> >
>> >> >> +               u8 buffer[2];
>> >> >> +               int ret;
>> >> >> +
>> >> >> +               buffer[0] = reg_offset;
>> >> >> +               buffer[1] = value;
>> >> >> +
>> >> >> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
>> >> >> +                               buffer, 2);
>> >> >> +               if (ret == 2)
>> >> >> +                       return 0;
>> >> >> +               return ret;
>> >> >> +       } else {
>> >> >> +               return -EINVAL;
>> >> >> +       }
>> >> >> +}
>> >> >> +
>> >> >> +static int hdmiphy_reg_write_buf(struct hdmiphy_context *hdata,
>> >> >> +                       u32 reg_offset, const u8 *buf, u32 len)
>> >> >> +{
>> >> >> +       if ((reg_offset + len) > HDMIPHY_REG_COUNT)
>> >> >> +               return -EINVAL;
>> >> >> +
>> >> >> +       if (i2c_verify_client(hdata->dev)) {
>> >> >
>> >> > Is this necessary?
>> >> >
>> >> >
>> >> >> +               int ret;
>> >> >> +
>> >> >> +               ret = i2c_master_send(to_i2c_client(hdata->dev),
>> >> >> +                               buf, len);
>> >> >
>> >> > Does this actually work? You don't seem to be using reg_offset
>> anywhere.
>> >> >
>> >>
>> >> reg_offset is not required here. I should remove this. This
>> >> procedure is to write the complete buf starting from 0.
>> >> hdmiphy_reg_writeb is supposed to be used for writing
>> >> value from some offset.
>> >>
>> >> >> +               if (ret == len)
>> >> >> +                       return 0;
>> >> >> +               return ret;
>> >> >> +       } else {
>> >> >> +               return -EINVAL;
>> >> >> +       }
>> >> >> +}
>> >> >> +
>> >> >> +int exynos_hdmiphy_check_mode(struct device *dev,
>> >> >> +                       struct drm_display_mode *mode)
>> >> >>  {
>> >> >> -       hdmi_attach_hdmiphy_client(client);
>> >> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> >> >> +       const struct hdmiphy_config *conf;
>> >> >> +
>> >> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> >> >
>> >> > Maybe you can merge this debug message with the one below.
>> >> >
>> >>
>> >> ok.
>> >>
>> >> >>
>> >> >> -       dev_info(&client->adapter->dev, "attached s5p_hdmiphy "
>> >> >> -               "into i2c adapter successfully\n");
>> >> >> +       if (!hdata) {
>> >> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> >> >> +               return -EINVAL;
>> >> >> +       }
>> >> >
>> >> > Can this happen? I think the phy driver registration should be
>> >> > synchronous with the hdmi driver registration. As such, it shouldn't
>> >> > be possible to get a check_mode callback until it's all set up.
>> >> >
>> >>
>> >> I will confirm on this.
>> >>
>> >> >>
>> >> >> +       DRM_DEBUG("xres=%d, yres=%d, refresh=%d, intl=%d
> clock=%d\n",
>> >> >> +               mode->hdisplay, mode->vdisplay,
>> >> >> +               mode->vrefresh, (mode->flags &
> DRM_MODE_FLAG_INTERLACE)
>> >> >> +               ? true : false, mode->clock * 1000);
>> >> >> +
>> >> >> +       conf = hdmiphy_find_conf(hdata, mode);
>> >> >> +       if (!conf) {
>> >> >> +               DRM_DEBUG("Display Mode is not supported.\n");
>> >> >> +               return -EINVAL;
>> >> >> +       }
>> >> >>         return 0;
>> >> >>  }
>> >> >>
>> >> >> -static int hdmiphy_remove(struct i2c_client *client)
>> >> >> +int exynos_hdmiphy_set_mode(struct device *dev,
>> >> >> +                       struct drm_display_mode *mode)
>> >> >>  {
>> >> >> -       dev_info(&client->adapter->dev, "detached s5p_hdmiphy "
>> >> >> -               "from i2c adapter successfully\n");
>> >> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> >> >> +
>> >> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> >> >> +
>> >> >> +       hdata->current_conf = hdmiphy_find_conf(hdata, mode);
>> >> >> +
>> >> >> +       if (!hdata) {
>> >> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> >> >> +               return -EINVAL;
>> >> >> +       }
>> >> >
>> >> > I really hope this check isn't necessary, since you've already
>> >> > dereferenced it 2 lines up :) See my comment above, I don't think you
>> >> > can ever hit this.
>> >> >
>> >> >>
>> >> >> +       if (!hdata->current_conf) {
>> >> >> +               DRM_ERROR("Display Mode is not supported.\n");
>> >> >> +               return -EINVAL;
>> >> >> +       }
>> >> >>         return 0;
>> >> >>  }
>> >> >>
>> >> >> -static struct of_device_id hdmiphy_match_types[] = {
>> >> >> +void exynos_hdmiphy_enable(struct device *dev)
>> >> >> +{
>> >> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> >> >> +       int ret;
>> >> >> +
>> >> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> >> >> +
>> >> >> +       if (!hdata) {
>> >> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> >> >> +               return;
>> >> >> +       }
>> >> >
>> >> > Same comment as above.
>> >> >
>> >> >> +
>> >> >> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
>> >> >> +                       HDMIPHY_MODE_EN);
>> >> >> +       if (ret < 0) {
>> >> >> +               DRM_ERROR("failed to disable hdmiphy.\n");
>> >> >> +               return;
>> >> >> +       }
>> >> >> +}
>> >> >> +
>> >> >> +void exynos_hdmiphy_disable(struct device *dev)
>> >> >> +{
>> >> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> >> >> +       int ret;
>> >> >> +
>> >> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> >> >> +
>> >> >> +       if (!hdata) {
>> >> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> >> >> +               return;
>> >> >> +       }
>> >> >> +
>> >> >> +       ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, 0);
>> >> >> +       if (ret < 0) {
>> >> >> +               DRM_ERROR("failed to enable hdmiphy.\n");
>> >> >
>> >> > If you're not going to return the error code, at least print it here.
>> >> >
>> >>
>> >> ok.
>> >>
>> >> >> +               return;
>> >> >> +       }
>> >> >> +}
>> >> >> +
>> >> >> +int exynos_hdmiphy_conf_apply(struct device *dev)
>> >> >> +{
>> >> >> +       struct hdmiphy_context *hdata = dev_get_drvdata(dev);
>> >> >> +       const u8 *hdmiphy_data;
>> >> >> +       int ret;
>> >> >> +
>> >> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> >> >> +
>> >> >> +       if (!hdata) {
>> >> >> +               DRM_ERROR("Invalid arg: hdmiphy device pointer.\n");
>> >> >> +               return -EINVAL;
>> >> >> +       }
>> >> >> +
>> >> >> +       /* pixel clock */
>> >> >
>> >> > I don't understand this comment.
>> >> >
>> >>
>> >> I will remove this.
>> >>
>> >> >> +       if (hdata->current_conf)
>> >> >> +               hdmiphy_data = hdata->current_conf->conf;
>> >> >> +       else
>> >> >> +               return -EINVAL;
>> >> >> +
>> >> >> +       ret = hdmiphy_reg_write_buf(hdata, 0, hdmiphy_data,
>> >> >> +                       HDMIPHY_REG_COUNT);
>> >> >
>> >> > I think the only reason this works is b/c you're writing to register
>> >> offset 0.
>> >> >
>> >> >> +       if (ret) {
>> >> >> +               DRM_ERROR("failed to configure hdmiphy.\n");
>> >> >> +               return -EINVAL;
>> >> >
>> >> > Why don't you return ret?
>> >> >
>> >>
>> >> ok.
>> >>
>> >> >> +       }
>> >> >> +       return 0;
>> >> >> +}
>> >> >> +
>> >> >> +static struct hdmiphy_drv_data exynos4212_hdmiphy_drv_data = {
>> >> >> +       .confs = hdmiphy_4212_configs,
>> >> >> +       .count = ARRAY_SIZE(hdmiphy_4212_configs)
>> >> >> +};
>> >> >> +
>> >> >> +static struct hdmiphy_drv_data exynos4210_hdmiphy_drv_data = {
>> >> >> +       .confs = hdmiphy_4210_configs,
>> >> >> +       .count = ARRAY_SIZE(hdmiphy_4210_configs)
>> >> >> +};
>> >> >> +
>> >> >> +static struct of_device_id hdmiphy_i2c_device_match_types[] = {
>> >> >>         {
>> >> >>                 .compatible = "samsung,exynos5-hdmiphy",
>> >> >> +               .data   = &exynos4212_hdmiphy_drv_data,
>> >> >>         }, {
>> >> >>                 .compatible = "samsung,exynos4210-hdmiphy",
>> >> >> +               .data   = &exynos4210_hdmiphy_drv_data,
>> >> >>         }, {
>> >> >>                 .compatible = "samsung,exynos4212-hdmiphy",
>> >> >> +               .data   = &exynos4212_hdmiphy_drv_data,
>> >> >>         }, {
>> >> >>                 /* end node */
>> >> >>         }
>> >> >>  };
>> >> >>
>> >> >> -struct i2c_driver hdmiphy_driver = {
>> >> >> +static int hdmiphy_i2c_device_probe(struct i2c_client *client,
>> >> >> +       const struct i2c_device_id *id)
>> >> >> +{
>> >> >> +       struct device *dev = &client->dev;
>> >> >> +       struct hdmiphy_context *hdata;
>> >> >> +       struct hdmiphy_drv_data *drv;
>> >> >> +       const struct of_device_id *match;
>> >> >> +
>> >> >> +       DRM_DEBUG_KMS("[%d]\n", __LINE__);
>> >> >> +
>> >> >> +       hdata = devm_kzalloc(dev, sizeof(*hdata), GFP_KERNEL);
>> >> >> +       if (!hdata) {
>> >> >> +               DRM_ERROR("failed to allocate hdmiphy context.\n");
>> >> >> +               return -ENOMEM;
>> >> >> +       }
>> >> >> +
>> >> >> +       match = of_match_node(of_match_ptr(
>> >> >> +               hdmiphy_i2c_device_match_types),
>> >> >> +               dev->of_node);
>> >> >> +
>> >> >> +       if (match == NULL)
>> >> >> +               return -ENODEV;
>> >> >> +
>> >> >> +       drv = (struct hdmiphy_drv_data *)match->data;
>> >> >> +
>> >> >> +       hdata->dev = dev;
>> >> >> +       hdata->confs = drv->confs;
>> >> >> +       hdata->nr_confs = drv->count;
>> >> >> +
>> >> >> +       i2c_set_clientdata(client, hdata);
>> >> >> +
>> >> >> +       return 0;
>> >> >> +}
>> >> >> +
>> >> >> +static const struct i2c_device_id hdmiphy_id[] = {
>> >> >> +       { },
>> >> >> +};
>> >> >> +
>> >> >> +struct i2c_driver hdmiphy_i2c_driver = {
>> >> >>         .driver = {
>> >> >>                 .name   = "exynos-hdmiphy",
>> >> >>                 .owner  = THIS_MODULE,
>> >> >> -               .of_match_table = hdmiphy_match_types,
>> >> >> +               .of_match_table = of_match_ptr(
>> >> >> +                               hdmiphy_i2c_device_match_types),
>> >> >>         },
>> >> >> -       .probe          = hdmiphy_probe,
>> >> >> -       .remove         = hdmiphy_remove,
>> >> >> +       .id_table               = hdmiphy_id,
>> >> >> +       .probe          = hdmiphy_i2c_device_probe,
>> >> >>         .command                = NULL,
>> >> >>  };
>> >> >> -EXPORT_SYMBOL(hdmiphy_driver);
>> >> >> +
>> >> >> +int exynos_hdmiphy_driver_register(void)
>> >> >> +{
>> >> >> +       int ret;
>> >> >> +
>> >> >> +       ret = i2c_add_driver(&hdmiphy_i2c_driver);
>> >> >> +       if (ret)
>> >> >> +               return ret;
>> >> >> +
>> >> >> +       return 0;
>> >> >> +}
>> >> >> +
>> >> >> +void exynos_hdmiphy_driver_unregister(void)
>> >> >> +{
>> >> >> +       i2c_del_driver(&hdmiphy_i2c_driver);
>> >> >> +}
>> >> >> diff --git a/drivers/gpu/drm/exynos/regs-hdmiphy.h
>> >> b/drivers/gpu/drm/exynos/regs-hdmiphy.h
>> >> >> new file mode 100644
>> >> >> index 0000000..d3f9d87
>> >> >> --- /dev/null
>> >> >> +++ b/drivers/gpu/drm/exynos/regs-hdmiphy.h
>> >> >> @@ -0,0 +1,35 @@
>> >> >> +/*
>> >> >> + *
>> >> >> + *  regs-hdmiphy.h
>> >> >> + *
>> >> >> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
>> >> >> + * http://www.samsung.com/
>> >> >> + *
>> >> >> + * HDMI-PHY register header file for Samsung HDMI driver
>> >> >> + *
>> >> >> + * This program is free software; you can redistribute it and/or
>> >> modify
>> >> >> + * it under the terms of the GNU General Public License version 2
>> as
>> >> >> + * published by the Free Software Foundation.
>> >> >> +*/
>> >> >> +
>> >> >> +#ifndef SAMSUNG_REGS_HDMIPHY_H
>> >> >> +#define SAMSUNG_REGS_HDMIPHY_H
>> >> >> +
>> >> >> +/*
>> >> >> + * Register part
>> >> >> +*/
>> >> >> +#define HDMIPHY_MODE_SET_DONE  (0x1f)
>> >> >> +
>> >> >> +/*
>> >> >> + * Bit definition part
>> >> >> + */
>> >> >> +
>> >> >> +/* HDMIPHY_MODE_SET_DONE */
>> >> >> +#define HDMIPHY_MODE_EN                (1 << 7)
>> >> >> +
>> >> >> +/* hdmiphy pmu control bits */
>> >> >> +#define PMU_HDMI_PHY_CONTROL_MASK      (1 << 0)
>> >> >> +#define PMU_HDMI_PHY_ENABLE            (1)
>> >> >> +#define PMU_HDMI_PHY_DISABLE           (0)
>> >> >
>> >> >
>> >> > You don't need the () around simple values
>> >> >
>> >>
>> >> ok.
>> >>
>> >> We also discussed previously to keep independent i2c and
>> >> platform phy drivers in exynos_hdmiphy_i2c.c and
>> >> exynos_hdmiphy_platform.c respectively, which will duplicate
>> >> the code to some extent.
>> >>
>> >> Second point is to implement exynos_i2c_hdmiphy_get_ops()
>> >> and exynos_platform_hdmiphy_get_ops() to get access to all
>> >> callbacks. This will limit the exposure of phy callbacks to the
>> >> phy controller.
>> >>
>> >> Please share your views on this.
>> >>
>> >> Regards,
>> >> Rahul Sharma.
>> >>
>> >> >> +
>> >> >> +#endif /* SAMSUNG_REGS_HDMIPHY_H */
>> >> >> --
>> >> >> 1.7.10.4
>> >> >>
>> >
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-samsung-
>> soc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-05  4:43             ` Rahul Sharma
@ 2013-09-05  5:22               ` Inki Dae
  2013-09-05  6:03                 ` Rahul Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Inki Dae @ 2013-09-05  5:22 UTC (permalink / raw)
  To: 'Rahul Sharma'
  Cc: 'Sean Paul', 'Rahul Sharma',
	'linux-samsung-soc', 'dri-devel',
	'kgene.kim', 'sw0312.kim', 'Lucas Stach',
	'Tomasz Figa', 'Sylwester Nawrocki',
	'sunil joshi', 'Shirish S'

> >> >> >> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
> >> >> >> +       {
> >> >> >> +               .pixel_clock = 27000000,
> >> >> >> +               .conf = {
> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30,
> > 0x40,
> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
> > 0x87,
> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
> > 0xE0,
> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
> > 0x00,
> >> >> >> +               },
> >> >> >> +       },
> >> >> >> +       {
> >> >> >> +               .pixel_clock = 27027000,
> >> >> >> +               .conf = {
> >> >> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09,
> > 0x64,
> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
> > 0x87,
> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
> > 0xE0,
> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
> > 0x00,
> >> >> >> +               },
> >> >> >> +       },
> >> >> >> +       {
> >> >> >> +               .pixel_clock = 74176000,
> >> >> >> +               .conf = {
> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef,
> > 0x5B,
> >> >> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54,
> > 0xb9,
> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
> > 0xE0,
> >> >> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00,
> > 0x00,
> >> >> >> +               },
> >> >> >> +       },
> >> >> >> +       {
> >> >> >> +               .pixel_clock = 74250000,
> >> >> >> +               .conf = {
> >> >> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8,
> > 0x40,
> >> >> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54,
> > 0xba,
> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10,
> > 0xe0,
> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00,
> > 0x00,
> >> >> >> +               },
> >> >> >> +       },
> >> >> >> +       {
> >> >> >> +               .pixel_clock = 148500000,
> >> >> >> +               .conf = {
> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8,
> > 0x40,
> >> >> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54,
> > 0xba,
> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10,
> > 0xE0,
> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00,
> > 0x00,
> >> >> >> +               },
> >> >> >> +       },
> >> >> >> +};
> >> >> >> +
> >> >> >
> >> >> > Are you aware of the effort to move these to dt? Since these are
> >> >> > board-specific values, it seems incorrect to apply them
> universally.
> >> >> > Shirish has uploaded a patch to the chromium review site to push
> >> these
> >> >> > into dt (https://chromium-review.googlesource.com/#/c/65581).
> Maybe
> >> >> > you can work that into your patch set?
> >> >> >
> >> >
> >> > Are these really board-specific values?
> >>
> >> According to your hardware people:
> >>
> >> "If the signal pattern doesn't change for new board, the phy setting
> >> is same as the current board. But if changed, you need to confirm with
> >> measurement of signals, because it may vary slightly by resistance of
> >> board pattern"
> >>
> >
> > Right. it seems that the phy configuration should be adjusted according
> to
> > PCB environment: OSC clock rate, 24MHz or 27MHz, could be decided by PCB
> > even though most PCBs use 27MHz.
> >
> >> That indicates to me that we might need to tweak these on a per-board
> >> basis.
> >>
> >> In the 5420 datasheet, there are a few register descriptions available
> >> for the phy. 0x145D0004 is CLK_SEL which seems like it would be
> >> board-specific, same with TX_* registers.
> >>
> >
> > And we can select HDMI Tx PHY internal PLL input clock by setting
> CLK_SEL.
> > Ok, Shirish's patch set is reasonable to me. However, that patch set
> should
> > be rebased on top of Rahul's patch set. Shirish and Rahul, please re-
> post
> > your patch set after discussing how to rebase these patch set.
> >
> > Thanks,
> > Inki Dae
> >
> 
> In that case, we need to test the phy confs for all the exynos boards,
> supported in
> mainline. Probably needs a analyser as well to precisely compare the
> deviation.

Shirish patch adds phy config data only to arndale and smdk5250 boards, and
these config data should have each board specific values. Therefore, for
other boards, shouldn't correct phy config data suitable to their boards be
added to their board dts files? Is the above analyzer really needed?

> Shirish patch is only for 5420 Peach board. Else, to start with we can
> mark
> phyconf as optional property which overrides the default Phy Confs for
> given SoC.

Hm.... you mean that hdmiphy driver use the default phy config data in
driver; most boards use the same data, and only in special case; a board
uses different OSC clock rate, the hdmiphy driver use phy config data from
dts file checking hdmiphy-confs property?


> 	
> regards,
> Rahul Sharma.
> 
> >> Sean
> >>
> >>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-05  5:22               ` Inki Dae
@ 2013-09-05  6:03                 ` Rahul Sharma
  2013-09-05  6:19                   ` Inki Dae
  0 siblings, 1 reply; 45+ messages in thread
From: Rahul Sharma @ 2013-09-05  6:03 UTC (permalink / raw)
  To: Inki Dae
  Cc: Sean Paul, Rahul Sharma, linux-samsung-soc, dri-devel, kgene.kim,
	sw0312.kim, Lucas Stach, Tomasz Figa, Sylwester Nawrocki,
	sunil joshi, Shirish S

On 5 September 2013 10:52, Inki Dae <inki.dae@samsung.com> wrote:
>> >> >> >> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
>> >> >> >> +       {
>> >> >> >> +               .pixel_clock = 27000000,
>> >> >> >> +               .conf = {
>> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30,
>> > 0x40,
>> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
>> > 0x87,
>> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
>> > 0xE0,
>> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
>> > 0x00,
>> >> >> >> +               },
>> >> >> >> +       },
>> >> >> >> +       {
>> >> >> >> +               .pixel_clock = 27027000,
>> >> >> >> +               .conf = {
>> >> >> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09,
>> > 0x64,
>> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
>> > 0x87,
>> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
>> > 0xE0,
>> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
>> > 0x00,
>> >> >> >> +               },
>> >> >> >> +       },
>> >> >> >> +       {
>> >> >> >> +               .pixel_clock = 74176000,
>> >> >> >> +               .conf = {
>> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef,
>> > 0x5B,
>> >> >> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54,
>> > 0xb9,
>> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
>> > 0xE0,
>> >> >> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00,
>> > 0x00,
>> >> >> >> +               },
>> >> >> >> +       },
>> >> >> >> +       {
>> >> >> >> +               .pixel_clock = 74250000,
>> >> >> >> +               .conf = {
>> >> >> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8,
>> > 0x40,
>> >> >> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54,
>> > 0xba,
>> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10,
>> > 0xe0,
>> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00,
>> > 0x00,
>> >> >> >> +               },
>> >> >> >> +       },
>> >> >> >> +       {
>> >> >> >> +               .pixel_clock = 148500000,
>> >> >> >> +               .conf = {
>> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8,
>> > 0x40,
>> >> >> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54,
>> > 0xba,
>> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10,
>> > 0xE0,
>> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00,
>> > 0x00,
>> >> >> >> +               },
>> >> >> >> +       },
>> >> >> >> +};
>> >> >> >> +
>> >> >> >
>> >> >> > Are you aware of the effort to move these to dt? Since these are
>> >> >> > board-specific values, it seems incorrect to apply them
>> universally.
>> >> >> > Shirish has uploaded a patch to the chromium review site to push
>> >> these
>> >> >> > into dt (https://chromium-review.googlesource.com/#/c/65581).
>> Maybe
>> >> >> > you can work that into your patch set?
>> >> >> >
>> >> >
>> >> > Are these really board-specific values?
>> >>
>> >> According to your hardware people:
>> >>
>> >> "If the signal pattern doesn't change for new board, the phy setting
>> >> is same as the current board. But if changed, you need to confirm with
>> >> measurement of signals, because it may vary slightly by resistance of
>> >> board pattern"
>> >>
>> >
>> > Right. it seems that the phy configuration should be adjusted according
>> to
>> > PCB environment: OSC clock rate, 24MHz or 27MHz, could be decided by PCB
>> > even though most PCBs use 27MHz.
>> >
>> >> That indicates to me that we might need to tweak these on a per-board
>> >> basis.
>> >>
>> >> In the 5420 datasheet, there are a few register descriptions available
>> >> for the phy. 0x145D0004 is CLK_SEL which seems like it would be
>> >> board-specific, same with TX_* registers.
>> >>
>> >
>> > And we can select HDMI Tx PHY internal PLL input clock by setting
>> CLK_SEL.
>> > Ok, Shirish's patch set is reasonable to me. However, that patch set
>> should
>> > be rebased on top of Rahul's patch set. Shirish and Rahul, please re-
>> post
>> > your patch set after discussing how to rebase these patch set.
>> >
>> > Thanks,
>> > Inki Dae
>> >
>>
>> In that case, we need to test the phy confs for all the exynos boards,
>> supported in
>> mainline. Probably needs a analyser as well to precisely compare the
>> deviation.
>
> Shirish patch adds phy config data only to arndale and smdk5250 boards, and
> these config data should have each board specific values. Therefore, for
> other boards, shouldn't correct phy config data suitable to their boards be
> added to their board dts files? Is the above analyzer really needed?
>

Sorry, I had only seen his patches for chromium tree. In mainline
version, he added for 5250 as well. But both sets (for arndale and
smdk) are exactly same as original 5250 configs which also works
with 4412 origen.

Some problem has been identified during conformance testing for
5420 peach board, which happens with analyser. It was always
working fine on the TV sets that I have. @Shirish/Sean please
correct me if wrong.

>> Shirish patch is only for 5420 Peach board. Else, to start with we can
>> mark
>> phyconf as optional property which overrides the default Phy Confs for
>> given SoC.
>
> Hm.... you mean that hdmiphy driver use the default phy config data in
> driver; most boards use the same data, and only in special case; a board
> uses different OSC clock rate, the hdmiphy driver use phy config data from
> dts file checking hdmiphy-confs property?
>

Yes. I meant same. I don't see the real need to duplicate so much
of data in all board dts files. We can add it for a particular board, if
really required.

Regards,
Rahul Sharma.

>
>>
>> regards,
>> Rahul Sharma.
>>
>> >> Sean
>> >>
>> >>
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-05  6:03                 ` Rahul Sharma
@ 2013-09-05  6:19                   ` Inki Dae
  2013-09-05 13:19                     ` Sean Paul
  0 siblings, 1 reply; 45+ messages in thread
From: Inki Dae @ 2013-09-05  6:19 UTC (permalink / raw)
  To: 'Rahul Sharma'
  Cc: 'Sean Paul', 'Rahul Sharma',
	'linux-samsung-soc', 'dri-devel',
	'kgene.kim', 'sw0312.kim', 'Lucas Stach',
	'Tomasz Figa', 'Sylwester Nawrocki',
	'sunil joshi', 'Shirish S'



> -----Original Message-----
> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-soc-
> owner@vger.kernel.org] On Behalf Of Rahul Sharma
> Sent: Thursday, September 05, 2013 3:04 PM
> To: Inki Dae
> Cc: Sean Paul; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
> Shirish S
> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
> driver
> 
> On 5 September 2013 10:52, Inki Dae <inki.dae@samsung.com> wrote:
> >> >> >> >> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
> >> >> >> >> +       {
> >> >> >> >> +               .pixel_clock = 27000000,
> >> >> >> >> +               .conf = {
> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C,
0x30,
> >> > 0x40,
> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2,
0x54,
> >> > 0x87,
> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
0x10,
> >> > 0xE0,
> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00,
0x00,
> >> > 0x00,
> >> >> >> >> +               },
> >> >> >> >> +       },
> >> >> >> >> +       {
> >> >> >> >> +               .pixel_clock = 27027000,
> >> >> >> >> +               .conf = {
> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C,
0x09,
> >> > 0x64,
> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2,
0x54,
> >> > 0x87,
> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
0x10,
> >> > 0xE0,
> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00,
0x00,
> >> > 0x00,
> >> >> >> >> +               },
> >> >> >> >> +       },
> >> >> >> >> +       {
> >> >> >> >> +               .pixel_clock = 74176000,
> >> >> >> >> +               .conf = {
> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C,
0xef,
> >> > 0x5B,
> >> >> >> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3,
0x54,
> >> > 0xb9,
> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
0x10,
> >> > 0xE0,
> >> >> >> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00,
0x00,
> >> > 0x00,
> >> >> >> >> +               },
> >> >> >> >> +       },
> >> >> >> >> +       {
> >> >> >> >> +               .pixel_clock = 74250000,
> >> >> >> >> +               .conf = {
> >> >> >> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c,
0xf8,
> >> > 0x40,
> >> >> >> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1,
0x54,
> >> > 0xba,
> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08,
0x10,
> >> > 0xe0,
> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00,
0x00,
> >> > 0x00,
> >> >> >> >> +               },
> >> >> >> >> +       },
> >> >> >> >> +       {
> >> >> >> >> +               .pixel_clock = 148500000,
> >> >> >> >> +               .conf = {
> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C,
0xf8,
> >> > 0x40,
> >> >> >> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1,
0x54,
> >> > 0xba,
> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08,
0x10,
> >> > 0xE0,
> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00,
0x00,
> >> > 0x00,
> >> >> >> >> +               },
> >> >> >> >> +       },
> >> >> >> >> +};
> >> >> >> >> +
> >> >> >> >
> >> >> >> > Are you aware of the effort to move these to dt? Since these
> are
> >> >> >> > board-specific values, it seems incorrect to apply them
> >> universally.
> >> >> >> > Shirish has uploaded a patch to the chromium review site to
> push
> >> >> these
> >> >> >> > into dt (https://chromium-review.googlesource.com/#/c/65581).
> >> Maybe
> >> >> >> > you can work that into your patch set?
> >> >> >> >
> >> >> >
> >> >> > Are these really board-specific values?
> >> >>
> >> >> According to your hardware people:
> >> >>
> >> >> "If the signal pattern doesn't change for new board, the phy setting
> >> >> is same as the current board. But if changed, you need to confirm
> with
> >> >> measurement of signals, because it may vary slightly by resistance
> of
> >> >> board pattern"
> >> >>
> >> >
> >> > Right. it seems that the phy configuration should be adjusted
> according
> >> to
> >> > PCB environment: OSC clock rate, 24MHz or 27MHz, could be decided by
> PCB
> >> > even though most PCBs use 27MHz.
> >> >
> >> >> That indicates to me that we might need to tweak these on a per-
> board
> >> >> basis.
> >> >>
> >> >> In the 5420 datasheet, there are a few register descriptions
> available
> >> >> for the phy. 0x145D0004 is CLK_SEL which seems like it would be
> >> >> board-specific, same with TX_* registers.
> >> >>
> >> >
> >> > And we can select HDMI Tx PHY internal PLL input clock by setting
> >> CLK_SEL.
> >> > Ok, Shirish's patch set is reasonable to me. However, that patch set
> >> should
> >> > be rebased on top of Rahul's patch set. Shirish and Rahul, please re-
> >> post
> >> > your patch set after discussing how to rebase these patch set.
> >> >
> >> > Thanks,
> >> > Inki Dae
> >> >
> >>
> >> In that case, we need to test the phy confs for all the exynos boards,
> >> supported in
> >> mainline. Probably needs a analyser as well to precisely compare the
> >> deviation.
> >
> > Shirish patch adds phy config data only to arndale and smdk5250 boards,
> and
> > these config data should have each board specific values. Therefore, for
> > other boards, shouldn't correct phy config data suitable to their boards
> be
> > added to their board dts files? Is the above analyzer really needed?
> >
> 
> Sorry, I had only seen his patches for chromium tree. In mainline
> version, he added for 5250 as well. But both sets (for arndale and
> smdk) are exactly same as original 5250 configs which also works
> with 4412 origen.
> 
> Some problem has been identified during conformance testing for
> 5420 peach board, which happens with analyser. It was always
> working fine on the TV sets that I have. @Shirish/Sean please
> correct me if wrong.
> 
> >> Shirish patch is only for 5420 Peach board. Else, to start with we can
> >> mark
> >> phyconf as optional property which overrides the default Phy Confs for
> >> given SoC.
> >
> > Hm.... you mean that hdmiphy driver use the default phy config data in
> > driver; most boards use the same data, and only in special case; a board
> > uses different OSC clock rate, the hdmiphy driver use phy config data
> from
> > dts file checking hdmiphy-confs property?
> >
> 
> Yes. I meant same. I don't see the real need to duplicate so much
> of data in all board dts files. We can add it for a particular board, if
> really required.
> 

Yes, reasonable to me. It's not good that board dts files have same phy
config data. How about using the phy config data from dts file if
hdmiphy-confs property exists, otherwise using default phy config data then?
This means that we don't need to remove the phy config data from driver;
that will be used as default values.

Rahul, let's go if there is other opinion. we SHOULD MERGE these this
time.:)

Thanks,
Inki Dae

> Regards,
> Rahul Sharma.
> 
> >
> >>
> >> regards,
> >> Rahul Sharma.
> >>
> >> >> Sean
> >> >>
> >> >>
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-
> soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-05  6:19                   ` Inki Dae
@ 2013-09-05 13:19                     ` Sean Paul
  2013-09-05 13:50                       ` Inki Dae
  0 siblings, 1 reply; 45+ messages in thread
From: Sean Paul @ 2013-09-05 13:19 UTC (permalink / raw)
  To: Inki Dae
  Cc: Rahul Sharma, Rahul Sharma, linux-samsung-soc, dri-devel,
	kgene.kim, sw0312.kim, Lucas Stach, Tomasz Figa,
	Sylwester Nawrocki, sunil joshi, Shirish S

On Thu, Sep 5, 2013 at 2:19 AM, Inki Dae <inki.dae@samsung.com> wrote:
>
>
>> -----Original Message-----
>> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-soc-
>> owner@vger.kernel.org] On Behalf Of Rahul Sharma
>> Sent: Thursday, September 05, 2013 3:04 PM
>> To: Inki Dae
>> Cc: Sean Paul; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
>> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
>> Shirish S
>> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
>> driver
>>
>> On 5 September 2013 10:52, Inki Dae <inki.dae@samsung.com> wrote:
>> >> >> >> >> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
>> >> >> >> >> +       {
>> >> >> >> >> +               .pixel_clock = 27000000,
>> >> >> >> >> +               .conf = {
>> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C,
> 0x30,
>> >> > 0x40,
>> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2,
> 0x54,
>> >> > 0x87,
>> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
> 0x10,
>> >> > 0xE0,
>> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00,
> 0x00,
>> >> > 0x00,
>> >> >> >> >> +               },
>> >> >> >> >> +       },
>> >> >> >> >> +       {
>> >> >> >> >> +               .pixel_clock = 27027000,
>> >> >> >> >> +               .conf = {
>> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C,
> 0x09,
>> >> > 0x64,
>> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2,
> 0x54,
>> >> > 0x87,
>> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
> 0x10,
>> >> > 0xE0,
>> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00,
> 0x00,
>> >> > 0x00,
>> >> >> >> >> +               },
>> >> >> >> >> +       },
>> >> >> >> >> +       {
>> >> >> >> >> +               .pixel_clock = 74176000,
>> >> >> >> >> +               .conf = {
>> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C,
> 0xef,
>> >> > 0x5B,
>> >> >> >> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3,
> 0x54,
>> >> > 0xb9,
>> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
> 0x10,
>> >> > 0xE0,
>> >> >> >> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00,
> 0x00,
>> >> > 0x00,
>> >> >> >> >> +               },
>> >> >> >> >> +       },
>> >> >> >> >> +       {
>> >> >> >> >> +               .pixel_clock = 74250000,
>> >> >> >> >> +               .conf = {
>> >> >> >> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c,
> 0xf8,
>> >> > 0x40,
>> >> >> >> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1,
> 0x54,
>> >> > 0xba,
>> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08,
> 0x10,
>> >> > 0xe0,
>> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00,
> 0x00,
>> >> > 0x00,
>> >> >> >> >> +               },
>> >> >> >> >> +       },
>> >> >> >> >> +       {
>> >> >> >> >> +               .pixel_clock = 148500000,
>> >> >> >> >> +               .conf = {
>> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C,
> 0xf8,
>> >> > 0x40,
>> >> >> >> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1,
> 0x54,
>> >> > 0xba,
>> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08,
> 0x10,
>> >> > 0xE0,
>> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00,
> 0x00,
>> >> > 0x00,
>> >> >> >> >> +               },
>> >> >> >> >> +       },
>> >> >> >> >> +};
>> >> >> >> >> +
>> >> >> >> >
>> >> >> >> > Are you aware of the effort to move these to dt? Since these
>> are
>> >> >> >> > board-specific values, it seems incorrect to apply them
>> >> universally.
>> >> >> >> > Shirish has uploaded a patch to the chromium review site to
>> push
>> >> >> these
>> >> >> >> > into dt (https://chromium-review.googlesource.com/#/c/65581).
>> >> Maybe
>> >> >> >> > you can work that into your patch set?
>> >> >> >> >
>> >> >> >
>> >> >> > Are these really board-specific values?
>> >> >>
>> >> >> According to your hardware people:
>> >> >>
>> >> >> "If the signal pattern doesn't change for new board, the phy setting
>> >> >> is same as the current board. But if changed, you need to confirm
>> with
>> >> >> measurement of signals, because it may vary slightly by resistance
>> of
>> >> >> board pattern"
>> >> >>
>> >> >
>> >> > Right. it seems that the phy configuration should be adjusted
>> according
>> >> to
>> >> > PCB environment: OSC clock rate, 24MHz or 27MHz, could be decided by
>> PCB
>> >> > even though most PCBs use 27MHz.
>> >> >
>> >> >> That indicates to me that we might need to tweak these on a per-
>> board
>> >> >> basis.
>> >> >>
>> >> >> In the 5420 datasheet, there are a few register descriptions
>> available
>> >> >> for the phy. 0x145D0004 is CLK_SEL which seems like it would be
>> >> >> board-specific, same with TX_* registers.
>> >> >>
>> >> >
>> >> > And we can select HDMI Tx PHY internal PLL input clock by setting
>> >> CLK_SEL.
>> >> > Ok, Shirish's patch set is reasonable to me. However, that patch set
>> >> should
>> >> > be rebased on top of Rahul's patch set. Shirish and Rahul, please re-
>> >> post
>> >> > your patch set after discussing how to rebase these patch set.
>> >> >
>> >> > Thanks,
>> >> > Inki Dae
>> >> >
>> >>
>> >> In that case, we need to test the phy confs for all the exynos boards,
>> >> supported in
>> >> mainline. Probably needs a analyser as well to precisely compare the
>> >> deviation.
>> >
>> > Shirish patch adds phy config data only to arndale and smdk5250 boards,
>> and
>> > these config data should have each board specific values. Therefore, for
>> > other boards, shouldn't correct phy config data suitable to their boards
>> be
>> > added to their board dts files? Is the above analyzer really needed?
>> >
>>
>> Sorry, I had only seen his patches for chromium tree. In mainline
>> version, he added for 5250 as well. But both sets (for arndale and
>> smdk) are exactly same as original 5250 configs which also works
>> with 4412 origen.
>>
>> Some problem has been identified during conformance testing for
>> 5420 peach board, which happens with analyser. It was always
>> working fine on the TV sets that I have. @Shirish/Sean please
>> correct me if wrong.
>>
>> >> Shirish patch is only for 5420 Peach board. Else, to start with we can
>> >> mark
>> >> phyconf as optional property which overrides the default Phy Confs for
>> >> given SoC.
>> >
>> > Hm.... you mean that hdmiphy driver use the default phy config data in
>> > driver; most boards use the same data, and only in special case; a board
>> > uses different OSC clock rate, the hdmiphy driver use phy config data
>> from
>> > dts file checking hdmiphy-confs property?
>> >
>>
>> Yes. I meant same. I don't see the real need to duplicate so much
>> of data in all board dts files. We can add it for a particular board, if
>> really required.
>>
>
> Yes, reasonable to me. It's not good that board dts files have same phy
> config data. How about using the phy config data from dts file if
> hdmiphy-confs property exists, otherwise using default phy config data then?
> This means that we don't need to remove the phy config data from driver;
> that will be used as default values.
>

Can you add the "default" configs to exynos5250.dtsi and
exynos5420.dtsi, then overwrite it in the board file if it needs to be
different?

Sean



> Rahul, let's go if there is other opinion. we SHOULD MERGE these this
> time.:)
>
> Thanks,
> Inki Dae
>
>> Regards,
>> Rahul Sharma.
>>
>> >
>> >>
>> >> regards,
>> >> Rahul Sharma.
>> >>
>> >> >> Sean
>> >> >>
>> >> >>
>> >
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-samsung-
>> soc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-05 13:19                     ` Sean Paul
@ 2013-09-05 13:50                       ` Inki Dae
  2013-09-05 16:31                         ` Sylwester Nawrocki
  2013-09-06  3:37                         ` Rahul Sharma
  0 siblings, 2 replies; 45+ messages in thread
From: Inki Dae @ 2013-09-05 13:50 UTC (permalink / raw)
  To: 'Sean Paul'
  Cc: 'Rahul Sharma', 'Rahul Sharma',
	'linux-samsung-soc', 'dri-devel',
	'kgene.kim', 'sw0312.kim', 'Lucas Stach',
	'Tomasz Figa', 'Sylwester Nawrocki',
	'sunil joshi', 'Shirish S'



> -----Original Message-----
> From: Sean Paul [mailto:seanpaul@chromium.org]
> Sent: Thursday, September 05, 2013 10:20 PM
> To: Inki Dae
> Cc: Rahul Sharma; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
> Shirish S
> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
> driver
> 
> On Thu, Sep 5, 2013 at 2:19 AM, Inki Dae <inki.dae@samsung.com> wrote:
> >
> >
> >> -----Original Message-----
> >> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-
> soc-
> >> owner@vger.kernel.org] On Behalf Of Rahul Sharma
> >> Sent: Thursday, September 05, 2013 3:04 PM
> >> To: Inki Dae
> >> Cc: Sean Paul; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
> >> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
> >> Shirish S
> >> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
> hdmiphy
> >> driver
> >>
> >> On 5 September 2013 10:52, Inki Dae <inki.dae@samsung.com> wrote:
> >> >> >> >> >> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
> >> >> >> >> >> +       {
> >> >> >> >> >> +               .pixel_clock = 27000000,
> >> >> >> >> >> +               .conf = {
> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C,
> > 0x30,
> >> >> > 0x40,
> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2,
> > 0x54,
> >> >> > 0x87,
> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
> > 0x10,
> >> >> > 0xE0,
> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00,
> > 0x00,
> >> >> > 0x00,
> >> >> >> >> >> +               },
> >> >> >> >> >> +       },
> >> >> >> >> >> +       {
> >> >> >> >> >> +               .pixel_clock = 27027000,
> >> >> >> >> >> +               .conf = {
> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C,
> > 0x09,
> >> >> > 0x64,
> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2,
> > 0x54,
> >> >> > 0x87,
> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
> > 0x10,
> >> >> > 0xE0,
> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00,
> > 0x00,
> >> >> > 0x00,
> >> >> >> >> >> +               },
> >> >> >> >> >> +       },
> >> >> >> >> >> +       {
> >> >> >> >> >> +               .pixel_clock = 74176000,
> >> >> >> >> >> +               .conf = {
> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C,
> > 0xef,
> >> >> > 0x5B,
> >> >> >> >> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3,
> > 0x54,
> >> >> > 0xb9,
> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
> > 0x10,
> >> >> > 0xE0,
> >> >> >> >> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00,
> > 0x00,
> >> >> > 0x00,
> >> >> >> >> >> +               },
> >> >> >> >> >> +       },
> >> >> >> >> >> +       {
> >> >> >> >> >> +               .pixel_clock = 74250000,
> >> >> >> >> >> +               .conf = {
> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c,
> > 0xf8,
> >> >> > 0x40,
> >> >> >> >> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1,
> > 0x54,
> >> >> > 0xba,
> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08,
> > 0x10,
> >> >> > 0xe0,
> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00,
> > 0x00,
> >> >> > 0x00,
> >> >> >> >> >> +               },
> >> >> >> >> >> +       },
> >> >> >> >> >> +       {
> >> >> >> >> >> +               .pixel_clock = 148500000,
> >> >> >> >> >> +               .conf = {
> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C,
> > 0xf8,
> >> >> > 0x40,
> >> >> >> >> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1,
> > 0x54,
> >> >> > 0xba,
> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08,
> > 0x10,
> >> >> > 0xE0,
> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00,
> > 0x00,
> >> >> > 0x00,
> >> >> >> >> >> +               },
> >> >> >> >> >> +       },
> >> >> >> >> >> +};
> >> >> >> >> >> +
> >> >> >> >> >
> >> >> >> >> > Are you aware of the effort to move these to dt? Since these
> >> are
> >> >> >> >> > board-specific values, it seems incorrect to apply them
> >> >> universally.
> >> >> >> >> > Shirish has uploaded a patch to the chromium review site to
> >> push
> >> >> >> these
> >> >> >> >> > into dt
(https://chromium-review.googlesource.com/#/c/65581).
> >> >> Maybe
> >> >> >> >> > you can work that into your patch set?
> >> >> >> >> >
> >> >> >> >
> >> >> >> > Are these really board-specific values?
> >> >> >>
> >> >> >> According to your hardware people:
> >> >> >>
> >> >> >> "If the signal pattern doesn't change for new board, the phy
> setting
> >> >> >> is same as the current board. But if changed, you need to confirm
> >> with
> >> >> >> measurement of signals, because it may vary slightly by
> resistance
> >> of
> >> >> >> board pattern"
> >> >> >>
> >> >> >
> >> >> > Right. it seems that the phy configuration should be adjusted
> >> according
> >> >> to
> >> >> > PCB environment: OSC clock rate, 24MHz or 27MHz, could be decided
> by
> >> PCB
> >> >> > even though most PCBs use 27MHz.
> >> >> >
> >> >> >> That indicates to me that we might need to tweak these on a per-
> >> board
> >> >> >> basis.
> >> >> >>
> >> >> >> In the 5420 datasheet, there are a few register descriptions
> >> available
> >> >> >> for the phy. 0x145D0004 is CLK_SEL which seems like it would be
> >> >> >> board-specific, same with TX_* registers.
> >> >> >>
> >> >> >
> >> >> > And we can select HDMI Tx PHY internal PLL input clock by setting
> >> >> CLK_SEL.
> >> >> > Ok, Shirish's patch set is reasonable to me. However, that patch
> set
> >> >> should
> >> >> > be rebased on top of Rahul's patch set. Shirish and Rahul, please
> re-
> >> >> post
> >> >> > your patch set after discussing how to rebase these patch set.
> >> >> >
> >> >> > Thanks,
> >> >> > Inki Dae
> >> >> >
> >> >>
> >> >> In that case, we need to test the phy confs for all the exynos
> boards,
> >> >> supported in
> >> >> mainline. Probably needs a analyser as well to precisely compare the
> >> >> deviation.
> >> >
> >> > Shirish patch adds phy config data only to arndale and smdk5250
> boards,
> >> and
> >> > these config data should have each board specific values. Therefore,
> for
> >> > other boards, shouldn't correct phy config data suitable to their
> boards
> >> be
> >> > added to their board dts files? Is the above analyzer really needed?
> >> >
> >>
> >> Sorry, I had only seen his patches for chromium tree. In mainline
> >> version, he added for 5250 as well. But both sets (for arndale and
> >> smdk) are exactly same as original 5250 configs which also works
> >> with 4412 origen.
> >>
> >> Some problem has been identified during conformance testing for
> >> 5420 peach board, which happens with analyser. It was always
> >> working fine on the TV sets that I have. @Shirish/Sean please
> >> correct me if wrong.
> >>
> >> >> Shirish patch is only for 5420 Peach board. Else, to start with we
> can
> >> >> mark
> >> >> phyconf as optional property which overrides the default Phy Confs
> for
> >> >> given SoC.
> >> >
> >> > Hm.... you mean that hdmiphy driver use the default phy config data
> in
> >> > driver; most boards use the same data, and only in special case; a
> board
> >> > uses different OSC clock rate, the hdmiphy driver use phy config data
> >> from
> >> > dts file checking hdmiphy-confs property?
> >> >
> >>
> >> Yes. I meant same. I don't see the real need to duplicate so much
> >> of data in all board dts files. We can add it for a particular board,
> if
> >> really required.
> >>
> >
> > Yes, reasonable to me. It's not good that board dts files have same phy
> > config data. How about using the phy config data from dts file if
> > hdmiphy-confs property exists, otherwise using default phy config data
> then?
> > This means that we don't need to remove the phy config data from driver;
> > that will be used as default values.
> >
> 
> Can you add the "default" configs to exynos5250.dtsi and
> exynos5420.dtsi, then overwrite it in the board file if it needs to be
> different?
> 

Good idea but how about adding default-hdmiphy-config property to each board
dts file and removing phy config data from board dts file if they are same
as default one of driver? With this, hdmiphy driver checks if
default-hdmiphy-config property exists, and then use default config data if
exists. And if not exists, hdmiphy driver gets and uses board specific phy
config data from board dts file.
And it seems that the phy config values of Shirish's patch set are same as
default ones of driver. So we can remove the phy config data from each board
dts files and add default-hdmiphy-config property to there so that default
data of driver can be used.


Thanks,
Inki Dae

> Sean
> 
> 
> 
> > Rahul, let's go if there is other opinion. we SHOULD MERGE these this
> > time.:)
> >
> > Thanks,
> > Inki Dae
> >
> >> Regards,
> >> Rahul Sharma.
> >>
> >> >
> >> >>
> >> >> regards,
> >> >> Rahul Sharma.
> >> >>
> >> >> >> Sean
> >> >> >>
> >> >> >>
> >> >
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-
> samsung-
> >> soc" in
> >> the body of a message to majordomo@vger.kernel.org
> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-05 13:50                       ` Inki Dae
@ 2013-09-05 16:31                         ` Sylwester Nawrocki
  2013-09-06  3:37                         ` Rahul Sharma
  1 sibling, 0 replies; 45+ messages in thread
From: Sylwester Nawrocki @ 2013-09-05 16:31 UTC (permalink / raw)
  To: 'linux-samsung-soc'
  Cc: Inki Dae, 'Sean Paul', 'Rahul Sharma',
	'Rahul Sharma', 'dri-devel', 'kgene.kim',
	'sw0312.kim', 'Lucas Stach',
	'Tomasz Figa', 'sunil joshi', 'Shirish S'


Can you please quote only related part of e-mails when replying ?
It discourages to read such discussions when you have to scroll
through few pages of "garbage" before getting to the actual reply
text.

--
Thanks,
Sylwester

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-05 13:50                       ` Inki Dae
  2013-09-05 16:31                         ` Sylwester Nawrocki
@ 2013-09-06  3:37                         ` Rahul Sharma
  2013-09-06 13:51                           ` Sean Paul
  1 sibling, 1 reply; 45+ messages in thread
From: Rahul Sharma @ 2013-09-06  3:37 UTC (permalink / raw)
  To: Inki Dae
  Cc: Sean Paul, Rahul Sharma, linux-samsung-soc, dri-devel, kgene.kim,
	sw0312.kim, Lucas Stach, Tomasz Figa, Sylwester Nawrocki,
	sunil joshi, Shirish S

On 5 September 2013 19:20, Inki Dae <inki.dae@samsung.com> wrote:
>
>
>> -----Original Message-----
>> From: Sean Paul [mailto:seanpaul@chromium.org]
>> Sent: Thursday, September 05, 2013 10:20 PM
>> To: Inki Dae
>> Cc: Rahul Sharma; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
>> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
>> Shirish S
>> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
>> driver
>>
>> On Thu, Sep 5, 2013 at 2:19 AM, Inki Dae <inki.dae@samsung.com> wrote:
>> >
>> >
>> >> -----Original Message-----
>> >> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-
>> soc-
>> >> owner@vger.kernel.org] On Behalf Of Rahul Sharma
>> >> Sent: Thursday, September 05, 2013 3:04 PM
>> >> To: Inki Dae
>> >> Cc: Sean Paul; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
>> >> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
>> >> Shirish S
>> >> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
>> hdmiphy
>> >> driver
>> >>
>> >> On 5 September 2013 10:52, Inki Dae <inki.dae@samsung.com> wrote:
>> >> >> >> >> >> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
>> >> >> >> >> >> +       {
>> >> >> >> >> >> +               .pixel_clock = 27000000,
>> >> >> >> >> >> +               .conf = {
>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C,
>> > 0x30,
>> >> >> > 0x40,
>> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2,
>> > 0x54,
>> >> >> > 0x87,
>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
>> > 0x10,
>> >> >> > 0xE0,
>> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00,
>> > 0x00,
>> >> >> > 0x00,
>> >> >> >> >> >> +               },
>> >> >> >> >> >> +       },
>> >> >> >> >> >> +       {
>> >> >> >> >> >> +               .pixel_clock = 27027000,
>> >> >> >> >> >> +               .conf = {
>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C,
>> > 0x09,
>> >> >> > 0x64,
>> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2,
>> > 0x54,
>> >> >> > 0x87,
>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
>> > 0x10,
>> >> >> > 0xE0,
>> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00,
>> > 0x00,
>> >> >> > 0x00,
>> >> >> >> >> >> +               },
>> >> >> >> >> >> +       },
>> >> >> >> >> >> +       {
>> >> >> >> >> >> +               .pixel_clock = 74176000,
>> >> >> >> >> >> +               .conf = {
>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C,
>> > 0xef,
>> >> >> > 0x5B,
>> >> >> >> >> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3,
>> > 0x54,
>> >> >> > 0xb9,
>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
>> > 0x10,
>> >> >> > 0xE0,
>> >> >> >> >> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00,
>> > 0x00,
>> >> >> > 0x00,
>> >> >> >> >> >> +               },
>> >> >> >> >> >> +       },
>> >> >> >> >> >> +       {
>> >> >> >> >> >> +               .pixel_clock = 74250000,
>> >> >> >> >> >> +               .conf = {
>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c,
>> > 0xf8,
>> >> >> > 0x40,
>> >> >> >> >> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1,
>> > 0x54,
>> >> >> > 0xba,
>> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08,
>> > 0x10,
>> >> >> > 0xe0,
>> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00,
>> > 0x00,
>> >> >> > 0x00,
>> >> >> >> >> >> +               },
>> >> >> >> >> >> +       },
>> >> >> >> >> >> +       {
>> >> >> >> >> >> +               .pixel_clock = 148500000,
>> >> >> >> >> >> +               .conf = {
>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C,
>> > 0xf8,
>> >> >> > 0x40,
>> >> >> >> >> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1,
>> > 0x54,
>> >> >> > 0xba,
>> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08,
>> > 0x10,
>> >> >> > 0xE0,
>> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00,
>> > 0x00,
>> >> >> > 0x00,
>> >> >> >> >> >> +               },
>> >> >> >> >> >> +       },
>> >> >> >> >> >> +};
>> >> >> >> >> >> +
>> >> >> >> >> >
>> >> >> >> >> > Are you aware of the effort to move these to dt? Since these
>> >> are
>> >> >> >> >> > board-specific values, it seems incorrect to apply them
>> >> >> universally.
>> >> >> >> >> > Shirish has uploaded a patch to the chromium review site to
>> >> push
>> >> >> >> these
>> >> >> >> >> > into dt
> (https://chromium-review.googlesource.com/#/c/65581).
>> >> >> Maybe
>> >> >> >> >> > you can work that into your patch set?
>> >> >> >> >> >
>> >> >> >> >
>> >> >> >> > Are these really board-specific values?
>> >> >> >>
>> >> >> >> According to your hardware people:
>> >> >> >>
>> >> >> >> "If the signal pattern doesn't change for new board, the phy
>> setting
>> >> >> >> is same as the current board. But if changed, you need to confirm
>> >> with
>> >> >> >> measurement of signals, because it may vary slightly by
>> resistance
>> >> of
>> >> >> >> board pattern"
>> >> >> >>
>> >> >> >
>> >> >> > Right. it seems that the phy configuration should be adjusted
>> >> according
>> >> >> to
>> >> >> > PCB environment: OSC clock rate, 24MHz or 27MHz, could be decided
>> by
>> >> PCB
>> >> >> > even though most PCBs use 27MHz.
>> >> >> >
>> >> >> >> That indicates to me that we might need to tweak these on a per-
>> >> board
>> >> >> >> basis.
>> >> >> >>
>> >> >> >> In the 5420 datasheet, there are a few register descriptions
>> >> available
>> >> >> >> for the phy. 0x145D0004 is CLK_SEL which seems like it would be
>> >> >> >> board-specific, same with TX_* registers.
>> >> >> >>
>> >> >> >
>> >> >> > And we can select HDMI Tx PHY internal PLL input clock by setting
>> >> >> CLK_SEL.
>> >> >> > Ok, Shirish's patch set is reasonable to me. However, that patch
>> set
>> >> >> should
>> >> >> > be rebased on top of Rahul's patch set. Shirish and Rahul, please
>> re-
>> >> >> post
>> >> >> > your patch set after discussing how to rebase these patch set.
>> >> >> >
>> >> >> > Thanks,
>> >> >> > Inki Dae
>> >> >> >
>> >> >>
>> >> >> In that case, we need to test the phy confs for all the exynos
>> boards,
>> >> >> supported in
>> >> >> mainline. Probably needs a analyser as well to precisely compare the
>> >> >> deviation.
>> >> >
>> >> > Shirish patch adds phy config data only to arndale and smdk5250
>> boards,
>> >> and
>> >> > these config data should have each board specific values. Therefore,
>> for
>> >> > other boards, shouldn't correct phy config data suitable to their
>> boards
>> >> be
>> >> > added to their board dts files? Is the above analyzer really needed?
>> >> >
>> >>
>> >> Sorry, I had only seen his patches for chromium tree. In mainline
>> >> version, he added for 5250 as well. But both sets (for arndale and
>> >> smdk) are exactly same as original 5250 configs which also works
>> >> with 4412 origen.
>> >>
>> >> Some problem has been identified during conformance testing for
>> >> 5420 peach board, which happens with analyser. It was always
>> >> working fine on the TV sets that I have. @Shirish/Sean please
>> >> correct me if wrong.
>> >>
>> >> >> Shirish patch is only for 5420 Peach board. Else, to start with we
>> can
>> >> >> mark
>> >> >> phyconf as optional property which overrides the default Phy Confs
>> for
>> >> >> given SoC.
>> >> >
>> >> > Hm.... you mean that hdmiphy driver use the default phy config data
>> in
>> >> > driver; most boards use the same data, and only in special case; a
>> board
>> >> > uses different OSC clock rate, the hdmiphy driver use phy config data
>> >> from
>> >> > dts file checking hdmiphy-confs property?
>> >> >
>> >>
>> >> Yes. I meant same. I don't see the real need to duplicate so much
>> >> of data in all board dts files. We can add it for a particular board,
>> if
>> >> really required.
>> >>
>> >
>> > Yes, reasonable to me. It's not good that board dts files have same phy
>> > config data. How about using the phy config data from dts file if
>> > hdmiphy-confs property exists, otherwise using default phy config data
>> then?
>> > This means that we don't need to remove the phy config data from driver;
>> > that will be used as default values.
>> >
>>
>> Can you add the "default" configs to exynos5250.dtsi and
>> exynos5420.dtsi, then overwrite it in the board file if it needs to be
>> different?
>>

This will still introduce some duplication as 4412 and 5250 share same
phy confs and have no common dtsi. Similar situation can arise for later
SoCs in exynos series.

>
> Good idea but how about adding default-hdmiphy-config property to each board
> dts file and removing phy config data from board dts file if they are same
> as default one of driver? With this, hdmiphy driver checks if
> default-hdmiphy-config property exists, and then use default config data if
> exists. And if not exists, hdmiphy driver gets and uses board specific phy
> config data from board dts file.
> And it seems that the phy config values of Shirish's patch set are same as
> default ones of driver. So we can remove the phy config data from each board
> dts files and add default-hdmiphy-config property to there so that default
> data of driver can be used.
>
>
> Thanks,
> Inki Dae
>

We can simplify it further by letting the driver use phy-conf
property from DT. If phy-conf property is not available switch to
default confs, provided in the driver. This way we don't need to add
default-hdmiphy-config property to all board files.

The number of exceptions where we need to override the default confs
is zero (as if now). 5420 based Peach and Smdk boards work exactly
the same with same set of phy confs on 3 hdmi displays, I have. It
may differ on Analyser. IMO we can defer this part till we have
unacceptable analyser results for any specific board.

Regards,
Rahul Sharma.

>> Sean
>>
>>
>>
>> > Rahul, let's go if there is other opinion. we SHOULD MERGE these this
>> > time.:)
>> >
>> > Thanks,
>> > Inki Dae
>> >
>> >> Regards,
>> >> Rahul Sharma.
>> >>
>> >> >
>> >> >>
>> >> >> regards,
>> >> >> Rahul Sharma.
>> >> >>
>> >> >> >> Sean
>> >> >> >>
>> >> >> >>
>> >> >
>> >> --
>> >> To unsubscribe from this list: send the line "unsubscribe linux-
>> samsung-
>> >> soc" in
>> >> the body of a message to majordomo@vger.kernel.org
>> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> >
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-06  3:37                         ` Rahul Sharma
@ 2013-09-06 13:51                           ` Sean Paul
  2013-09-10  8:27                             ` Rahul Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Sean Paul @ 2013-09-06 13:51 UTC (permalink / raw)
  To: Rahul Sharma
  Cc: Inki Dae, Rahul Sharma, linux-samsung-soc, dri-devel, kgene.kim,
	sw0312.kim, Lucas Stach, Tomasz Figa, Sylwester Nawrocki,
	sunil joshi, Shirish S

On Thu, Sep 5, 2013 at 11:37 PM, Rahul Sharma <r.sh.open@gmail.com> wrote:
> On 5 September 2013 19:20, Inki Dae <inki.dae@samsung.com> wrote:
>>
>>
>>> -----Original Message-----
>>> From: Sean Paul [mailto:seanpaul@chromium.org]
>>> Sent: Thursday, September 05, 2013 10:20 PM
>>> To: Inki Dae
>>> Cc: Rahul Sharma; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
>>> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
>>> Shirish S
>>> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
>>> driver
>>>
>>> On Thu, Sep 5, 2013 at 2:19 AM, Inki Dae <inki.dae@samsung.com> wrote:
>>> >
>>> >
>>> >> -----Original Message-----
>>> >> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-
>>> soc-
>>> >> owner@vger.kernel.org] On Behalf Of Rahul Sharma
>>> >> Sent: Thursday, September 05, 2013 3:04 PM
>>> >> To: Inki Dae
>>> >> Cc: Sean Paul; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
>>> >> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
>>> >> Shirish S
>>> >> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
>>> hdmiphy
>>> >> driver
>>> >>
>>> >> On 5 September 2013 10:52, Inki Dae <inki.dae@samsung.com> wrote:
>>> >> >> >> >> >> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
>>> >> >> >> >> >> +       {
>>> >> >> >> >> >> +               .pixel_clock = 27000000,
>>> >> >> >> >> >> +               .conf = {
>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C,
>>> > 0x30,
>>> >> >> > 0x40,
>>> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2,
>>> > 0x54,
>>> >> >> > 0x87,
>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
>>> > 0x10,
>>> >> >> > 0xE0,
>>> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00,
>>> > 0x00,
>>> >> >> > 0x00,
>>> >> >> >> >> >> +               },
>>> >> >> >> >> >> +       },
>>> >> >> >> >> >> +       {
>>> >> >> >> >> >> +               .pixel_clock = 27027000,
>>> >> >> >> >> >> +               .conf = {
>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C,
>>> > 0x09,
>>> >> >> > 0x64,
>>> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2,
>>> > 0x54,
>>> >> >> > 0x87,
>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
>>> > 0x10,
>>> >> >> > 0xE0,
>>> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00,
>>> > 0x00,
>>> >> >> > 0x00,
>>> >> >> >> >> >> +               },
>>> >> >> >> >> >> +       },
>>> >> >> >> >> >> +       {
>>> >> >> >> >> >> +               .pixel_clock = 74176000,
>>> >> >> >> >> >> +               .conf = {
>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C,
>>> > 0xef,
>>> >> >> > 0x5B,
>>> >> >> >> >> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3,
>>> > 0x54,
>>> >> >> > 0xb9,
>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
>>> > 0x10,
>>> >> >> > 0xE0,
>>> >> >> >> >> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00,
>>> > 0x00,
>>> >> >> > 0x00,
>>> >> >> >> >> >> +               },
>>> >> >> >> >> >> +       },
>>> >> >> >> >> >> +       {
>>> >> >> >> >> >> +               .pixel_clock = 74250000,
>>> >> >> >> >> >> +               .conf = {
>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c,
>>> > 0xf8,
>>> >> >> > 0x40,
>>> >> >> >> >> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1,
>>> > 0x54,
>>> >> >> > 0xba,
>>> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08,
>>> > 0x10,
>>> >> >> > 0xe0,
>>> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00,
>>> > 0x00,
>>> >> >> > 0x00,
>>> >> >> >> >> >> +               },
>>> >> >> >> >> >> +       },
>>> >> >> >> >> >> +       {
>>> >> >> >> >> >> +               .pixel_clock = 148500000,
>>> >> >> >> >> >> +               .conf = {
>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C,
>>> > 0xf8,
>>> >> >> > 0x40,
>>> >> >> >> >> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1,
>>> > 0x54,
>>> >> >> > 0xba,
>>> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08,
>>> > 0x10,
>>> >> >> > 0xE0,
>>> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00,
>>> > 0x00,
>>> >> >> > 0x00,
>>> >> >> >> >> >> +               },
>>> >> >> >> >> >> +       },
>>> >> >> >> >> >> +};
>>> >> >> >> >> >> +
>>> >> >> >> >> >
>>> >> >> >> >> > Are you aware of the effort to move these to dt? Since these
>>> >> are
>>> >> >> >> >> > board-specific values, it seems incorrect to apply them
>>> >> >> universally.
>>> >> >> >> >> > Shirish has uploaded a patch to the chromium review site to
>>> >> push
>>> >> >> >> these
>>> >> >> >> >> > into dt
>> (https://chromium-review.googlesource.com/#/c/65581).
>>> >> >> Maybe
>>> >> >> >> >> > you can work that into your patch set?
>>> >> >> >> >> >
>>> >> >> >> >
>>> >> >> >> > Are these really board-specific values?
>>> >> >> >>
>>> >> >> >> According to your hardware people:
>>> >> >> >>
>>> >> >> >> "If the signal pattern doesn't change for new board, the phy
>>> setting
>>> >> >> >> is same as the current board. But if changed, you need to confirm
>>> >> with
>>> >> >> >> measurement of signals, because it may vary slightly by
>>> resistance
>>> >> of
>>> >> >> >> board pattern"
>>> >> >> >>
>>> >> >> >
>>> >> >> > Right. it seems that the phy configuration should be adjusted
>>> >> according
>>> >> >> to
>>> >> >> > PCB environment: OSC clock rate, 24MHz or 27MHz, could be decided
>>> by
>>> >> PCB
>>> >> >> > even though most PCBs use 27MHz.
>>> >> >> >
>>> >> >> >> That indicates to me that we might need to tweak these on a per-
>>> >> board
>>> >> >> >> basis.
>>> >> >> >>
>>> >> >> >> In the 5420 datasheet, there are a few register descriptions
>>> >> available
>>> >> >> >> for the phy. 0x145D0004 is CLK_SEL which seems like it would be
>>> >> >> >> board-specific, same with TX_* registers.
>>> >> >> >>
>>> >> >> >
>>> >> >> > And we can select HDMI Tx PHY internal PLL input clock by setting
>>> >> >> CLK_SEL.
>>> >> >> > Ok, Shirish's patch set is reasonable to me. However, that patch
>>> set
>>> >> >> should
>>> >> >> > be rebased on top of Rahul's patch set. Shirish and Rahul, please
>>> re-
>>> >> >> post
>>> >> >> > your patch set after discussing how to rebase these patch set.
>>> >> >> >
>>> >> >> > Thanks,
>>> >> >> > Inki Dae
>>> >> >> >
>>> >> >>
>>> >> >> In that case, we need to test the phy confs for all the exynos
>>> boards,
>>> >> >> supported in
>>> >> >> mainline. Probably needs a analyser as well to precisely compare the
>>> >> >> deviation.
>>> >> >
>>> >> > Shirish patch adds phy config data only to arndale and smdk5250
>>> boards,
>>> >> and
>>> >> > these config data should have each board specific values. Therefore,
>>> for
>>> >> > other boards, shouldn't correct phy config data suitable to their
>>> boards
>>> >> be
>>> >> > added to their board dts files? Is the above analyzer really needed?
>>> >> >
>>> >>
>>> >> Sorry, I had only seen his patches for chromium tree. In mainline
>>> >> version, he added for 5250 as well. But both sets (for arndale and
>>> >> smdk) are exactly same as original 5250 configs which also works
>>> >> with 4412 origen.
>>> >>
>>> >> Some problem has been identified during conformance testing for
>>> >> 5420 peach board, which happens with analyser. It was always
>>> >> working fine on the TV sets that I have. @Shirish/Sean please
>>> >> correct me if wrong.
>>> >>
>>> >> >> Shirish patch is only for 5420 Peach board. Else, to start with we
>>> can
>>> >> >> mark
>>> >> >> phyconf as optional property which overrides the default Phy Confs
>>> for
>>> >> >> given SoC.
>>> >> >
>>> >> > Hm.... you mean that hdmiphy driver use the default phy config data
>>> in
>>> >> > driver; most boards use the same data, and only in special case; a
>>> board
>>> >> > uses different OSC clock rate, the hdmiphy driver use phy config data
>>> >> from
>>> >> > dts file checking hdmiphy-confs property?
>>> >> >
>>> >>
>>> >> Yes. I meant same. I don't see the real need to duplicate so much
>>> >> of data in all board dts files. We can add it for a particular board,
>>> if
>>> >> really required.
>>> >>
>>> >
>>> > Yes, reasonable to me. It's not good that board dts files have same phy
>>> > config data. How about using the phy config data from dts file if
>>> > hdmiphy-confs property exists, otherwise using default phy config data
>>> then?
>>> > This means that we don't need to remove the phy config data from driver;
>>> > that will be used as default values.
>>> >
>>>
>>> Can you add the "default" configs to exynos5250.dtsi and
>>> exynos5420.dtsi, then overwrite it in the board file if it needs to be
>>> different?
>>>
>
> This will still introduce some duplication as 4412 and 5250 share same
> phy confs and have no common dtsi. Similar situation can arise for later
> SoCs in exynos series.
>
>>
>> Good idea but how about adding default-hdmiphy-config property to each board
>> dts file and removing phy config data from board dts file if they are same
>> as default one of driver? With this, hdmiphy driver checks if
>> default-hdmiphy-config property exists, and then use default config data if
>> exists. And if not exists, hdmiphy driver gets and uses board specific phy
>> config data from board dts file.
>> And it seems that the phy config values of Shirish's patch set are same as
>> default ones of driver. So we can remove the phy config data from each board
>> dts files and add default-hdmiphy-config property to there so that default
>> data of driver can be used.
>>
>>
>> Thanks,
>> Inki Dae
>>
>
> We can simplify it further by letting the driver use phy-conf
> property from DT. If phy-conf property is not available switch to
> default confs, provided in the driver. This way we don't need to add
> default-hdmiphy-config property to all board files.
>

This is probably a worthwhile discussion to have on Shirish's patch
with devicetree-discuss. I'm unsure which is the preferred way to do
something like this.

Sean

> The number of exceptions where we need to override the default confs
> is zero (as if now). 5420 based Peach and Smdk boards work exactly
> the same with same set of phy confs on 3 hdmi displays, I have. It
> may differ on Analyser. IMO we can defer this part till we have
> unacceptable analyser results for any specific board.
>
> Regards,
> Rahul Sharma.
>
>>> Sean
>>>
>>>
>>>
>>> > Rahul, let's go if there is other opinion. we SHOULD MERGE these this
>>> > time.:)
>>> >
>>> > Thanks,
>>> > Inki Dae
>>> >
>>> >> Regards,
>>> >> Rahul Sharma.
>>> >>
>>> >> >
>>> >> >>
>>> >> >> regards,
>>> >> >> Rahul Sharma.
>>> >> >>
>>> >> >> >> Sean
>>> >> >> >>
>>> >> >> >>
>>> >> >
>>> >> --
>>> >> To unsubscribe from this list: send the line "unsubscribe linux-
>>> samsung-
>>> >> soc" in
>>> >> the body of a message to majordomo@vger.kernel.org
>>> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>> >
>>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-06 13:51                           ` Sean Paul
@ 2013-09-10  8:27                             ` Rahul Sharma
  2013-09-16 12:40                               ` Inki Dae
  0 siblings, 1 reply; 45+ messages in thread
From: Rahul Sharma @ 2013-09-10  8:27 UTC (permalink / raw)
  To: Sean Paul
  Cc: Inki Dae, Rahul Sharma, linux-samsung-soc, dri-devel, kgene.kim,
	sw0312.kim, Lucas Stach, Tomasz Figa, Sylwester Nawrocki,
	sunil joshi, Shirish S

On 6 September 2013 19:21, Sean Paul <seanpaul@chromium.org> wrote:
> On Thu, Sep 5, 2013 at 11:37 PM, Rahul Sharma <r.sh.open@gmail.com> wrote:
>> On 5 September 2013 19:20, Inki Dae <inki.dae@samsung.com> wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Sean Paul [mailto:seanpaul@chromium.org]
>>>> Sent: Thursday, September 05, 2013 10:20 PM
>>>> To: Inki Dae
>>>> Cc: Rahul Sharma; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
>>>> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
>>>> Shirish S
>>>> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
>>>> driver
>>>>
>>>> On Thu, Sep 5, 2013 at 2:19 AM, Inki Dae <inki.dae@samsung.com> wrote:
>>>> >
>>>> >
>>>> >> -----Original Message-----
>>>> >> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-
>>>> soc-
>>>> >> owner@vger.kernel.org] On Behalf Of Rahul Sharma
>>>> >> Sent: Thursday, September 05, 2013 3:04 PM
>>>> >> To: Inki Dae
>>>> >> Cc: Sean Paul; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
>>>> >> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
>>>> >> Shirish S
>>>> >> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
>>>> hdmiphy
>>>> >> driver
>>>> >>
>>>> >> On 5 September 2013 10:52, Inki Dae <inki.dae@samsung.com> wrote:
>>>> >> >> >> >> >> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
>>>> >> >> >> >> >> +       {
>>>> >> >> >> >> >> +               .pixel_clock = 27000000,
>>>> >> >> >> >> >> +               .conf = {
>>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C,
>>>> > 0x30,
>>>> >> >> > 0x40,
>>>> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2,
>>>> > 0x54,
>>>> >> >> > 0x87,
>>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
>>>> > 0x10,
>>>> >> >> > 0xE0,
>>>> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00,
>>>> > 0x00,
>>>> >> >> > 0x00,
>>>> >> >> >> >> >> +               },
>>>> >> >> >> >> >> +       },
>>>> >> >> >> >> >> +       {
>>>> >> >> >> >> >> +               .pixel_clock = 27027000,
>>>> >> >> >> >> >> +               .conf = {
>>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C,
>>>> > 0x09,
>>>> >> >> > 0x64,
>>>> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2,
>>>> > 0x54,
>>>> >> >> > 0x87,
>>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
>>>> > 0x10,
>>>> >> >> > 0xE0,
>>>> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00,
>>>> > 0x00,
>>>> >> >> > 0x00,
>>>> >> >> >> >> >> +               },
>>>> >> >> >> >> >> +       },
>>>> >> >> >> >> >> +       {
>>>> >> >> >> >> >> +               .pixel_clock = 74176000,
>>>> >> >> >> >> >> +               .conf = {
>>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C,
>>>> > 0xef,
>>>> >> >> > 0x5B,
>>>> >> >> >> >> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3,
>>>> > 0x54,
>>>> >> >> > 0xb9,
>>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08,
>>>> > 0x10,
>>>> >> >> > 0xE0,
>>>> >> >> >> >> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01, 0x00,
>>>> > 0x00,
>>>> >> >> > 0x00,
>>>> >> >> >> >> >> +               },
>>>> >> >> >> >> >> +       },
>>>> >> >> >> >> >> +       {
>>>> >> >> >> >> >> +               .pixel_clock = 74250000,
>>>> >> >> >> >> >> +               .conf = {
>>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c,
>>>> > 0xf8,
>>>> >> >> > 0x40,
>>>> >> >> >> >> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1,
>>>> > 0x54,
>>>> >> >> > 0xba,
>>>> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08,
>>>> > 0x10,
>>>> >> >> > 0xe0,
>>>> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01, 0x00,
>>>> > 0x00,
>>>> >> >> > 0x00,
>>>> >> >> >> >> >> +               },
>>>> >> >> >> >> >> +       },
>>>> >> >> >> >> >> +       {
>>>> >> >> >> >> >> +               .pixel_clock = 148500000,
>>>> >> >> >> >> >> +               .conf = {
>>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C,
>>>> > 0xf8,
>>>> >> >> > 0x40,
>>>> >> >> >> >> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1,
>>>> > 0x54,
>>>> >> >> > 0xba,
>>>> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00, 0x08,
>>>> > 0x10,
>>>> >> >> > 0xE0,
>>>> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02, 0x00,
>>>> > 0x00,
>>>> >> >> > 0x00,
>>>> >> >> >> >> >> +               },
>>>> >> >> >> >> >> +       },
>>>> >> >> >> >> >> +};
>>>> >> >> >> >> >> +
>>>> >> >> >> >> >
>>>> >> >> >> >> > Are you aware of the effort to move these to dt? Since these
>>>> >> are
>>>> >> >> >> >> > board-specific values, it seems incorrect to apply them
>>>> >> >> universally.
>>>> >> >> >> >> > Shirish has uploaded a patch to the chromium review site to
>>>> >> push
>>>> >> >> >> these
>>>> >> >> >> >> > into dt
>>> (https://chromium-review.googlesource.com/#/c/65581).
>>>> >> >> Maybe
>>>> >> >> >> >> > you can work that into your patch set?
>>>> >> >> >> >> >
>>>> >> >> >> >
>>>> >> >> >> > Are these really board-specific values?
>>>> >> >> >>
>>>> >> >> >> According to your hardware people:
>>>> >> >> >>
>>>> >> >> >> "If the signal pattern doesn't change for new board, the phy
>>>> setting
>>>> >> >> >> is same as the current board. But if changed, you need to confirm
>>>> >> with
>>>> >> >> >> measurement of signals, because it may vary slightly by
>>>> resistance
>>>> >> of
>>>> >> >> >> board pattern"
>>>> >> >> >>
>>>> >> >> >
>>>> >> >> > Right. it seems that the phy configuration should be adjusted
>>>> >> according
>>>> >> >> to
>>>> >> >> > PCB environment: OSC clock rate, 24MHz or 27MHz, could be decided
>>>> by
>>>> >> PCB
>>>> >> >> > even though most PCBs use 27MHz.
>>>> >> >> >
>>>> >> >> >> That indicates to me that we might need to tweak these on a per-
>>>> >> board
>>>> >> >> >> basis.
>>>> >> >> >>
>>>> >> >> >> In the 5420 datasheet, there are a few register descriptions
>>>> >> available
>>>> >> >> >> for the phy. 0x145D0004 is CLK_SEL which seems like it would be
>>>> >> >> >> board-specific, same with TX_* registers.
>>>> >> >> >>
>>>> >> >> >
>>>> >> >> > And we can select HDMI Tx PHY internal PLL input clock by setting
>>>> >> >> CLK_SEL.
>>>> >> >> > Ok, Shirish's patch set is reasonable to me. However, that patch
>>>> set
>>>> >> >> should
>>>> >> >> > be rebased on top of Rahul's patch set. Shirish and Rahul, please
>>>> re-
>>>> >> >> post
>>>> >> >> > your patch set after discussing how to rebase these patch set.
>>>> >> >> >
>>>> >> >> > Thanks,
>>>> >> >> > Inki Dae
>>>> >> >> >
>>>> >> >>
>>>> >> >> In that case, we need to test the phy confs for all the exynos
>>>> boards,
>>>> >> >> supported in
>>>> >> >> mainline. Probably needs a analyser as well to precisely compare the
>>>> >> >> deviation.
>>>> >> >
>>>> >> > Shirish patch adds phy config data only to arndale and smdk5250
>>>> boards,
>>>> >> and
>>>> >> > these config data should have each board specific values. Therefore,
>>>> for
>>>> >> > other boards, shouldn't correct phy config data suitable to their
>>>> boards
>>>> >> be
>>>> >> > added to their board dts files? Is the above analyzer really needed?
>>>> >> >
>>>> >>
>>>> >> Sorry, I had only seen his patches for chromium tree. In mainline
>>>> >> version, he added for 5250 as well. But both sets (for arndale and
>>>> >> smdk) are exactly same as original 5250 configs which also works
>>>> >> with 4412 origen.
>>>> >>
>>>> >> Some problem has been identified during conformance testing for
>>>> >> 5420 peach board, which happens with analyser. It was always
>>>> >> working fine on the TV sets that I have. @Shirish/Sean please
>>>> >> correct me if wrong.
>>>> >>
>>>> >> >> Shirish patch is only for 5420 Peach board. Else, to start with we
>>>> can
>>>> >> >> mark
>>>> >> >> phyconf as optional property which overrides the default Phy Confs
>>>> for
>>>> >> >> given SoC.
>>>> >> >
>>>> >> > Hm.... you mean that hdmiphy driver use the default phy config data
>>>> in
>>>> >> > driver; most boards use the same data, and only in special case; a
>>>> board
>>>> >> > uses different OSC clock rate, the hdmiphy driver use phy config data
>>>> >> from
>>>> >> > dts file checking hdmiphy-confs property?
>>>> >> >
>>>> >>
>>>> >> Yes. I meant same. I don't see the real need to duplicate so much
>>>> >> of data in all board dts files. We can add it for a particular board,
>>>> if
>>>> >> really required.
>>>> >>
>>>> >
>>>> > Yes, reasonable to me. It's not good that board dts files have same phy
>>>> > config data. How about using the phy config data from dts file if
>>>> > hdmiphy-confs property exists, otherwise using default phy config data
>>>> then?
>>>> > This means that we don't need to remove the phy config data from driver;
>>>> > that will be used as default values.
>>>> >
>>>>
>>>> Can you add the "default" configs to exynos5250.dtsi and
>>>> exynos5420.dtsi, then overwrite it in the board file if it needs to be
>>>> different?
>>>>
>>
>> This will still introduce some duplication as 4412 and 5250 share same
>> phy confs and have no common dtsi. Similar situation can arise for later
>> SoCs in exynos series.
>>
>>>
>>> Good idea but how about adding default-hdmiphy-config property to each board
>>> dts file and removing phy config data from board dts file if they are same
>>> as default one of driver? With this, hdmiphy driver checks if
>>> default-hdmiphy-config property exists, and then use default config data if
>>> exists. And if not exists, hdmiphy driver gets and uses board specific phy
>>> config data from board dts file.
>>> And it seems that the phy config values of Shirish's patch set are same as
>>> default ones of driver. So we can remove the phy config data from each board
>>> dts files and add default-hdmiphy-config property to there so that default
>>> data of driver can be used.
>>>
>>>
>>> Thanks,
>>> Inki Dae
>>>
>>
>> We can simplify it further by letting the driver use phy-conf
>> property from DT. If phy-conf property is not available switch to
>> default confs, provided in the driver. This way we don't need to add
>> default-hdmiphy-config property to all board files.
>>
>
> This is probably a worthwhile discussion to have on Shirish's patch
> with devicetree-discuss. I'm unsure which is the preferred way to do
> something like this.

I agree.

Shall we keep those patches for "phy conf from DT" independent to this
series? Until this phy separation patches get merged, hdmi will remain
broken for 5250 and 5420.

regards,
Rahul Sharma.

>
> Sean
>
>> The number of exceptions where we need to override the default confs
>> is zero (as if now). 5420 based Peach and Smdk boards work exactly
>> the same with same set of phy confs on 3 hdmi displays, I have. It
>> may differ on Analyser. IMO we can defer this part till we have
>> unacceptable analyser results for any specific board.
>>
>> Regards,
>> Rahul Sharma.
>>
>>>> Sean
>>>>
>>>>
>>>>
>>>> > Rahul, let's go if there is other opinion. we SHOULD MERGE these this
>>>> > time.:)
>>>> >
>>>> > Thanks,
>>>> > Inki Dae
>>>> >
>>>> >> Regards,
>>>> >> Rahul Sharma.
>>>> >>
>>>> >> >
>>>> >> >>
>>>> >> >> regards,
>>>> >> >> Rahul Sharma.
>>>> >> >>
>>>> >> >> >> Sean
>>>> >> >> >>
>>>> >> >> >>
>>>> >> >
>>>> >> --
>>>> >> To unsubscribe from this list: send the line "unsubscribe linux-
>>>> samsung-
>>>> >> soc" in
>>>> >> the body of a message to majordomo@vger.kernel.org
>>>> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>> >
>>>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-10  8:27                             ` Rahul Sharma
@ 2013-09-16 12:40                               ` Inki Dae
  2013-09-27  4:53                                 ` Rahul Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Inki Dae @ 2013-09-16 12:40 UTC (permalink / raw)
  To: 'Rahul Sharma', 'Sean Paul'
  Cc: 'Rahul Sharma', 'linux-samsung-soc',
	'dri-devel', 'kgene.kim', 'sw0312.kim',
	'Lucas Stach', 'Tomasz Figa',
	'Sylwester Nawrocki', 'sunil joshi',
	'Shirish S',
	devicetree

CCing devicetree,

> -----Original Message-----
> From: Rahul Sharma [mailto:r.sh.open@gmail.com]
> Sent: Tuesday, September 10, 2013 5:28 PM
> To: Sean Paul
> Cc: Inki Dae; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
> Shirish S
> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
> driver
> 
> On 6 September 2013 19:21, Sean Paul <seanpaul@chromium.org> wrote:
> > On Thu, Sep 5, 2013 at 11:37 PM, Rahul Sharma <r.sh.open@gmail.com>
> wrote:
> >> On 5 September 2013 19:20, Inki Dae <inki.dae@samsung.com> wrote:
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Sean Paul [mailto:seanpaul@chromium.org]
> >>>> Sent: Thursday, September 05, 2013 10:20 PM
> >>>> To: Inki Dae
> >>>> Cc: Rahul Sharma; Rahul Sharma; linux-samsung-soc; dri-devel;
> kgene.kim;
> >>>> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil
joshi;
> >>>> Shirish S
> >>>> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
> hdmiphy
> >>>> driver
> >>>>
> >>>> On Thu, Sep 5, 2013 at 2:19 AM, Inki Dae <inki.dae@samsung.com>
wrote:
> >>>> >
> >>>> >
> >>>> >> -----Original Message-----
> >>>> >> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-
> samsung-
> >>>> soc-
> >>>> >> owner@vger.kernel.org] On Behalf Of Rahul Sharma
> >>>> >> Sent: Thursday, September 05, 2013 3:04 PM
> >>>> >> To: Inki Dae
> >>>> >> Cc: Sean Paul; Rahul Sharma; linux-samsung-soc; dri-devel;
> kgene.kim;
> >>>> >> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil
> joshi;
> >>>> >> Shirish S
> >>>> >> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
> >>>> hdmiphy
> >>>> >> driver
> >>>> >>
> >>>> >> On 5 September 2013 10:52, Inki Dae <inki.dae@samsung.com> wrote:
> >>>> >> >> >> >> >> +static struct hdmiphy_config hdmiphy_4210_configs[] =
> {
> >>>> >> >> >> >> >> +       {
> >>>> >> >> >> >> >> +               .pixel_clock = 27000000,
> >>>> >> >> >> >> >> +               .conf = {
> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10,
0x1C,
> >>>> > 0x30,
> >>>> >> >> > 0x40,
> >>>> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF,
0xF2,
> >>>> > 0x54,
> >>>> >> >> > 0x87,
> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00,
0x08,
> >>>> > 0x10,
> >>>> >> >> > 0xE0,
> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00,
0x00,
> >>>> > 0x00,
> >>>> >> >> > 0x00,
> >>>> >> >> >> >> >> +               },
> >>>> >> >> >> >> >> +       },
> >>>> >> >> >> >> >> +       {
> >>>> >> >> >> >> >> +               .pixel_clock = 27027000,
> >>>> >> >> >> >> >> +               .conf = {
> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10,
0x9C,
> >>>> > 0x09,
> >>>> >> >> > 0x64,
> >>>> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF,
0xF2,
> >>>> > 0x54,
> >>>> >> >> > 0x87,
> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00,
0x08,
> >>>> > 0x10,
> >>>> >> >> > 0xE0,
> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00,
0x00,
> >>>> > 0x00,
> >>>> >> >> > 0x00,
> >>>> >> >> >> >> >> +               },
> >>>> >> >> >> >> >> +       },
> >>>> >> >> >> >> >> +       {
> >>>> >> >> >> >> >> +               .pixel_clock = 74176000,
> >>>> >> >> >> >> >> +               .conf = {
> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10,
0x9C,
> >>>> > 0xef,
> >>>> >> >> > 0x5B,
> >>>> >> >> >> >> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef,
0xF3,
> >>>> > 0x54,
> >>>> >> >> > 0xb9,
> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00,
0x08,
> >>>> > 0x10,
> >>>> >> >> > 0xE0,
> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01,
0x00,
> >>>> > 0x00,
> >>>> >> >> > 0x00,
> >>>> >> >> >> >> >> +               },
> >>>> >> >> >> >> >> +       },
> >>>> >> >> >> >> >> +       {
> >>>> >> >> >> >> >> +               .pixel_clock = 74250000,
> >>>> >> >> >> >> >> +               .conf = {
> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10,
0x9c,
> >>>> > 0xf8,
> >>>> >> >> > 0x40,
> >>>> >> >> >> >> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff,
0xf1,
> >>>> > 0x54,
> >>>> >> >> > 0xba,
> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00,
0x08,
> >>>> > 0x10,
> >>>> >> >> > 0xe0,
> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01,
0x00,
> >>>> > 0x00,
> >>>> >> >> > 0x00,
> >>>> >> >> >> >> >> +               },
> >>>> >> >> >> >> >> +       },
> >>>> >> >> >> >> >> +       {
> >>>> >> >> >> >> >> +               .pixel_clock = 148500000,
> >>>> >> >> >> >> >> +               .conf = {
> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10,
0x9C,
> >>>> > 0xf8,
> >>>> >> >> > 0x40,
> >>>> >> >> >> >> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff,
0xF1,
> >>>> > 0x54,
> >>>> >> >> > 0xba,
> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00,
0x08,
> >>>> > 0x10,
> >>>> >> >> > 0xE0,
> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02,
0x00,
> >>>> > 0x00,
> >>>> >> >> > 0x00,
> >>>> >> >> >> >> >> +               },
> >>>> >> >> >> >> >> +       },
> >>>> >> >> >> >> >> +};
> >>>> >> >> >> >> >> +
> >>>> >> >> >> >> >
> >>>> >> >> >> >> > Are you aware of the effort to move these to dt? Since
> these
> >>>> >> are
> >>>> >> >> >> >> > board-specific values, it seems incorrect to apply them
> >>>> >> >> universally.
> >>>> >> >> >> >> > Shirish has uploaded a patch to the chromium review
> site to
> >>>> >> push
> >>>> >> >> >> these
> >>>> >> >> >> >> > into dt
> >>> (https://chromium-review.googlesource.com/#/c/65581).
> >>>> >> >> Maybe
> >>>> >> >> >> >> > you can work that into your patch set?
> >>>> >> >> >> >> >
> >>>> >> >> >> >
> >>>> >> >> >> > Are these really board-specific values?
> >>>> >> >> >>
> >>>> >> >> >> According to your hardware people:
> >>>> >> >> >>
> >>>> >> >> >> "If the signal pattern doesn't change for new board, the phy
> >>>> setting
> >>>> >> >> >> is same as the current board. But if changed, you need to
> confirm
> >>>> >> with
> >>>> >> >> >> measurement of signals, because it may vary slightly by
> >>>> resistance
> >>>> >> of
> >>>> >> >> >> board pattern"
> >>>> >> >> >>
> >>>> >> >> >
> >>>> >> >> > Right. it seems that the phy configuration should be adjusted
> >>>> >> according
> >>>> >> >> to
> >>>> >> >> > PCB environment: OSC clock rate, 24MHz or 27MHz, could be
> decided
> >>>> by
> >>>> >> PCB
> >>>> >> >> > even though most PCBs use 27MHz.
> >>>> >> >> >
> >>>> >> >> >> That indicates to me that we might need to tweak these on a
> per-
> >>>> >> board
> >>>> >> >> >> basis.
> >>>> >> >> >>
> >>>> >> >> >> In the 5420 datasheet, there are a few register descriptions
> >>>> >> available
> >>>> >> >> >> for the phy. 0x145D0004 is CLK_SEL which seems like it would
> be
> >>>> >> >> >> board-specific, same with TX_* registers.
> >>>> >> >> >>
> >>>> >> >> >
> >>>> >> >> > And we can select HDMI Tx PHY internal PLL input clock by
> setting
> >>>> >> >> CLK_SEL.
> >>>> >> >> > Ok, Shirish's patch set is reasonable to me. However, that
> patch
> >>>> set
> >>>> >> >> should
> >>>> >> >> > be rebased on top of Rahul's patch set. Shirish and Rahul,
> please
> >>>> re-
> >>>> >> >> post
> >>>> >> >> > your patch set after discussing how to rebase these patch
set.
> >>>> >> >> >
> >>>> >> >> > Thanks,
> >>>> >> >> > Inki Dae
> >>>> >> >> >
> >>>> >> >>
> >>>> >> >> In that case, we need to test the phy confs for all the exynos
> >>>> boards,
> >>>> >> >> supported in
> >>>> >> >> mainline. Probably needs a analyser as well to precisely
> compare the
> >>>> >> >> deviation.
> >>>> >> >
> >>>> >> > Shirish patch adds phy config data only to arndale and smdk5250
> >>>> boards,
> >>>> >> and
> >>>> >> > these config data should have each board specific values.
> Therefore,
> >>>> for
> >>>> >> > other boards, shouldn't correct phy config data suitable to
> their
> >>>> boards
> >>>> >> be
> >>>> >> > added to their board dts files? Is the above analyzer really
> needed?
> >>>> >> >
> >>>> >>
> >>>> >> Sorry, I had only seen his patches for chromium tree. In mainline
> >>>> >> version, he added for 5250 as well. But both sets (for arndale and
> >>>> >> smdk) are exactly same as original 5250 configs which also works
> >>>> >> with 4412 origen.
> >>>> >>
> >>>> >> Some problem has been identified during conformance testing for
> >>>> >> 5420 peach board, which happens with analyser. It was always
> >>>> >> working fine on the TV sets that I have. @Shirish/Sean please
> >>>> >> correct me if wrong.
> >>>> >>
> >>>> >> >> Shirish patch is only for 5420 Peach board. Else, to start with
> we
> >>>> can
> >>>> >> >> mark
> >>>> >> >> phyconf as optional property which overrides the default Phy
> Confs
> >>>> for
> >>>> >> >> given SoC.
> >>>> >> >
> >>>> >> > Hm.... you mean that hdmiphy driver use the default phy config
> data
> >>>> in
> >>>> >> > driver; most boards use the same data, and only in special case;
> a
> >>>> board
> >>>> >> > uses different OSC clock rate, the hdmiphy driver use phy config
> data
> >>>> >> from
> >>>> >> > dts file checking hdmiphy-confs property?
> >>>> >> >
> >>>> >>
> >>>> >> Yes. I meant same. I don't see the real need to duplicate so much
> >>>> >> of data in all board dts files. We can add it for a particular
> board,
> >>>> if
> >>>> >> really required.
> >>>> >>
> >>>> >
> >>>> > Yes, reasonable to me. It's not good that board dts files have same
> phy
> >>>> > config data. How about using the phy config data from dts file if
> >>>> > hdmiphy-confs property exists, otherwise using default phy config
> data
> >>>> then?
> >>>> > This means that we don't need to remove the phy config data from
> driver;
> >>>> > that will be used as default values.
> >>>> >
> >>>>
> >>>> Can you add the "default" configs to exynos5250.dtsi and
> >>>> exynos5420.dtsi, then overwrite it in the board file if it needs to
> be
> >>>> different?
> >>>>
> >>
> >> This will still introduce some duplication as 4412 and 5250 share same
> >> phy confs and have no common dtsi. Similar situation can arise for
> later
> >> SoCs in exynos series.
> >>
> >>>
> >>> Good idea but how about adding default-hdmiphy-config property to each
> board
> >>> dts file and removing phy config data from board dts file if they are
> same
> >>> as default one of driver? With this, hdmiphy driver checks if
> >>> default-hdmiphy-config property exists, and then use default config
> data if
> >>> exists. And if not exists, hdmiphy driver gets and uses board specific
> phy
> >>> config data from board dts file.
> >>> And it seems that the phy config values of Shirish's patch set are
> same as
> >>> default ones of driver. So we can remove the phy config data from each
> board
> >>> dts files and add default-hdmiphy-config property to there so that
> default
> >>> data of driver can be used.
> >>>
> >>>
> >>> Thanks,
> >>> Inki Dae
> >>>
> >>
> >> We can simplify it further by letting the driver use phy-conf
> >> property from DT. If phy-conf property is not available switch to
> >> default confs, provided in the driver. This way we don't need to add
> >> default-hdmiphy-config property to all board files.
> >>
> >
> > This is probably a worthwhile discussion to have on Shirish's patch
> > with devicetree-discuss. I'm unsure which is the preferred way to do
> > something like this.
> 
> I agree.
> 
> Shall we keep those patches for "phy conf from DT" independent to this
> series? Until this phy separation patches get merged, hdmi will remain
> broken for 5250 and 5420.
> 

Sorry for being late. I was so busy.

I have pondered over whether we should use default phy config values of
driver or not. My opinion is that we need to keep the default phy config
values in dts file because the values couldn't be used as default for all
boards: the default means that all boards should work well with the default
values, but wouldn't work. Therefore, the default values we are discussing
are specific to some boards even though most boards work well with the
values.

So I tend to agree with Sean Paul. Let's just add the default phy config
values to each board dts file that works well even though the values are
duplicated. For this, Rahul, we could rebase your patch set on top of
Shirish's patch.

Other opinions?

Thanks,
Inki Dae

> regards,
> Rahul Sharma.
> 
> >
> > Sean
> >
> >> The number of exceptions where we need to override the default confs
> >> is zero (as if now). 5420 based Peach and Smdk boards work exactly
> >> the same with same set of phy confs on 3 hdmi displays, I have. It
> >> may differ on Analyser. IMO we can defer this part till we have
> >> unacceptable analyser results for any specific board.
> >>
> >> Regards,
> >> Rahul Sharma.
> >>
> >>>> Sean
> >>>>
> >>>>
> >>>>
> >>>> > Rahul, let's go if there is other opinion. we SHOULD MERGE these
> this
> >>>> > time.:)
> >>>> >
> >>>> > Thanks,
> >>>> > Inki Dae
> >>>> >
> >>>> >> Regards,
> >>>> >> Rahul Sharma.
> >>>> >>
> >>>> >> >
> >>>> >> >>
> >>>> >> >> regards,
> >>>> >> >> Rahul Sharma.
> >>>> >> >>
> >>>> >> >> >> Sean
> >>>> >> >> >>
> >>>> >> >> >>
> >>>> >> >
> >>>> >> --
> >>>> >> To unsubscribe from this list: send the line "unsubscribe linux-
> >>>> samsung-
> >>>> >> soc" in
> >>>> >> the body of a message to majordomo@vger.kernel.org
> >>>> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >>>> >
> >>>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-16 12:40                               ` Inki Dae
@ 2013-09-27  4:53                                 ` Rahul Sharma
  2013-09-28 16:10                                   ` Inki Dae
  0 siblings, 1 reply; 45+ messages in thread
From: Rahul Sharma @ 2013-09-27  4:53 UTC (permalink / raw)
  To: Inki Dae
  Cc: Sean Paul, Rahul Sharma, linux-samsung-soc, dri-devel, kgene.kim,
	sw0312.kim, Lucas Stach, Tomasz Figa, Sylwester Nawrocki,
	sunil joshi, Shirish S, devicetree

On 16 September 2013 18:10, Inki Dae <inki.dae@samsung.com> wrote:
> CCing devicetree,
>
>> -----Original Message-----
>> From: Rahul Sharma [mailto:r.sh.open@gmail.com]
>> Sent: Tuesday, September 10, 2013 5:28 PM
>> To: Sean Paul
>> Cc: Inki Dae; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
>> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
>> Shirish S
>> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
>> driver
>>
>> On 6 September 2013 19:21, Sean Paul <seanpaul@chromium.org> wrote:
>> > On Thu, Sep 5, 2013 at 11:37 PM, Rahul Sharma <r.sh.open@gmail.com>
>> wrote:
>> >> On 5 September 2013 19:20, Inki Dae <inki.dae@samsung.com> wrote:
>> >>>
>> >>>
>> >>>> -----Original Message-----
>> >>>> From: Sean Paul [mailto:seanpaul@chromium.org]
>> >>>> Sent: Thursday, September 05, 2013 10:20 PM
>> >>>> To: Inki Dae
>> >>>> Cc: Rahul Sharma; Rahul Sharma; linux-samsung-soc; dri-devel;
>> kgene.kim;
>> >>>> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil
> joshi;
>> >>>> Shirish S
>> >>>> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
>> hdmiphy
>> >>>> driver
>> >>>>
>> >>>> On Thu, Sep 5, 2013 at 2:19 AM, Inki Dae <inki.dae@samsung.com>
> wrote:
>> >>>> >
>> >>>> >
>> >>>> >> -----Original Message-----
>> >>>> >> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-
>> samsung-
>> >>>> soc-
>> >>>> >> owner@vger.kernel.org] On Behalf Of Rahul Sharma
>> >>>> >> Sent: Thursday, September 05, 2013 3:04 PM
>> >>>> >> To: Inki Dae
>> >>>> >> Cc: Sean Paul; Rahul Sharma; linux-samsung-soc; dri-devel;
>> kgene.kim;
>> >>>> >> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil
>> joshi;
>> >>>> >> Shirish S
>> >>>> >> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
>> >>>> hdmiphy
>> >>>> >> driver
>> >>>> >>
>> >>>> >> On 5 September 2013 10:52, Inki Dae <inki.dae@samsung.com> wrote:
>> >>>> >> >> >> >> >> +static struct hdmiphy_config hdmiphy_4210_configs[] =
>> {
>> >>>> >> >> >> >> >> +       {
>> >>>> >> >> >> >> >> +               .pixel_clock = 27000000,
>> >>>> >> >> >> >> >> +               .conf = {
>> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10,
> 0x1C,
>> >>>> > 0x30,
>> >>>> >> >> > 0x40,
>> >>>> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF,
> 0xF2,
>> >>>> > 0x54,
>> >>>> >> >> > 0x87,
>> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00,
> 0x08,
>> >>>> > 0x10,
>> >>>> >> >> > 0xE0,
>> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00,
> 0x00,
>> >>>> > 0x00,
>> >>>> >> >> > 0x00,
>> >>>> >> >> >> >> >> +               },
>> >>>> >> >> >> >> >> +       },
>> >>>> >> >> >> >> >> +       {
>> >>>> >> >> >> >> >> +               .pixel_clock = 27027000,
>> >>>> >> >> >> >> >> +               .conf = {
>> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD4, 0x10,
> 0x9C,
>> >>>> > 0x09,
>> >>>> >> >> > 0x64,
>> >>>> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF,
> 0xF2,
>> >>>> > 0x54,
>> >>>> >> >> > 0x87,
>> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00,
> 0x08,
>> >>>> > 0x10,
>> >>>> >> >> > 0xE0,
>> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00,
> 0x00,
>> >>>> > 0x00,
>> >>>> >> >> > 0x00,
>> >>>> >> >> >> >> >> +               },
>> >>>> >> >> >> >> >> +       },
>> >>>> >> >> >> >> >> +       {
>> >>>> >> >> >> >> >> +               .pixel_clock = 74176000,
>> >>>> >> >> >> >> >> +               .conf = {
>> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10,
> 0x9C,
>> >>>> > 0xef,
>> >>>> >> >> > 0x5B,
>> >>>> >> >> >> >> >> +                       0x6D, 0x10, 0x01, 0x51, 0xef,
> 0xF3,
>> >>>> > 0x54,
>> >>>> >> >> > 0xb9,
>> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38, 0x00,
> 0x08,
>> >>>> > 0x10,
>> >>>> >> >> > 0xE0,
>> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xa5, 0x26, 0x01,
> 0x00,
>> >>>> > 0x00,
>> >>>> >> >> > 0x00,
>> >>>> >> >> >> >> >> +               },
>> >>>> >> >> >> >> >> +       },
>> >>>> >> >> >> >> >> +       {
>> >>>> >> >> >> >> >> +               .pixel_clock = 74250000,
>> >>>> >> >> >> >> >> +               .conf = {
>> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xd8, 0x10,
> 0x9c,
>> >>>> > 0xf8,
>> >>>> >> >> > 0x40,
>> >>>> >> >> >> >> >> +                       0x6a, 0x10, 0x01, 0x51, 0xff,
> 0xf1,
>> >>>> > 0x54,
>> >>>> >> >> > 0xba,
>> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00,
> 0x08,
>> >>>> > 0x10,
>> >>>> >> >> > 0xe0,
>> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x01,
> 0x00,
>> >>>> > 0x00,
>> >>>> >> >> > 0x00,
>> >>>> >> >> >> >> >> +               },
>> >>>> >> >> >> >> >> +       },
>> >>>> >> >> >> >> >> +       {
>> >>>> >> >> >> >> >> +               .pixel_clock = 148500000,
>> >>>> >> >> >> >> >> +               .conf = {
>> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10,
> 0x9C,
>> >>>> > 0xf8,
>> >>>> >> >> > 0x40,
>> >>>> >> >> >> >> >> +                       0x6A, 0x18, 0x00, 0x51, 0xff,
> 0xF1,
>> >>>> > 0x54,
>> >>>> >> >> > 0xba,
>> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38, 0x00,
> 0x08,
>> >>>> > 0x10,
>> >>>> >> >> > 0xE0,
>> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26, 0x02,
> 0x00,
>> >>>> > 0x00,
>> >>>> >> >> > 0x00,
>> >>>> >> >> >> >> >> +               },
>> >>>> >> >> >> >> >> +       },
>> >>>> >> >> >> >> >> +};
>> >>>> >> >> >> >> >> +
>> >>>> >> >> >> >> >
>> >>>> >> >> >> >> > Are you aware of the effort to move these to dt? Since
>> these
>> >>>> >> are
>> >>>> >> >> >> >> > board-specific values, it seems incorrect to apply them
>> >>>> >> >> universally.
>> >>>> >> >> >> >> > Shirish has uploaded a patch to the chromium review
>> site to
>> >>>> >> push
>> >>>> >> >> >> these
>> >>>> >> >> >> >> > into dt
>> >>> (https://chromium-review.googlesource.com/#/c/65581).
>> >>>> >> >> Maybe
>> >>>> >> >> >> >> > you can work that into your patch set?
>> >>>> >> >> >> >> >
>> >>>> >> >> >> >
>> >>>> >> >> >> > Are these really board-specific values?
>> >>>> >> >> >>
>> >>>> >> >> >> According to your hardware people:
>> >>>> >> >> >>
>> >>>> >> >> >> "If the signal pattern doesn't change for new board, the phy
>> >>>> setting
>> >>>> >> >> >> is same as the current board. But if changed, you need to
>> confirm
>> >>>> >> with
>> >>>> >> >> >> measurement of signals, because it may vary slightly by
>> >>>> resistance
>> >>>> >> of
>> >>>> >> >> >> board pattern"
>> >>>> >> >> >>
>> >>>> >> >> >
>> >>>> >> >> > Right. it seems that the phy configuration should be adjusted
>> >>>> >> according
>> >>>> >> >> to
>> >>>> >> >> > PCB environment: OSC clock rate, 24MHz or 27MHz, could be
>> decided
>> >>>> by
>> >>>> >> PCB
>> >>>> >> >> > even though most PCBs use 27MHz.
>> >>>> >> >> >
>> >>>> >> >> >> That indicates to me that we might need to tweak these on a
>> per-
>> >>>> >> board
>> >>>> >> >> >> basis.
>> >>>> >> >> >>
>> >>>> >> >> >> In the 5420 datasheet, there are a few register descriptions
>> >>>> >> available
>> >>>> >> >> >> for the phy. 0x145D0004 is CLK_SEL which seems like it would
>> be
>> >>>> >> >> >> board-specific, same with TX_* registers.
>> >>>> >> >> >>
>> >>>> >> >> >
>> >>>> >> >> > And we can select HDMI Tx PHY internal PLL input clock by
>> setting
>> >>>> >> >> CLK_SEL.
>> >>>> >> >> > Ok, Shirish's patch set is reasonable to me. However, that
>> patch
>> >>>> set
>> >>>> >> >> should
>> >>>> >> >> > be rebased on top of Rahul's patch set. Shirish and Rahul,
>> please
>> >>>> re-
>> >>>> >> >> post
>> >>>> >> >> > your patch set after discussing how to rebase these patch
> set.
>> >>>> >> >> >
>> >>>> >> >> > Thanks,
>> >>>> >> >> > Inki Dae
>> >>>> >> >> >
>> >>>> >> >>
>> >>>> >> >> In that case, we need to test the phy confs for all the exynos
>> >>>> boards,
>> >>>> >> >> supported in
>> >>>> >> >> mainline. Probably needs a analyser as well to precisely
>> compare the
>> >>>> >> >> deviation.
>> >>>> >> >
>> >>>> >> > Shirish patch adds phy config data only to arndale and smdk5250
>> >>>> boards,
>> >>>> >> and
>> >>>> >> > these config data should have each board specific values.
>> Therefore,
>> >>>> for
>> >>>> >> > other boards, shouldn't correct phy config data suitable to
>> their
>> >>>> boards
>> >>>> >> be
>> >>>> >> > added to their board dts files? Is the above analyzer really
>> needed?
>> >>>> >> >
>> >>>> >>
>> >>>> >> Sorry, I had only seen his patches for chromium tree. In mainline
>> >>>> >> version, he added for 5250 as well. But both sets (for arndale and
>> >>>> >> smdk) are exactly same as original 5250 configs which also works
>> >>>> >> with 4412 origen.
>> >>>> >>
>> >>>> >> Some problem has been identified during conformance testing for
>> >>>> >> 5420 peach board, which happens with analyser. It was always
>> >>>> >> working fine on the TV sets that I have. @Shirish/Sean please
>> >>>> >> correct me if wrong.
>> >>>> >>
>> >>>> >> >> Shirish patch is only for 5420 Peach board. Else, to start with
>> we
>> >>>> can
>> >>>> >> >> mark
>> >>>> >> >> phyconf as optional property which overrides the default Phy
>> Confs
>> >>>> for
>> >>>> >> >> given SoC.
>> >>>> >> >
>> >>>> >> > Hm.... you mean that hdmiphy driver use the default phy config
>> data
>> >>>> in
>> >>>> >> > driver; most boards use the same data, and only in special case;
>> a
>> >>>> board
>> >>>> >> > uses different OSC clock rate, the hdmiphy driver use phy config
>> data
>> >>>> >> from
>> >>>> >> > dts file checking hdmiphy-confs property?
>> >>>> >> >
>> >>>> >>
>> >>>> >> Yes. I meant same. I don't see the real need to duplicate so much
>> >>>> >> of data in all board dts files. We can add it for a particular
>> board,
>> >>>> if
>> >>>> >> really required.
>> >>>> >>
>> >>>> >
>> >>>> > Yes, reasonable to me. It's not good that board dts files have same
>> phy
>> >>>> > config data. How about using the phy config data from dts file if
>> >>>> > hdmiphy-confs property exists, otherwise using default phy config
>> data
>> >>>> then?
>> >>>> > This means that we don't need to remove the phy config data from
>> driver;
>> >>>> > that will be used as default values.
>> >>>> >
>> >>>>
>> >>>> Can you add the "default" configs to exynos5250.dtsi and
>> >>>> exynos5420.dtsi, then overwrite it in the board file if it needs to
>> be
>> >>>> different?
>> >>>>
>> >>
>> >> This will still introduce some duplication as 4412 and 5250 share same
>> >> phy confs and have no common dtsi. Similar situation can arise for
>> later
>> >> SoCs in exynos series.
>> >>
>> >>>
>> >>> Good idea but how about adding default-hdmiphy-config property to each
>> board
>> >>> dts file and removing phy config data from board dts file if they are
>> same
>> >>> as default one of driver? With this, hdmiphy driver checks if
>> >>> default-hdmiphy-config property exists, and then use default config
>> data if
>> >>> exists. And if not exists, hdmiphy driver gets and uses board specific
>> phy
>> >>> config data from board dts file.
>> >>> And it seems that the phy config values of Shirish's patch set are
>> same as
>> >>> default ones of driver. So we can remove the phy config data from each
>> board
>> >>> dts files and add default-hdmiphy-config property to there so that
>> default
>> >>> data of driver can be used.
>> >>>
>> >>>
>> >>> Thanks,
>> >>> Inki Dae
>> >>>
>> >>
>> >> We can simplify it further by letting the driver use phy-conf
>> >> property from DT. If phy-conf property is not available switch to
>> >> default confs, provided in the driver. This way we don't need to add
>> >> default-hdmiphy-config property to all board files.
>> >>
>> >
>> > This is probably a worthwhile discussion to have on Shirish's patch
>> > with devicetree-discuss. I'm unsure which is the preferred way to do
>> > something like this.
>>
>> I agree.
>>
>> Shall we keep those patches for "phy conf from DT" independent to this
>> series? Until this phy separation patches get merged, hdmi will remain
>> broken for 5250 and 5420.
>>
>
> Sorry for being late. I was so busy.
>
> I have pondered over whether we should use default phy config values of
> driver or not. My opinion is that we need to keep the default phy config
> values in dts file because the values couldn't be used as default for all
> boards: the default means that all boards should work well with the default
> values, but wouldn't work. Therefore, the default values we are discussing
> are specific to some boards even though most boards work well with the
> values.
>
> So I tend to agree with Sean Paul. Let's just add the default phy config
> values to each board dts file that works well even though the values are
> duplicated. For this, Rahul, we could rebase your patch set on top of
> Shirish's patch.
>
> Other opinions?
>

Any opinion from Device-Tree folks?

IMO, we should have same consensus on Shirish patches before proceeding.

Regards,
Rahul Sharma.

> Thanks,
> Inki Dae
>
>> regards,
>> Rahul Sharma.
>>
>> >
>> > Sean
>> >
>> >> The number of exceptions where we need to override the default confs
>> >> is zero (as if now). 5420 based Peach and Smdk boards work exactly
>> >> the same with same set of phy confs on 3 hdmi displays, I have. It
>> >> may differ on Analyser. IMO we can defer this part till we have
>> >> unacceptable analyser results for any specific board.
>> >>
>> >> Regards,
>> >> Rahul Sharma.
>> >>
>> >>>> Sean
>> >>>>
>> >>>>
>> >>>>
>> >>>> > Rahul, let's go if there is other opinion. we SHOULD MERGE these
>> this
>> >>>> > time.:)
>> >>>> >
>> >>>> > Thanks,
>> >>>> > Inki Dae
>> >>>> >
>> >>>> >> Regards,
>> >>>> >> Rahul Sharma.
>> >>>> >>
>> >>>> >> >
>> >>>> >> >>
>> >>>> >> >> regards,
>> >>>> >> >> Rahul Sharma.
>> >>>> >> >>
>> >>>> >> >> >> Sean
>> >>>> >> >> >>
>> >>>> >> >> >>
>> >>>> >> >
>> >>>> >> --
>> >>>> >> To unsubscribe from this list: send the line "unsubscribe linux-
>> >>>> samsung-
>> >>>> >> soc" in
>> >>>> >> the body of a message to majordomo@vger.kernel.org
>> >>>> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> >>>> >
>> >>>
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-27  4:53                                 ` Rahul Sharma
@ 2013-09-28 16:10                                   ` Inki Dae
       [not found]                                     ` <CAAQKjZPtxLAJOz6573+hEPZokEnvGF8BTMXoxcYUQ8zySAn-OA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
       [not found]                                     ` <5248A4EE.9000708@samsung.com>
  0 siblings, 2 replies; 45+ messages in thread
From: Inki Dae @ 2013-09-28 16:10 UTC (permalink / raw)
  To: Rahul Sharma
  Cc: devicetree, linux-samsung-soc, sw0312.kim, sunil joshi,
	dri-devel, kgene.kim, Shirish S, Sylwester Nawrocki,
	Rahul Sharma


[-- Attachment #1.1: Type: text/plain, Size: 15738 bytes --]

2013/9/27 Rahul Sharma <r.sh.open@gmail.com>

> On 16 September 2013 18:10, Inki Dae <inki.dae@samsung.com> wrote:
> > CCing devicetree,
> >
> >> -----Original Message-----
> >> From: Rahul Sharma [mailto:r.sh.open@gmail.com]
> >> Sent: Tuesday, September 10, 2013 5:28 PM
> >> To: Sean Paul
> >> Cc: Inki Dae; Rahul Sharma; linux-samsung-soc; dri-devel; kgene.kim;
> >> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil joshi;
> >> Shirish S
> >> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
> hdmiphy
> >> driver
> >>
> >> On 6 September 2013 19:21, Sean Paul <seanpaul@chromium.org> wrote:
> >> > On Thu, Sep 5, 2013 at 11:37 PM, Rahul Sharma <r.sh.open@gmail.com>
> >> wrote:
> >> >> On 5 September 2013 19:20, Inki Dae <inki.dae@samsung.com> wrote:
> >> >>>
> >> >>>
> >> >>>> -----Original Message-----
> >> >>>> From: Sean Paul [mailto:seanpaul@chromium.org]
> >> >>>> Sent: Thursday, September 05, 2013 10:20 PM
> >> >>>> To: Inki Dae
> >> >>>> Cc: Rahul Sharma; Rahul Sharma; linux-samsung-soc; dri-devel;
> >> kgene.kim;
> >> >>>> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil
> > joshi;
> >> >>>> Shirish S
> >> >>>> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
> >> hdmiphy
> >> >>>> driver
> >> >>>>
> >> >>>> On Thu, Sep 5, 2013 at 2:19 AM, Inki Dae <inki.dae@samsung.com>
> > wrote:
> >> >>>> >
> >> >>>> >
> >> >>>> >> -----Original Message-----
> >> >>>> >> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-
> >> samsung-
> >> >>>> soc-
> >> >>>> >> owner@vger.kernel.org] On Behalf Of Rahul Sharma
> >> >>>> >> Sent: Thursday, September 05, 2013 3:04 PM
> >> >>>> >> To: Inki Dae
> >> >>>> >> Cc: Sean Paul; Rahul Sharma; linux-samsung-soc; dri-devel;
> >> kgene.kim;
> >> >>>> >> sw0312.kim; Lucas Stach; Tomasz Figa; Sylwester Nawrocki; sunil
> >> joshi;
> >> >>>> >> Shirish S
> >> >>>> >> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code
> to
> >> >>>> hdmiphy
> >> >>>> >> driver
> >> >>>> >>
> >> >>>> >> On 5 September 2013 10:52, Inki Dae <inki.dae@samsung.com>
> wrote:
> >> >>>> >> >> >> >> >> +static struct hdmiphy_config
> hdmiphy_4210_configs[] =
> >> {
> >> >>>> >> >> >> >> >> +       {
> >> >>>> >> >> >> >> >> +               .pixel_clock = 27000000,
> >> >>>> >> >> >> >> >> +               .conf = {
> >> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8,
> 0x10,
> > 0x1C,
> >> >>>> > 0x30,
> >> >>>> >> >> > 0x40,
> >> >>>> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51,
> 0xDF,
> > 0xF2,
> >> >>>> > 0x54,
> >> >>>> >> >> > 0x87,
> >> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38,
> 0x00,
> > 0x08,
> >> >>>> > 0x10,
> >> >>>> >> >> > 0xE0,
> >> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26,
> 0x00,
> > 0x00,
> >> >>>> > 0x00,
> >> >>>> >> >> > 0x00,
> >> >>>> >> >> >> >> >> +               },
> >> >>>> >> >> >> >> >> +       },
> >> >>>> >> >> >> >> >> +       {
> >> >>>> >> >> >> >> >> +               .pixel_clock = 27027000,
> >> >>>> >> >> >> >> >> +               .conf = {
> >> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD4,
> 0x10,
> > 0x9C,
> >> >>>> > 0x09,
> >> >>>> >> >> > 0x64,
> >> >>>> >> >> >> >> >> +                       0x6B, 0x10, 0x02, 0x51,
> 0xDF,
> > 0xF2,
> >> >>>> > 0x54,
> >> >>>> >> >> > 0x87,
> >> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38,
> 0x00,
> > 0x08,
> >> >>>> > 0x10,
> >> >>>> >> >> > 0xE0,
> >> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xE3, 0x26,
> 0x00,
> > 0x00,
> >> >>>> > 0x00,
> >> >>>> >> >> > 0x00,
> >> >>>> >> >> >> >> >> +               },
> >> >>>> >> >> >> >> >> +       },
> >> >>>> >> >> >> >> >> +       {
> >> >>>> >> >> >> >> >> +               .pixel_clock = 74176000,
> >> >>>> >> >> >> >> >> +               .conf = {
> >> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8,
> 0x10,
> > 0x9C,
> >> >>>> > 0xef,
> >> >>>> >> >> > 0x5B,
> >> >>>> >> >> >> >> >> +                       0x6D, 0x10, 0x01, 0x51,
> 0xef,
> > 0xF3,
> >> >>>> > 0x54,
> >> >>>> >> >> > 0xb9,
> >> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x30, 0x38,
> 0x00,
> > 0x08,
> >> >>>> > 0x10,
> >> >>>> >> >> > 0xE0,
> >> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xa5, 0x26,
> 0x01,
> > 0x00,
> >> >>>> > 0x00,
> >> >>>> >> >> > 0x00,
> >> >>>> >> >> >> >> >> +               },
> >> >>>> >> >> >> >> >> +       },
> >> >>>> >> >> >> >> >> +       {
> >> >>>> >> >> >> >> >> +               .pixel_clock = 74250000,
> >> >>>> >> >> >> >> >> +               .conf = {
> >> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xd8,
> 0x10,
> > 0x9c,
> >> >>>> > 0xf8,
> >> >>>> >> >> > 0x40,
> >> >>>> >> >> >> >> >> +                       0x6a, 0x10, 0x01, 0x51,
> 0xff,
> > 0xf1,
> >> >>>> > 0x54,
> >> >>>> >> >> > 0xba,
> >> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38,
> 0x00,
> > 0x08,
> >> >>>> > 0x10,
> >> >>>> >> >> > 0xe0,
> >> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26,
> 0x01,
> > 0x00,
> >> >>>> > 0x00,
> >> >>>> >> >> > 0x00,
> >> >>>> >> >> >> >> >> +               },
> >> >>>> >> >> >> >> >> +       },
> >> >>>> >> >> >> >> >> +       {
> >> >>>> >> >> >> >> >> +               .pixel_clock = 148500000,
> >> >>>> >> >> >> >> >> +               .conf = {
> >> >>>> >> >> >> >> >> +                       0x01, 0x05, 0x00, 0xD8,
> 0x10,
> > 0x9C,
> >> >>>> > 0xf8,
> >> >>>> >> >> > 0x40,
> >> >>>> >> >> >> >> >> +                       0x6A, 0x18, 0x00, 0x51,
> 0xff,
> > 0xF1,
> >> >>>> > 0x54,
> >> >>>> >> >> > 0xba,
> >> >>>> >> >> >> >> >> +                       0x84, 0x00, 0x10, 0x38,
> 0x00,
> > 0x08,
> >> >>>> > 0x10,
> >> >>>> >> >> > 0xE0,
> >> >>>> >> >> >> >> >> +                       0x22, 0x40, 0xa4, 0x26,
> 0x02,
> > 0x00,
> >> >>>> > 0x00,
> >> >>>> >> >> > 0x00,
> >> >>>> >> >> >> >> >> +               },
> >> >>>> >> >> >> >> >> +       },
> >> >>>> >> >> >> >> >> +};
> >> >>>> >> >> >> >> >> +
> >> >>>> >> >> >> >> >
> >> >>>> >> >> >> >> > Are you aware of the effort to move these to dt?
> Since
> >> these
> >> >>>> >> are
> >> >>>> >> >> >> >> > board-specific values, it seems incorrect to apply
> them
> >> >>>> >> >> universally.
> >> >>>> >> >> >> >> > Shirish has uploaded a patch to the chromium review
> >> site to
> >> >>>> >> push
> >> >>>> >> >> >> these
> >> >>>> >> >> >> >> > into dt
> >> >>> (https://chromium-review.googlesource.com/#/c/65581).
> >> >>>> >> >> Maybe
> >> >>>> >> >> >> >> > you can work that into your patch set?
> >> >>>> >> >> >> >> >
> >> >>>> >> >> >> >
> >> >>>> >> >> >> > Are these really board-specific values?
> >> >>>> >> >> >>
> >> >>>> >> >> >> According to your hardware people:
> >> >>>> >> >> >>
> >> >>>> >> >> >> "If the signal pattern doesn't change for new board, the
> phy
> >> >>>> setting
> >> >>>> >> >> >> is same as the current board. But if changed, you need to
> >> confirm
> >> >>>> >> with
> >> >>>> >> >> >> measurement of signals, because it may vary slightly by
> >> >>>> resistance
> >> >>>> >> of
> >> >>>> >> >> >> board pattern"
> >> >>>> >> >> >>
> >> >>>> >> >> >
> >> >>>> >> >> > Right. it seems that the phy configuration should be
> adjusted
> >> >>>> >> according
> >> >>>> >> >> to
> >> >>>> >> >> > PCB environment: OSC clock rate, 24MHz or 27MHz, could be
> >> decided
> >> >>>> by
> >> >>>> >> PCB
> >> >>>> >> >> > even though most PCBs use 27MHz.
> >> >>>> >> >> >
> >> >>>> >> >> >> That indicates to me that we might need to tweak these on
> a
> >> per-
> >> >>>> >> board
> >> >>>> >> >> >> basis.
> >> >>>> >> >> >>
> >> >>>> >> >> >> In the 5420 datasheet, there are a few register
> descriptions
> >> >>>> >> available
> >> >>>> >> >> >> for the phy. 0x145D0004 is CLK_SEL which seems like it
> would
> >> be
> >> >>>> >> >> >> board-specific, same with TX_* registers.
> >> >>>> >> >> >>
> >> >>>> >> >> >
> >> >>>> >> >> > And we can select HDMI Tx PHY internal PLL input clock by
> >> setting
> >> >>>> >> >> CLK_SEL.
> >> >>>> >> >> > Ok, Shirish's patch set is reasonable to me. However, that
> >> patch
> >> >>>> set
> >> >>>> >> >> should
> >> >>>> >> >> > be rebased on top of Rahul's patch set. Shirish and Rahul,
> >> please
> >> >>>> re-
> >> >>>> >> >> post
> >> >>>> >> >> > your patch set after discussing how to rebase these patch
> > set.
> >> >>>> >> >> >
> >> >>>> >> >> > Thanks,
> >> >>>> >> >> > Inki Dae
> >> >>>> >> >> >
> >> >>>> >> >>
> >> >>>> >> >> In that case, we need to test the phy confs for all the
> exynos
> >> >>>> boards,
> >> >>>> >> >> supported in
> >> >>>> >> >> mainline. Probably needs a analyser as well to precisely
> >> compare the
> >> >>>> >> >> deviation.
> >> >>>> >> >
> >> >>>> >> > Shirish patch adds phy config data only to arndale and
> smdk5250
> >> >>>> boards,
> >> >>>> >> and
> >> >>>> >> > these config data should have each board specific values.
> >> Therefore,
> >> >>>> for
> >> >>>> >> > other boards, shouldn't correct phy config data suitable to
> >> their
> >> >>>> boards
> >> >>>> >> be
> >> >>>> >> > added to their board dts files? Is the above analyzer really
> >> needed?
> >> >>>> >> >
> >> >>>> >>
> >> >>>> >> Sorry, I had only seen his patches for chromium tree. In
> mainline
> >> >>>> >> version, he added for 5250 as well. But both sets (for arndale
> and
> >> >>>> >> smdk) are exactly same as original 5250 configs which also works
> >> >>>> >> with 4412 origen.
> >> >>>> >>
> >> >>>> >> Some problem has been identified during conformance testing for
> >> >>>> >> 5420 peach board, which happens with analyser. It was always
> >> >>>> >> working fine on the TV sets that I have. @Shirish/Sean please
> >> >>>> >> correct me if wrong.
> >> >>>> >>
> >> >>>> >> >> Shirish patch is only for 5420 Peach board. Else, to start
> with
> >> we
> >> >>>> can
> >> >>>> >> >> mark
> >> >>>> >> >> phyconf as optional property which overrides the default Phy
> >> Confs
> >> >>>> for
> >> >>>> >> >> given SoC.
> >> >>>> >> >
> >> >>>> >> > Hm.... you mean that hdmiphy driver use the default phy config
> >> data
> >> >>>> in
> >> >>>> >> > driver; most boards use the same data, and only in special
> case;
> >> a
> >> >>>> board
> >> >>>> >> > uses different OSC clock rate, the hdmiphy driver use phy
> config
> >> data
> >> >>>> >> from
> >> >>>> >> > dts file checking hdmiphy-confs property?
> >> >>>> >> >
> >> >>>> >>
> >> >>>> >> Yes. I meant same. I don't see the real need to duplicate so
> much
> >> >>>> >> of data in all board dts files. We can add it for a particular
> >> board,
> >> >>>> if
> >> >>>> >> really required.
> >> >>>> >>
> >> >>>> >
> >> >>>> > Yes, reasonable to me. It's not good that board dts files have
> same
> >> phy
> >> >>>> > config data. How about using the phy config data from dts file if
> >> >>>> > hdmiphy-confs property exists, otherwise using default phy config
> >> data
> >> >>>> then?
> >> >>>> > This means that we don't need to remove the phy config data from
> >> driver;
> >> >>>> > that will be used as default values.
> >> >>>> >
> >> >>>>
> >> >>>> Can you add the "default" configs to exynos5250.dtsi and
> >> >>>> exynos5420.dtsi, then overwrite it in the board file if it needs to
> >> be
> >> >>>> different?
> >> >>>>
> >> >>
> >> >> This will still introduce some duplication as 4412 and 5250 share
> same
> >> >> phy confs and have no common dtsi. Similar situation can arise for
> >> later
> >> >> SoCs in exynos series.
> >> >>
> >> >>>
> >> >>> Good idea but how about adding default-hdmiphy-config property to
> each
> >> board
> >> >>> dts file and removing phy config data from board dts file if they
> are
> >> same
> >> >>> as default one of driver? With this, hdmiphy driver checks if
> >> >>> default-hdmiphy-config property exists, and then use default config
> >> data if
> >> >>> exists. And if not exists, hdmiphy driver gets and uses board
> specific
> >> phy
> >> >>> config data from board dts file.
> >> >>> And it seems that the phy config values of Shirish's patch set are
> >> same as
> >> >>> default ones of driver. So we can remove the phy config data from
> each
> >> board
> >> >>> dts files and add default-hdmiphy-config property to there so that
> >> default
> >> >>> data of driver can be used.
> >> >>>
> >> >>>
> >> >>> Thanks,
> >> >>> Inki Dae
> >> >>>
> >> >>
> >> >> We can simplify it further by letting the driver use phy-conf
> >> >> property from DT. If phy-conf property is not available switch to
> >> >> default confs, provided in the driver. This way we don't need to add
> >> >> default-hdmiphy-config property to all board files.
> >> >>
> >> >
> >> > This is probably a worthwhile discussion to have on Shirish's patch
> >> > with devicetree-discuss. I'm unsure which is the preferred way to do
> >> > something like this.
> >>
> >> I agree.
> >>
> >> Shall we keep those patches for "phy conf from DT" independent to this
> >> series? Until this phy separation patches get merged, hdmi will remain
> >> broken for 5250 and 5420.
> >>
> >
> > Sorry for being late. I was so busy.
> >
> > I have pondered over whether we should use default phy config values of
> > driver or not. My opinion is that we need to keep the default phy config
> > values in dts file because the values couldn't be used as default for all
> > boards: the default means that all boards should work well with the
> default
> > values, but wouldn't work. Therefore, the default values we are
> discussing
> > are specific to some boards even though most boards work well with the
> > values.
> >
> > So I tend to agree with Sean Paul. Let's just add the default phy config
> > values to each board dts file that works well even though the values are
> > duplicated. For this, Rahul, we could rebase your patch set on top of
> > Shirish's patch.
> >
> > Other opinions?
> >
>
> Any opinion from Device-Tree folks?
>
> IMO, we should have same consensus on Shirish patches before proceeding.
>
>
Rahul, it seems that DT people have no interest in this issue. So let's
have a consensus about this issue internally.

To Mr. Kyungmin, Sylwester, Kukjin Kim, and Tomasz,
How about keeping hdmiphy config data in each board dts file?

Thanks,
Inki Dae


> Regards,
> Rahul Sharma.
>
> > Thanks,
> > Inki Dae
> >
> >> regards,
> >> Rahul Sharma.
> >>
> >> >
> >> > Sean
> >> >
> >> >> The number of exceptions where we need to override the default confs
> >> >> is zero (as if now). 5420 based Peach and Smdk boards work exactly
> >> >> the same with same set of phy confs on 3 hdmi displays, I have. It
> >> >> may differ on Analyser. IMO we can defer this part till we have
> >> >> unacceptable analyser results for any specific board.
> >> >>
> >> >> Regards,
> >> >> Rahul Sharma.
> >> >>
> >> >>>> Sean
> >> >>>>
> >> >>>>
> >> >>>>
> >> >>>> > Rahul, let's go if there is other opinion. we SHOULD MERGE these
> >> this
> >> >>>> > time.:)
> >> >>>> >
> >> >>>> > Thanks,
> >> >>>> > Inki Dae
> >> >>>> >
> >> >>>> >> Regards,
> >> >>>> >> Rahul Sharma.
> >> >>>> >>
> >> >>>> >> >
> >> >>>> >> >>
> >> >>>> >> >> regards,
> >> >>>> >> >> Rahul Sharma.
> >> >>>> >> >>
> >> >>>> >> >> >> Sean
> >> >>>> >> >> >>
> >> >>>> >> >> >>
> >> >>>> >> >
> >> >>>> >> --
> >> >>>> >> To unsubscribe from this list: send the line "unsubscribe linux-
> >> >>>> samsung-
> >> >>>> >> soc" in
> >> >>>> >> the body of a message to majordomo@vger.kernel.org
> >> >>>> >> More majordomo info at
> http://vger.kernel.org/majordomo-info.html
> >> >>>> >
> >> >>>
> >
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>

[-- Attachment #1.2: Type: text/html, Size: 27720 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
       [not found]                                     ` <CAAQKjZPtxLAJOz6573+hEPZokEnvGF8BTMXoxcYUQ8zySAn-OA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2013-09-29 22:08                                       ` Sylwester Nawrocki
  2013-09-29 23:13                                         ` Tomasz Figa
  0 siblings, 1 reply; 45+ messages in thread
From: Sylwester Nawrocki @ 2013-09-29 22:08 UTC (permalink / raw)
  To: Inki Dae
  Cc: Rahul Sharma, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc, sw0312.kim, sunil joshi, dri-devel, kgene.kim,
	Shirish S, Sylwester Nawrocki, Rahul Sharma, Stephen Warren,
	Mark Rutland, Kumar Gala, Pawel Moll, Rob Herring, Sean Paul

On 09/28/2013 06:10 PM, Inki Dae wrote:
>> Any opinion from Device-Tree folks?
>>
>> IMO, we should have same consensus on Shirish patches before proceeding.
>
> Rahul, it seems that DT people have no interest in this issue. So let's
> have a consensus about this issue internally.
>
> To Mr. Kyungmin, Sylwester, Kukjin Kim, and Tomasz,
> How about keeping hdmiphy config data in each board dts file?

Please don't use HTML and quote only relevant part of e-mails. Otherwise
there are good chances your messages end up in people's spam box.

It often helps to Cc a DT binding maintainer directly.

Then, you consider moving the HDMI phy configuration to the device tree.
As Sean suggested in this thread:

">> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
>> +       {
>> +               .pixel_clock = 27000000,
>> +               .conf = {
>> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
>> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
>> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
>> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
>> +               },
>> +       },
[trimmed couple more entries]
>> +};
>>
> Are you aware of the effort to move these to dt? Since these are
> board-specific values, it seems incorrect to apply them universally.
> Shirish has uploaded a patch to the chromium review site to push these
> into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
> you can work that into your patch set?"

The configuration data is 64 bytes of the register values IIUC. Would it be
possible to figure out exact meaning of each byte ? Do all of these bytes
need to be changed per board ? Perhaps we can have per SoC static tables in
the PHY driver and be overwriting only some of the bytes with values read
from device tree ?

AFAIR firmware-like binary blobs (register address/value pairs) are not
supposed to be stored in DT.

If there is no detailed documentation for theese PHY configuration tables
I guess there is no choice but to put these raw 64 bytes in DT. Presumably
this should be a an required property defined only by board dts, since those
values are PCB design dependent.

However, if not all boards need tweaking this configuration data, then it
could make sense to define recommended per-SoC tables in the driver and
overwrite from DT only if it is specified there for a specific board.
If we can come up with universal configuration for a SoC and selected pixel
clock frequency then it could likely be better to store that in the driver
rather than in DT.

--
Thanks,
Sylwester
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-29 22:08                                       ` Sylwester Nawrocki
@ 2013-09-29 23:13                                         ` Tomasz Figa
  2013-10-01  4:40                                           ` Inki Dae
  0 siblings, 1 reply; 45+ messages in thread
From: Tomasz Figa @ 2013-09-29 23:13 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: Inki Dae, Rahul Sharma, devicetree, linux-samsung-soc,
	sw0312.kim, sunil joshi, dri-devel, kgene.kim, Shirish S,
	Sylwester Nawrocki, Rahul Sharma, Stephen Warren, Mark Rutland,
	Kumar Gala, Pawel Moll, Rob Herring, Sean Paul

On Monday 30 of September 2013 00:08:46 Sylwester Nawrocki wrote:
> On 09/28/2013 06:10 PM, Inki Dae wrote:
> >> Any opinion from Device-Tree folks?
> >> 
> >> IMO, we should have same consensus on Shirish patches before
> >> proceeding.> 
> > Rahul, it seems that DT people have no interest in this issue. So
> > let's
> > have a consensus about this issue internally.
> > 
> > To Mr. Kyungmin, Sylwester, Kukjin Kim, and Tomasz,
> > How about keeping hdmiphy config data in each board dts file?
> 
> Please don't use HTML and quote only relevant part of e-mails. Otherwise
> there are good chances your messages end up in people's spam box.
> 
> It often helps to Cc a DT binding maintainer directly.
> 
> Then, you consider moving the HDMI phy configuration to the device tree.
> As Sean suggested in this thread:
> 
> ">> +static struct hdmiphy_config hdmiphy_4210_configs[] = {

I'd like to only add that patches introducing or modifying a device tree 
binding need to be acked by at least one DT binding maintainer to be 
merged.

> >> +       {
> >> +               .pixel_clock = 27000000,
> >> +               .conf = {
> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30,
> >> 0x40,
> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
> >> 0x87,
> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
> >> 0xE0,
> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
> >> 0x00,
> >> +               },
> >> +       },
> 
> [trimmed couple more entries]
> 
> >> +};
> > 
> > Are you aware of the effort to move these to dt? Since these are
> > board-specific values, it seems incorrect to apply them universally.
> > Shirish has uploaded a patch to the chromium review site to push these
> > into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
> > you can work that into your patch set?"
> 
> The configuration data is 64 bytes of the register values IIUC. Would it
> be possible to figure out exact meaning of each byte ?

This is definitely something that I would go for. Then for board specific 
data appropriate device tree properties could be defined, not just a 
binary blob.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-08-30  6:59 ` [PATCH 1/7] " Rahul Sharma
  2013-09-03 14:45   ` Sean Paul
@ 2013-09-30 10:50   ` Tushar Behera
  1 sibling, 0 replies; 45+ messages in thread
From: Tushar Behera @ 2013-09-30 10:50 UTC (permalink / raw)
  To: Rahul Sharma
  Cc: linux-samsung-soc, dri-devel, Kukjin Kim, sw0312.kim, inki.dae,
	seanpaul, l.stach, Tomasz Figa, s.nawrocki, sunil joshi,
	r.sh.open

On 30 August 2013 12:29, Rahul Sharma <rahul.sharma@samsung.com> wrote:
> Exynos hdmiphy operations and configs are kept inside
> the hdmi driver. Hdmiphy related code is tightly coupled
> with hdmi IP driver.
>
> This patche moves hdmiphy related code to hdmiphy driver.
> It will help in cleanly supporting the hdmiphy variations
> in further SoCs.
>
> Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
> ---

> +static const struct i2c_device_id hdmiphy_id[] = {
> +       { },
> +};
> +

[ snip ]

> +       .id_table               = hdmiphy_id,

This is fixing a regression on v3.12 kernel (same as patch 5/7 in this
series). Would you please split this and send it as a separate patch
for v3.12?

-- 
Tushar Behera

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
       [not found]                                         ` <5248A4EE.9000708-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2013-10-01  4:39                                           ` Inki Dae
  2013-10-03  2:28                                             ` Shirish S
  0 siblings, 1 reply; 45+ messages in thread
From: Inki Dae @ 2013-10-01  4:39 UTC (permalink / raw)
  To: 'Sylwester Nawrocki'
  Cc: 'Rahul Sharma',
	devicetree-u79uwXL29TY76Z2rM5mHXA, 'linux-samsung-soc',
	'sw0312.kim', 'sunil joshi', 'dri-devel',
	'kgene.kim', 'Shirish S',
	'Sylwester Nawrocki', 'Rahul Sharma',
	'Stephen Warren', 'Mark Rutland',
	'Kumar Gala', 'Pawel Moll', 'Rob Herring',
	'Sean Paul'



> -----Original Message-----
> From: Sylwester Nawrocki [mailto:sylvester.nawrocki-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org]
> Sent: Monday, September 30, 2013 7:09 AM
> To: Inki Dae
> Cc: Rahul Sharma; devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-samsung-soc;
> sw0312.kim; sunil joshi; dri-devel; kgene.kim; Shirish S; Sylwester
> Nawrocki; Rahul Sharma; Stephen Warren; Mark Rutland; Kumar Gala; Pawel
> Moll; Rob Herring; Sean Paul
> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
> driver
> 
> On 09/28/2013 06:10 PM, Inki Dae wrote:
> >> Any opinion from Device-Tree folks?
> >>
> >> IMO, we should have same consensus on Shirish patches before
proceeding.
> >
> > Rahul, it seems that DT people have no interest in this issue. So let's
> > have a consensus about this issue internally.
> >
> > To Mr. Kyungmin, Sylwester, Kukjin Kim, and Tomasz,
> > How about keeping hdmiphy config data in each board dts file?
> 
> Please don't use HTML and quote only relevant part of e-mails. Otherwise
> there are good chances your messages end up in people's spam box.
> 

Ah, I missed checking text mode. Sorry about this. :)



> It often helps to Cc a DT binding maintainer directly.
> 

Good idea.

> Then, you consider moving the HDMI phy configuration to the device tree.
> As Sean suggested in this thread:
> 

Right.

> ">> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
> >> +       {
> >> +               .pixel_clock = 27000000,
> >> +               .conf = {
> >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
> >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
> >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
> >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
> >> +               },
> >> +       },
> [trimmed couple more entries]
> >> +};
> >>
> > Are you aware of the effort to move these to dt? Since these are
> > board-specific values, it seems incorrect to apply them universally.
> > Shirish has uploaded a patch to the chromium review site to push these
> > into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
> > you can work that into your patch set?"
> 
> The configuration data is 64 bytes of the register values IIUC. Would it
> be
> possible to figure out exact meaning of each byte ? Do all of these bytes

Right, but the user manual doesn't describe that enough so we might need to
inquire for what it means to design team. 

> need to be changed per board ? Perhaps we can have per SoC static tables
> in
> the PHY driver and be overwriting only some of the bytes with values read
> from device tree ?
> 
> AFAIR firmware-like binary blobs (register address/value pairs) are not
> supposed to be stored in DT.
> 
> If there is no detailed documentation for theese PHY configuration tables
> I guess there is no choice but to put these raw 64 bytes in DT. Presumably
> this should be a an required property defined only by board dts, since
> those
> values are PCB design dependent.
> 
> However, if not all boards need tweaking this configuration data, then it
> could make sense to define recommended per-SoC tables in the driver and
> overwrite from DT only if it is specified there for a specific board.
> If we can come up with universal configuration for a SoC and selected
> pixel
> clock frequency then it could likely be better to store that in the driver
> rather than in DT.
> 

Thanks you your opinion. However, we need to make sure how we take care of
the PHY configuration values. So I will have two steps to merge this pages
set.

To Rahul,
Could you post only your patch set regardless of Shirish's patch? I will
merge your patch set first because as is, Exynos drm hdmi driver is broken.
And, we need more discussions about Shirish patch. So I will not merge this
patch until we have a consensus about it.

To Shirish,
For your patch, it seems that you need to make sure to figure out exact
meaning of each byte of the PHY configuration values first. Maybe you need
to inquire for that to hardware or design team. And please separate the
values into common and specific parts if needed.


Thanks,
Inki Dae

> --
> Thanks,
> Sylwester

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-09-29 23:13                                         ` Tomasz Figa
@ 2013-10-01  4:40                                           ` Inki Dae
  0 siblings, 0 replies; 45+ messages in thread
From: Inki Dae @ 2013-10-01  4:40 UTC (permalink / raw)
  To: 'Tomasz Figa', 'Sylwester Nawrocki'
  Cc: 'Rahul Sharma',
	devicetree-u79uwXL29TY76Z2rM5mHXA, 'linux-samsung-soc',
	'sw0312.kim', 'sunil joshi', 'dri-devel',
	'kgene.kim', 'Shirish S',
	'Sylwester Nawrocki', 'Rahul Sharma',
	'Stephen Warren', 'Mark Rutland',
	'Kumar Gala', 'Pawel Moll', 'Rob Herring',
	'Sean Paul'



> -----Original Message-----
> From: linux-samsung-soc-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org [mailto:linux-samsung-soc-
> owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org] On Behalf Of Tomasz Figa
> Sent: Monday, September 30, 2013 8:13 AM
> To: Sylwester Nawrocki
> Cc: Inki Dae; Rahul Sharma; devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-samsung-soc;
> sw0312.kim; sunil joshi; dri-devel; kgene.kim; Shirish S; Sylwester
> Nawrocki; Rahul Sharma; Stephen Warren; Mark Rutland; Kumar Gala; Pawel
> Moll; Rob Herring; Sean Paul
> Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
> driver
> 
> On Monday 30 of September 2013 00:08:46 Sylwester Nawrocki wrote:
> > On 09/28/2013 06:10 PM, Inki Dae wrote:
> > >> Any opinion from Device-Tree folks?
> > >>
> > >> IMO, we should have same consensus on Shirish patches before
> > >> proceeding.>
> > > Rahul, it seems that DT people have no interest in this issue. So
> > > let's
> > > have a consensus about this issue internally.
> > >
> > > To Mr. Kyungmin, Sylwester, Kukjin Kim, and Tomasz,
> > > How about keeping hdmiphy config data in each board dts file?
> >
> > Please don't use HTML and quote only relevant part of e-mails. Otherwise
> > there are good chances your messages end up in people's spam box.
> >
> > It often helps to Cc a DT binding maintainer directly.
> >
> > Then, you consider moving the HDMI phy configuration to the device tree.
> > As Sean suggested in this thread:
> >
> > ">> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
> 
> I'd like to only add that patches introducing or modifying a device tree
> binding need to be acked by at least one DT binding maintainer to be
> merged.
> 
> > >> +       {
> > >> +               .pixel_clock = 27000000,
> > >> +               .conf = {
> > >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30,
> > >> 0x40,
> > >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
> > >> 0x87,
> > >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
> > >> 0xE0,
> > >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
> > >> 0x00,
> > >> +               },
> > >> +       },
> >
> > [trimmed couple more entries]
> >
> > >> +};
> > >
> > > Are you aware of the effort to move these to dt? Since these are
> > > board-specific values, it seems incorrect to apply them universally.
> > > Shirish has uploaded a patch to the chromium review site to push these
> > > into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
> > > you can work that into your patch set?"
> >
> > The configuration data is 64 bytes of the register values IIUC. Would it
> > be possible to figure out exact meaning of each byte ?
> 
> This is definitely something that I would go for. Then for board specific
> data appropriate device tree properties could be defined, not just a
> binary blob.
> 

Agree. Thanks for your opinion.

Thanks,
Inki Dae

> Best regards,
> Tomasz
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-
> soc" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-10-01  4:39                                           ` Inki Dae
@ 2013-10-03  2:28                                             ` Shirish S
  2013-10-28  6:06                                               ` Shirish S
  0 siblings, 1 reply; 45+ messages in thread
From: Shirish S @ 2013-10-03  2:28 UTC (permalink / raw)
  To: Inki Dae
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Stephen Warren, sw0312.kim, sunil joshi, dri-devel, kgene.kim,
	Rob Herring, Sylwester Nawrocki, Kumar Gala, Sylwester Nawrocki,
	Rahul Sharma


[-- Attachment #1.1: Type: text/plain, Size: 4697 bytes --]

Hi,
First of all sorry for the late response,


On Tue, Oct 1, 2013 at 10:09 AM, Inki Dae <inki.dae@samsung.com> wrote:

>
>
> > -----Original Message-----
> > From: Sylwester Nawrocki [mailto:sylvester.nawrocki@gmail.com]
> > Sent: Monday, September 30, 2013 7:09 AM
> > To: Inki Dae
> > Cc: Rahul Sharma; devicetree@vger.kernel.org; linux-samsung-soc;
> > sw0312.kim; sunil joshi; dri-devel; kgene.kim; Shirish S; Sylwester
> > Nawrocki; Rahul Sharma; Stephen Warren; Mark Rutland; Kumar Gala; Pawel
> > Moll; Rob Herring; Sean Paul
> > Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy
> > driver
> >
> > On 09/28/2013 06:10 PM, Inki Dae wrote:
> > >> Any opinion from Device-Tree folks?
> > >>
> > >> IMO, we should have same consensus on Shirish patches before
> proceeding.
> > >
> > > Rahul, it seems that DT people have no interest in this issue. So let's
> > > have a consensus about this issue internally.
> > >
> > > To Mr. Kyungmin, Sylwester, Kukjin Kim, and Tomasz,
> > > How about keeping hdmiphy config data in each board dts file?
> >
> > Please don't use HTML and quote only relevant part of e-mails. Otherwise
> > there are good chances your messages end up in people's spam box.
> >
>
> Ah, I missed checking text mode. Sorry about this. :)
>
>
>
> > It often helps to Cc a DT binding maintainer directly.
> >
>
> Good idea.
>
> > Then, you consider moving the HDMI phy configuration to the device tree.
> > As Sean suggested in this thread:
> >
>
> Right.
>
> > ">> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
> > >> +       {
> > >> +               .pixel_clock = 27000000,
> > >> +               .conf = {
> > >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30,
> 0x40,
> > >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
> 0x87,
> > >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
> 0xE0,
> > >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
> 0x00,
> > >> +               },
> > >> +       },
> > [trimmed couple more entries]
> > >> +};
> > >>
> > > Are you aware of the effort to move these to dt? Since these are
> > > board-specific values, it seems incorrect to apply them universally.
> > > Shirish has uploaded a patch to the chromium review site to push these
> > > into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
> > > you can work that into your patch set?"
> >
> > The configuration data is 64 bytes of the register values IIUC. Would it
> > be
> > possible to figure out exact meaning of each byte ? Do all of these bytes
>
> Right, but the user manual doesn't describe that enough so we might need to
> inquire for what it means to design team.
>
> > need to be changed per board ? Perhaps we can have per SoC static tables
> > in
> > the PHY driver and be overwriting only some of the bytes with values read
> > from device tree ?
> >
> > AFAIR firmware-like binary blobs (register address/value pairs) are not
> > supposed to be stored in DT.
> >
> > If there is no detailed documentation for theese PHY configuration tables
> > I guess there is no choice but to put these raw 64 bytes in DT.
> Presumably
> > this should be a an required property defined only by board dts, since
> > those
> > values are PCB design dependent.
> >
> > However, if not all boards need tweaking this configuration data, then it
> > could make sense to define recommended per-SoC tables in the driver and
> > overwrite from DT only if it is specified there for a specific board.
> > If we can come up with universal configuration for a SoC and selected
> > pixel
> > clock frequency then it could likely be better to store that in the
> driver
> > rather than in DT.
> >
>
> Thanks you your opinion. However, we need to make sure how we take care of
> the PHY configuration values. So I will have two steps to merge this pages
> set.
>
> To Rahul,
> Could you post only your patch set regardless of Shirish's patch? I will
> merge your patch set first because as is, Exynos drm hdmi driver is broken.
> And, we need more discussions about Shirish patch. So I will not merge this
> patch until we have a consensus about it.
>
> To Shirish,
> For your patch, it seems that you need to make sure to figure out exact
> meaning of each byte of the PHY configuration values first. Maybe you need
> to inquire for that to hardware or design team. And please separate the
> values into common and specific parts if needed.
>
> Agreed, I shall request our hardware team to provide description about the
phy values, and will update the patch, once i receive the same.


>
> Thanks,
> Inki Dae
>
> > --
> > Thanks,
> > Sylwester
>
> Thanks,
Shirish S

[-- Attachment #1.2: Type: text/html, Size: 6313 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to hdmiphy driver
  2013-10-03  2:28                                             ` Shirish S
@ 2013-10-28  6:06                                               ` Shirish S
  0 siblings, 0 replies; 45+ messages in thread
From: Shirish S @ 2013-10-28  6:06 UTC (permalink / raw)
  To: Inki Dae
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Stephen Warren, sw0312.kim, sunil joshi, dri-devel, kgene.kim,
	Rob Herring, Sylwester Nawrocki, Kumar Gala, Sylwester Nawrocki,
	Rahul Sharma


[-- Attachment #1.1: Type: text/plain, Size: 5045 bytes --]

Hi,
I have uploaded patch set 2, with only required registers being moved to dt
file.
Thanks,
Shirish S


On Thu, Oct 3, 2013 at 7:58 AM, Shirish S <shirish@chromium.org> wrote:

> Hi,
> First of all sorry for the late response,
>
>
> On Tue, Oct 1, 2013 at 10:09 AM, Inki Dae <inki.dae@samsung.com> wrote:
>
>>
>>
>> > -----Original Message-----
>> > From: Sylwester Nawrocki [mailto:sylvester.nawrocki@gmail.com]
>> > Sent: Monday, September 30, 2013 7:09 AM
>> > To: Inki Dae
>> > Cc: Rahul Sharma; devicetree@vger.kernel.org; linux-samsung-soc;
>> > sw0312.kim; sunil joshi; dri-devel; kgene.kim; Shirish S; Sylwester
>> > Nawrocki; Rahul Sharma; Stephen Warren; Mark Rutland; Kumar Gala; Pawel
>> > Moll; Rob Herring; Sean Paul
>> > Subject: Re: [PATCH 1/7] drm/exynos: move hdmiphy related code to
>> hdmiphy
>> > driver
>> >
>> > On 09/28/2013 06:10 PM, Inki Dae wrote:
>> > >> Any opinion from Device-Tree folks?
>> > >>
>> > >> IMO, we should have same consensus on Shirish patches before
>> proceeding.
>> > >
>> > > Rahul, it seems that DT people have no interest in this issue. So
>> let's
>> > > have a consensus about this issue internally.
>> > >
>> > > To Mr. Kyungmin, Sylwester, Kukjin Kim, and Tomasz,
>> > > How about keeping hdmiphy config data in each board dts file?
>> >
>> > Please don't use HTML and quote only relevant part of e-mails. Otherwise
>> > there are good chances your messages end up in people's spam box.
>> >
>>
>> Ah, I missed checking text mode. Sorry about this. :)
>>
>>
>>
>> > It often helps to Cc a DT binding maintainer directly.
>> >
>>
>> Good idea.
>>
>> > Then, you consider moving the HDMI phy configuration to the device tree.
>> > As Sean suggested in this thread:
>> >
>>
>> Right.
>>
>> > ">> +static struct hdmiphy_config hdmiphy_4210_configs[] = {
>> > >> +       {
>> > >> +               .pixel_clock = 27000000,
>> > >> +               .conf = {
>> > >> +                       0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30,
>> 0x40,
>> > >> +                       0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54,
>> 0x87,
>> > >> +                       0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10,
>> 0xE0,
>> > >> +                       0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00,
>> 0x00,
>> > >> +               },
>> > >> +       },
>> > [trimmed couple more entries]
>> > >> +};
>> > >>
>> > > Are you aware of the effort to move these to dt? Since these are
>> > > board-specific values, it seems incorrect to apply them universally.
>> > > Shirish has uploaded a patch to the chromium review site to push these
>> > > into dt (https://chromium-review.googlesource.com/#/c/65581). Maybe
>> > > you can work that into your patch set?"
>> >
>> > The configuration data is 64 bytes of the register values IIUC. Would it
>> > be
>> > possible to figure out exact meaning of each byte ? Do all of these
>> bytes
>>
>> Right, but the user manual doesn't describe that enough so we might need
>> to
>> inquire for what it means to design team.
>>
>> > need to be changed per board ? Perhaps we can have per SoC static tables
>> > in
>> > the PHY driver and be overwriting only some of the bytes with values
>> read
>> > from device tree ?
>> >
>> > AFAIR firmware-like binary blobs (register address/value pairs) are not
>> > supposed to be stored in DT.
>> >
>> > If there is no detailed documentation for theese PHY configuration
>> tables
>> > I guess there is no choice but to put these raw 64 bytes in DT.
>> Presumably
>> > this should be a an required property defined only by board dts, since
>> > those
>> > values are PCB design dependent.
>> >
>> > However, if not all boards need tweaking this configuration data, then
>> it
>> > could make sense to define recommended per-SoC tables in the driver and
>> > overwrite from DT only if it is specified there for a specific board.
>> > If we can come up with universal configuration for a SoC and selected
>> > pixel
>> > clock frequency then it could likely be better to store that in the
>> driver
>> > rather than in DT.
>> >
>>
>> Thanks you your opinion. However, we need to make sure how we take care of
>> the PHY configuration values. So I will have two steps to merge this pages
>> set.
>>
>> To Rahul,
>> Could you post only your patch set regardless of Shirish's patch? I will
>> merge your patch set first because as is, Exynos drm hdmi driver is
>> broken.
>> And, we need more discussions about Shirish patch. So I will not merge
>> this
>> patch until we have a consensus about it.
>>
>> To Shirish,
>> For your patch, it seems that you need to make sure to figure out exact
>> meaning of each byte of the PHY configuration values first. Maybe you need
>> to inquire for that to hardware or design team. And please separate the
>> values into common and specific parts if needed.
>>
>> Agreed, I shall request our hardware team to provide description about
> the phy values, and will update the patch, once i receive the same.
>
>
>>
>> Thanks,
>> Inki Dae
>>
>> > --
>> > Thanks,
>> > Sylwester
>>
>> Thanks,
> Shirish S
>

[-- Attachment #1.2: Type: text/html, Size: 6813 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2013-10-28  6:06 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-30  6:59 [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Rahul Sharma
2013-08-30  6:59 ` [PATCH 1/7] " Rahul Sharma
2013-09-03 14:45   ` Sean Paul
2013-09-04  5:47     ` Rahul Sharma
2013-09-04  7:37       ` Inki Dae
2013-09-04 14:51         ` Sean Paul
2013-09-05  4:16           ` Inki Dae
2013-09-05  4:43             ` Rahul Sharma
2013-09-05  5:22               ` Inki Dae
2013-09-05  6:03                 ` Rahul Sharma
2013-09-05  6:19                   ` Inki Dae
2013-09-05 13:19                     ` Sean Paul
2013-09-05 13:50                       ` Inki Dae
2013-09-05 16:31                         ` Sylwester Nawrocki
2013-09-06  3:37                         ` Rahul Sharma
2013-09-06 13:51                           ` Sean Paul
2013-09-10  8:27                             ` Rahul Sharma
2013-09-16 12:40                               ` Inki Dae
2013-09-27  4:53                                 ` Rahul Sharma
2013-09-28 16:10                                   ` Inki Dae
     [not found]                                     ` <CAAQKjZPtxLAJOz6573+hEPZokEnvGF8BTMXoxcYUQ8zySAn-OA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-09-29 22:08                                       ` Sylwester Nawrocki
2013-09-29 23:13                                         ` Tomasz Figa
2013-10-01  4:40                                           ` Inki Dae
     [not found]                                     ` <5248A4EE.9000708@samsung.com>
     [not found]                                       ` <gmail.com@samsung.com>
     [not found]                                         ` <5248A4EE.9000708-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-10-01  4:39                                           ` Inki Dae
2013-10-03  2:28                                             ` Shirish S
2013-10-28  6:06                                               ` Shirish S
2013-09-04 14:33       ` Sean Paul
2013-09-30 10:50   ` Tushar Behera
2013-08-30  6:59 ` [PATCH 2/7] drm/exynos: remove dummy hdmiphy clock Rahul Sharma
2013-09-03 15:58   ` Sean Paul
2013-08-30  6:59 ` [PATCH 3/7] drm/exynos: add hdmiphy pmu bit control in hdmiphy driver Rahul Sharma
2013-09-03 16:10   ` Sean Paul
2013-08-30  6:59 ` [PATCH 4/7] drm/exynos: add support for exynos5420 hdmiphy Rahul Sharma
2013-09-03 16:15   ` Sean Paul
2013-08-30  6:59 ` [PATCH 5/7] exynos/drm: fix ddc i2c device probe failure Rahul Sharma
2013-08-30  6:59 ` [PATCH 6/7] ARM: dts: update hdmiphy dt node for exynos5250 Rahul Sharma
2013-08-30  6:59 ` [PATCH 7/7] ARM: dts: update hdmiphy dt node for exynos5420 Rahul Sharma
2013-08-30  8:33 ` [PATCH 0/7] drm/exynos: move hdmiphy related code to hdmiphy driver Inki Dae
2013-08-30  9:06   ` Inki Dae
2013-08-30 10:05   ` Rahul Sharma
2013-09-02  5:08     ` Inki Dae
2013-09-02  6:28       ` Rahul Sharma
2013-09-02  7:22         ` Inki Dae
2013-09-02  9:06           ` Rahul Sharma
2013-09-02 10:06             ` Inki Dae

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.