All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/3] ARM: dts: add fimd device support for exynos3250-rinato
@ 2015-01-19  7:52 Hyungwon Hwang
  2015-01-19  7:52 ` [PATCH v3 2/3] drm/panel: add s6e63j0x03 LCD panel driver Hyungwon Hwang
  2015-01-19  7:52 ` [PATCH v3 3/3] ARM: dts: add Panel device support for exynos3250-rinato Hyungwon Hwang
  0 siblings, 2 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-01-19  7:52 UTC (permalink / raw)
  To: dri-devel; +Cc: treding, Hyungwon Hwang

From: Inki Dae <inki.dae@samsung.com>

This patch adds fimd device node which is a display controller
for Exynos3250 Rinato board.

Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Changes for v2:
- None
Changes for v3:
- None
 arch/arm/boot/dts/exynos3250-rinato.dts | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 6ac1e4e..8b033b5 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -125,6 +125,17 @@
 	};
 };

+&fimd {
+	status = "okay";
+
+	i80-if-timings {
+		cs-setup = <0>;
+		wr-setup = <0>;
+		wr-act = <1>;
+		wr-hold = <0>;
+	};
+};
+
 &i2c_0 {
 	#address-cells = <1>;
 	#size-cells = <0>;
--
1.9.1

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

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

* [PATCH v3 2/3] drm/panel: add s6e63j0x03 LCD panel driver
  2015-01-19  7:52 [PATCH v3 1/3] ARM: dts: add fimd device support for exynos3250-rinato Hyungwon Hwang
@ 2015-01-19  7:52 ` Hyungwon Hwang
  2015-02-03 14:00   ` Thierry Reding
  2015-06-12 13:03   ` [v3,2/3] " Hyungwon Hwang
  2015-01-19  7:52 ` [PATCH v3 3/3] ARM: dts: add Panel device support for exynos3250-rinato Hyungwon Hwang
  1 sibling, 2 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-01-19  7:52 UTC (permalink / raw)
  To: dri-devel; +Cc: treding, Hyungwon Hwang

From: Inki Dae <inki.dae@samsung.com>

This patch adds MIPI-DSI based S6E63J0X03 AMOLED LCD panel driver
which uses mipi_dsi bus to communicate with panel. The panel has
320×320 resolution in 1.63-inch physical panel. This panel is used in
Samsung Galaxy Gear 2.

Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Changes for v2:
- Change the gamma table to 2-dimensional array
- Change the way to make index for brightness
- Make command functions to an array so that it can be called simply
- Change command id for reading device ID
- Change the way to handle the error condition
- Remove power variable, and use the same name variable in bl_dev
- Add the state FB_BLANK_NORMAL to represent the state which the panel
is working but blanked
- Miscellaneous changes to increase the readability and follow the
  coding-style standard
Changes for v3:
- Add DT binding documentation
- Add the code getting DT properties of 'panel-width-mm' and 'panel-height-mm'
- Remove the code getting unnecessary DT properties flip-*
 .../bindings/panel/samsung,s6e63j0x03.txt          |  55 +++
 drivers/gpu/drm/panel/Kconfig                      |   6 +
 drivers/gpu/drm/panel/Makefile                     |   1 +
 drivers/gpu/drm/panel/panel-s6e63j0x03.c           | 546 +++++++++++++++++++++
 4 files changed, 608 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt
 create mode 100644 drivers/gpu/drm/panel/panel-s6e63j0x03.c

diff --git a/Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt b/Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt
new file mode 100644
index 0000000..f8215e4
--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt
@@ -0,0 +1,55 @@
+Samsung S6E63J0X03 1.63" 320x320 TFT LCD panel
+
+Required properties:
+  - compatible: "samsung,s6e63j0x03"
+  - reg: the virtual channel number of a DSI peripheral
+  - vdd3-supply: core voltage supply
+  - vci-supply: voltage supply for analog circuits
+  - reset-gpios: a GPIO spec for the reset pin
+  - te-gpios: a GPIO spec for the tearing effect synchronization signal gpio pin
+
+Optional properties:
+  - display-timings: timings for the connected panel as described by [1]
+  - power-on-delay: delay after turning regulators on [ms]
+  - power-off-delay: delay after turning regulators off [ms]
+  - reset-delay: delay after reset sequence [ms]
+  - panel-width-mm: physical panel width [mm]
+  - panel-height-mm: physical panel height [mm]
+
+The device node can contain one 'port' child node with one child
+'endpoint' node, according to the bindings defined in [2]. This
+node should describe panel's video bus.
+
+[1]: Documentation/devicetree/bindings/video/display-timing.txt
+[2]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example:
+
+panel@0 {
+	compatible = "samsung,s6e63j0x03";
+	reg = <0>;
+	vdd3-supply = <&ldo16_reg>;
+	vci-supply = <&ldo20_reg>;
+	reset-gpios = <&gpe0 1 0>;
+	te-gpios = <&gpx0 6 0>;
+	power-on-delay= <30>;
+	power-off-delay= <120>;
+	reset-delay = <5>;
+	init-delay = <100>;
+	panel-width-mm = <29>;
+	panel-height-mm = <29>;
+
+	display-timings {
+		timing-0 {
+			clock-frequency = <0>;
+			hactive = <320>;
+			vactive = <320>;
+			hfront-porch = <1>;
+			hback-porch = <1>;
+			hsync-len = <1>;
+			vfront-porch = <150>;
+			vback-porch = <1>;
+			vsync-len = <2>;
+		};
+	};
+};
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 3df9b9b..8fa7610 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -46,4 +46,10 @@ config DRM_PANEL_S6E3HA2
 	select DRM_MIPI_DSI
 	select VIDEOMODE_HELPERS

+config DRM_PANEL_S6E63J0X03
+	tristate "S6E63J0X03 DSI video mode panel"
+	depends on OF
+	select DRM_MIPI_DSI
+	select VIDEOMODE_HELPERS
+
 endmenu
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 16ff312..9054da1 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o
 obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
 obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
 obj-$(CONFIG_DRM_PANEL_S6E3HA2) += panel-s6e3ha2.o
+obj-$(CONFIG_DRM_PANEL_S6E63J0X03) += panel-s6e63j0x03.o
diff --git a/drivers/gpu/drm/panel/panel-s6e63j0x03.c b/drivers/gpu/drm/panel/panel-s6e63j0x03.c
new file mode 100644
index 0000000..51cf1f6
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-s6e63j0x03.c
@@ -0,0 +1,546 @@
+/*
+ * MIPI-DSI based S6E63J0X03 AMOLED lcd 1.63 inch panel driver.
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd
+ *
+ * Inki Dae, <inki.dae@samsung.com>
+ *
+ * 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.
+*/
+
+#include <drm/drmP.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/backlight.h>
+
+#include <video/mipi_display.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+#define READ_ID1		0xDA
+#define READ_ID2		0xDB
+#define READ_ID3		0xDC
+
+#define MCS_LEVEL2_KEY		0xf0
+#define MCS_MTP_KEY		0xf1
+#define MCS_MTP_SET3		0xd4
+
+#define MIN_BRIGHTNESS		0
+#define MAX_BRIGHTNESS		100
+#define DEFAULT_BRIGHTNESS	80
+
+#define GAMMA_LEVEL_NUM		30
+#define NUM_GAMMA_STEPS		9
+#define GAMMA_CMD_CNT		28
+
+struct s6e63j0x03 {
+	struct device *dev;
+	struct drm_panel panel;
+	struct backlight_device *bl_dev;
+
+	struct regulator_bulk_data supplies[2];
+	struct gpio_desc *reset_gpio;
+	u32 power_on_delay;
+	u32 power_off_delay;
+	u32 reset_delay;
+	u32 init_delay;
+	struct videomode vm;
+	unsigned int width_mm;
+	unsigned int height_mm;
+};
+
+static const unsigned char gamma_tbl[NUM_GAMMA_STEPS][GAMMA_CMD_CNT] = {
+	{	/* Gamma 10 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x52, 0x6b, 0x6f, 0x26,
+		0x28, 0x2d, 0x28, 0x26, 0x27, 0x33, 0x34, 0x32, 0x36, 0x36,
+		0x35, 0x00, 0xab, 0x00, 0xae, 0x00, 0xbf
+	},
+	{	/* gamma 30 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x70, 0x7f, 0x7f, 0x4e, 0x64, 0x69, 0x26,
+		0x27, 0x2a, 0x28, 0x29, 0x27, 0x31, 0x32, 0x31, 0x35, 0x34,
+		0x35, 0x00, 0xc4, 0x00, 0xca, 0x00, 0xdc
+	},
+	{	/* gamma 60 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x65, 0x7b, 0x7d, 0x5f, 0x67, 0x68, 0x2a,
+		0x28, 0x29, 0x28, 0x2a, 0x27, 0x31, 0x2f, 0x30, 0x34, 0x33,
+		0x34, 0x00, 0xd9, 0x00, 0xe4, 0x00, 0xf5
+	},
+	{	/* gamma 90 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x4d, 0x6f, 0x71, 0x67, 0x6a, 0x6c, 0x29,
+		0x28, 0x28, 0x28, 0x29, 0x27, 0x30, 0x2e, 0x30, 0x32, 0x31,
+		0x31, 0x00, 0xea, 0x00, 0xf6, 0x01, 0x09
+	},
+	{	/* gamma 120 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x3d, 0x66, 0x68, 0x69, 0x69, 0x69, 0x28,
+		0x28, 0x27, 0x28, 0x28, 0x27, 0x30, 0x2e, 0x2f, 0x31, 0x31,
+		0x30, 0x00, 0xf9, 0x01, 0x05, 0x01, 0x1b
+	},
+	{	/* gamma 150 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x31, 0x51, 0x53, 0x66, 0x66, 0x67, 0x28,
+		0x29, 0x27, 0x28, 0x27, 0x27, 0x2e, 0x2d, 0x2e, 0x31, 0x31,
+		0x30, 0x01, 0x04, 0x01, 0x11, 0x01, 0x29
+	},
+	{	/* gamma 200 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x2f, 0x4f, 0x51, 0x67, 0x65, 0x65, 0x29,
+		0x2a, 0x28, 0x27, 0x25, 0x26, 0x2d, 0x2c, 0x2c, 0x30, 0x30,
+		0x30, 0x01, 0x14, 0x01, 0x23, 0x01, 0x3b
+	},
+	{	/* gamma 240 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x2c, 0x4d, 0x50, 0x65, 0x63, 0x64, 0x2a,
+		0x2c, 0x29, 0x26, 0x24, 0x25, 0x2c, 0x2b, 0x2b, 0x30, 0x30,
+		0x30, 0x01, 0x1e, 0x01, 0x2f, 0x01, 0x47
+	},
+	{	/* gamma 300 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x38, 0x61, 0x64, 0x65, 0x63, 0x64, 0x28,
+		0x2a, 0x27, 0x26, 0x23, 0x25, 0x2b, 0x2b, 0x2a, 0x30, 0x2f,
+		0x30, 0x01, 0x2d, 0x01, 0x3f, 0x01, 0x57
+	}
+};
+
+static const unsigned char prepare_cmds1[][15] = {
+	{ 3, 0xf2, 0x1c, 0x28 },		/* porch_adjustment */
+	{ 4, 0xb5, 0x00, 0x02, 0x00 },		/* frame_freq */
+	{ 5, 0x2a, 0x00, 0x14, 0x01, 0x53 },	/* mem_addr_set_0 */
+	{ 5, 0x2b, 0x00, 0x00, 0x01, 0x3f },	/* mem_addr_set_1 */
+	{ 14, 0xf8, 0x08, 0x08, 0x08, 0x17,	/* ltps_timming_set_0_60hz */
+	      0x00, 0x2a, 0x02, 0x26,
+	      0x00, 0x00, 0x02, 0x00, 0x00 },
+	{ 2, 0xf7, 0x02 },			/* ltps_timming_set_1 */
+	{ 2, 0xb0, 0x01 },			/* param_pos_te_edge */
+	{ 2, 0xe2, 0x0f },			/* te_rising_edge */
+	{ 2, 0xb0, 0x00 },			/* param_pos_default */
+	{ 1, MIPI_DCS_EXIT_SLEEP_MODE },
+};
+
+static const  unsigned char prepare_cmds2[][4] = {
+	{ 3, 0xb1, 0x00, 0x09 },	/* elvss_cond */
+	{ 2, 0x36, 0x40 },		/* set_pos */
+	{ 2, 0x51, 0xff },		/* white_brightness_default */
+	{ 2, 0x53, 0x20 },		/* white_ctrl */
+	{ 2, 0x55, 0x00 },		/* acl_off */
+	{ 1, MIPI_DCS_SET_TEAR_ON },
+};
+
+
+static inline struct s6e63j0x03 *panel_to_s6e63j0x03(struct drm_panel *panel)
+{
+	return container_of(panel, struct s6e63j0x03, panel);
+}
+
+static inline ssize_t s6e63j0x03_dcs_write_seq(struct s6e63j0x03 *ctx,
+					const u8 *seq, const unsigned char len)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+	return mipi_dsi_dcs_write(dsi, seq, len);
+}
+
+static inline int s6e63j0x03_enable_lv2_command(struct s6e63j0x03 *ctx)
+{
+	unsigned char seq[] = { MCS_LEVEL2_KEY, 0x5a, 0x5a };
+
+	return s6e63j0x03_dcs_write_seq(ctx, seq, ARRAY_SIZE(seq));
+}
+
+static inline int s6e63j0x03_apply_mtp_key(struct s6e63j0x03 *ctx, bool on)
+{
+	unsigned char seq1[3] = { MCS_MTP_KEY, 0x5a, 0x5a };
+	unsigned char seq2[3] = { MCS_MTP_KEY, 0xa5, 0xa5 };
+
+	return s6e63j0x03_dcs_write_seq(ctx, on ? seq1 : seq2,
+					ARRAY_SIZE(seq1));
+}
+
+static int s6e63j0x03_read_mtp_id(struct s6e63j0x03 *ctx)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	unsigned char cmds[3] = { READ_ID1, READ_ID2, READ_ID3 };
+	unsigned char id[3];
+	int ret;
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		ret = mipi_dsi_dcs_read(dsi, cmds[i], &id[i], 1);
+
+		if (ret < 0)
+			return ret;
+	}
+
+	dev_info(ctx->dev, "ID: 0x%02x, 0x%02x, 0x%02x\n", id[0], id[1], id[2]);
+
+	return 0;
+}
+
+static int s6e63j0x03_power_on(struct s6e63j0x03 *ctx)
+{
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret < 0)
+		return ret;
+
+	msleep(ctx->power_on_delay);
+
+	gpiod_set_value(ctx->reset_gpio, 0);
+	usleep_range(1000, 2000);
+	gpiod_set_value(ctx->reset_gpio, 1);
+
+	usleep_range(ctx->reset_delay * 1000, (ctx->reset_delay + 1) * 1000);
+
+	return 0;
+}
+
+static int s6e63j0x03_power_off(struct s6e63j0x03 *ctx)
+{
+	int ret;
+
+	gpiod_set_value(ctx->reset_gpio, 0);
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int s6e63j0x03_get_brightness(struct backlight_device *bl_dev)
+{
+	return bl_dev->props.brightness;
+}
+
+static unsigned int s6e63j0x03_get_brightness_index(unsigned int brightness)
+{
+	unsigned int index;
+
+	index = brightness / (MAX_BRIGHTNESS / NUM_GAMMA_STEPS);
+
+	if (index >= NUM_GAMMA_STEPS)
+		index = NUM_GAMMA_STEPS - 1;
+
+	return index;
+}
+
+static int s6e63j0x03_update_gamma(struct s6e63j0x03 *ctx,
+					unsigned int brightness)
+{
+	struct backlight_device *bl_dev = ctx->bl_dev;
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	unsigned int index = s6e63j0x03_get_brightness_index(brightness);
+	int ret;
+
+	ret = s6e63j0x03_apply_mtp_key(ctx, true);
+	if (ret < 0)
+		return ret;
+
+	ret = mipi_dsi_dcs_write(dsi, gamma_tbl[index], GAMMA_CMD_CNT);
+	if (ret < 0)
+		return ret;
+
+	ret = s6e63j0x03_apply_mtp_key(ctx, false);
+	if (ret < 0)
+		return ret;
+
+	bl_dev->props.brightness = brightness;
+
+	return 0;
+}
+
+static int s6e63j0x03_set_brightness(struct backlight_device *bl_dev)
+{
+	struct s6e63j0x03 *ctx = (struct s6e63j0x03 *)bl_get_data(bl_dev);
+	unsigned int brightness = bl_dev->props.brightness;
+	int ret;
+
+	if (brightness < MIN_BRIGHTNESS ||
+		brightness > bl_dev->props.max_brightness) {
+		dev_err(ctx->dev, "Invalid brightness: %u\n", brightness);
+		return -EINVAL;
+	}
+
+	if (bl_dev->props.power > FB_BLANK_NORMAL) {
+		dev_err(ctx->dev,
+			"panel must be at least in fb blank normal state\n");
+		return -EPERM;
+	}
+
+	ret = s6e63j0x03_update_gamma(ctx, brightness);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static const struct backlight_ops s6e63j0x03_bl_ops = {
+	.get_brightness = s6e63j0x03_get_brightness,
+	.update_status = s6e63j0x03_set_brightness,
+};
+
+static int s6e63j0x03_disable(struct drm_panel *panel)
+{
+	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
+	struct backlight_device *bl_dev = ctx->bl_dev;
+	u8 seq[] = { MIPI_DCS_SET_DISPLAY_OFF };
+	int ret;
+
+	ret = s6e63j0x03_dcs_write_seq(ctx, seq, ARRAY_SIZE(seq));
+	if (ret > 0)
+		bl_dev->props.power = FB_BLANK_NORMAL;
+
+	return 0;
+}
+
+static int s6e63j0x03_unprepare(struct drm_panel *panel)
+{
+	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
+	struct backlight_device *bl_dev = ctx->bl_dev;
+	u8 seq[] = { MIPI_DCS_ENTER_SLEEP_MODE };
+	int ret;
+
+	ret = s6e63j0x03_dcs_write_seq(ctx, seq, ARRAY_SIZE(seq));
+	if (ret < 0)
+		return ret;
+
+	msleep(ctx->power_off_delay);
+
+	ret = s6e63j0x03_power_off(ctx);
+	if (ret < 0)
+		return ret;
+
+	bl_dev->props.power = FB_BLANK_POWERDOWN;
+
+	return 0;
+}
+
+static int s6e63j0x03_prepare(struct drm_panel *panel)
+{
+	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
+	struct backlight_device *bl_dev = ctx->bl_dev;
+	int ret;
+	int i;
+
+	ret = s6e63j0x03_power_on(ctx);
+	if (ret < 0)
+		return ret;
+
+	ret = s6e63j0x03_enable_lv2_command(ctx);
+	if (ret < 0)
+		return ret;
+
+	ret = s6e63j0x03_apply_mtp_key(ctx, true);
+	if (ret < 0)
+		return ret;
+
+	ret = s6e63j0x03_read_mtp_id(ctx);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(prepare_cmds1); i++) {
+		ret = s6e63j0x03_dcs_write_seq(ctx, &prepare_cmds1[i][1],
+							prepare_cmds1[i][0]);
+		if (ret < 0)
+			return ret;
+	}
+
+	msleep(120);
+
+	for (i = 0; i < ARRAY_SIZE(prepare_cmds2); i++) {
+		ret = s6e63j0x03_dcs_write_seq(ctx, &prepare_cmds2[i][1],
+							prepare_cmds2[i][0]);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = s6e63j0x03_apply_mtp_key(ctx, false);
+	if (ret < 0)
+		return ret;
+
+	bl_dev->props.power = FB_BLANK_NORMAL;
+
+	return 0;
+}
+
+static int s6e63j0x03_enable(struct drm_panel *panel)
+{
+	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
+	struct backlight_device *bl_dev = ctx->bl_dev;
+	u8 seq[] = { MIPI_DCS_SET_DISPLAY_ON };
+	int ret;
+
+	ret = s6e63j0x03_dcs_write_seq(ctx, seq, ARRAY_SIZE(seq));
+	if (ret > 0)
+		bl_dev->props.power = FB_BLANK_UNBLANK;
+
+	return 0;
+}
+
+static int s6e63j0x03_get_modes(struct drm_panel *panel)
+{
+	struct drm_connector *connector = panel->connector;
+	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
+	struct drm_display_mode *mode;
+
+	mode = drm_mode_create(connector->dev);
+	if (!mode) {
+		DRM_ERROR("failed to create a new display mode\n");
+		return 0;
+	}
+
+	drm_display_mode_from_videomode(&ctx->vm, mode);
+	mode->width_mm = ctx->width_mm;
+	mode->height_mm = ctx->height_mm;
+	connector->display_info.width_mm = mode->width_mm;
+	connector->display_info.height_mm = mode->height_mm;
+
+	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+	drm_mode_probed_add(connector, mode);
+
+	return 1;
+}
+
+static const struct drm_panel_funcs s6e63j0x03_funcs = {
+	.disable = s6e63j0x03_disable,
+	.unprepare = s6e63j0x03_unprepare,
+	.prepare = s6e63j0x03_prepare,
+	.enable = s6e63j0x03_enable,
+	.get_modes = s6e63j0x03_get_modes,
+};
+
+static int s6e63j0x03_parse_dt(struct s6e63j0x03 *ctx)
+{
+	struct device *dev = ctx->dev;
+	struct device_node *np = dev->of_node;
+	int ret;
+
+	ret = of_get_videomode(np, &ctx->vm, 0);
+	if (ret < 0)
+		return ret;
+
+	of_property_read_u32(np, "power-on-delay", &ctx->power_on_delay);
+	of_property_read_u32(np, "power-off-delay", &ctx->power_off_delay);
+	of_property_read_u32(np, "reset-delay", &ctx->reset_delay);
+	of_property_read_u32(np, "init-delay", &ctx->init_delay);
+	of_property_read_u32(np, "panel-width-mm", &ctx->width_mm);
+	of_property_read_u32(np, "panel-height-mm", &ctx->height_mm);
+
+	return ret;
+}
+
+static int s6e63j0x03_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct s6e63j0x03 *ctx;
+	int ret;
+
+	ctx = devm_kzalloc(dev, sizeof(struct s6e63j0x03), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	mipi_dsi_set_drvdata(dsi, ctx);
+
+	ctx->dev = dev;
+
+	dsi->lanes = 1;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+	dsi->mode_flags = MIPI_DSI_MODE_EOT_PACKET | MIPI_DSI_MODE_VIDEO_BURST;
+
+	ret = s6e63j0x03_parse_dt(ctx);
+	if (ret < 0)
+		return ret;
+
+	ctx->supplies[0].supply = "vdd3";
+	ctx->supplies[1].supply = "vci";
+	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
+				      ctx->supplies);
+	if (ret < 0) {
+		dev_err(dev, "failed to get regulators: %d\n", ret);
+		return ret;
+	}
+
+	ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(ctx->reset_gpio)) {
+		dev_err(dev, "cannot get reset-gpio: %ld\n",
+				PTR_ERR(ctx->reset_gpio));
+		return PTR_ERR(ctx->reset_gpio);
+	}
+
+	drm_panel_init(&ctx->panel);
+	ctx->panel.dev = dev;
+	ctx->panel.funcs = &s6e63j0x03_funcs;
+
+	ctx->bl_dev = backlight_device_register("s6e63j0x03", dev, ctx,
+						&s6e63j0x03_bl_ops, NULL);
+	if (IS_ERR(ctx->bl_dev)) {
+		dev_err(dev, "failed to register backlight device\n");
+		return PTR_ERR(ctx->bl_dev);
+	}
+
+	ctx->bl_dev->props.max_brightness = MAX_BRIGHTNESS;
+	ctx->bl_dev->props.brightness = DEFAULT_BRIGHTNESS;
+	ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
+
+
+	ret = drm_panel_add(&ctx->panel);
+	if (ret < 0)
+		goto unregister_backlight;
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret < 0)
+		goto remove_panel;
+
+	return ret;
+
+remove_panel:
+	drm_panel_remove(&ctx->panel);
+
+unregister_backlight:
+	backlight_device_unregister(ctx->bl_dev);
+
+	return ret;
+}
+
+static int s6e63j0x03_remove(struct mipi_dsi_device *dsi)
+{
+	struct s6e63j0x03 *ctx = mipi_dsi_get_drvdata(dsi);
+
+	mipi_dsi_detach(dsi);
+	drm_panel_remove(&ctx->panel);
+
+	backlight_device_unregister(ctx->bl_dev);
+
+	return 0;
+}
+
+static const struct of_device_id s6e63j0x03_of_match[] = {
+	{ .compatible = "samsung,s6e63j0x03" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, s6e63j0x03_of_match);
+
+static struct mipi_dsi_driver s6e63j0x03_driver = {
+	.probe = s6e63j0x03_probe,
+	.remove = s6e63j0x03_remove,
+	.driver = {
+		.name = "panel_s6e63j0x03",
+		.of_match_table = s6e63j0x03_of_match,
+	},
+};
+module_mipi_dsi_driver(s6e63j0x03_driver);
+
+MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
+MODULE_DESCRIPTION("MIPI-DSI based s6e8aa0 AMOLED LCD Panel Driver");
+MODULE_LICENSE("GPL v2");
--
1.9.1

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

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

* [PATCH v3 3/3] ARM: dts: add Panel device support for exynos3250-rinato
  2015-01-19  7:52 [PATCH v3 1/3] ARM: dts: add fimd device support for exynos3250-rinato Hyungwon Hwang
  2015-01-19  7:52 ` [PATCH v3 2/3] drm/panel: add s6e63j0x03 LCD panel driver Hyungwon Hwang
@ 2015-01-19  7:52 ` Hyungwon Hwang
  1 sibling, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-01-19  7:52 UTC (permalink / raw)
  To: dri-devel; +Cc: treding, Hyungwon Hwang

From: Inki Dae <inki.dae@samsung.com>

This patch adds MIPI-DSI and MIPI-DSI based S6E63J0X03 AMOLED panel
device nodes for Exynos3250 Rinato board.

Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Changes for v2:
- None
Changes for v3:
- Remove unnecessary DT properties of flip-*
 arch/arm/boot/dts/exynos3250-rinato.dts | 116 ++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 8b033b5..659068f 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -125,6 +125,122 @@
 	};
 };

+&dsi_0 {
+	vddcore-supply = <&ldo6_reg>;
+	vddio-supply = <&ldo6_reg>;
+	samsung,pll-clock-frequency = <24000000>;
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@1 {
+			reg = <1>;
+
+			dsi_out: endpoint {
+				remote-endpoint = <&dsi_in>;
+				samsung,burst-clock-frequency = <250000000>;
+				samsung,esc-clock-frequency = <20000000>;
+			};
+		};
+	};
+
+	panel@0 {
+		compatible = "samsung,s6e63j0x03";
+		reg = <0>;
+		vdd3-supply = <&ldo16_reg>;
+		vci-supply = <&ldo20_reg>;
+		reset-gpios = <&gpe0 1 0>;
+		te-gpios = <&gpx0 6 0>;
+		power-on-delay= <30>;
+		power-off-delay= <120>;
+		reset-delay = <5>;
+		init-delay = <100>;
+		panel-width-mm = <29>;
+		panel-height-mm = <29>;
+
+
+		display-timings {
+			timing-0 {
+				clock-frequency = <0>;
+				hactive = <320>;
+				vactive = <320>;
+				hfront-porch = <1>;
+				hback-porch = <1>;
+				hsync-len = <1>;
+				vfront-porch = <150>;
+				vback-porch = <1>;
+				vsync-len = <2>;
+			};
+		};
+
+		port {
+			dsi_in: endpoint {
+				remote-endpoint = <&dsi_out>;
+			};
+		};
+	};
+};
+
+&dsi_0 {
+	vddcore-supply = <&ldo6_reg>;
+	vddio-supply = <&ldo6_reg>;
+	samsung,pll-clock-frequency = <24000000>;
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@1 {
+			reg = <1>;
+
+			dsi_out: endpoint {
+				remote-endpoint = <&dsi_in>;
+				samsung,burst-clock-frequency = <250000000>;
+				samsung,esc-clock-frequency = <20000000>;
+			};
+		};
+	};
+
+	panel@0 {
+		compatible = "samsung,s6e63j0x03";
+		reg = <0>;
+		vdd3-supply = <&ldo16_reg>;
+		vci-supply = <&ldo20_reg>;
+		reset-gpios = <&gpe0 1 0>;
+		te-gpios = <&gpx0 6 0>;
+		power-on-delay= <30>;
+		power-off-delay= <120>;
+		reset-delay = <5>;
+		init-delay = <100>;
+		panel-width-mm = <29>;
+		panel-height-mm = <29>;
+
+
+		display-timings {
+			timing-0 {
+				clock-frequency = <0>;
+				hactive = <320>;
+				vactive = <320>;
+				hfront-porch = <1>;
+				hback-porch = <1>;
+				hsync-len = <1>;
+				vfront-porch = <150>;
+				vback-porch = <1>;
+				vsync-len = <2>;
+			};
+		};
+
+		port {
+			dsi_in: endpoint {
+				remote-endpoint = <&dsi_out>;
+			};
+		};
+	};
+};
+
 &fimd {
 	status = "okay";

--
1.9.1

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

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

* Re: [PATCH v3 2/3] drm/panel: add s6e63j0x03 LCD panel driver
  2015-01-19  7:52 ` [PATCH v3 2/3] drm/panel: add s6e63j0x03 LCD panel driver Hyungwon Hwang
@ 2015-02-03 14:00   ` Thierry Reding
  2015-06-12 13:03   ` [v3,2/3] " Hyungwon Hwang
  1 sibling, 0 replies; 50+ messages in thread
From: Thierry Reding @ 2015-02-03 14:00 UTC (permalink / raw)
  To: Hyungwon Hwang; +Cc: treding, dri-devel


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

On Mon, Jan 19, 2015 at 04:52:32PM +0900, Hyungwon Hwang wrote:
> From: Inki Dae <inki.dae@samsung.com>
> 
> This patch adds MIPI-DSI based S6E63J0X03 AMOLED LCD panel driver
> which uses mipi_dsi bus to communicate with panel. The panel has
> 320×320 resolution in 1.63-inch physical panel. This panel is used in
> Samsung Galaxy Gear 2.
> 
> Signed-off-by: Inki Dae <inki.dae@samsung.com>
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
> Changes for v2:
> - Change the gamma table to 2-dimensional array
> - Change the way to make index for brightness
> - Make command functions to an array so that it can be called simply
> - Change command id for reading device ID
> - Change the way to handle the error condition
> - Remove power variable, and use the same name variable in bl_dev
> - Add the state FB_BLANK_NORMAL to represent the state which the panel
> is working but blanked
> - Miscellaneous changes to increase the readability and follow the
>   coding-style standard
> Changes for v3:
> - Add DT binding documentation
> - Add the code getting DT properties of 'panel-width-mm' and 'panel-height-mm'
> - Remove the code getting unnecessary DT properties flip-*
>  .../bindings/panel/samsung,s6e63j0x03.txt          |  55 +++
>  drivers/gpu/drm/panel/Kconfig                      |   6 +
>  drivers/gpu/drm/panel/Makefile                     |   1 +
>  drivers/gpu/drm/panel/panel-s6e63j0x03.c           | 546 +++++++++++++++++++++
>  4 files changed, 608 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt
>  create mode 100644 drivers/gpu/drm/panel/panel-s6e63j0x03.c

I have pretty much the same comments as for the SA6E3HA2 panel driver
that I reviewed earlier.

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 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] 50+ messages in thread

* [PATCH v6 00/15] Add drivers for Exynos5433 display
@ 2015-06-12 12:58 Hyungwon Hwang
  2015-06-12 12:58 ` [PATCH v6 02/15] drm/exynos: Add the dependency for DRM_EXYNOS to DPI/DSI/DP Hyungwon Hwang
                   ` (11 more replies)
  0 siblings, 12 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:58 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: inki.dae-Sze3O3UU22JBDgjK7y7TUQ, daniel-rLtY4a/8tF1rovVCs/uTlw,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ, Hyungwon Hwang

This patchset is based on the git(branch name: exynos-drm-next) which is
maintained by Inki Dae.
https://kernel.googlesource.com/pub/scm/linux/kernel/git/...

This patchset adds 2 new device drivers, Exynos54333 decon and mic, and adds
support for Exynos5433 mipi dsi. To enable display in a Exynos5433 board,
decon(display controller), MIC(Mobile image compressor), mipi dsi, and panel
have to be turned on. This patchset contains support for 3 drivers for SoC
level devices.

Changes for v2:
- change config, file, and variable names of decon to represnt exynos5433
instead of exynos to distinguish them from exynos7 decon
- change the initialization order of decon to make it initialized in order like
FIMD or exynos7 decon
- make mic driver to be registered by exynos drm driver instead as a module
driver
- change the description of mic driver in documentation
- add module author at the top of the source file removing MODULE_OWNER,
MODULE_DESCRIPTION, MODULE_LICENSE
- change the author of "drm/exynos: dsi: add support for Exynos5433 SoC" to
Hyungwon Hwang by the previous author's will

Changes for v3:
< Decon >
- fail fast when the proper image format is not set
- remove unnecessary checking code
- add and modify the function to make DPMS work well
< MIC >
- move if statement out of function, so that the function is not called
unnecessarily
- Make it use syscon framework for controlling system register
< DSI >
- separate the previous one patch to three
- renaming patch: rename pll clock to sclk clock
- generalizing patch: generalize the way to getting address and values
- Exynos5433 patch: adds support for Exynos5433 dsi
- use defines for more readable code
- fix typos

Changes for v4:
- rebased to exynos-drm-next with the clean-up patchset by Gustavo Padovan.

Changes for v5:
- separated the refactoring patch of MIPI DSI driver into 3 patches
- added the patch to make DSI driver compatiable with the old clock name
- added the patch to rename the DSI driver's clock
- rename the newly added dsi variables for clarity

Changes for v6:
- Clean up the build dependencies of Exynos DRM devices as preparation
- Introduce new common function drm_iommu_attach_device_if_possible()
- Add support for atomic modeset in Exynos5433 decon driver

Hyungwon Hwang (14):
  drm/exynos: remove the dependency of DP driver for ARCH_EXYNOS
  drm/exynos: Add the dependency for DRM_EXYNOS to DPI/DSI/DP
  drm/exynos: add drm_iommu_attach_device_if_possible()
  drm/exynos: fix the input prompt of Exynos7 DECON
  of: add helper for getting endpoint node of specific identifiers
  drm/exynos: mic: add MIC driver
  drm/exynos: dsi: rename pll_clk to sclk_clk
  drm/exynos: dsi: add macros for register access
  drm/exynos: dsi: make use of driver data for static values
  drm/exynos: dsi: make use of array for clock access
  drm/exynos: dsi: add support for Exynos5433
  drm/exynos: dsi: add support for MIC driver as a bridge
  drm/exynos: dsi: do not set TE GPIO direction by input
  ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi'

Joonyoung Shim (1):
  drm/exynos: add Exynos5433 decon driver

 .../devicetree/bindings/video/exynos-mic.txt       |  51 ++
 .../devicetree/bindings/video/exynos5433-decon.txt |  65 ++
 .../devicetree/bindings/video/exynos_dsim.txt      |  31 +-
 arch/arm/boot/dts/exynos4.dtsi                     |   2 +-
 drivers/gpu/drm/exynos/Kconfig                     |  20 +-
 drivers/gpu/drm/exynos/Makefile                    |   2 +
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c      | 694 +++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos7_drm_decon.c         |  25 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c            |   3 +
 drivers/gpu/drm/exynos/exynos_drm_drv.h            |   3 +
 drivers/gpu/drm/exynos/exynos_drm_dsi.c            | 484 +++++++++-----
 drivers/gpu/drm/exynos/exynos_drm_fimd.c           |  34 +-
 drivers/gpu/drm/exynos/exynos_drm_iommu.c          |  14 +
 drivers/gpu/drm/exynos/exynos_drm_iommu.h          |  11 +
 drivers/gpu/drm/exynos/exynos_drm_mic.c            | 490 +++++++++++++++
 drivers/gpu/drm/exynos/exynos_mixer.c              |   8 +-
 drivers/of/base.c                                  |  33 +
 include/linux/of_graph.h                           |   8 +
 include/video/exynos5433_decon.h                   | 165 +++++
 19 files changed, 1937 insertions(+), 206 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/video/exynos-mic.txt
 create mode 100644 Documentation/devicetree/bindings/video/exynos5433-decon.txt
 create mode 100644 drivers/gpu/drm/exynos/exynos5433_drm_decon.c
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_mic.c
 create mode 100644 include/video/exynos5433_decon.h

--
1.9.1

--
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] 50+ messages in thread

* [PATCH v6 01/15] drm/exynos: remove the dependency of DP driver for ARCH_EXYNOS
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2015-06-12 12:58   ` Hyungwon Hwang
  2015-06-12 12:59   ` [PATCH v6 05/15] drm/exynos: add Exynos5433 decon driver Hyungwon Hwang
                     ` (9 subsequent siblings)
  10 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:58 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: inki.dae-Sze3O3UU22JBDgjK7y7TUQ, daniel-rLtY4a/8tF1rovVCs/uTlw,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ, Hyungwon Hwang

This dependency is a historical thing. It is added when this DP driver is
under media subsystem. Now because it is under Exynos DRM, this dependency
is not needed anymore.

Signed-off-by: Hyungwon Hwang <human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
Changes for v6:
- New
 drivers/gpu/drm/exynos/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 8203283..926ed36 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -50,7 +50,7 @@ config DRM_EXYNOS_DSI

 config DRM_EXYNOS_DP
 	bool "EXYNOS DRM DP driver support"
-	depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
+	depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
 	default DRM_EXYNOS
 	select DRM_PANEL
 	help
--
1.9.1

--
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 related	[flat|nested] 50+ messages in thread

* [PATCH v6 02/15] drm/exynos: Add the dependency for DRM_EXYNOS to DPI/DSI/DP
  2015-06-12 12:58 [PATCH v6 00/15] Add drivers for Exynos5433 display Hyungwon Hwang
@ 2015-06-12 12:58 ` Hyungwon Hwang
  2015-06-12 12:58 ` [PATCH v6 03/15] drm/exynos: add drm_iommu_attach_device_if_possible() Hyungwon Hwang
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:58 UTC (permalink / raw)
  To: dri-devel, devicetree; +Cc: sw0312.kim

Without this dependency, Kbuild is confused and the configs below
them are not placed under Exynos DRM. This patch fixes it, so the
configs below them become to be placed under Exynos DRM.

Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
---
Changes for v6:
- New
 drivers/gpu/drm/exynos/Kconfig | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 926ed36..f1b1239 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -33,7 +33,7 @@ config DRM_EXYNOS7_DECON

 config DRM_EXYNOS_DPI
 	bool "EXYNOS DRM parallel output support"
-	depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON)
+	depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON)
 	select DRM_PANEL
 	default n
 	help
@@ -41,7 +41,7 @@ config DRM_EXYNOS_DPI

 config DRM_EXYNOS_DSI
 	bool "EXYNOS DRM MIPI-DSI driver support"
-	depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON)
+	depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON)
 	select DRM_MIPI_DSI
 	select DRM_PANEL
 	default n
@@ -50,7 +50,7 @@ config DRM_EXYNOS_DSI

 config DRM_EXYNOS_DP
 	bool "EXYNOS DRM DP driver support"
-	depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
+	depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
 	default DRM_EXYNOS
 	select DRM_PANEL
 	help
--
1.9.1

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

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

* [PATCH v6 03/15] drm/exynos: add drm_iommu_attach_device_if_possible()
  2015-06-12 12:58 [PATCH v6 00/15] Add drivers for Exynos5433 display Hyungwon Hwang
  2015-06-12 12:58 ` [PATCH v6 02/15] drm/exynos: Add the dependency for DRM_EXYNOS to DPI/DSI/DP Hyungwon Hwang
@ 2015-06-12 12:58 ` Hyungwon Hwang
  2015-06-12 12:58 ` [PATCH v6 04/15] drm/exynos: fix the input prompt of Exynos7 DECON Hyungwon Hwang
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:58 UTC (permalink / raw)
  To: dri-devel, devicetree; +Cc: sw0312.kim

Every CRTC drivers in Exynos DRM implements the code which checks
whether IOMMU is supported or not, and if supported enable it.
Making new helper for it generalize each CRTC drivers.

Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
---
Changes for v6:
- New
 drivers/gpu/drm/exynos/exynos7_drm_decon.c | 25 +++++++---------------
 drivers/gpu/drm/exynos/exynos_drm_drv.h    |  1 +
 drivers/gpu/drm/exynos/exynos_drm_fimd.c   | 34 +++++++-----------------------
 drivers/gpu/drm/exynos/exynos_drm_iommu.c  | 14 ++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_iommu.h  | 11 ++++++++++
 drivers/gpu/drm/exynos/exynos_mixer.c      |  8 ++++---
 6 files changed, 47 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 7d0955d..b0261dd 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -89,8 +89,9 @@ static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc)
 		DRM_DEBUG_KMS("vblank wait timed out.\n");
 }

-static void decon_clear_channel(struct decon_context *ctx)
+static void decon_clear_channels(struct exynos_drm_crtc *crtc)
 {
+	struct decon_context *ctx = crtc->ctx;
 	unsigned int win, ch_enabled = 0;

 	DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -120,27 +121,16 @@ static int decon_ctx_initialize(struct decon_context *ctx,
 			struct drm_device *drm_dev)
 {
 	struct exynos_drm_private *priv = drm_dev->dev_private;
+	int ret;

 	ctx->drm_dev = drm_dev;
 	ctx->pipe = priv->pipe++;

-	/* attach this sub driver to iommu mapping if supported. */
-	if (is_drm_iommu_supported(ctx->drm_dev)) {
-		int ret;
-
-		/*
-		 * If any channel is already active, iommu will throw
-		 * a PAGE FAULT when enabled. So clear any channel if enabled.
-		 */
-		decon_clear_channel(ctx);
-		ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
-		if (ret) {
-			DRM_ERROR("drm_iommu_attach failed.\n");
-			return ret;
-		}
-	}
+	ret = drm_iommu_attach_device_if_possible(ctx->crtc, drm_dev, ctx->dev);
+	if (ret)
+		priv->pipe--;

-	return 0;
+	return ret;
 }

 static void decon_ctx_remove(struct decon_context *ctx)
@@ -684,6 +674,7 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
 	.wait_for_vblank = decon_wait_for_vblank,
 	.win_commit = decon_win_commit,
 	.win_disable = decon_win_disable,
+	.clear_channels = decon_clear_channels,
 };


diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 6b4958b..1ba34f1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -182,6 +182,7 @@ struct exynos_drm_crtc_ops {
 	void (*win_disable)(struct exynos_drm_crtc *crtc, unsigned int zpos);
 	void (*te_handler)(struct exynos_drm_crtc *crtc);
 	void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable);
+	void (*clear_channels)(struct exynos_drm_crtc *crtc);
 };

 /*
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 9cce2bc..ddf4c84 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -242,8 +242,9 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx,
 	writel(val, ctx->regs + SHADOWCON);
 }

-static void fimd_clear_channel(struct fimd_context *ctx)
+static void fimd_clear_channels(struct exynos_drm_crtc *crtc)
 {
+	struct fimd_context *ctx = crtc->ctx;
 	unsigned int win, ch_enabled = 0;

 	DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -273,30 +274,6 @@ static void fimd_clear_channel(struct fimd_context *ctx)
 	}
 }

-static int fimd_iommu_attach_devices(struct fimd_context *ctx,
-			struct drm_device *drm_dev)
-{
-
-	/* attach this sub driver to iommu mapping if supported. */
-	if (is_drm_iommu_supported(ctx->drm_dev)) {
-		int ret;
-
-		/*
-		 * If any channel is already active, iommu will throw
-		 * a PAGE FAULT when enabled. So clear any channel if enabled.
-		 */
-		fimd_clear_channel(ctx);
-		ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
-		if (ret) {
-			DRM_ERROR("drm_iommu_attach failed.\n");
-			return ret;
-		}
-
-	}
-
-	return 0;
-}
-
 static void fimd_iommu_detach_devices(struct fimd_context *ctx)
 {
 	/* detach this sub driver from iommu mapping if supported. */
@@ -943,6 +920,7 @@ static const struct exynos_drm_crtc_ops fimd_crtc_ops = {
 	.win_disable = fimd_win_disable,
 	.te_handler = fimd_te_handler,
 	.clock_enable = fimd_dp_clock_enable,
+	.clear_channels = fimd_clear_channels,
 };

 static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
@@ -1012,7 +990,11 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
 	if (ctx->display)
 		exynos_drm_create_enc_conn(drm_dev, ctx->display);

-	return fimd_iommu_attach_devices(ctx, drm_dev);
+	ret = drm_iommu_attach_device_if_possible(ctx->crtc, drm_dev, dev);
+	if (ret)
+		priv->pipe--;
+
+	return ret;
 }

 static void fimd_unbind(struct device *dev, struct device *master,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
index b32b291..6f07479 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
@@ -141,3 +141,17 @@ void drm_iommu_detach_device(struct drm_device *drm_dev,
 	iommu_detach_device(mapping->domain, subdrv_dev);
 	drm_release_iommu_mapping(drm_dev);
 }
+
+int drm_iommu_attach_device_if_possible(struct exynos_drm_crtc *exynos_crtc,
+			struct drm_device *drm_dev, struct device *subdrv_dev)
+{
+	int ret = 0;
+
+	if (is_drm_iommu_supported(drm_dev)) {
+		if (exynos_crtc->ops->clear_channels)
+			exynos_crtc->ops->clear_channels(exynos_crtc);
+		return drm_iommu_attach_device(drm_dev, subdrv_dev);
+	}
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.h b/drivers/gpu/drm/exynos/exynos_drm_iommu.h
index 35d2588..8341c7a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.h
@@ -38,6 +38,10 @@ static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
 #endif
 }

+int drm_iommu_attach_device_if_possible(
+		struct exynos_drm_crtc *exynos_crtc, struct drm_device *drm_dev,
+		struct device *subdrv_dev);
+
 #else

 static inline int drm_create_iommu_mapping(struct drm_device *drm_dev)
@@ -65,5 +69,12 @@ static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
 	return false;
 }

+static inline int drm_iommu_attach_device_if_possible(
+		struct exynos_drm_crtc *exynos_crtc, struct drm_device *drm_dev,
+		struct device *subdrv_dev)
+{
+	return 0;
+}
+
 #endif
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 854b6d8..6a2ede4 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -882,10 +882,12 @@ static int mixer_initialize(struct mixer_context *mixer_ctx,
 		}
 	}

-	if (!is_drm_iommu_supported(mixer_ctx->drm_dev))
-		return 0;
+	ret = drm_iommu_attach_device_if_possible(mixer_ctx->crtc, drm_dev,
+								mixer_ctx->dev);
+	if (ret)
+		priv->pipe--;

-	return drm_iommu_attach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
+	return ret;
 }

 static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
--
1.9.1

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

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

* [PATCH v6 04/15] drm/exynos: fix the input prompt of Exynos7 DECON
  2015-06-12 12:58 [PATCH v6 00/15] Add drivers for Exynos5433 display Hyungwon Hwang
  2015-06-12 12:58 ` [PATCH v6 02/15] drm/exynos: Add the dependency for DRM_EXYNOS to DPI/DSI/DP Hyungwon Hwang
  2015-06-12 12:58 ` [PATCH v6 03/15] drm/exynos: add drm_iommu_attach_device_if_possible() Hyungwon Hwang
@ 2015-06-12 12:58 ` Hyungwon Hwang
  2015-06-12 12:59 ` [PATCH v6 06/15] of: add helper for getting endpoint node of specific identifiers Hyungwon Hwang
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:58 UTC (permalink / raw)
  To: dri-devel, devicetree; +Cc: sw0312.kim

This patch is a preparation patch for adding support for Exynos5433
DECON. Exynos7 DECON have to be distinguished from Exynos5433 DECON.

Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
---
Changes for v6:
- New
 drivers/gpu/drm/exynos/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index f1b1239..ddb7c8a 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -25,7 +25,7 @@ config DRM_EXYNOS_FIMD
 	  Choose this option if you want to use Exynos FIMD for DRM.

 config DRM_EXYNOS7_DECON
-	bool "Exynos DRM DECON"
+	bool "Exynos7 DRM DECON"
 	depends on DRM_EXYNOS && !FB_S3C
 	select FB_MODE_HELPERS
 	help
--
1.9.1

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

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

* [PATCH v6 05/15] drm/exynos: add Exynos5433 decon driver
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
  2015-06-12 12:58   ` [PATCH v6 01/15] drm/exynos: remove the dependency of DP driver for ARCH_EXYNOS Hyungwon Hwang
@ 2015-06-12 12:59   ` Hyungwon Hwang
  2015-06-22 11:16     ` [PATCH v7 " Inki Dae
  2015-06-12 12:59   ` [PATCH v6 08/15] drm/exynos: dsi: rename pll_clk to sclk_clk Hyungwon Hwang
                     ` (8 subsequent siblings)
  10 siblings, 1 reply; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: inki.dae-Sze3O3UU22JBDgjK7y7TUQ, daniel-rLtY4a/8tF1rovVCs/uTlw,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ, Hyungwon Hwang

From: Joonyoung Shim <jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>

DECON(Display and Enhancement Controller) is new IP replacing FIMD in
Exynos5433. This patch adds Exynos5433 decon driver.

Signed-off-by: Joonyoung Shim <jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Hyungwon Hwang <human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
Changes before:
- Refer https://patchwork.kernel.org/patch/6192071/
Changes for v6:
- Add support for atomic modeset
 .../devicetree/bindings/video/exynos5433-decon.txt |  65 ++
 drivers/gpu/drm/exynos/Kconfig                     |   6 +
 drivers/gpu/drm/exynos/Makefile                    |   1 +
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c      | 694 +++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_drv.h            |   1 +
 include/video/exynos5433_decon.h                   | 165 +++++
 6 files changed, 932 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/exynos5433-decon.txt
 create mode 100644 drivers/gpu/drm/exynos/exynos5433_drm_decon.c
 create mode 100644 include/video/exynos5433_decon.h

diff --git a/Documentation/devicetree/bindings/video/exynos5433-decon.txt b/Documentation/devicetree/bindings/video/exynos5433-decon.txt
new file mode 100644
index 0000000..377afbf
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos5433-decon.txt
@@ -0,0 +1,65 @@
+Device-Tree bindings for Samsung Exynos SoC display controller (DECON)
+
+DECON (Display and Enhancement Controller) is the Display Controller for the
+Exynos series of SoCs which transfers the image data from a video memory
+buffer to an external LCD interface.
+
+Required properties:
+- compatible: value should be "samsung,exynos5433-decon";
+- reg: physical base address and length of the DECON registers set.
+- interrupts: should contain a list of all DECON IP block interrupts in the
+	      order: VSYNC, LCD_SYSTEM. The interrupt specifier format
+	      depends on the interrupt controller used.
+- interrupt-names: should contain the interrupt names: "vsync", "lcd_sys"
+		   in the same order as they were listed in the interrupts
+		   property.
+- clocks: must include clock specifiers corresponding to entries in the
+	  clock-names property.
+- clock-names: list of clock names sorted in the same order as the clocks
+	       property. Must contain "aclk_decon", "aclk_smmu_decon0x",
+	       "aclk_xiu_decon0x", "pclk_smmu_decon0x", clk_decon_vclk",
+	       "sclk_decon_eclk"
+- ports: contains a port which is connected to mic node. address-cells and
+	 size-cells must 1 and 0, respectively.
+- port: contains an endpoint node which is connected to the endpoint in the mic
+	node. The reg value muset be 0.
+- i80-if-timings: specify whether the panel which is connected to decon uses
+		  i80 lcd interface or mipi video interface. This node contains
+		  no timing information as that of fimd does. Because there is
+		  no register in decon to specify i80 interface timing value,
+		  it is not needed, but make it remain to use same kind of node
+		  in fimd and exynos7 decon.
+
+Example:
+SoC specific DT entry:
+decon: decon@13800000 {
+	compatible = "samsung,exynos5433-decon";
+	reg = <0x13800000 0x2104>;
+	clocks = <&cmu_disp CLK_ACLK_DECON>, <&cmu_disp CLK_ACLK_SMMU_DECON0X>,
+		<&cmu_disp CLK_ACLK_XIU_DECON0X>,
+		<&cmu_disp CLK_PCLK_SMMU_DECON0X>,
+		<&cmu_disp CLK_SCLK_DECON_VCLK>,
+		<&cmu_disp CLK_SCLK_DECON_ECLK>;
+	clock-names = "aclk_decon", "aclk_smmu_decon0x", "aclk_xiu_decon0x",
+		"pclk_smmu_decon0x", "sclk_decon_vclk", "sclk_decon_eclk";
+	interrupt-names = "vsync", "lcd_sys";
+	interrupts = <0 202 0>, <0 203 0>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			decon_to_mic: endpoint {
+				remote-endpoint = <&mic_to_decon>;
+			};
+		};
+	};
+};
+
+Board specific DT entry:
+&decon {
+	i80-if-timings {
+	};
+};
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index ddb7c8a..51a4eb5 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -24,6 +24,12 @@ config DRM_EXYNOS_FIMD
 	help
 	  Choose this option if you want to use Exynos FIMD for DRM.

+config DRM_EXYNOS5433_DECON
+	bool "Exynos5433 DRM DECON"
+	depends on DRM_EXYNOS
+	help
+	  Choose this option if you want to use Exynos5433 DECON for DRM.
+
 config DRM_EXYNOS7_DECON
 	bool "Exynos7 DRM DECON"
 	depends on DRM_EXYNOS && !FB_S3C
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index cc90679..fbd084d 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -10,6 +10,7 @@ exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o \

 exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)	+= exynos_drm_fimd.o
+exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON)	+= exynos5433_drm_decon.o
 exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON)	+= exynos7_drm_decon.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_DPI)	+= exynos_drm_dpi.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_DSI)	+= exynos_drm_dsi.o
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
new file mode 100644
index 0000000..a33c0b7
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -0,0 +1,694 @@
+/* drivers/gpu/drm/exynos5433_drm_decon.c
+ *
+ * Copyright (C) 2015 Samsung Electronics Co.Ltd
+ * Authors:
+ *	Joonyoung Shim <jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *	Hyungwon Hwang <human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *
+ * 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 Foundationr
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_gpio.h>
+
+#include <video/exynos5433_decon.h>
+
+#include "exynos_drm_drv.h"
+#include "exynos_drm_crtc.h"
+#include "exynos_drm_plane.h"
+#include "exynos_drm_iommu.h"
+
+#define WINDOWS_NR	3
+#define MIN_FB_WIDTH_FOR_16WORD_BURST	128
+
+struct decon_context {
+	struct device			*dev;
+	struct drm_device		*drm_dev;
+	struct exynos_drm_crtc		*crtc;
+	struct exynos_drm_plane		planes[WINDOWS_NR];
+	void __iomem			*addr;
+	struct clk			*clks[6];
+	unsigned int			default_win;
+	int				pipe;
+	bool				suspended;
+
+#define BIT_CLKS_ENABLED		0
+#define BIT_IRQS_ENABLED		1
+	unsigned long			enabled;
+	bool				i80_if;
+	atomic_t			win_updated;
+};
+
+static const char * const decon_clks_name[] = {
+	"aclk_decon",
+	"aclk_smmu_decon0x",
+	"aclk_xiu_decon0x",
+	"pclk_smmu_decon0x",
+	"sclk_decon_vclk",
+	"sclk_decon_eclk",
+};
+
+static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+	u32 val;
+
+	if (ctx->suspended)
+		return -EPERM;
+
+	if (!test_and_set_bit(BIT_IRQS_ENABLED, &ctx->enabled)) {
+		val = VIDINTCON0_INTEN;
+		if (ctx->i80_if)
+			val |= VIDINTCON0_FRAMEDONE;
+		else
+			val |= VIDINTCON0_INTFRMEN;
+
+		writel(val, ctx->addr + DECON_VIDINTCON0);
+	}
+
+	return 0;
+}
+
+static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+
+	if (ctx->suspended)
+		return;
+
+	if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->enabled))
+		writel(0, ctx->addr + DECON_VIDINTCON0);
+}
+
+static void decon_setup_trigger(struct decon_context *ctx)
+{
+	u32 val = TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
+			TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN;
+	writel(val, ctx->addr + DECON_TRIGCON);
+}
+
+static void decon_commit(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+	struct drm_display_mode *mode = &crtc->base.mode;
+	u32 val;
+
+	if (ctx->suspended)
+		return;
+
+	/* enable clock gate */
+	val = CMU_CLKGAGE_MODE_SFR_F | CMU_CLKGAGE_MODE_MEM_F;
+	writel(val, ctx->addr + DECON_CMU);
+
+	/* lcd on and use command if */
+	val = VIDOUT_LCD_ON;
+	if (ctx->i80_if)
+		val |= VIDOUT_COMMAND_IF;
+	else
+		val |= VIDOUT_RGB_IF;
+	writel(val, ctx->addr + DECON_VIDOUTCON0);
+
+	val = VIDTCON2_LINEVAL(mode->vdisplay - 1) |
+		VIDTCON2_HOZVAL(mode->hdisplay - 1);
+	writel(val, ctx->addr + DECON_VIDTCON2);
+
+	if (!ctx->i80_if) {
+		val = VIDTCON00_VBPD_F(
+				mode->crtc_vtotal - mode->crtc_vsync_end) |
+			VIDTCON00_VFPD_F(
+				mode->crtc_vsync_start - mode->crtc_vdisplay);
+		writel(val, ctx->addr + DECON_VIDTCON00);
+
+		val = VIDTCON01_VSPW_F(
+				mode->crtc_vsync_end - mode->crtc_vsync_start);
+		writel(val, ctx->addr + DECON_VIDTCON01);
+
+		val = VIDTCON10_HBPD_F(
+				mode->crtc_htotal - mode->crtc_hsync_end) |
+			VIDTCON10_HFPD_F(
+				mode->crtc_hsync_start - mode->crtc_hdisplay);
+		writel(val, ctx->addr + DECON_VIDTCON10);
+
+		val = VIDTCON11_HSPW_F(
+				mode->crtc_hsync_end - mode->crtc_hsync_start);
+		writel(val, ctx->addr + DECON_VIDTCON11);
+	}
+
+	decon_setup_trigger(ctx);
+
+	/* enable output and display signal */
+	val = VIDCON0_ENVID | VIDCON0_ENVID_F;
+	writel(val, ctx->addr + DECON_VIDCON0);
+}
+
+#define COORDINATE_X(x)		(((x) & 0xfff) << 12)
+#define COORDINATE_Y(x)		((x) & 0xfff)
+#define OFFSIZE(x)		(((x) & 0x3fff) << 14)
+#define PAGEWIDTH(x)		((x) & 0x3fff)
+
+static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win)
+{
+	struct exynos_drm_plane *plane = &ctx->planes[win];
+	unsigned long val;
+
+	val = readl(ctx->addr + DECON_WINCONx(win));
+	val &= ~WINCONx_BPPMODE_MASK;
+
+	switch (plane->pixel_format) {
+	case DRM_FORMAT_XRGB1555:
+		val |= WINCONx_BPPMODE_16BPP_I1555;
+		val |= WINCONx_HAWSWP_F;
+		val |= WINCONx_BURSTLEN_16WORD;
+		break;
+	case DRM_FORMAT_RGB565:
+		val |= WINCONx_BPPMODE_16BPP_565;
+		val |= WINCONx_HAWSWP_F;
+		val |= WINCONx_BURSTLEN_16WORD;
+		break;
+	case DRM_FORMAT_XRGB8888:
+		val |= WINCONx_BPPMODE_24BPP_888;
+		val |= WINCONx_WSWP_F;
+		val |= WINCONx_BURSTLEN_16WORD;
+		break;
+	case DRM_FORMAT_ARGB8888:
+		val |= WINCONx_BPPMODE_32BPP_A8888;
+		val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F;
+		val |= WINCONx_BURSTLEN_16WORD;
+		break;
+	default:
+		DRM_ERROR("Proper pixel format is not set\n");
+		return;
+	}
+
+	DRM_DEBUG_KMS("bpp = %u\n", plane->bpp);
+
+	/*
+	 * In case of exynos, setting dma-burst to 16Word causes permanent
+	 * tearing for very small buffers, e.g. cursor buffer. Burst Mode
+	 * switching which is based on plane size is not recommended as
+	 * plane size varies a lot towards the end of the screen and rapid
+	 * movement causes unstable DMA which results into iommu crash/tear.
+	 */
+
+	if (plane->fb_width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
+		val &= ~WINCONx_BURSTLEN_MASK;
+		val |= WINCONx_BURSTLEN_8WORD;
+	}
+
+	writel(val, ctx->addr + DECON_WINCONx(win));
+}
+
+static void decon_shadow_protect_win(struct decon_context *ctx, int win,
+					bool protect)
+{
+	u32 val;
+
+	val = readl(ctx->addr + DECON_SHADOWCON);
+
+	if (protect)
+		val |= SHADOWCON_Wx_PROTECT(win);
+	else
+		val &= ~SHADOWCON_Wx_PROTECT(win);
+
+	writel(val, ctx->addr + DECON_SHADOWCON);
+}
+
+static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
+{
+	struct decon_context *ctx = crtc->ctx;
+	struct exynos_drm_plane *plane;
+	u32 val;
+
+	if (win < 0 || win >= WINDOWS_NR)
+		return;
+
+	plane = &ctx->planes[win];
+
+	/* If suspended, enable this on resume */
+	if (ctx->suspended) {
+		plane->resume = true;
+		return;
+	}
+
+	decon_shadow_protect_win(ctx, win, true);
+
+	val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y);
+	writel(val, ctx->addr + DECON_VIDOSDxA(win));
+
+	val = COORDINATE_X(plane->crtc_x + plane->crtc_width - 1) |
+		COORDINATE_Y(plane->crtc_y + plane->crtc_height - 1);
+	writel(val, ctx->addr + DECON_VIDOSDxB(win));
+
+	val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
+		VIDOSD_Wx_ALPHA_B_F(0x0);
+	writel(val, ctx->addr + DECON_VIDOSDxC(win));
+
+	val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
+		VIDOSD_Wx_ALPHA_B_F(0x0);
+	writel(val, ctx->addr + DECON_VIDOSDxD(win));
+
+	writel(plane->dma_addr[0], ctx->addr + DECON_VIDW0xADD0B0(win));
+
+	val = plane->dma_addr[0] + plane->pitch * plane->crtc_height;
+	writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
+
+	val = OFFSIZE(plane->pitch - plane->crtc_width * (plane->bpp >> 3))
+		| PAGEWIDTH(plane->crtc_width * (plane->bpp >> 3));
+	writel(val, ctx->addr + DECON_VIDW0xADD2(win));
+
+	decon_win_set_pixfmt(ctx, win);
+
+	/* window enable */
+	val = readl(ctx->addr + DECON_WINCONx(win));
+	val |= WINCONx_ENWIN_F;
+	writel(val, ctx->addr + DECON_WINCONx(win));
+
+	decon_shadow_protect_win(ctx, win, false);
+
+	/* standalone update */
+	val = readl(ctx->addr + DECON_UPDATE);
+	val |= STANDALONE_UPDATE_F;
+	writel(val, ctx->addr + DECON_UPDATE);
+
+	if (ctx->i80_if)
+		atomic_set(&ctx->win_updated, 1);
+
+	plane->enabled = true;
+}
+
+static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
+{
+	struct decon_context *ctx = crtc->ctx;
+	struct exynos_drm_plane *plane;
+	u32 val;
+
+	if (win < 0 || win >= WINDOWS_NR)
+		return;
+
+	plane = &ctx->planes[win];
+
+	if (ctx->suspended) {
+		plane->resume = false;
+		return;
+	}
+
+	decon_shadow_protect_win(ctx, win, true);
+
+	/* window disable */
+	val = readl(ctx->addr + DECON_WINCONx(win));
+	val &= ~WINCONx_ENWIN_F;
+	writel(val, ctx->addr + DECON_WINCONx(win));
+
+	decon_shadow_protect_win(ctx, win, false);
+
+	/* standalone update */
+	val = readl(ctx->addr + DECON_UPDATE);
+	val |= STANDALONE_UPDATE_F;
+	writel(val, ctx->addr + DECON_UPDATE);
+
+	plane->enabled = false;
+}
+
+static void decon_window_suspend(struct decon_context *ctx)
+{
+	struct exynos_drm_plane *plane;
+	int i;
+
+	for (i = 0; i < WINDOWS_NR; i++) {
+		plane = &ctx->planes[i];
+		plane->resume = plane->enabled;
+		if (plane->enabled)
+			decon_win_disable(ctx->crtc, i);
+	}
+}
+
+static void decon_window_resume(struct decon_context *ctx)
+{
+	struct exynos_drm_plane *plane;
+	int i;
+
+	for (i = 0; i < WINDOWS_NR; i++) {
+		plane = &ctx->planes[i];
+		plane->enabled = plane->resume;
+		plane->resume = false;
+	}
+}
+
+static void decon_apply(struct decon_context *ctx)
+{
+	struct exynos_drm_plane *plane;
+	int i;
+
+	decon_setup_trigger(ctx);
+
+	for (i = 0; i < WINDOWS_NR; i++) {
+		plane = &ctx->planes[i];
+		if (plane->enabled)
+			decon_win_commit(ctx->crtc, i);
+		else
+			decon_win_disable(ctx->crtc, i);
+	}
+
+	decon_commit(ctx->crtc);
+}
+
+static void decon_enable(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+	int ret;
+	int i;
+
+	if (!ctx->suspended)
+		return;
+
+	ctx->suspended = false;
+
+	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
+		ret = clk_prepare_enable(ctx->clks[i]);
+		if (ret < 0)
+			goto err;
+	}
+
+	set_bit(BIT_CLKS_ENABLED, &ctx->enabled);
+
+	decon_window_resume(ctx);
+	decon_apply(ctx);
+
+	return;
+err:
+	while (--i >= 0)
+		clk_disable_unprepare(ctx->clks[i]);
+
+	ctx->suspended = true;
+}
+
+static void decon_swreset(struct decon_context *ctx)
+{
+	unsigned int tries;
+
+	writel(0, ctx->addr + DECON_VIDCON0);
+	for (tries = 2000; tries; --tries) {
+		if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_STOP_STATUS)
+			break;
+		udelay(10);
+	}
+
+	WARN(tries == 0, "failed to disable DECON\n");
+
+	writel(VIDCON0_SWRESET, ctx->addr + DECON_VIDCON0);
+	for (tries = 2000; tries; --tries) {
+		if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_SWRESET)
+			break;
+		udelay(10);
+	}
+
+	WARN(tries == 0, "failed to software reset DECON\n");
+}
+
+static void decon_disable(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+	int i;
+
+	if (ctx->suspended)
+		return;
+
+	clear_bit(BIT_CLKS_ENABLED, &ctx->enabled);
+	decon_window_suspend(ctx);
+	decon_swreset(ctx);
+
+	for (i = ARRAY_SIZE(decon_clks_name) - 1; i >= 0; i--)
+		clk_disable_unprepare(ctx->clks[i]);
+
+	ctx->suspended = true;
+}
+
+void decon_te_irq_handler(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+	u32 val;
+
+	if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled))
+		return;
+
+	if (atomic_add_unless(&ctx->win_updated, -1, 0)) {
+		/* trigger */
+		val = readl(ctx->addr + DECON_TRIGCON);
+		val |= TRIGCON_SWTRIGCMD;
+		writel(val, ctx->addr + DECON_TRIGCON);
+	}
+
+	drm_handle_vblank(ctx->drm_dev, ctx->pipe);
+}
+
+static void decon_clear_channels(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+	int win, i, ret;
+	u32 val;
+
+	DRM_DEBUG_KMS("%s\n", __FILE__);
+
+	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
+		ret = clk_prepare_enable(ctx->clks[i]);
+		if (ret < 0)
+			goto err;
+	}
+
+	for (win = 0; win < WINDOWS_NR; win++) {
+		/* shadow update disable */
+		val = readl(ctx->addr + DECON_SHADOWCON);
+		val |= SHADOWCON_Wx_PROTECT(win);
+		writel(val, ctx->addr + DECON_SHADOWCON);
+
+		/* window disable */
+		val = readl(ctx->addr + DECON_WINCONx(win));
+		val &= ~WINCONx_ENWIN_F;
+		writel(val, ctx->addr + DECON_WINCONx(win));
+
+		/* shadow update enable */
+		val = readl(ctx->addr + DECON_SHADOWCON);
+		val &= ~SHADOWCON_Wx_PROTECT(win);
+		writel(val, ctx->addr + DECON_SHADOWCON);
+
+		/* standalone update */
+		val = readl(ctx->addr + DECON_UPDATE);
+		val |= STANDALONE_UPDATE_F;
+		writel(val, ctx->addr + DECON_UPDATE);
+	}
+	/* TODO: wait for possible vsync */
+	msleep(50);
+
+err:
+	while (--i >= 0)
+		clk_disable_unprepare(ctx->clks[i]);
+}
+
+static struct exynos_drm_crtc_ops decon_crtc_ops = {
+	.enable			= decon_enable,
+	.disable		= decon_disable,
+	.commit			= decon_commit,
+	.enable_vblank		= decon_enable_vblank,
+	.disable_vblank		= decon_disable_vblank,
+	.commit			= decon_commit,
+	.win_commit		= decon_win_commit,
+	.win_disable		= decon_win_disable,
+	.te_handler		= decon_te_irq_handler,
+	.clear_channels		= decon_clear_channels,
+};
+
+static int decon_bind(struct device *dev, struct device *master, void *data)
+{
+	struct decon_context *ctx = dev_get_drvdata(dev);
+	struct drm_device *drm_dev = data;
+	struct exynos_drm_private *priv = drm_dev->dev_private;
+	struct exynos_drm_plane *exynos_plane;
+	enum drm_plane_type type;
+	unsigned int zpos;
+	int ret;
+
+	ctx->drm_dev = drm_dev;
+	ctx->pipe = priv->pipe++;
+
+	for (zpos = 0; zpos < WINDOWS_NR; zpos++) {
+		type = (zpos == ctx->default_win) ? DRM_PLANE_TYPE_PRIMARY :
+							DRM_PLANE_TYPE_OVERLAY;
+		ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
+				1 << ctx->pipe, type, zpos);
+		if (ret)
+			return ret;
+	}
+
+	exynos_plane = &ctx->planes[ctx->default_win];
+	ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
+					ctx->pipe, EXYNOS_DISPLAY_TYPE_LCD,
+					&decon_crtc_ops, ctx);
+	if (IS_ERR(ctx->crtc)) {
+		ret = PTR_ERR(ctx->crtc);
+		goto err;
+	}
+
+	ret = drm_iommu_attach_device_if_possible(ctx->crtc, drm_dev, dev);
+	if (ret)
+		goto err;
+
+	return ret;
+err:
+	priv->pipe--;
+	return ret;
+}
+
+static void decon_unbind(struct device *dev, struct device *master, void *data)
+{
+	struct decon_context *ctx = dev_get_drvdata(dev);
+
+	decon_disable(ctx->crtc);
+
+	/* detach this sub driver from iommu mapping if supported. */
+	if (is_drm_iommu_supported(ctx->drm_dev))
+		drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
+}
+
+static const struct component_ops decon_component_ops = {
+	.bind	= decon_bind,
+	.unbind = decon_unbind,
+};
+
+static irqreturn_t decon_vsync_irq_handler(int irq, void *dev_id)
+{
+	struct decon_context *ctx = dev_id;
+	u32 val;
+
+	if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled))
+		goto out;
+
+	val = readl(ctx->addr + DECON_VIDINTCON1);
+	if (val & VIDINTCON1_INTFRMPEND) {
+		drm_handle_vblank(ctx->drm_dev, ctx->pipe);
+
+		/* clear */
+		writel(VIDINTCON1_INTFRMPEND, ctx->addr + DECON_VIDINTCON1);
+	}
+
+out:
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t decon_lcd_sys_irq_handler(int irq, void *dev_id)
+{
+	struct decon_context *ctx = dev_id;
+	u32 val;
+
+	if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled))
+		goto out;
+
+	val = readl(ctx->addr + DECON_VIDINTCON1);
+	if (val & VIDINTCON1_INTFRMDONEPEND) {
+		exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
+
+		/* clear */
+		writel(VIDINTCON1_INTFRMDONEPEND,
+				ctx->addr + DECON_VIDINTCON1);
+	}
+
+out:
+	return IRQ_HANDLED;
+}
+
+static int exynos5433_decon_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct decon_context *ctx;
+	struct resource *res;
+	int ret;
+	int i;
+
+	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->default_win = 0;
+	ctx->suspended = true;
+	ctx->dev = dev;
+	if (of_get_child_by_name(dev->of_node, "i80-if-timings"))
+		ctx->i80_if = true;
+
+	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
+		struct clk *clk;
+
+		clk = devm_clk_get(ctx->dev, decon_clks_name[i]);
+		if (IS_ERR(clk))
+			return PTR_ERR(clk);
+
+		ctx->clks[i] = clk;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "cannot find IO resource\n");
+		return -ENXIO;
+	}
+
+	ctx->addr = devm_ioremap_resource(dev, res);
+	if (IS_ERR(ctx->addr)) {
+		dev_err(dev, "ioremap failed\n");
+		return PTR_ERR(ctx->addr);
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
+			ctx->i80_if ? "lcd_sys" : "vsync");
+	if (!res) {
+		dev_err(dev, "cannot find IRQ resource\n");
+		return -ENXIO;
+	}
+
+	ret = devm_request_irq(dev, res->start, ctx->i80_if ?
+			decon_lcd_sys_irq_handler : decon_vsync_irq_handler, 0,
+			"drm_decon", ctx);
+	if (ret < 0) {
+		dev_err(dev, "lcd_sys irq request failed\n");
+		return ret;
+	}
+
+	ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
+				       EXYNOS_DISPLAY_TYPE_LCD);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, ctx);
+
+	ret = component_add(dev, &decon_component_ops);
+	if (ret < 0) {
+		exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int exynos5433_decon_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &decon_component_ops);
+	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
+
+	return 0;
+}
+
+static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
+	{ .compatible = "samsung,exynos5433-decon" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match);
+
+struct platform_driver exynos5433_decon_driver = {
+	.probe		= exynos5433_decon_probe,
+	.remove		= exynos5433_decon_remove,
+	.driver		= {
+		.name	= "exynos5433-decon",
+		.of_match_table = exynos5433_decon_driver_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 1ba34f1..769edfd 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -306,6 +306,7 @@ int exynos_drm_create_enc_conn(struct drm_device *dev,
 				struct exynos_drm_display *display);

 extern struct platform_driver fimd_driver;
+extern struct platform_driver exynos5433_decon_driver;
 extern struct platform_driver decon_driver;
 extern struct platform_driver dp_driver;
 extern struct platform_driver dsi_driver;
diff --git a/include/video/exynos5433_decon.h b/include/video/exynos5433_decon.h
new file mode 100644
index 0000000..3696575
--- /dev/null
+++ b/include/video/exynos5433_decon.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics Co.Ltd
+ *
+ * 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 Foundationr
+ */
+
+#ifndef EXYNOS_REGS_DECON_H
+#define EXYNOS_REGS_DECON_H
+
+/* Exynos543X DECON */
+#define DECON_VIDCON0			0x0000
+#define DECON_VIDOUTCON0		0x0010
+#define DECON_WINCONx(n)		(0x0020 + ((n) * 4))
+#define DECON_VIDOSDxH(n)		(0x0080 + ((n) * 4))
+#define DECON_SHADOWCON			0x00A0
+#define DECON_VIDOSDxA(n)		(0x00B0 + ((n) * 0x20))
+#define DECON_VIDOSDxB(n)		(0x00B4 + ((n) * 0x20))
+#define DECON_VIDOSDxC(n)		(0x00B8 + ((n) * 0x20))
+#define DECON_VIDOSDxD(n)		(0x00BC + ((n) * 0x20))
+#define DECON_VIDOSDxE(n)		(0x00C0 + ((n) * 0x20))
+#define DECON_VIDW0xADD0B0(n)		(0x0150 + ((n) * 0x10))
+#define DECON_VIDW0xADD0B1(n)		(0x0154 + ((n) * 0x10))
+#define DECON_VIDW0xADD0B2(n)		(0x0158 + ((n) * 0x10))
+#define DECON_VIDW0xADD1B0(n)		(0x01A0 + ((n) * 0x10))
+#define DECON_VIDW0xADD1B1(n)		(0x01A4 + ((n) * 0x10))
+#define DECON_VIDW0xADD1B2(n)		(0x01A8 + ((n) * 0x10))
+#define DECON_VIDW0xADD2(n)		(0x0200 + ((n) * 4))
+#define DECON_LOCALxSIZE(n)		(0x0214 + ((n) * 4))
+#define DECON_VIDINTCON0		0x0220
+#define DECON_VIDINTCON1		0x0224
+#define DECON_WxKEYCON0(n)		(0x0230 + ((n - 1) * 8))
+#define DECON_WxKEYCON1(n)		(0x0234 + ((n - 1) * 8))
+#define DECON_WxKEYALPHA(n)		(0x0250 + ((n - 1) * 4))
+#define DECON_WINxMAP(n)		(0x0270 + ((n) * 4))
+#define DECON_QOSLUT07_00		0x02C0
+#define DECON_QOSLUT15_08		0x02C4
+#define DECON_QOSCTRL			0x02C8
+#define DECON_BLENDERQx(n)		(0x0300 + ((n - 1) * 4))
+#define DECON_BLENDCON			0x0310
+#define DECON_OPE_VIDW0xADD0(n)		(0x0400 + ((n) * 4))
+#define DECON_OPE_VIDW0xADD1(n)		(0x0414 + ((n) * 4))
+#define DECON_FRAMEFIFO_REG7		0x051C
+#define DECON_FRAMEFIFO_REG8		0x0520
+#define DECON_FRAMEFIFO_STATUS		0x0524
+#define DECON_CMU			0x1404
+#define DECON_UPDATE			0x1410
+#define DECON_UPDATE_SCHEME		0x1438
+#define DECON_VIDCON1			0x2000
+#define DECON_VIDCON2			0x2004
+#define DECON_VIDCON3			0x2008
+#define DECON_VIDCON4			0x200C
+#define DECON_VIDTCON2			0x2028
+#define DECON_FRAME_SIZE		0x2038
+#define DECON_LINECNT_OP_THRESHOLD	0x203C
+#define DECON_TRIGCON			0x2040
+#define DECON_TRIGSKIP			0x2050
+#define DECON_CRCRDATA			0x20B0
+#define DECON_CRCCTRL			0x20B4
+
+/* Exynos5430 DECON */
+#define DECON_VIDTCON0			0x2020
+#define DECON_VIDTCON1			0x2024
+
+/* Exynos5433 DECON */
+#define DECON_VIDTCON00			0x2010
+#define DECON_VIDTCON01			0x2014
+#define DECON_VIDTCON10			0x2018
+#define DECON_VIDTCON11			0x201C
+
+/* Exynos543X DECON Internal */
+#define DECON_W013DSTREOCON		0x0320
+#define DECON_W233DSTREOCON		0x0324
+#define DECON_FRAMEFIFO_REG0		0x0500
+#define DECON_ENHANCER_CTRL		0x2100
+
+/* Exynos543X DECON TV */
+#define DECON_VCLKCON0			0x0014
+#define DECON_VIDINTCON2		0x0228
+#define DECON_VIDINTCON3		0x022C
+
+/* VIDCON0 */
+#define VIDCON0_SWRESET			(1 << 28)
+#define VIDCON0_STOP_STATUS		(1 << 2)
+#define VIDCON0_ENVID			(1 << 1)
+#define VIDCON0_ENVID_F			(1 << 0)
+
+/* VIDOUTCON0 */
+#define VIDOUT_LCD_ON			(1 << 24)
+#define VIDOUT_IF_F_MASK		(0x3 << 20)
+#define VIDOUT_RGB_IF			(0x0 << 20)
+#define VIDOUT_COMMAND_IF		(0x2 << 20)
+
+/* WINCONx */
+#define WINCONx_HAWSWP_F		(1 << 16)
+#define WINCONx_WSWP_F			(1 << 15)
+#define WINCONx_BURSTLEN_MASK		(0x3 << 10)
+#define WINCONx_BURSTLEN_16WORD		(0x0 << 10)
+#define WINCONx_BURSTLEN_8WORD		(0x1 << 10)
+#define WINCONx_BURSTLEN_4WORD		(0x2 << 10)
+#define WINCONx_BLD_PIX_F		(1 << 6)
+#define WINCONx_BPPMODE_MASK		(0xf << 2)
+#define WINCONx_BPPMODE_16BPP_565	(0x5 << 2)
+#define WINCONx_BPPMODE_16BPP_A1555	(0x6 << 2)
+#define WINCONx_BPPMODE_16BPP_I1555	(0x7 << 2)
+#define WINCONx_BPPMODE_24BPP_888	(0xb << 2)
+#define WINCONx_BPPMODE_24BPP_A1887	(0xc << 2)
+#define WINCONx_BPPMODE_25BPP_A1888	(0xd << 2)
+#define WINCONx_BPPMODE_32BPP_A8888	(0xd << 2)
+#define WINCONx_BPPMODE_16BPP_A4444	(0xe << 2)
+#define WINCONx_ALPHA_SEL_F		(1 << 1)
+#define WINCONx_ENWIN_F			(1 << 0)
+
+/* SHADOWCON */
+#define SHADOWCON_Wx_PROTECT(n)		(1 << (10 + (n)))
+
+/* VIDOSDxD */
+#define VIDOSD_Wx_ALPHA_R_F(n)		(((n) & 0xff) << 16)
+#define VIDOSD_Wx_ALPHA_G_F(n)		(((n) & 0xff) << 8)
+#define VIDOSD_Wx_ALPHA_B_F(n)		(((n) & 0xff) << 0)
+
+/* VIDINTCON0 */
+#define VIDINTCON0_FRAMEDONE		(1 << 17)
+#define VIDINTCON0_INTFRMEN		(1 << 12)
+#define VIDINTCON0_INTEN		(1 << 0)
+
+/* VIDINTCON1 */
+#define VIDINTCON1_INTFRMDONEPEND	(1 << 2)
+#define VIDINTCON1_INTFRMPEND		(1 << 1)
+#define VIDINTCON1_INTFIFOPEND		(1 << 0)
+
+/* DECON_CMU */
+#define CMU_CLKGAGE_MODE_SFR_F		(1 << 1)
+#define CMU_CLKGAGE_MODE_MEM_F		(1 << 0)
+
+/* DECON_UPDATE */
+#define STANDALONE_UPDATE_F		(1 << 0)
+
+/* DECON_VIDTCON00 */
+#define VIDTCON00_VBPD_F(x)		(((x) & 0xfff) << 16)
+#define VIDTCON00_VFPD_F(x)		((x) & 0xfff)
+
+/* DECON_VIDTCON01 */
+#define VIDTCON01_VSPW_F(x)		(((x) & 0xfff) << 16)
+
+/* DECON_VIDTCON10 */
+#define VIDTCON10_HBPD_F(x)		(((x) & 0xfff) << 16)
+#define VIDTCON10_HFPD_F(x)		((x) & 0xfff)
+
+/* DECON_VIDTCON11 */
+#define VIDTCON11_HSPW_F(x)		(((x) & 0xfff) << 16)
+
+/* DECON_VIDTCON2 */
+#define VIDTCON2_LINEVAL(x)		(((x) & 0xfff) << 16)
+#define VIDTCON2_HOZVAL(x)		((x) & 0xfff)
+
+/* TRIGCON */
+#define TRIGCON_TRIGEN_PER_F		(1 << 31)
+#define TRIGCON_TRIGEN_F		(1 << 30)
+#define TRIGCON_TE_AUTO_MASK		(1 << 29)
+#define TRIGCON_SWTRIGCMD		(1 << 1)
+#define TRIGCON_SWTRIGEN		(1 << 0)
+
+#endif /* EXYNOS_REGS_DECON_H */
--
1.9.1

--
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 related	[flat|nested] 50+ messages in thread

* [PATCH v6 06/15] of: add helper for getting endpoint node of specific identifiers
  2015-06-12 12:58 [PATCH v6 00/15] Add drivers for Exynos5433 display Hyungwon Hwang
                   ` (2 preceding siblings ...)
  2015-06-12 12:58 ` [PATCH v6 04/15] drm/exynos: fix the input prompt of Exynos7 DECON Hyungwon Hwang
@ 2015-06-12 12:59 ` Hyungwon Hwang
  2015-06-23  0:19   ` Dave Airlie
  2015-06-12 12:59 ` [PATCH v6 07/15] drm/exynos: mic: add MIC driver Hyungwon Hwang
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel, devicetree; +Cc: sw0312.kim

When there are multiple ports or multiple endpoints in a port, they have to be
distinguished by the value of reg property. It is common. The drivers can get
the specific endpoint in the specific port via this function. Now the drivers
have to implement this code in themselves or have to force the order of dt nodes
to get the right node.

Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
Acked-by: Rob Herring <robh+dt@kernel.org>
---
Changes before:
- Refer https://patchwork.kernel.org/patch/6191751/
Changes for v6:
- None
 drivers/of/base.c        | 33 +++++++++++++++++++++++++++++++++
 include/linux/of_graph.h |  8 ++++++++
 2 files changed, 41 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 99764db..f3b583b 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2233,6 +2233,39 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
 EXPORT_SYMBOL(of_graph_get_next_endpoint);

 /**
+ * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers
+ * @parent: pointer to the parent device node
+ * @port_reg: identifier (value of reg property) of the parent port node
+ * @reg: identifier (value of reg property) of the endpoint node
+ *
+ * Return: An 'endpoint' node pointer which is identified by reg and at the same
+ * is the child of a port node identified by port_reg. reg and port_reg are
+ * ignored when they are -1.
+ */
+struct device_node *of_graph_get_endpoint_by_regs(
+	const struct device_node *parent, int port_reg, int reg)
+{
+	struct of_endpoint endpoint;
+	struct device_node *node, *prev_node = NULL;
+
+	while (1) {
+		node = of_graph_get_next_endpoint(parent, prev_node);
+		of_node_put(prev_node);
+		if (!node)
+			break;
+
+		of_graph_parse_endpoint(node, &endpoint);
+		if (((port_reg == -1) || (endpoint.port == port_reg)) &&
+			((reg == -1) || (endpoint.id == reg)))
+			return node;
+
+		prev_node = node;
+	}
+
+	return NULL;
+}
+
+/**
  * of_graph_get_remote_port_parent() - get remote port's parent node
  * @node: pointer to a local endpoint device_node
  *
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index 7bc92e0..1c1d5b9 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -45,6 +45,8 @@ int of_graph_parse_endpoint(const struct device_node *node,
 struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
 struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
 					struct device_node *previous);
+struct device_node *of_graph_get_endpoint_by_regs(
+		const struct device_node *parent, int port_reg, int reg);
 struct device_node *of_graph_get_remote_port_parent(
 					const struct device_node *node);
 struct device_node *of_graph_get_remote_port(const struct device_node *node);
@@ -69,6 +71,12 @@ static inline struct device_node *of_graph_get_next_endpoint(
 	return NULL;
 }

+struct device_node *of_graph_get_endpoint_by_regs(
+		const struct device_node *parent, int port_reg, int reg)
+{
+	return NULL;
+}
+
 static inline struct device_node *of_graph_get_remote_port_parent(
 					const struct device_node *node)
 {
--
1.9.1

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

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

* [PATCH v6 07/15] drm/exynos: mic: add MIC driver
  2015-06-12 12:58 [PATCH v6 00/15] Add drivers for Exynos5433 display Hyungwon Hwang
                   ` (3 preceding siblings ...)
  2015-06-12 12:59 ` [PATCH v6 06/15] of: add helper for getting endpoint node of specific identifiers Hyungwon Hwang
@ 2015-06-12 12:59 ` Hyungwon Hwang
  2015-06-12 12:59 ` [PATCH v6 12/15] drm/exynos: dsi: add support for Exynos5433 Hyungwon Hwang
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel, devicetree; +Cc: sw0312.kim

MIC(Mobile image compressor) is newly added IP in Exynos5433. MIC
resides between decon and mipi dsim, and compresses frame data by 50%.
With dsi, not display port, to send frame data to the panel, the
bandwidth is not enough. That is why this compressor is introduced.

Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
---
Changes before:
- Refer https://patchwork.kernel.org/patch/6191711/
Changes for v6:
- None
 .../devicetree/bindings/video/exynos-mic.txt       |  51 +++
 drivers/gpu/drm/exynos/Kconfig                     |   6 +
 drivers/gpu/drm/exynos/Makefile                    |   1 +
 drivers/gpu/drm/exynos/exynos_drm_drv.c            |   3 +
 drivers/gpu/drm/exynos/exynos_drm_drv.h            |   1 +
 drivers/gpu/drm/exynos/exynos_drm_mic.c            | 490 +++++++++++++++++++++
 6 files changed, 552 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/exynos-mic.txt
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_mic.c

diff --git a/Documentation/devicetree/bindings/video/exynos-mic.txt b/Documentation/devicetree/bindings/video/exynos-mic.txt
new file mode 100644
index 0000000..0fba2ee
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos-mic.txt
@@ -0,0 +1,51 @@
+Device-Tree bindings for Samsung Exynos SoC mobile image compressor (MIC)
+
+MIC (mobile image compressor) resides between decon and mipi dsi. Mipi dsi is
+not capable to transfer high resoltuion frame data as decon can send. MIC
+solves this problem by compressing the frame data by 1/2 before it is
+transferred through mipi dsi. The compressed frame data must be uncompressed in
+the panel PCB.
+
+Required properties:
+- compatible: value should be "samsung,exynos5433-mic".
+- reg: physical base address and length of the MIC registers set and system
+       register of mic.
+- clocks: must include clock specifiers corresponding to entries in the
+	  clock-names property.
+- clock-names: list of clock names sorted in the same order as the clocks
+	       property. Must contain "pclk_mic0", "sclk_rgb_vclk_to_mic0".
+- samsung,disp-syscon: the reference node for syscon for DISP block.
+- ports: contains a port which is connected to decon node and dsi node.
+	 address-cells and size-cells must 1 and 0, respectively.
+- port: contains an endpoint node which is connected to the endpoint in the
+	decon node or dsi node. The reg value must be 0 and 1 respectively.
+
+Example:
+SoC specific DT entry:
+mic: mic@13930000 {
+	compatible = "samsung,exynos5433-mic";
+	reg = <0x13930000 0x48>;
+	clocks = <&cmu_disp CLK_PCLK_MIC0>,
+	       <&cmu_disp CLK_SCLK_RGB_VCLK_TO_MIC0>;
+	clock-names = "pclk_mic0", "sclk_rgb_vclk_to_mic0";
+	samsung,disp-syscon = <&syscon_disp>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			mic_to_decon: endpoint {
+				remote-endpoint = <&decon_to_mic>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			mic_to_dsi: endpoint {
+				remote-endpoint = <&dsi_to_mic>;
+			};
+		};
+	};
+};
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 51a4eb5..12e4e62 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -103,3 +103,9 @@ config DRM_EXYNOS_GSC
 	depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && !ARCH_MULTIPLATFORM
 	help
 	  Choose this option if you want to use Exynos GSC for DRM.
+
+config DRM_EXYNOS_MIC
+	bool "Exynos DRM MIC"
+	depends on (DRM_EXYNOS && DRM_EXYNOS5433_DECON)
+	help
+	  Choose this option if you want to use Exynos MIC for DRM.
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index fbd084d..7de0b10 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -22,5 +22,6 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_IPP)	+= exynos_drm_ipp.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMC)	+= exynos_drm_fimc.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_ROTATOR)	+= exynos_drm_rotator.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_GSC)	+= exynos_drm_gsc.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_MIC)     += exynos_drm_mic.o

 obj-$(CONFIG_DRM_EXYNOS)		+= exynosdrm.o
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 591bdec..c14b44a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -357,6 +357,9 @@ static struct platform_driver *const exynos_drm_kms_drivers[] = {
 #ifdef CONFIG_DRM_EXYNOS7_DECON
 	&decon_driver,
 #endif
+#ifdef CONFIG_DRM_EXYNOS_MIC
+	&mic_driver,
+#endif
 #ifdef CONFIG_DRM_EXYNOS_DP
 	&dp_driver,
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 769edfd..b3dbdd4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -319,4 +319,5 @@ extern struct platform_driver fimc_driver;
 extern struct platform_driver rotator_driver;
 extern struct platform_driver gsc_driver;
 extern struct platform_driver ipp_driver;
+extern struct platform_driver mic_driver;
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
new file mode 100644
index 0000000..8994eab
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics Co.Ltd
+ * Authors:
+ *	Hyungwon Hwang <human.hwang@samsung.com>
+ *
+ * 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 Foundationr
+ */
+
+#include <linux/platform_device.h>
+#include <video/of_videomode.h>
+#include <linux/of_address.h>
+#include <video/videomode.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/clk.h>
+#include <drm/drmP.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+/* Sysreg registers for MIC */
+#define DSD_CFG_MUX	0x1004
+#define MIC0_RGB_MUX	(1 << 0)
+#define MIC0_I80_MUX	(1 << 1)
+#define MIC0_ON_MUX	(1 << 5)
+
+/* MIC registers */
+#define MIC_OP				0x0
+#define MIC_IP_VER			0x0004
+#define MIC_V_TIMING_0			0x0008
+#define MIC_V_TIMING_1			0x000C
+#define MIC_IMG_SIZE			0x0010
+#define MIC_INPUT_TIMING_0		0x0014
+#define MIC_INPUT_TIMING_1		0x0018
+#define MIC_2D_OUTPUT_TIMING_0		0x001C
+#define MIC_2D_OUTPUT_TIMING_1		0x0020
+#define MIC_2D_OUTPUT_TIMING_2		0x0024
+#define MIC_3D_OUTPUT_TIMING_0		0x0028
+#define MIC_3D_OUTPUT_TIMING_1		0x002C
+#define MIC_3D_OUTPUT_TIMING_2		0x0030
+#define MIC_CORE_PARA_0			0x0034
+#define MIC_CORE_PARA_1			0x0038
+#define MIC_CTC_CTRL			0x0040
+#define MIC_RD_DATA			0x0044
+
+#define MIC_UPD_REG			(1 << 31)
+#define MIC_ON_REG			(1 << 30)
+#define MIC_TD_ON_REG			(1 << 29)
+#define MIC_BS_CHG_OUT			(1 << 16)
+#define MIC_VIDEO_TYPE(x)		(((x) & 0xf) << 12)
+#define MIC_PSR_EN			(1 << 5)
+#define MIC_SW_RST			(1 << 4)
+#define MIC_ALL_RST			(1 << 3)
+#define MIC_CORE_VER_CONTROL		(1 << 2)
+#define MIC_MODE_SEL_COMMAND_MODE	(1 << 1)
+#define MIC_MODE_SEL_MASK		(1 << 1)
+#define MIC_CORE_EN			(1 << 0)
+
+#define MIC_V_PULSE_WIDTH(x)		(((x) & 0x3fff) << 16)
+#define MIC_V_PERIOD_LINE(x)		((x) & 0x3fff)
+
+#define MIC_VBP_SIZE(x)			(((x) & 0x3fff) << 16)
+#define MIC_VFP_SIZE(x)			((x) & 0x3fff)
+
+#define MIC_IMG_V_SIZE(x)		(((x) & 0x3fff) << 16)
+#define MIC_IMG_H_SIZE(x)		((x) & 0x3fff)
+
+#define MIC_H_PULSE_WIDTH_IN(x)		(((x) & 0x3fff) << 16)
+#define MIC_H_PERIOD_PIXEL_IN(x)	((x) & 0x3fff)
+
+#define MIC_HBP_SIZE_IN(x)		(((x) & 0x3fff) << 16)
+#define MIC_HFP_SIZE_IN(x)		((x) & 0x3fff)
+
+#define MIC_H_PULSE_WIDTH_2D(x)		(((x) & 0x3fff) << 16)
+#define MIC_H_PERIOD_PIXEL_2D(x)	((x) & 0x3fff)
+
+#define MIC_HBP_SIZE_2D(x)		(((x) & 0x3fff) << 16)
+#define MIC_HFP_SIZE_2D(x)		((x) & 0x3fff)
+
+#define MIC_BS_SIZE_2D(x)	((x) & 0x3fff)
+
+enum {
+	ENDPOINT_DECON_NODE,
+	ENDPOINT_DSI_NODE,
+	NUM_ENDPOINTS
+};
+
+static char *clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" };
+#define NUM_CLKS		ARRAY_SIZE(clk_names)
+static DEFINE_MUTEX(mic_mutex);
+
+struct exynos_mic {
+	struct device *dev;
+	void __iomem *reg;
+	struct regmap *sysreg;
+	struct clk *clks[NUM_CLKS];
+
+	bool i80_mode;
+	struct videomode vm;
+	struct drm_encoder *encoder;
+	struct drm_bridge bridge;
+
+	bool enabled;
+};
+
+static void mic_set_path(struct exynos_mic *mic, bool enable)
+{
+	int ret;
+	unsigned int val;
+
+	ret = regmap_read(mic->sysreg, DSD_CFG_MUX, &val);
+	if (ret) {
+		DRM_ERROR("mic: Failed to read system register\n");
+		return;
+	}
+
+	if (enable) {
+		if (mic->i80_mode)
+			val |= MIC0_I80_MUX;
+		else
+			val |= MIC0_RGB_MUX;
+
+		val |=  MIC0_ON_MUX;
+	} else
+		val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX);
+
+	regmap_write(mic->sysreg, DSD_CFG_MUX, val);
+	if (ret)
+		DRM_ERROR("mic: Failed to read system register\n");
+}
+
+static int mic_sw_reset(struct exynos_mic *mic)
+{
+	unsigned int retry = 100;
+	int ret;
+
+	writel(MIC_SW_RST, mic->reg + MIC_OP);
+
+	while (retry-- > 0) {
+		ret = readl(mic->reg + MIC_OP);
+		if (!(ret & MIC_SW_RST))
+			return 0;
+
+		udelay(10);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static void mic_set_porch_timing(struct exynos_mic *mic)
+{
+	struct videomode vm = mic->vm;
+	u32 reg;
+
+	reg = MIC_V_PULSE_WIDTH(vm.vsync_len) +
+		MIC_V_PERIOD_LINE(vm.vsync_len + vm.vactive +
+				vm.vback_porch + vm.vfront_porch);
+	writel(reg, mic->reg + MIC_V_TIMING_0);
+
+	reg = MIC_VBP_SIZE(vm.vback_porch) +
+		MIC_VFP_SIZE(vm.vfront_porch);
+	writel(reg, mic->reg + MIC_V_TIMING_1);
+
+	reg = MIC_V_PULSE_WIDTH(vm.hsync_len) +
+		MIC_V_PERIOD_LINE(vm.hsync_len + vm.hactive +
+				vm.hback_porch + vm.hfront_porch);
+	writel(reg, mic->reg + MIC_INPUT_TIMING_0);
+
+	reg = MIC_VBP_SIZE(vm.hback_porch) +
+		MIC_VFP_SIZE(vm.hfront_porch);
+	writel(reg, mic->reg + MIC_INPUT_TIMING_1);
+}
+
+static void mic_set_img_size(struct exynos_mic *mic)
+{
+	struct videomode *vm = &mic->vm;
+	u32 reg;
+
+	reg = MIC_IMG_H_SIZE(vm->hactive) +
+		MIC_IMG_V_SIZE(vm->vactive);
+
+	writel(reg, mic->reg + MIC_IMG_SIZE);
+}
+
+static void mic_set_output_timing(struct exynos_mic *mic)
+{
+	struct videomode vm = mic->vm;
+	u32 reg, bs_size_2d;
+
+	DRM_DEBUG("w: %u, h: %u\n", vm.hactive, vm.vactive);
+	bs_size_2d = ((vm.hactive >> 2) << 1) + (vm.vactive % 4);
+	reg = MIC_BS_SIZE_2D(bs_size_2d);
+	writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_2);
+
+	if (!mic->i80_mode) {
+		reg = MIC_H_PULSE_WIDTH_2D(vm.hsync_len) +
+			MIC_H_PERIOD_PIXEL_2D(vm.hsync_len + bs_size_2d +
+					vm.hback_porch + vm.hfront_porch);
+		writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_0);
+
+		reg = MIC_HBP_SIZE_2D(vm.hback_porch) +
+			MIC_H_PERIOD_PIXEL_2D(vm.hfront_porch);
+		writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_1);
+	}
+}
+
+static void mic_set_reg_on(struct exynos_mic *mic, bool enable)
+{
+	u32 reg = readl(mic->reg + MIC_OP);
+
+	if (enable) {
+		reg &= ~(MIC_MODE_SEL_MASK | MIC_CORE_VER_CONTROL | MIC_PSR_EN);
+		reg |= (MIC_CORE_EN | MIC_BS_CHG_OUT | MIC_ON_REG);
+
+		reg  &= ~MIC_MODE_SEL_COMMAND_MODE;
+		if (mic->i80_mode)
+			reg |= MIC_MODE_SEL_COMMAND_MODE;
+	} else {
+		reg &= ~MIC_CORE_EN;
+	}
+
+	reg |= MIC_UPD_REG;
+	writel(reg, mic->reg + MIC_OP);
+}
+
+static struct device_node *get_remote_node(struct device_node *from, int reg)
+{
+	struct device_node *endpoint = NULL, *remote_node = NULL;
+
+	endpoint = of_graph_get_endpoint_by_regs(from, reg, -1);
+	if (!endpoint) {
+		DRM_ERROR("mic: Failed to find remote port from %s",
+				from->full_name);
+		goto exit;
+	}
+
+	remote_node = of_graph_get_remote_port_parent(endpoint);
+	if (!remote_node) {
+		DRM_ERROR("mic: Failed to find remote port parent from %s",
+							from->full_name);
+		goto exit;
+	}
+
+exit:
+	of_node_put(endpoint);
+	return remote_node;
+}
+
+static int parse_dt(struct exynos_mic *mic)
+{
+	int ret = 0, i, j;
+	struct device_node *remote_node;
+	struct device_node *nodes[3];
+
+	/*
+	 * The order of endpoints does matter.
+	 * The first node must be for decon and the second one must be for dsi.
+	 */
+	for (i = 0, j = 0; i < NUM_ENDPOINTS; i++) {
+		remote_node = get_remote_node(mic->dev->of_node, i);
+		if (!remote_node) {
+			ret = -EPIPE;
+			goto exit;
+		}
+		nodes[j++] = remote_node;
+
+		switch (i) {
+		case ENDPOINT_DECON_NODE:
+			/* decon node */
+			if (of_get_child_by_name(remote_node,
+						"i80-if-timings"))
+				mic->i80_mode = 1;
+
+			break;
+		case ENDPOINT_DSI_NODE:
+			/* panel node */
+			remote_node = get_remote_node(remote_node, 1);
+			if (!remote_node) {
+				ret = -EPIPE;
+				goto exit;
+			}
+			nodes[j++] = remote_node;
+
+			ret = of_get_videomode(remote_node,
+							&mic->vm, 0);
+			if (ret) {
+				DRM_ERROR("mic: failed to get videomode");
+				goto exit;
+			}
+
+			break;
+		default:
+			DRM_ERROR("mic: Unknown endpoint from MIC");
+			break;
+		}
+	}
+
+exit:
+	while (--j > -1)
+		of_node_put(nodes[j]);
+
+	return ret;
+}
+
+void mic_disable(struct drm_bridge *bridge) { }
+
+void mic_post_disable(struct drm_bridge *bridge)
+{
+	struct exynos_mic *mic = bridge->driver_private;
+	int i;
+
+	mutex_lock(&mic_mutex);
+	if (!mic->enabled)
+		goto already_disabled;
+
+	mic_set_path(mic, 0);
+
+	for (i = NUM_CLKS - 1; i > -1; i--)
+		clk_disable_unprepare(mic->clks[i]);
+
+	mic->enabled = 0;
+
+already_disabled:
+	mutex_unlock(&mic_mutex);
+}
+
+void mic_pre_enable(struct drm_bridge *bridge)
+{
+	struct exynos_mic *mic = bridge->driver_private;
+	int ret, i;
+
+	mutex_lock(&mic_mutex);
+	if (mic->enabled)
+		goto already_enabled;
+
+	for (i = 0; i < NUM_CLKS; i++) {
+		ret = clk_prepare_enable(mic->clks[i]);
+		if (ret < 0) {
+			DRM_ERROR("Failed to enable clock (%s)\n",
+							clk_names[i]);
+			goto turn_off_clks;
+		}
+	}
+
+	mic_set_path(mic, 1);
+
+	ret = mic_sw_reset(mic);
+	if (ret) {
+		DRM_ERROR("Failed to reset\n");
+		goto turn_off_clks;
+	}
+
+	if (!mic->i80_mode)
+		mic_set_porch_timing(mic);
+	mic_set_img_size(mic);
+	mic_set_output_timing(mic);
+	mic_set_reg_on(mic, 1);
+	mic->enabled = 1;
+	mutex_unlock(&mic_mutex);
+
+	return;
+
+turn_off_clks:
+	while (--i > -1)
+		clk_disable_unprepare(mic->clks[i]);
+already_enabled:
+	mutex_unlock(&mic_mutex);
+}
+
+void mic_enable(struct drm_bridge *bridge) { }
+
+void mic_destroy(struct drm_bridge *bridge)
+{
+	struct exynos_mic *mic = bridge->driver_private;
+	int i;
+
+	mutex_lock(&mic_mutex);
+	if (!mic->enabled)
+		goto already_disabled;
+
+	for (i = NUM_CLKS - 1; i > -1; i--)
+		clk_disable_unprepare(mic->clks[i]);
+
+already_disabled:
+	mutex_unlock(&mic_mutex);
+}
+
+struct drm_bridge_funcs mic_bridge_funcs = {
+	.disable = mic_disable,
+	.post_disable = mic_post_disable,
+	.pre_enable = mic_pre_enable,
+	.enable = mic_enable,
+};
+
+int exynos_mic_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct exynos_mic *mic;
+	struct resource res;
+	int ret, i;
+
+	mic = devm_kzalloc(dev, sizeof(*mic), GFP_KERNEL);
+	if (!mic) {
+		DRM_ERROR("mic: Failed to allocate memory for MIC object\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	mic->dev = dev;
+
+	ret = parse_dt(mic);
+	if (ret)
+		goto err;
+
+	ret = of_address_to_resource(dev->of_node, 0, &res);
+	if (ret) {
+		DRM_ERROR("mic: Failed to get mem region for MIC\n");
+		goto err;
+	}
+	mic->reg = devm_ioremap(dev, res.start, resource_size(&res));
+	if (!mic->reg) {
+		DRM_ERROR("mic: Failed to remap for MIC\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	mic->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
+							"samsung,disp-syscon");
+	if (IS_ERR(mic->sysreg)) {
+		DRM_ERROR("mic: Failed to get system register.\n");
+		goto err;
+	}
+
+	mic->bridge.funcs = &mic_bridge_funcs;
+	mic->bridge.of_node = dev->of_node;
+	mic->bridge.driver_private = mic;
+	ret = drm_bridge_add(&mic->bridge);
+	if (ret) {
+		DRM_ERROR("mic: Failed to add MIC to the global bridge list\n");
+		goto err;
+	}
+
+	for (i = 0; i < NUM_CLKS; i++) {
+		mic->clks[i] = of_clk_get_by_name(dev->of_node, clk_names[i]);
+		if (IS_ERR(mic->clks[i])) {
+			DRM_ERROR("mic: Failed to get clock (%s)\n",
+								clk_names[i]);
+			ret = PTR_ERR(mic->clks[i]);
+			goto err;
+		}
+	}
+
+	DRM_DEBUG_KMS("MIC has been probed\n");
+
+err:
+	return ret;
+}
+
+static int exynos_mic_remove(struct platform_device *pdev)
+{
+	struct exynos_mic *mic = platform_get_drvdata(pdev);
+	int i;
+
+	drm_bridge_remove(&mic->bridge);
+
+	for (i = NUM_CLKS - 1; i > -1; i--)
+		clk_put(mic->clks[i]);
+
+	return 0;
+}
+
+static const struct of_device_id exynos_mic_of_match[] = {
+	{ .compatible = "samsung,exynos5433-mic" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, exynos_mic_of_match);
+
+struct platform_driver mic_driver = {
+	.probe		= exynos_mic_probe,
+	.remove		= exynos_mic_remove,
+	.driver		= {
+		.name	= "exynos-mic",
+		.owner	= THIS_MODULE,
+		.of_match_table = exynos_mic_of_match,
+	},
+};
--
1.9.1

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

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

* [PATCH v6 08/15] drm/exynos: dsi: rename pll_clk to sclk_clk
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
  2015-06-12 12:58   ` [PATCH v6 01/15] drm/exynos: remove the dependency of DP driver for ARCH_EXYNOS Hyungwon Hwang
  2015-06-12 12:59   ` [PATCH v6 05/15] drm/exynos: add Exynos5433 decon driver Hyungwon Hwang
@ 2015-06-12 12:59   ` Hyungwon Hwang
  2015-06-22 12:25     ` Inki Dae
  2015-06-12 12:59   ` [PATCH v6 09/15] drm/exynos: dsi: add macros for register access Hyungwon Hwang
                     ` (7 subsequent siblings)
  10 siblings, 1 reply; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: inki.dae-Sze3O3UU22JBDgjK7y7TUQ, daniel-rLtY4a/8tF1rovVCs/uTlw,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ, Hyungwon Hwang

This patch renames pll_clk to sclk_clk. The clock referenced by pll_clk
is actually not the pll input clock for dsi. The pll input clock comes
from the board's oscillator directly. But for the backward
compatibility, the old clock name "pll_clk" is also OK.

Signed-off-by: Hyungwon Hwang <human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
Changes before:
- Refer https://patchwork.kernel.org/patch/6191721
Changes for v6:
- Merged 2 patches
   drm/exynos: dsi: add the backward compatibility for the renamed clock
   drm/exynos: dsi: rename pll_clk to sclk_clk

 .../devicetree/bindings/video/exynos_dsim.txt      |  7 +++--
 drivers/gpu/drm/exynos/exynos_drm_dsi.c            | 36 ++++++++++------------
 2 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/Documentation/devicetree/bindings/video/exynos_dsim.txt b/Documentation/devicetree/bindings/video/exynos_dsim.txt
index 802aa7e..44659dd 100644
--- a/Documentation/devicetree/bindings/video/exynos_dsim.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dsim.txt
@@ -10,13 +10,14 @@ Required properties:
   - interrupts: should contain DSI interrupt
   - clocks: list of clock specifiers, must contain an entry for each required
     entry in clock-names
-  - clock-names: should include "bus_clk"and "pll_clk" entries
+  - clock-names: should include "bus_clk"and "sclk_mipi" entries
+		 the use of "pll_clk" is deprecated
   - phys: list of phy specifiers, must contain an entry for each required
     entry in phy-names
   - phy-names: should include "dsim" entry
   - vddcore-supply: MIPI DSIM Core voltage supply (e.g. 1.1V)
   - vddio-supply: MIPI DSIM I/O and PLL voltage supply (e.g. 1.8V)
-  - samsung,pll-clock-frequency: specifies frequency of the "pll_clk" clock
+  - samsung,pll-clock-frequency: specifies frequency of the oscillator clock
   - #address-cells, #size-cells: should be set respectively to <1> and <0>
     according to DSI host bindings (see MIPI DSI bindings [1])

@@ -48,7 +49,7 @@ Example:
 		reg = <0x11C80000 0x10000>;
 		interrupts = <0 79 0>;
 		clocks = <&clock 286>, <&clock 143>;
-		clock-names = "bus_clk", "pll_clk";
+		clock-names = "bus_clk", "sclk_mipi";
 		phys = <&mipi_phy 1>;
 		phy-names = "dsim";
 		vddcore-supply = <&vusb_reg>;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index c1999ad..a3bfac2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -235,6 +235,8 @@
 #define DSI_XFER_TIMEOUT_MS		100
 #define DSI_RX_FIFO_EMPTY		0x30800002

+#define OLD_SCLK_MIPI_CLK_NAME "pll_clk"
+
 enum exynos_dsi_transfer_type {
 	EXYNOS_DSI_TX,
 	EXYNOS_DSI_RX,
@@ -279,7 +281,7 @@ struct exynos_dsi {

 	void __iomem *reg_base;
 	struct phy *phy;
-	struct clk *pll_clk;
+	struct clk *sclk_clk;
 	struct clk *bus_clk;
 	struct regulator_bulk_data supplies[2];
 	int irq;
@@ -433,16 +435,7 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
 	u16 m;
 	u32 reg;

-	clk_set_rate(dsi->pll_clk, dsi->pll_clk_rate);
-
-	fin = clk_get_rate(dsi->pll_clk);
-	if (!fin) {
-		dev_err(dsi->dev, "failed to get PLL clock frequency\n");
-		return 0;
-	}
-
-	dev_dbg(dsi->dev, "PLL input frequency: %lu\n", fin);
-
+	fin = dsi->pll_clk_rate;
 	fout = exynos_dsi_pll_find_pms(dsi, fin, freq, &p, &m, &s);
 	if (!fout) {
 		dev_err(dsi->dev,
@@ -1313,10 +1306,10 @@ static int exynos_dsi_poweron(struct exynos_dsi *dsi)
 		goto err_bus_clk;
 	}

-	ret = clk_prepare_enable(dsi->pll_clk);
+	ret = clk_prepare_enable(dsi->sclk_clk);
 	if (ret < 0) {
 		dev_err(dsi->dev, "cannot enable pll clock %d\n", ret);
-		goto err_pll_clk;
+		goto err_sclk_clk;
 	}

 	ret = phy_power_on(dsi->phy);
@@ -1328,8 +1321,8 @@ static int exynos_dsi_poweron(struct exynos_dsi *dsi)
 	return 0;

 err_phy:
-	clk_disable_unprepare(dsi->pll_clk);
-err_pll_clk:
+	clk_disable_unprepare(dsi->sclk_clk);
+err_sclk_clk:
 	clk_disable_unprepare(dsi->bus_clk);
 err_bus_clk:
 	regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
@@ -1355,7 +1348,7 @@ static void exynos_dsi_poweroff(struct exynos_dsi *dsi)

 	phy_power_off(dsi->phy);

-	clk_disable_unprepare(dsi->pll_clk);
+	clk_disable_unprepare(dsi->sclk_clk);
 	clk_disable_unprepare(dsi->bus_clk);

 	ret = regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
@@ -1722,10 +1715,13 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 		return -EPROBE_DEFER;
 	}

-	dsi->pll_clk = devm_clk_get(dev, "pll_clk");
-	if (IS_ERR(dsi->pll_clk)) {
-		dev_info(dev, "failed to get dsi pll input clock\n");
-		return PTR_ERR(dsi->pll_clk);
+	dsi->sclk_clk = devm_clk_get(dev, "sclk_mipi");
+	if (IS_ERR(dsi->sclk_clk)) {
+		dsi->sclk_clk = devm_clk_get(dev, OLD_SCLK_MIPI_CLK_NAME);
+		if (IS_ERR(dsi->sclk_clk)) {
+			dev_info(dev, "failed to get dsi sclk clock\n");
+			eturn PTR_ERR(dsi->sclk_clk);
+		}
 	}

 	dsi->bus_clk = devm_clk_get(dev, "bus_clk");
--
1.9.1

--
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 related	[flat|nested] 50+ messages in thread

* [PATCH v6 09/15] drm/exynos: dsi: add macros for register access
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                     ` (2 preceding siblings ...)
  2015-06-12 12:59   ` [PATCH v6 08/15] drm/exynos: dsi: rename pll_clk to sclk_clk Hyungwon Hwang
@ 2015-06-12 12:59   ` Hyungwon Hwang
  2015-06-12 12:59   ` [PATCH v6 10/15] drm/exynos: dsi: make use of driver data for static values Hyungwon Hwang
                     ` (6 subsequent siblings)
  10 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: inki.dae-Sze3O3UU22JBDgjK7y7TUQ, daniel-rLtY4a/8tF1rovVCs/uTlw,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ, Hyungwon Hwang

This patch adds macros for register writing/reading. This is needed for
adding support Exynos5433 MIPI DSI driver, not by using if statement, but
by using driver data.

Signed-off-by: Hyungwon Hwang <human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
Changes before:
- Refer https://patchwork.kernel.org/patch/6191761
Changes for v6:
- None

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 98 +++++++++++++++++----------------
 1 file changed, 51 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index a3bfac2..70367d0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -237,6 +237,9 @@

 #define OLD_SCLK_MIPI_CLK_NAME "pll_clk"

+#define DSI_WRITE(dsi, reg, val)	writel((val), (dsi)->reg_base + (reg))
+#define DSI_READ(dsi, reg)		readl((dsi)->reg_base + (reg))
+
 enum exynos_dsi_transfer_type {
 	EXYNOS_DSI_TX,
 	EXYNOS_DSI_RX,
@@ -365,8 +368,10 @@ static void exynos_dsi_wait_for_reset(struct exynos_dsi *dsi)

 static void exynos_dsi_reset(struct exynos_dsi *dsi)
 {
+	struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
+
 	reinit_completion(&dsi->completed);
-	writel(DSIM_SWRST, dsi->reg_base + DSIM_SWRST_REG);
+	DSI_WRITE(dsi, DSIM_SWRST_REG, DSIM_SWRST);
 }

 #ifndef MHZ
@@ -376,6 +381,7 @@ static void exynos_dsi_reset(struct exynos_dsi *dsi)
 static unsigned long exynos_dsi_pll_find_pms(struct exynos_dsi *dsi,
 		unsigned long fin, unsigned long fout, u8 *p, u16 *m, u8 *s)
 {
+	struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
 	unsigned long best_freq = 0;
 	u32 min_delta = 0xffffffff;
 	u8 p_min, p_max;
@@ -466,7 +472,7 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
 		reg |= DSIM_FREQ_BAND(band);
 	}

-	writel(reg, dsi->reg_base + DSIM_PLLCTRL_REG);
+	DSI_WRITE(dsi, DSIM_PLLCTRL_REG, reg);

 	timeout = 1000;
 	do {
@@ -474,7 +480,7 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
 			dev_err(dsi->dev, "PLL failed to stabilize\n");
 			return 0;
 		}
-		reg = readl(dsi->reg_base + DSIM_STATUS_REG);
+		reg = DSI_READ(dsi, DSIM_STATUS_REG);
 	} while ((reg & DSIM_PLL_STABLE) == 0);

 	return fout;
@@ -504,7 +510,7 @@ static int exynos_dsi_enable_clock(struct exynos_dsi *dsi)
 	dev_dbg(dsi->dev, "hs_clk = %lu, byte_clk = %lu, esc_clk = %lu\n",
 		hs_clk, byte_clk, esc_clk);

-	reg = readl(dsi->reg_base + DSIM_CLKCTRL_REG);
+	reg = DSI_READ(dsi, DSIM_CLKCTRL_REG);
 	reg &= ~(DSIM_ESC_PRESCALER_MASK | DSIM_LANE_ESC_CLK_EN_CLK
 			| DSIM_LANE_ESC_CLK_EN_DATA_MASK | DSIM_PLL_BYPASS
 			| DSIM_BYTE_CLK_SRC_MASK);
@@ -514,7 +520,7 @@ static int exynos_dsi_enable_clock(struct exynos_dsi *dsi)
 			| DSIM_LANE_ESC_CLK_EN_DATA(BIT(dsi->lanes) - 1)
 			| DSIM_BYTE_CLK_SRC(0)
 			| DSIM_TX_REQUEST_HSCLK;
-	writel(reg, dsi->reg_base + DSIM_CLKCTRL_REG);
+	DSI_WRITE(dsi, DSIM_CLKCTRL_REG, reg);

 	return 0;
 }
@@ -529,7 +535,7 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)

 	/* B D-PHY: D-PHY Master & Slave Analog Block control */
 	reg = DSIM_PHYCTRL_ULPS_EXIT(0x0af);
-	writel(reg, dsi->reg_base + DSIM_PHYCTRL_REG);
+	DSI_WRITE(dsi, DSIM_PHYCTRL_REG, reg);

 	/*
 	 * T LPX: Transmitted length of any Low-Power state period
@@ -537,7 +543,7 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
 	 *	burst
 	 */
 	reg = DSIM_PHYTIMING_LPX(0x06) | DSIM_PHYTIMING_HS_EXIT(0x0b);
-	writel(reg, dsi->reg_base + DSIM_PHYTIMING_REG);
+	DSI_WRITE(dsi, DSIM_PHYTIMING_REG, reg);

 	/*
 	 * T CLK-PREPARE: Time that the transmitter drives the Clock Lane LP-00
@@ -556,7 +562,7 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
 			DSIM_PHYTIMING1_CLK_ZERO(0x27) |
 			DSIM_PHYTIMING1_CLK_POST(0x0d) |
 			DSIM_PHYTIMING1_CLK_TRAIL(0x08);
-	writel(reg, dsi->reg_base + DSIM_PHYTIMING1_REG);
+	DSI_WRITE(dsi, DSIM_PHYTIMING1_REG, reg);

 	/*
 	 * T HS-PREPARE: Time that the transmitter drives the Data Lane LP-00
@@ -569,21 +575,21 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
 	 */
 	reg = DSIM_PHYTIMING2_HS_PREPARE(0x09) | DSIM_PHYTIMING2_HS_ZERO(0x0d) |
 			DSIM_PHYTIMING2_HS_TRAIL(0x0b);
-	writel(reg, dsi->reg_base + DSIM_PHYTIMING2_REG);
+	DSI_WRITE(dsi, DSIM_PHYTIMING2_REG, reg);
 }

 static void exynos_dsi_disable_clock(struct exynos_dsi *dsi)
 {
 	u32 reg;

-	reg = readl(dsi->reg_base + DSIM_CLKCTRL_REG);
+	reg = DSI_READ(dsi, DSIM_CLKCTRL_REG);
 	reg &= ~(DSIM_LANE_ESC_CLK_EN_CLK | DSIM_LANE_ESC_CLK_EN_DATA_MASK
 			| DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN);
-	writel(reg, dsi->reg_base + DSIM_CLKCTRL_REG);
+	DSI_WRITE(dsi, DSIM_CLKCTRL_REG, reg);

-	reg = readl(dsi->reg_base + DSIM_PLLCTRL_REG);
+	reg = DSI_READ(dsi, DSIM_PLLCTRL_REG);
 	reg &= ~DSIM_PLL_EN;
-	writel(reg, dsi->reg_base + DSIM_PLLCTRL_REG);
+	DSI_WRITE(dsi, DSIM_PLLCTRL_REG, reg);
 }

 static int exynos_dsi_init_link(struct exynos_dsi *dsi)
@@ -594,15 +600,14 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 	u32 lanes_mask;

 	/* Initialize FIFO pointers */
-	reg = readl(dsi->reg_base + DSIM_FIFOCTRL_REG);
+	reg = DSI_READ(dsi, DSIM_FIFOCTRL_REG);
 	reg &= ~0x1f;
-	writel(reg, dsi->reg_base + DSIM_FIFOCTRL_REG);
+	DSI_WRITE(dsi, DSIM_FIFOCTRL_REG, reg);

 	usleep_range(9000, 11000);

 	reg |= 0x1f;
-	writel(reg, dsi->reg_base + DSIM_FIFOCTRL_REG);
-
+	DSI_WRITE(dsi, DSIM_FIFOCTRL_REG, reg);
 	usleep_range(9000, 11000);

 	/* DSI configuration */
@@ -661,14 +666,14 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)

 	reg |= DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1);

-	writel(reg, dsi->reg_base + DSIM_CONFIG_REG);
+	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);

 	reg |= DSIM_LANE_EN_CLK;
-	writel(reg, dsi->reg_base + DSIM_CONFIG_REG);
+	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);

 	lanes_mask = BIT(dsi->lanes) - 1;
 	reg |= DSIM_LANE_EN(lanes_mask);
-	writel(reg, dsi->reg_base + DSIM_CONFIG_REG);
+	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);

 	/*
 	 * Use non-continuous clock mode if the periparal wants and
@@ -681,7 +686,7 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 	if (driver_data->has_clklane_stop &&
 			dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
 		reg |= DSIM_CLKLANE_STOP;
-		writel(reg, dsi->reg_base + DSIM_CONFIG_REG);
+		DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
 	}

 	/* Check clock and data lane state are stop state */
@@ -692,19 +697,19 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 			return -EFAULT;
 		}

-		reg = readl(dsi->reg_base + DSIM_STATUS_REG);
+		reg = DSI_READ(dsi, DSIM_STATUS_REG);
 		if ((reg & DSIM_STOP_STATE_DAT(lanes_mask))
 		    != DSIM_STOP_STATE_DAT(lanes_mask))
 			continue;
 	} while (!(reg & (DSIM_STOP_STATE_CLK | DSIM_TX_READY_HS_CLK)));

-	reg = readl(dsi->reg_base + DSIM_ESCMODE_REG);
+	reg = DSI_READ(dsi, DSIM_ESCMODE_REG);
 	reg &= ~DSIM_STOP_STATE_CNT_MASK;
 	reg |= DSIM_STOP_STATE_CNT(0xf);
-	writel(reg, dsi->reg_base + DSIM_ESCMODE_REG);
+	DSI_WRITE(dsi, DSIM_ESCMODE_REG, reg);

 	reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff);
-	writel(reg, dsi->reg_base + DSIM_TIMEOUT_REG);
+	DSI_WRITE(dsi, DSIM_TIMEOUT_REG, reg);

 	return 0;
 }
@@ -718,19 +723,19 @@ static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
 		reg = DSIM_CMD_ALLOW(0xf)
 			| DSIM_STABLE_VFP(vm->vfront_porch)
 			| DSIM_MAIN_VBP(vm->vback_porch);
-		writel(reg, dsi->reg_base + DSIM_MVPORCH_REG);
+		DSI_WRITE(dsi, DSIM_MVPORCH_REG, reg);

 		reg = DSIM_MAIN_HFP(vm->hfront_porch)
 			| DSIM_MAIN_HBP(vm->hback_porch);
-		writel(reg, dsi->reg_base + DSIM_MHPORCH_REG);
+		DSI_WRITE(dsi, DSIM_MHPORCH_REG, reg);

 		reg = DSIM_MAIN_VSA(vm->vsync_len)
 			| DSIM_MAIN_HSA(vm->hsync_len);
-		writel(reg, dsi->reg_base + DSIM_MSYNC_REG);
+		DSI_WRITE(dsi, DSIM_MSYNC_REG, reg);
 	}

 	reg = DSIM_MAIN_HRESOL(vm->hactive) | DSIM_MAIN_VRESOL(vm->vactive);
-	writel(reg, dsi->reg_base + DSIM_MDRESOL_REG);
+	DSI_WRITE(dsi, DSIM_MDRESOL_REG, reg);

 	dev_dbg(dsi->dev, "LCD size = %dx%d\n", vm->hactive, vm->vactive);
 }
@@ -739,12 +744,12 @@ static void exynos_dsi_set_display_enable(struct exynos_dsi *dsi, bool enable)
 {
 	u32 reg;

-	reg = readl(dsi->reg_base + DSIM_MDRESOL_REG);
+	reg = DSI_READ(dsi, DSIM_MDRESOL_REG);
 	if (enable)
 		reg |= DSIM_MAIN_STAND_BY;
 	else
 		reg &= ~DSIM_MAIN_STAND_BY;
-	writel(reg, dsi->reg_base + DSIM_MDRESOL_REG);
+	DSI_WRITE(dsi, DSIM_MDRESOL_REG, reg);
 }

 static int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi)
@@ -752,7 +757,7 @@ static int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi)
 	int timeout = 2000;

 	do {
-		u32 reg = readl(dsi->reg_base + DSIM_FIFOCTRL_REG);
+		u32 reg = DSI_READ(dsi, DSIM_FIFOCTRL_REG);

 		if (!(reg & DSIM_SFR_HEADER_FULL))
 			return 0;
@@ -766,22 +771,21 @@ static int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi)

 static void exynos_dsi_set_cmd_lpm(struct exynos_dsi *dsi, bool lpm)
 {
-	u32 v = readl(dsi->reg_base + DSIM_ESCMODE_REG);
+	u32 v = DSI_READ(dsi, DSIM_ESCMODE_REG);

 	if (lpm)
 		v |= DSIM_CMD_LPDT_LP;
 	else
 		v &= ~DSIM_CMD_LPDT_LP;

-	writel(v, dsi->reg_base + DSIM_ESCMODE_REG);
+	DSI_WRITE(dsi, DSIM_ESCMODE_REG, v);
 }

 static void exynos_dsi_force_bta(struct exynos_dsi *dsi)
 {
-	u32 v = readl(dsi->reg_base + DSIM_ESCMODE_REG);
-
+	u32 v = DSI_READ(dsi, DSIM_ESCMODE_REG);
 	v |= DSIM_FORCE_BTA;
-	writel(v, dsi->reg_base + DSIM_ESCMODE_REG);
+	DSI_WRITE(dsi, DSIM_ESCMODE_REG, v);
 }

 static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
@@ -805,7 +809,7 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
 	while (length >= 4) {
 		reg = (payload[3] << 24) | (payload[2] << 16)
 					| (payload[1] << 8) | payload[0];
-		writel(reg, dsi->reg_base + DSIM_PAYLOAD_REG);
+		DSI_WRITE(dsi, DSIM_PAYLOAD_REG, reg);
 		payload += 4;
 		length -= 4;
 	}
@@ -820,7 +824,7 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
 		/* Fall through */
 	case 1:
 		reg |= payload[0];
-		writel(reg, dsi->reg_base + DSIM_PAYLOAD_REG);
+		DSI_WRITE(dsi, DSIM_PAYLOAD_REG, reg);
 		break;
 	case 0:
 		/* Do nothing */
@@ -843,7 +847,7 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
 		dsi->state ^= DSIM_STATE_CMD_LPM;
 	}

-	writel(reg, dsi->reg_base + DSIM_PKTHDR_REG);
+	DSI_WRITE(dsi, DSIM_PKTHDR_REG, reg);

 	if (xfer->flags & MIPI_DSI_MSG_REQ_ACK)
 		exynos_dsi_force_bta(dsi);
@@ -859,7 +863,7 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi,
 	u32 reg;

 	if (first) {
-		reg = readl(dsi->reg_base + DSIM_RXFIFO_REG);
+		reg = DSI_READ(dsi, DSIM_RXFIFO_REG);

 		switch (reg & 0x3f) {
 		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
@@ -898,7 +902,7 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi,

 	/* Receive payload */
 	while (length >= 4) {
-		reg = readl(dsi->reg_base + DSIM_RXFIFO_REG);
+		reg = DSI_READ(dsi, DSIM_RXFIFO_REG);
 		payload[0] = (reg >>  0) & 0xff;
 		payload[1] = (reg >>  8) & 0xff;
 		payload[2] = (reg >> 16) & 0xff;
@@ -908,7 +912,7 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi,
 	}

 	if (length) {
-		reg = readl(dsi->reg_base + DSIM_RXFIFO_REG);
+		reg = DSI_READ(dsi, DSIM_RXFIFO_REG);
 		switch (length) {
 		case 3:
 			payload[2] = (reg >> 16) & 0xff;
@@ -927,7 +931,7 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi,
 clear_fifo:
 	length = DSI_RX_FIFO_SIZE / 4;
 	do {
-		reg = readl(dsi->reg_base + DSIM_RXFIFO_REG);
+		reg = DSI_READ(dsi, DSIM_RXFIFO_REG);
 		if (reg == DSI_RX_FIFO_EMPTY)
 			break;
 	} while (--length);
@@ -1083,18 +1087,18 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
 	struct exynos_dsi *dsi = dev_id;
 	u32 status;

-	status = readl(dsi->reg_base + DSIM_INTSRC_REG);
+	status = DSI_READ(dsi, DSIM_INTSRC_REG);
 	if (!status) {
 		static unsigned long int j;
 		if (printk_timed_ratelimit(&j, 500))
 			dev_warn(dsi->dev, "spurious interrupt\n");
 		return IRQ_HANDLED;
 	}
-	writel(status, dsi->reg_base + DSIM_INTSRC_REG);
+	DSI_WRITE(dsi, DSIM_INTSRC_REG, status);

 	if (status & DSIM_INT_SW_RST_RELEASE) {
 		u32 mask = ~(DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY);
-		writel(mask, dsi->reg_base + DSIM_INTMSK_REG);
+		DSI_WRITE(dsi, DSIM_INTMSK_REG, mask);
 		complete(&dsi->completed);
 		return IRQ_HANDLED;
 	}
--
1.9.1

--
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 related	[flat|nested] 50+ messages in thread

* [PATCH v6 10/15] drm/exynos: dsi: make use of driver data for static values
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                     ` (3 preceding siblings ...)
  2015-06-12 12:59   ` [PATCH v6 09/15] drm/exynos: dsi: add macros for register access Hyungwon Hwang
@ 2015-06-12 12:59   ` Hyungwon Hwang
  2015-06-12 12:59   ` [PATCH v6 11/15] drm/exynos: dsi: make use of array for clock access Hyungwon Hwang
                     ` (5 subsequent siblings)
  10 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: inki.dae-Sze3O3UU22JBDgjK7y7TUQ, daniel-rLtY4a/8tF1rovVCs/uTlw,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ, Hyungwon Hwang

Exynos MIPI DSI driver uses some static values such as address offsets,
register setting values, and etc. This patch makes the driver get those
values from the driver data.

Signed-off-by: Hyungwon Hwang <human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
Changes before:
- Refer https://patchwork.kernel.org/patch/6191731
Changes for v6:
- None

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 196 +++++++++++++++++++++++---------
 1 file changed, 145 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 70367d0..0b468d7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -34,38 +34,6 @@
 /* returns true iff both arguments logically differs */
 #define NEQV(a, b) (!(a) ^ !(b))

-#define DSIM_STATUS_REG		0x0	/* Status register */
-#define DSIM_SWRST_REG		0x4	/* Software reset register */
-#define DSIM_CLKCTRL_REG	0x8	/* Clock control register */
-#define DSIM_TIMEOUT_REG	0xc	/* Time out register */
-#define DSIM_CONFIG_REG		0x10	/* Configuration register */
-#define DSIM_ESCMODE_REG	0x14	/* Escape mode register */
-
-/* Main display image resolution register */
-#define DSIM_MDRESOL_REG	0x18
-#define DSIM_MVPORCH_REG	0x1c	/* Main display Vporch register */
-#define DSIM_MHPORCH_REG	0x20	/* Main display Hporch register */
-#define DSIM_MSYNC_REG		0x24	/* Main display sync area register */
-
-/* Sub display image resolution register */
-#define DSIM_SDRESOL_REG	0x28
-#define DSIM_INTSRC_REG		0x2c	/* Interrupt source register */
-#define DSIM_INTMSK_REG		0x30	/* Interrupt mask register */
-#define DSIM_PKTHDR_REG		0x34	/* Packet Header FIFO register */
-#define DSIM_PAYLOAD_REG	0x38	/* Payload FIFO register */
-#define DSIM_RXFIFO_REG		0x3c	/* Read FIFO register */
-#define DSIM_FIFOTHLD_REG	0x40	/* FIFO threshold level register */
-#define DSIM_FIFOCTRL_REG	0x44	/* FIFO status and control register */
-
-/* FIFO memory AC characteristic register */
-#define DSIM_PLLCTRL_REG	0x4c	/* PLL control register */
-#define DSIM_PHYACCHR_REG	0x54	/* D-PHY AC characteristic register */
-#define DSIM_PHYACCHR1_REG	0x58	/* D-PHY AC characteristic register1 */
-#define DSIM_PHYCTRL_REG	0x5c
-#define DSIM_PHYTIMING_REG	0x64
-#define DSIM_PHYTIMING1_REG	0x68
-#define DSIM_PHYTIMING2_REG	0x6c
-
 /* DSIM_STATUS */
 #define DSIM_STOP_STATE_DAT(x)		(((x) & 0xf) << 0)
 #define DSIM_STOP_STATE_CLK		(1 << 8)
@@ -129,8 +97,8 @@

 /* DSIM_MDRESOL */
 #define DSIM_MAIN_STAND_BY		(1 << 31)
-#define DSIM_MAIN_VRESOL(x)		(((x) & 0x7ff) << 16)
-#define DSIM_MAIN_HRESOL(x)		(((x) & 0X7ff) << 0)
+#define DSIM_MAIN_VRESOL(x, num_bits)	(((x) & ((1 << (num_bits)) - 1)) << 16)
+#define DSIM_MAIN_HRESOL(x, num_bits)	(((x) & ((1 << (num_bits)) - 1)) << 0)

 /* DSIM_MVPORCH */
 #define DSIM_CMD_ALLOW(x)		((x) << 28)
@@ -237,8 +205,11 @@

 #define OLD_SCLK_MIPI_CLK_NAME "pll_clk"

-#define DSI_WRITE(dsi, reg, val)	writel((val), (dsi)->reg_base + (reg))
-#define DSI_READ(dsi, reg)		readl((dsi)->reg_base + (reg))
+#define REG_ADDR(dsi, reg_idx)		((dsi)->reg_base + \
+					dsi->driver_data->reg_ofs[(reg_idx)])
+#define DSI_WRITE(dsi, reg_idx, val)	writel((val), \
+					REG_ADDR((dsi), (reg_idx)))
+#define DSI_READ(dsi, reg_idx)		readl(REG_ADDR((dsi), (reg_idx)))

 enum exynos_dsi_transfer_type {
 	EXYNOS_DSI_TX,
@@ -268,10 +239,15 @@ struct exynos_dsi_transfer {
 #define DSIM_STATE_VIDOUT_AVAILABLE	BIT(3)

 struct exynos_dsi_driver_data {
+	unsigned int *reg_ofs;
 	unsigned int plltmr_reg;
-
 	unsigned int has_freqband:1;
 	unsigned int has_clklane_stop:1;
+	unsigned int num_clks;
+	unsigned int max_freq;
+	unsigned int wait_for_reset;
+	unsigned int num_bits_resol;
+	unsigned int *reg_values;
 };

 struct exynos_dsi {
@@ -316,25 +292,133 @@ static inline struct exynos_dsi *display_to_dsi(struct exynos_drm_display *d)
 	return container_of(d, struct exynos_dsi, display);
 }

+enum reg_idx {
+	DSIM_STATUS_REG,	/* Status register */
+	DSIM_SWRST_REG,		/* Software reset register */
+	DSIM_CLKCTRL_REG,	/* Clock control register */
+	DSIM_TIMEOUT_REG,	/* Time out register */
+	DSIM_CONFIG_REG,	/* Configuration register */
+	DSIM_ESCMODE_REG,	/* Escape mode register */
+	DSIM_MDRESOL_REG,
+	DSIM_MVPORCH_REG,	/* Main display Vporch register */
+	DSIM_MHPORCH_REG,	/* Main display Hporch register */
+	DSIM_MSYNC_REG,		/* Main display sync area register */
+	DSIM_INTSRC_REG,	/* Interrupt source register */
+	DSIM_INTMSK_REG,	/* Interrupt mask register */
+	DSIM_PKTHDR_REG,	/* Packet Header FIFO register */
+	DSIM_PAYLOAD_REG,	/* Payload FIFO register */
+	DSIM_RXFIFO_REG,	/* Read FIFO register */
+	DSIM_FIFOCTRL_REG,	/* FIFO status and control register */
+	DSIM_PLLCTRL_REG,	/* PLL control register */
+	DSIM_PHYCTRL_REG,
+	DSIM_PHYTIMING_REG,
+	DSIM_PHYTIMING1_REG,
+	DSIM_PHYTIMING2_REG,
+	NUM_REGS
+};
+static unsigned int exynos_reg_ofs[] = {
+	[DSIM_STATUS_REG] =  0x00,
+	[DSIM_SWRST_REG] =  0x04,
+	[DSIM_CLKCTRL_REG] =  0x08,
+	[DSIM_TIMEOUT_REG] =  0x0c,
+	[DSIM_CONFIG_REG] =  0x10,
+	[DSIM_ESCMODE_REG] =  0x14,
+	[DSIM_MDRESOL_REG] =  0x18,
+	[DSIM_MVPORCH_REG] =  0x1c,
+	[DSIM_MHPORCH_REG] =  0x20,
+	[DSIM_MSYNC_REG] =  0x24,
+	[DSIM_INTSRC_REG] =  0x2c,
+	[DSIM_INTMSK_REG] =  0x30,
+	[DSIM_PKTHDR_REG] =  0x34,
+	[DSIM_PAYLOAD_REG] =  0x38,
+	[DSIM_RXFIFO_REG] =  0x3c,
+	[DSIM_FIFOCTRL_REG] =  0x44,
+	[DSIM_PLLCTRL_REG] =  0x4c,
+	[DSIM_PHYCTRL_REG] =  0x5c,
+	[DSIM_PHYTIMING_REG] =  0x64,
+	[DSIM_PHYTIMING1_REG] =  0x68,
+	[DSIM_PHYTIMING2_REG] =  0x6c,
+};
+
+enum reg_value_idx {
+	RESET_TYPE,
+	PLL_TIMER,
+	STOP_STATE_CNT,
+	PHYCTRL_ULPS_EXIT,
+	PHYCTRL_VREG_LP,
+	PHYCTRL_SLEW_UP,
+	PHYTIMING_LPX,
+	PHYTIMING_HS_EXIT,
+	PHYTIMING_CLK_PREPARE,
+	PHYTIMING_CLK_ZERO,
+	PHYTIMING_CLK_POST,
+	PHYTIMING_CLK_TRAIL,
+	PHYTIMING_HS_PREPARE,
+	PHYTIMING_HS_ZERO,
+	PHYTIMING_HS_TRAIL
+};
+
+static unsigned int reg_values[] = {
+	[RESET_TYPE] = DSIM_SWRST,
+	[PLL_TIMER] = 500,
+	[STOP_STATE_CNT] = 0xf,
+	[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x0af),
+	[PHYCTRL_VREG_LP] = 0,
+	[PHYCTRL_SLEW_UP] = 0,
+	[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),
+	[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0b),
+	[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x07),
+	[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x27),
+	[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d),
+	[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x08),
+	[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x09),
+	[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0d),
+	[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),
+};
+
 static struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
+	.reg_ofs = exynos_reg_ofs,
 	.plltmr_reg = 0x50,
 	.has_freqband = 1,
 	.has_clklane_stop = 1,
+	.num_clks = 2,
+	.max_freq = 1000,
+	.wait_for_reset = 1,
+	.num_bits_resol = 11,
+	.reg_values = reg_values,
 };

 static struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
+	.reg_ofs = exynos_reg_ofs,
 	.plltmr_reg = 0x50,
 	.has_freqband = 1,
 	.has_clklane_stop = 1,
+	.num_clks = 2,
+	.max_freq = 1000,
+	.wait_for_reset = 1,
+	.num_bits_resol = 11,
+	.reg_values = reg_values,
 };

 static struct exynos_dsi_driver_data exynos4415_dsi_driver_data = {
+	.reg_ofs = exynos_reg_ofs,
 	.plltmr_reg = 0x58,
 	.has_clklane_stop = 1,
+	.num_clks = 2,
+	.max_freq = 1000,
+	.wait_for_reset = 1,
+	.num_bits_resol = 11,
+	.reg_values = reg_values,
 };

 static struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
+	.reg_ofs = exynos_reg_ofs,
 	.plltmr_reg = 0x58,
+	.num_clks = 2,
+	.max_freq = 1000,
+	.wait_for_reset = 1,
+	.num_bits_resol = 11,
+	.reg_values = reg_values,
 };

 static struct of_device_id exynos_dsi_of_match[] = {
@@ -371,7 +455,7 @@ static void exynos_dsi_reset(struct exynos_dsi *dsi)
 	struct exynos_dsi_driver_data *driver_data = dsi->driver_data;

 	reinit_completion(&dsi->completed);
-	DSI_WRITE(dsi, DSIM_SWRST_REG, DSIM_SWRST);
+	DSI_WRITE(dsi, DSIM_SWRST_REG, driver_data->reg_values[RESET_TYPE]);
 }

 #ifndef MHZ
@@ -405,7 +489,8 @@ static unsigned long exynos_dsi_pll_find_pms(struct exynos_dsi *dsi,

 			tmp = (u64)_m * fin;
 			do_div(tmp, _p);
-			if (tmp < 500 * MHZ || tmp > 1000 * MHZ)
+			if (tmp < 500 * MHZ ||
+					tmp > driver_data->max_freq * MHZ)
 				continue;

 			tmp = (u64)_m * fin;
@@ -450,7 +535,8 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
 	}
 	dev_dbg(dsi->dev, "PLL freq %lu, (p %d, m %d, s %d)\n", fout, p, m, s);

-	writel(500, dsi->reg_base + driver_data->plltmr_reg);
+	writel(driver_data->reg_values[PLL_TIMER],
+			dsi->reg_base + driver_data->plltmr_reg);

 	reg = DSIM_PLL_EN | DSIM_PLL_P(p) | DSIM_PLL_M(m) | DSIM_PLL_S(s);

@@ -528,13 +614,15 @@ static int exynos_dsi_enable_clock(struct exynos_dsi *dsi)
 static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
 {
 	struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
+	unsigned int *reg_values = driver_data->reg_values;
 	u32 reg;

 	if (driver_data->has_freqband)
 		return;

 	/* B D-PHY: D-PHY Master & Slave Analog Block control */
-	reg = DSIM_PHYCTRL_ULPS_EXIT(0x0af);
+	reg = reg_values[PHYCTRL_ULPS_EXIT] | reg_values[PHYCTRL_VREG_LP] |
+		reg_values[PHYCTRL_SLEW_UP];
 	DSI_WRITE(dsi, DSIM_PHYCTRL_REG, reg);

 	/*
@@ -542,7 +630,7 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
 	 * T HS-EXIT: Time that the transmitter drives LP-11 following a HS
 	 *	burst
 	 */
-	reg = DSIM_PHYTIMING_LPX(0x06) | DSIM_PHYTIMING_HS_EXIT(0x0b);
+	reg = reg_values[PHYTIMING_LPX] | reg_values[PHYTIMING_HS_EXIT];
 	DSI_WRITE(dsi, DSIM_PHYTIMING_REG, reg);

 	/*
@@ -558,10 +646,11 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
 	 * T CLK-TRAIL: Time that the transmitter drives the HS-0 state after
 	 *	the last payload clock bit of a HS transmission burst
 	 */
-	reg = DSIM_PHYTIMING1_CLK_PREPARE(0x07) |
-			DSIM_PHYTIMING1_CLK_ZERO(0x27) |
-			DSIM_PHYTIMING1_CLK_POST(0x0d) |
-			DSIM_PHYTIMING1_CLK_TRAIL(0x08);
+	reg = reg_values[PHYTIMING_CLK_PREPARE] |
+		reg_values[PHYTIMING_CLK_ZERO] |
+		reg_values[PHYTIMING_CLK_POST] |
+		reg_values[PHYTIMING_CLK_TRAIL];
+
 	DSI_WRITE(dsi, DSIM_PHYTIMING1_REG, reg);

 	/*
@@ -573,8 +662,8 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
 	 * T HS-TRAIL: Time that the transmitter drives the flipped differential
 	 *	state after last payload data bit of a HS transmission burst
 	 */
-	reg = DSIM_PHYTIMING2_HS_PREPARE(0x09) | DSIM_PHYTIMING2_HS_ZERO(0x0d) |
-			DSIM_PHYTIMING2_HS_TRAIL(0x0b);
+	reg = reg_values[PHYTIMING_HS_PREPARE] | reg_values[PHYTIMING_HS_ZERO] |
+		reg_values[PHYTIMING_HS_TRAIL];
 	DSI_WRITE(dsi, DSIM_PHYTIMING2_REG, reg);
 }

@@ -705,7 +794,7 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)

 	reg = DSI_READ(dsi, DSIM_ESCMODE_REG);
 	reg &= ~DSIM_STOP_STATE_CNT_MASK;
-	reg |= DSIM_STOP_STATE_CNT(0xf);
+	reg |= DSIM_STOP_STATE_CNT(driver_data->reg_values[STOP_STATE_CNT]);
 	DSI_WRITE(dsi, DSIM_ESCMODE_REG, reg);

 	reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff);
@@ -717,6 +806,7 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
 {
 	struct videomode *vm = &dsi->vm;
+	unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;
 	u32 reg;

 	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
@@ -733,8 +823,9 @@ static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
 			| DSIM_MAIN_HSA(vm->hsync_len);
 		DSI_WRITE(dsi, DSIM_MSYNC_REG, reg);
 	}
+	reg =  DSIM_MAIN_HRESOL(vm->hactive, num_bits_resol) |
+		DSIM_MAIN_VRESOL(vm->vactive, num_bits_resol);

-	reg = DSIM_MAIN_HRESOL(vm->hactive) | DSIM_MAIN_VRESOL(vm->vactive);
 	DSI_WRITE(dsi, DSIM_MDRESOL_REG, reg);

 	dev_dbg(dsi->dev, "LCD size = %dx%d\n", vm->hactive, vm->vactive);
@@ -1141,10 +1232,13 @@ static void exynos_dsi_disable_irq(struct exynos_dsi *dsi)

 static int exynos_dsi_init(struct exynos_dsi *dsi)
 {
+	struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
+
 	exynos_dsi_reset(dsi);
 	exynos_dsi_enable_irq(dsi);
 	exynos_dsi_enable_clock(dsi);
-	exynos_dsi_wait_for_reset(dsi);
+	if (driver_data->wait_for_reset)
+		exynos_dsi_wait_for_reset(dsi);
 	exynos_dsi_set_phy_ctrl(dsi);
 	exynos_dsi_init_link(dsi);

--
1.9.1

--
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 related	[flat|nested] 50+ messages in thread

* [PATCH v6 11/15] drm/exynos: dsi: make use of array for clock access
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                     ` (4 preceding siblings ...)
  2015-06-12 12:59   ` [PATCH v6 10/15] drm/exynos: dsi: make use of driver data for static values Hyungwon Hwang
@ 2015-06-12 12:59   ` Hyungwon Hwang
  2015-06-12 12:59   ` [PATCH v6 13/15] drm/exynos: dsi: add support for MIC driver as a bridge Hyungwon Hwang
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: inki.dae-Sze3O3UU22JBDgjK7y7TUQ, daniel-rLtY4a/8tF1rovVCs/uTlw,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ, Hyungwon Hwang

This patch make the driver to use an array for clock access. The number
of clocks are different from the existing MIPI DSI driver and Exynos5433
MIPI DSI driver. So this patch is needed before adding support for
Exynos5433 MIPI DSI driver.

Signed-off-by: Hyungwon Hwang <human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
Changes before:
- Refer https://patchwork.kernel.org/patch/6191801
Changes for v6:
- None

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 68 ++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 0b468d7..557b9d2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -211,6 +211,8 @@
 					REG_ADDR((dsi), (reg_idx)))
 #define DSI_READ(dsi, reg_idx)		readl(REG_ADDR((dsi), (reg_idx)))

+static char *clk_names[2] = { "bus_clk", "sclk_mipi" };
+
 enum exynos_dsi_transfer_type {
 	EXYNOS_DSI_TX,
 	EXYNOS_DSI_RX,
@@ -260,8 +262,7 @@ struct exynos_dsi {

 	void __iomem *reg_base;
 	struct phy *phy;
-	struct clk *sclk_clk;
-	struct clk *bus_clk;
+	struct clk **clks;
 	struct regulator_bulk_data supplies[2];
 	int irq;
 	int te_gpio;
@@ -1390,7 +1391,8 @@ static const struct mipi_dsi_host_ops exynos_dsi_ops = {

 static int exynos_dsi_poweron(struct exynos_dsi *dsi)
 {
-	int ret;
+	struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
+	int ret, i;

 	ret = regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
 	if (ret < 0) {
@@ -1398,31 +1400,23 @@ static int exynos_dsi_poweron(struct exynos_dsi *dsi)
 		return ret;
 	}

-	ret = clk_prepare_enable(dsi->bus_clk);
-	if (ret < 0) {
-		dev_err(dsi->dev, "cannot enable bus clock %d\n", ret);
-		goto err_bus_clk;
-	}
-
-	ret = clk_prepare_enable(dsi->sclk_clk);
-	if (ret < 0) {
-		dev_err(dsi->dev, "cannot enable pll clock %d\n", ret);
-		goto err_sclk_clk;
+	for (i = 0; i < driver_data->num_clks; i++) {
+		ret = clk_prepare_enable(dsi->clks[i]);
+		if (ret < 0)
+			goto err_clk;
 	}

 	ret = phy_power_on(dsi->phy);
 	if (ret < 0) {
 		dev_err(dsi->dev, "cannot enable phy %d\n", ret);
-		goto err_phy;
+		goto err_clk;
 	}

 	return 0;

-err_phy:
-	clk_disable_unprepare(dsi->sclk_clk);
-err_sclk_clk:
-	clk_disable_unprepare(dsi->bus_clk);
-err_bus_clk:
+err_clk:
+	while (--i > -1)
+		clk_disable_unprepare(dsi->clks[i]);
 	regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);

 	return ret;
@@ -1430,7 +1424,8 @@ err_bus_clk:

 static void exynos_dsi_poweroff(struct exynos_dsi *dsi)
 {
-	int ret;
+	struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
+	int ret, i;

 	usleep_range(10000, 20000);

@@ -1446,8 +1441,8 @@ static void exynos_dsi_poweroff(struct exynos_dsi *dsi)

 	phy_power_off(dsi->phy);

-	clk_disable_unprepare(dsi->sclk_clk);
-	clk_disable_unprepare(dsi->bus_clk);
+	for (i = driver_data->num_clks - 1; i > -1; i--)
+		clk_disable_unprepare(dsi->clks[i]);

 	ret = regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
 	if (ret < 0)
@@ -1778,7 +1773,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct resource *res;
 	struct exynos_dsi *dsi;
-	int ret;
+	int ret, i;

 	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
 	if (!dsi)
@@ -1813,19 +1808,22 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 		return -EPROBE_DEFER;
 	}

-	dsi->sclk_clk = devm_clk_get(dev, "sclk_mipi");
-	if (IS_ERR(dsi->sclk_clk)) {
-		dsi->sclk_clk = devm_clk_get(dev, OLD_SCLK_MIPI_CLK_NAME);
-		if (IS_ERR(dsi->sclk_clk)) {
-			dev_info(dev, "failed to get dsi sclk clock\n");
-			eturn PTR_ERR(dsi->sclk_clk);
-		}
-	}
+	dsi->clks = devm_kzalloc(dev,
+			sizeof(*dsi->clks) * dsi->driver_data->num_clks,
+			GFP_KERNEL);
+	for (i = 0; i < dsi->driver_data->num_clks; i++) {
+		dsi->clks[i] = devm_clk_get(dev, clk_names[i]);
+		if (IS_ERR(dsi->clks[i])) {
+			if (strcmp(clk_names[i], "sclk_mipi") == 0) {
+				strcpy(clk_names[i], OLD_SCLK_MIPI_CLK_NAME);
+				i--;
+				continue;
+			}

-	dsi->bus_clk = devm_clk_get(dev, "bus_clk");
-	if (IS_ERR(dsi->bus_clk)) {
-		dev_info(dev, "failed to get dsi bus clock\n");
-		return PTR_ERR(dsi->bus_clk);
+			dev_info(dev, "failed to get the clock: %s\n",
+					clk_names[i]);
+			return PTR_ERR(dsi->clks[i]);
+		}
 	}

 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
--
1.9.1

--
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 related	[flat|nested] 50+ messages in thread

* [PATCH v6 12/15] drm/exynos: dsi: add support for Exynos5433
  2015-06-12 12:58 [PATCH v6 00/15] Add drivers for Exynos5433 display Hyungwon Hwang
                   ` (4 preceding siblings ...)
  2015-06-12 12:59 ` [PATCH v6 07/15] drm/exynos: mic: add MIC driver Hyungwon Hwang
@ 2015-06-12 12:59 ` Hyungwon Hwang
  2015-06-12 12:59 ` [PATCH v6 14/15] drm/exynos: dsi: do not set TE GPIO direction by input Hyungwon Hwang
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel, devicetree; +Cc: sw0312.kim

This patch adds support for Exynos5433 mipi dsi.

Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
---
Changes before:
- Refer https://patchwork.kernel.org/patch/6191811
Changes for v6:
- Change the order of DSIM_CONFIG_REG register
- Add error checking code in probe function

 .../devicetree/bindings/video/exynos_dsim.txt      |   1 +
 drivers/gpu/drm/exynos/Kconfig                     |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_dsi.c            | 100 +++++++++++++++++----
 3 files changed, 87 insertions(+), 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/video/exynos_dsim.txt b/Documentation/devicetree/bindings/video/exynos_dsim.txt
index 44659dd..11ccac9 100644
--- a/Documentation/devicetree/bindings/video/exynos_dsim.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dsim.txt
@@ -6,6 +6,7 @@ Required properties:
 		"samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */
 		"samsung,exynos4415-mipi-dsi" /* for Exynos4415 SoC */
 		"samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */
+		"samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */
   - reg: physical base address and length of the registers set for the device
   - interrupts: should contain DSI interrupt
   - clocks: list of clock specifiers, must contain an entry for each required
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 12e4e62..43003c4 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -47,7 +47,7 @@ config DRM_EXYNOS_DPI

 config DRM_EXYNOS_DSI
 	bool "EXYNOS DRM MIPI-DSI driver support"
-	depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON)
+	depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS5433_DECON || DRM_EXYNOS7_DECON)
 	select DRM_MIPI_DSI
 	select DRM_PANEL
 	default n
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 557b9d2..d9bcdb9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -132,6 +132,7 @@
 #define DSIM_INT_PLL_STABLE		(1 << 31)
 #define DSIM_INT_SW_RST_RELEASE		(1 << 30)
 #define DSIM_INT_SFR_FIFO_EMPTY		(1 << 29)
+#define DSIM_INT_SFR_HDR_FIFO_EMPTY	(1 << 28)
 #define DSIM_INT_BTA			(1 << 25)
 #define DSIM_INT_FRAME_DONE		(1 << 24)
 #define DSIM_INT_RX_TIMEOUT		(1 << 21)
@@ -180,6 +181,8 @@

 /* DSIM_PHYCTRL */
 #define DSIM_PHYCTRL_ULPS_EXIT(x)	(((x) & 0x1ff) << 0)
+#define DSIM_PHYCTRL_B_DPHYCTL_VREG_LP	(1 << 30)
+#define DSIM_PHYCTRL_B_DPHYCTL_SLEW_UP	(1 << 14)

 /* DSIM_PHYTIMING */
 #define DSIM_PHYTIMING_LPX(x)		((x) << 8)
@@ -211,7 +214,9 @@
 					REG_ADDR((dsi), (reg_idx)))
 #define DSI_READ(dsi, reg_idx)		readl(REG_ADDR((dsi), (reg_idx)))

-static char *clk_names[2] = { "bus_clk", "sclk_mipi" };
+static char *clk_names[5] = { "bus_clk", "sclk_mipi",
+	"phyclk_mipidphy0_bitclkdiv8", "phyclk_mipidphy0_rxclkesc0",
+	"sclk_rgb_vclk_to_dsim0" };

 enum exynos_dsi_transfer_type {
 	EXYNOS_DSI_TX,
@@ -341,6 +346,30 @@ static unsigned int exynos_reg_ofs[] = {
 	[DSIM_PHYTIMING2_REG] =  0x6c,
 };

+static unsigned int exynos5433_reg_ofs[] = {
+	[DSIM_STATUS_REG] = 0x04,
+	[DSIM_SWRST_REG] = 0x0C,
+	[DSIM_CLKCTRL_REG] = 0x10,
+	[DSIM_TIMEOUT_REG] = 0x14,
+	[DSIM_CONFIG_REG] = 0x18,
+	[DSIM_ESCMODE_REG] = 0x1C,
+	[DSIM_MDRESOL_REG] = 0x20,
+	[DSIM_MVPORCH_REG] = 0x24,
+	[DSIM_MHPORCH_REG] = 0x28,
+	[DSIM_MSYNC_REG] = 0x2C,
+	[DSIM_INTSRC_REG] = 0x34,
+	[DSIM_INTMSK_REG] = 0x38,
+	[DSIM_PKTHDR_REG] = 0x3C,
+	[DSIM_PAYLOAD_REG] = 0x40,
+	[DSIM_RXFIFO_REG] = 0x44,
+	[DSIM_FIFOCTRL_REG] = 0x4C,
+	[DSIM_PLLCTRL_REG] = 0x94,
+	[DSIM_PHYCTRL_REG] = 0xA4,
+	[DSIM_PHYTIMING_REG] = 0xB4,
+	[DSIM_PHYTIMING1_REG] = 0xB8,
+	[DSIM_PHYTIMING2_REG] = 0xBC,
+};
+
 enum reg_value_idx {
 	RESET_TYPE,
 	PLL_TIMER,
@@ -377,6 +406,24 @@ static unsigned int reg_values[] = {
 	[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),
 };

+static unsigned int exynos5433_reg_values[] = {
+	[RESET_TYPE] = DSIM_FUNCRST,
+	[PLL_TIMER] = 22200,
+	[STOP_STATE_CNT] = 0xa,
+	[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x190),
+	[PHYCTRL_VREG_LP] = DSIM_PHYCTRL_B_DPHYCTL_VREG_LP,
+	[PHYCTRL_SLEW_UP] = DSIM_PHYCTRL_B_DPHYCTL_SLEW_UP,
+	[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x07),
+	[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0c),
+	[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x09),
+	[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x2d),
+	[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0e),
+	[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x09),
+	[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x0b),
+	[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x10),
+	[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c),
+};
+
 static struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
 	.reg_ofs = exynos_reg_ofs,
 	.plltmr_reg = 0x50,
@@ -422,6 +469,17 @@ static struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
 	.reg_values = reg_values,
 };

+static struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
+	.reg_ofs = exynos5433_reg_ofs,
+	.plltmr_reg = 0xa0,
+	.has_clklane_stop = 1,
+	.num_clks = 5,
+	.max_freq = 1500,
+	.wait_for_reset = 0,
+	.num_bits_resol = 12,
+	.reg_values = exynos5433_reg_values,
+};
+
 static struct of_device_id exynos_dsi_of_match[] = {
 	{ .compatible = "samsung,exynos3250-mipi-dsi",
 	  .data = &exynos3_dsi_driver_data },
@@ -431,6 +489,8 @@ static struct of_device_id exynos_dsi_of_match[] = {
 	  .data = &exynos4415_dsi_driver_data },
 	{ .compatible = "samsung,exynos5410-mipi-dsi",
 	  .data = &exynos5_dsi_driver_data },
+	{ .compatible = "samsung,exynos5433-mipi-dsi",
+	  .data = &exynos5433_dsi_driver_data },
 	{ }
 };

@@ -682,6 +742,14 @@ static void exynos_dsi_disable_clock(struct exynos_dsi *dsi)
 	DSI_WRITE(dsi, DSIM_PLLCTRL_REG, reg);
 }

+static void exynos_dsi_enable_lane(struct exynos_dsi *dsi, u32 lane)
+{
+	u32 reg = DSI_READ(dsi, DSIM_CONFIG_REG);
+	reg |= (DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1) | DSIM_LANE_EN_CLK |
+			DSIM_LANE_EN(lane));
+	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
+}
+
 static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 {
 	struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
@@ -754,17 +822,6 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 		return -EINVAL;
 	}

-	reg |= DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1);
-
-	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
-
-	reg |= DSIM_LANE_EN_CLK;
-	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
-
-	lanes_mask = BIT(dsi->lanes) - 1;
-	reg |= DSIM_LANE_EN(lanes_mask);
-	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
-
 	/*
 	 * Use non-continuous clock mode if the periparal wants and
 	 * host controller supports
@@ -776,8 +833,11 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 	if (driver_data->has_clklane_stop &&
 			dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
 		reg |= DSIM_CLKLANE_STOP;
-		DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
 	}
+	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
+
+	lanes_mask = BIT(dsi->lanes) - 1;
+	exynos_dsi_enable_lane(dsi, lanes_mask);

 	/* Check clock and data lane state are stop state */
 	timeout = 100;
@@ -1189,13 +1249,16 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
 	DSI_WRITE(dsi, DSIM_INTSRC_REG, status);

 	if (status & DSIM_INT_SW_RST_RELEASE) {
-		u32 mask = ~(DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY);
+		u32 mask = ~(DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY |
+			DSIM_INT_SFR_HDR_FIFO_EMPTY | DSIM_INT_FRAME_DONE |
+			DSIM_INT_RX_ECC_ERR | DSIM_INT_SW_RST_RELEASE);
 		DSI_WRITE(dsi, DSIM_INTMSK_REG, mask);
 		complete(&dsi->completed);
 		return IRQ_HANDLED;
 	}

-	if (!(status & (DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY)))
+	if (!(status & (DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY |
+			DSIM_INT_FRAME_DONE | DSIM_INT_PLL_STABLE)))
 		return IRQ_HANDLED;

 	if (exynos_dsi_transfer_finish(dsi))
@@ -1237,6 +1300,10 @@ static int exynos_dsi_init(struct exynos_dsi *dsi)

 	exynos_dsi_reset(dsi);
 	exynos_dsi_enable_irq(dsi);
+
+	if (driver_data->reg_values[RESET_TYPE] == DSIM_FUNCRST)
+		exynos_dsi_enable_lane(dsi, BIT(dsi->lanes) - 1);
+
 	exynos_dsi_enable_clock(dsi);
 	if (driver_data->wait_for_reset)
 		exynos_dsi_wait_for_reset(dsi);
@@ -1811,6 +1878,9 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	dsi->clks = devm_kzalloc(dev,
 			sizeof(*dsi->clks) * dsi->driver_data->num_clks,
 			GFP_KERNEL);
+	if (!dsi->clks)
+		return -ENOMEM;
+
 	for (i = 0; i < dsi->driver_data->num_clks; i++) {
 		dsi->clks[i] = devm_clk_get(dev, clk_names[i]);
 		if (IS_ERR(dsi->clks[i])) {
--
1.9.1

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

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

* [PATCH v6 13/15] drm/exynos: dsi: add support for MIC driver as a bridge
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                     ` (5 preceding siblings ...)
  2015-06-12 12:59   ` [PATCH v6 11/15] drm/exynos: dsi: make use of array for clock access Hyungwon Hwang
@ 2015-06-12 12:59   ` Hyungwon Hwang
  2015-06-12 12:59   ` [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi' Hyungwon Hwang
                     ` (3 subsequent siblings)
  10 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: inki.dae-Sze3O3UU22JBDgjK7y7TUQ, daniel-rLtY4a/8tF1rovVCs/uTlw,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ, Hyungwon Hwang

MIC must be initilized by MIPI DSI when it is being bound.

Signed-off-by: Hyungwon Hwang <human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
Changes before:
- Refer https://patchwork.kernel.org/patch/6191811
Changes for v6:
- None

 .../devicetree/bindings/video/exynos_dsim.txt      | 23 ++++++++++++++++++---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c            | 24 ++++++++++++++++++++++
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/video/exynos_dsim.txt b/Documentation/devicetree/bindings/video/exynos_dsim.txt
index 11ccac9..0be0362 100644
--- a/Documentation/devicetree/bindings/video/exynos_dsim.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dsim.txt
@@ -32,10 +32,19 @@ Video interfaces:
   Device node can contain video interface port nodes according to [2].
   The following are properties specific to those nodes:

-  port node:
-    - reg: (required) can be 0 for input RGB/I80 port or 1 for DSI port;
+  port node inbound:
+    - reg: (required) must be 0.
+  port node outbound:
+    - reg: (required) must be 1.

-  endpoint node of DSI port (reg = 1):
+  endpoint node connected from mic node (reg = 0):
+    - remote-endpoint: specifies the endpoint in mic node. This node is required
+		       for Exynos5433 mipi dsi. So mic can access to panel node
+		       thoughout this dsi node.
+  endpoint node connected to panel node (reg = 1):
+    - remote-endpoint: specifies the endpoint in panel node. This node is
+		       required in all kinds of exynos mipi dsi to represent
+		       the connection between mipi dsi and panel.
     - samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst
       mode
     - samsung,esc-clock-frequency: specifies DSI frequency in escape mode
@@ -74,7 +83,15 @@ Example:
 			#address-cells = <1>;
 			#size-cells = <0>;

+			port@0 {
+				reg = <0>;
+				decon_to_mic: endpoint {
+					remote-endpoint = <&mic_to_decon>;
+				};
+			};
+
 			port@1 {
+				reg = <1>;
 				dsi_ep: endpoint {
 					reg = <0>;
 					samsung,burst-clock-frequency = <500000000>;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index d9bcdb9..0719114 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -21,6 +21,7 @@
 #include <linux/irq.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
+#include <linux/of_graph.h>
 #include <linux/phy/phy.h>
 #include <linux/regulator/consumer.h>
 #include <linux/component.h>
@@ -288,6 +289,7 @@ struct exynos_dsi {
 	struct list_head transfer_list;

 	struct exynos_dsi_driver_data *driver_data;
+	struct device_node *bridge_node;
 };

 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
@@ -1794,7 +1796,22 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)

 	ret = exynos_dsi_of_read_u32(ep, "samsung,esc-clock-frequency",
 				     &dsi->esc_clk_rate);
+	if (ret < 0)
+		goto end;
+
+	of_node_put(ep);
+
+	ep = of_graph_get_next_endpoint(node, NULL);
+	if (!ep) {
+		ret = -ENXIO;
+		goto end;
+	}

+	dsi->bridge_node = of_graph_get_remote_port_parent(ep);
+	if (!dsi->bridge_node) {
+		ret = -ENXIO;
+		goto end;
+	}
 end:
 	of_node_put(ep);

@@ -1807,6 +1824,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 	struct exynos_drm_display *display = dev_get_drvdata(dev);
 	struct exynos_dsi *dsi = display_to_dsi(display);
 	struct drm_device *drm_dev = data;
+	struct drm_bridge *bridge;
 	int ret;

 	ret = exynos_drm_create_enc_conn(drm_dev, display);
@@ -1816,6 +1834,12 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 		return ret;
 	}

+	bridge = of_drm_find_bridge(dsi->bridge_node);
+	if (bridge) {
+		display->encoder->bridge = bridge;
+		drm_bridge_attach(drm_dev, bridge);
+	}
+
 	return mipi_dsi_host_register(&dsi->dsi_host);
 }

--
1.9.1

--
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 related	[flat|nested] 50+ messages in thread

* [PATCH v6 14/15] drm/exynos: dsi: do not set TE GPIO direction by input
  2015-06-12 12:58 [PATCH v6 00/15] Add drivers for Exynos5433 display Hyungwon Hwang
                   ` (5 preceding siblings ...)
  2015-06-12 12:59 ` [PATCH v6 12/15] drm/exynos: dsi: add support for Exynos5433 Hyungwon Hwang
@ 2015-06-12 12:59 ` Hyungwon Hwang
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel, devicetree; +Cc: sw0312.kim

On some board, TE GPIO should be configured properly thoughout pinctrl driver
as an wakeup interrupt. So this gpio should be configurable in the board's DT,
not being requested as a input pin.

Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
---
Changes before:
- Refer https://patchwork.kernel.org/patch/6191811
Changes for v6:
- None

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 0719114..0e58b36 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1327,15 +1327,15 @@ static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi)
 		goto out;
 	}

-	ret = gpio_request_one(dsi->te_gpio, GPIOF_IN, "te_gpio");
+	ret = gpio_request(dsi->te_gpio, "te_gpio");
 	if (ret) {
 		dev_err(dsi->dev, "gpio request failed with %d\n", ret);
 		goto out;
 	}

 	te_gpio_irq = gpio_to_irq(dsi->te_gpio);
-
 	irq_set_status_flags(te_gpio_irq, IRQ_NOAUTOEN);
+
 	ret = request_threaded_irq(te_gpio_irq, exynos_dsi_te_irq_handler, NULL,
 					IRQF_TRIGGER_RISING, "TE", dsi);
 	if (ret) {
--
1.9.1

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

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

* [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi'
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                     ` (6 preceding siblings ...)
  2015-06-12 12:59   ` [PATCH v6 13/15] drm/exynos: dsi: add support for MIC driver as a bridge Hyungwon Hwang
@ 2015-06-12 12:59   ` Hyungwon Hwang
  2015-06-22  9:10     ` Inki Dae
  2015-06-12 12:59   ` [PATCH 1/2] drm/exynos: ipp: fix wrong index referencing a config element Hyungwon Hwang
                     ` (2 subsequent siblings)
  10 siblings, 1 reply; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: inki.dae-Sze3O3UU22JBDgjK7y7TUQ, daniel-rLtY4a/8tF1rovVCs/uTlw,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ, Hyungwon Hwang

The clock which was named as 'pll_clk' is actually not the clock source
of PLL in MIPI DSI. This patch fixes this disagreement.

Signed-off-by: Hyungwon Hwang <human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
Changes before:
- Refer https://patchwork.kernel.org/patch/6191811
Changes for v6:
- None

 arch/arm/boot/dts/exynos4.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index e20cdc2..1538d7a 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -167,7 +167,7 @@
 		phys = <&mipi_phy 1>;
 		phy-names = "dsim";
 		clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
-		clock-names = "bus_clk", "pll_clk";
+		clock-names = "bus_clk", "sclk_mipi";
 		status = "disabled";
 		#address-cells = <1>;
 		#size-cells = <0>;
--
1.9.1

--
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 related	[flat|nested] 50+ messages in thread

* [PATCH 1/2] drm/exynos: ipp: fix wrong index referencing a config element
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                     ` (7 preceding siblings ...)
  2015-06-12 12:59   ` [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi' Hyungwon Hwang
@ 2015-06-12 12:59   ` Hyungwon Hwang
  2015-06-12 13:02     ` Hyungwon Hwang
  2015-06-12 12:59   ` [PATCH 2/3] ARM: dts: Add the reference node for syscon to mipi phy for Exynos3250 Hyungwon Hwang
  2015-06-12 12:59   ` [v3,2/3] drm/panel: add s6e63j0x03 LCD panel driver Hyungwon Hwang
  10 siblings, 1 reply; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: inki.dae-Sze3O3UU22JBDgjK7y7TUQ, daniel-rLtY4a/8tF1rovVCs/uTlw,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ, Hyungwon Hwang

Config depends on the opreation. So it must be referenced by an
operation id, not a property id.

Signed-off-by: Hyungwon Hwang <human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 drivers/gpu/drm/exynos/exynos_drm_ipp.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index b7f1cbc..54c5cf4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -486,8 +486,7 @@ static int ipp_validate_mem_node(struct drm_device *drm_dev,
 	unsigned int bpp;
 	int i;
 
-	/* The property id should already be varified */
-	ipp_cfg = &c_node->property.config[m_node->prop_id];
+	ipp_cfg = &c_node->property.config[m_node->ops_id];
 	num_plane = drm_format_num_planes(ipp_cfg->fmt);
 
 	/**
-- 
1.9.1

--
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 related	[flat|nested] 50+ messages in thread

* [PATCH 2/2] drm/exynos: ipp: validate a GEM handle with multiple planes
  2015-06-12 12:58 [PATCH v6 00/15] Add drivers for Exynos5433 display Hyungwon Hwang
                   ` (7 preceding siblings ...)
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2015-06-12 12:59 ` Hyungwon Hwang
  2015-06-12 13:02   ` Hyungwon Hwang
  2015-06-12 12:59   ` Hyungwon Hwang
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel, devicetree; +Cc: sw0312.kim

FIMC & GSC driver can calculate the offset of planes. So there are
use cases which IPP receives just one GEM handle of an image with
multiple plane. This patch extends ipp_validate_mem_node() to validate
this case.

Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_ipp.c | 51 ++++++++++++++++++++++++---------
 1 file changed, 38 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 54c5cf4..b3dc778 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -482,8 +482,8 @@ static int ipp_validate_mem_node(struct drm_device *drm_dev,
 {
 	struct drm_exynos_ipp_config *ipp_cfg;
 	unsigned int num_plane;
-	unsigned long min_size, size;
-	unsigned int bpp;
+	unsigned long size, buf_size = 0, plane_size, img_size = 0;
+	unsigned int bpp, width, height;
 	int i;
 
 	ipp_cfg = &c_node->property.config[m_node->ops_id];
@@ -497,20 +497,45 @@ static int ipp_validate_mem_node(struct drm_device *drm_dev,
 	 * but it seems more than enough
 	 */
 	for (i = 0; i < num_plane; ++i) {
-		if (!m_node->buf_info.handles[i]) {
-			DRM_ERROR("invalid handle for plane %d\n", i);
-			return -EINVAL;
-		}
+		width = ipp_cfg->sz.hsize;
+		height = ipp_cfg->sz.vsize;
 		bpp = drm_format_plane_cpp(ipp_cfg->fmt, i);
-		min_size = (ipp_cfg->sz.hsize * ipp_cfg->sz.vsize * bpp) >> 3;
-		size = exynos_drm_gem_get_size(drm_dev,
-					       m_node->buf_info.handles[i],
-					       c_node->filp);
-		if (min_size > size) {
-			DRM_ERROR("invalid size for plane %d\n", i);
-			return -EINVAL;
+
+		/*
+		 * The result of drm_format_plane_cpp() for chroma planes must
+		 * be used with drm_format_xxxx_chroma_subsampling() for
+		 * correct result.
+		 */
+		if (i > 0) {
+			width /= drm_format_horz_chroma_subsampling(
+								ipp_cfg->fmt);
+			height /= drm_format_vert_chroma_subsampling(
+								ipp_cfg->fmt);
 		}
+		plane_size = width * height * bpp;
+		img_size += plane_size;
+
+		if (m_node->buf_info.handles[i]) {
+			size = exynos_drm_gem_get_size(drm_dev,
+					m_node->buf_info.handles[i],
+					c_node->filp);
+			if (plane_size > size) {
+				DRM_ERROR(
+					"buffer %d is smaller than required\n",
+					i);
+				return -EINVAL;
+			}
+
+			buf_size += size;
+		}
+	}
+
+	if (buf_size < img_size) {
+		DRM_ERROR("size of buffers(%lu) is smaller than image(%lu)\n",
+			buf_size, img_size);
+		return -EINVAL;
 	}
+
 	return 0;
 }
 
-- 
1.9.1

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

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

* [PATCH] ARM: dts: set display clock correctly for exynos4412-trats2
  2015-06-12 12:58 [PATCH v6 00/15] Add drivers for Exynos5433 display Hyungwon Hwang
@ 2015-06-12 12:59   ` Hyungwon Hwang
  2015-06-12 12:58 ` [PATCH v6 03/15] drm/exynos: add drm_iommu_attach_device_if_possible() Hyungwon Hwang
                     ` (10 subsequent siblings)
  11 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel, devicetree; +Cc: sw0312.kim, stable, Kukjin Kim

From: Inki Dae <inki.dae@samsung.com>

This patch sets display clock correctly. If Display clock isn't set
correctly then you would find below messages and Display controller
doesn't work correctly.

 exynos-drm: No connectors reported connected with modes
 [drm] Cannot find any crtc or sizes - going 1024x768

Fixes: abc0b1447d49 ("drm: Perform basic sanity checks on probed modes")
Cc: <stable@vger.kernel.org>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Tested-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Kukjin Kim <kgene@kernel.org>
---
 arch/arm/boot/dts/exynos4412-trats2.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index 173ffa4..792394d 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -736,7 +736,7 @@
 
 			display-timings {
 				timing-0 {
-					clock-frequency = <0>;
+					clock-frequency = <57153600>;
 					hactive = <720>;
 					vactive = <1280>;
 					hfront-porch = <5>;
-- 
1.9.1

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

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

* [PATCH] ARM: dts: set display clock correctly for exynos4412-trats2
@ 2015-06-12 12:59   ` Hyungwon Hwang
  0 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel, devicetree
  Cc: inki.dae, daniel, sw0312.kim, jy0922.shim, stable, Kukjin Kim

From: Inki Dae <inki.dae@samsung.com>

This patch sets display clock correctly. If Display clock isn't set
correctly then you would find below messages and Display controller
doesn't work correctly.

 exynos-drm: No connectors reported connected with modes
 [drm] Cannot find any crtc or sizes - going 1024x768

Fixes: abc0b1447d49 ("drm: Perform basic sanity checks on probed modes")
Cc: <stable@vger.kernel.org>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Tested-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Kukjin Kim <kgene@kernel.org>
---
 arch/arm/boot/dts/exynos4412-trats2.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index 173ffa4..792394d 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -736,7 +736,7 @@
 
 			display-timings {
 				timing-0 {
-					clock-frequency = <0>;
+					clock-frequency = <57153600>;
 					hactive = <720>;
 					vactive = <1280>;
 					hfront-porch = <5>;
-- 
1.9.1


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

* [PATCH 1/3] drm/panel: add s6e63j0x03 LCD panel driver
  2015-06-12 12:58 [PATCH v6 00/15] Add drivers for Exynos5433 display Hyungwon Hwang
                   ` (9 preceding siblings ...)
  2015-06-12 12:59   ` Hyungwon Hwang
@ 2015-06-12 12:59 ` Hyungwon Hwang
  2015-06-12 13:02   ` Hyungwon Hwang
  2015-06-12 12:59 ` [PATCH 3/3] ARM: dts: fix the clock-frequency of rinato board's panel Hyungwon Hwang
  11 siblings, 1 reply; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel, devicetree; +Cc: sw0312.kim

From: Inki Dae <inki.dae@samsung.com>

This patch adds MIPI-DSI based S6E63J0X03 AMOLED LCD panel driver
which uses mipi_dsi bus to communicate with panel. The panel has
320×320 resolution in 1.63-inch physical panel. This panel is used in
Samsung Galaxy Gear 2.

Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 31 +++++++++++++++++++------------
 drivers/gpu/drm/panel/Kconfig           |  6 ++++++
 drivers/gpu/drm/panel/Makefile          |  1 +
 3 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 5576cc3..6cb4887 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -743,6 +743,14 @@ static void exynos_dsi_disable_clock(struct exynos_dsi *dsi)
 	DSI_WRITE(dsi, DSIM_PLLCTRL_REG, reg);
 }
 
+static void exynos_dsi_enable_lane(struct exynos_dsi *dsi, u32 lane)
+{
+	u32 reg = DSI_READ(dsi, DSIM_CONFIG_REG);
+	reg |= (DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1) | DSIM_LANE_EN_CLK |
+			DSIM_LANE_EN(lane));
+	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
+}
+
 static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 {
 	struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
@@ -815,17 +823,6 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 		return -EINVAL;
 	}
 
-	reg |= DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1);
-
-	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
-
-	reg |= DSIM_LANE_EN_CLK;
-	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
-
-	lanes_mask = BIT(dsi->lanes) - 1;
-	reg |= DSIM_LANE_EN(lanes_mask);
-	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
-
 	/*
 	 * Use non-continuous clock mode if the periparal wants and
 	 * host controller supports
@@ -837,8 +834,11 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 	if (driver_data->has_clklane_stop &&
 			dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
 		reg |= DSIM_CLKLANE_STOP;
-		DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
 	}
+	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
+
+	lanes_mask = BIT(dsi->lanes) - 1;
+	exynos_dsi_enable_lane(dsi, lanes_mask);
 
 	/* Check clock and data lane state are stop state */
 	timeout = 100;
@@ -1301,6 +1301,10 @@ static int exynos_dsi_init(struct exynos_dsi *dsi)
 
 	exynos_dsi_reset(dsi);
 	exynos_dsi_enable_irq(dsi);
+
+	if (driver_data->values[RESET_TYPE] == DSIM_FUNCRST)
+		exynos_dsi_enable_lane(dsi, BIT(dsi->lanes) - 1);
+
 	exynos_dsi_enable_clock(dsi);
 	if (driver_data->wait_for_reset)
 		exynos_dsi_wait_for_reset(dsi);
@@ -1893,6 +1897,9 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	dsi->clks = devm_kzalloc(dev,
 			sizeof(*dsi->clks) * dsi->driver_data->num_clks,
 			GFP_KERNEL);
+	if (!dsi->clks)
+		goto err_del_component;
+
 	for (i = 0; i < dsi->driver_data->num_clks; i++) {
 		dsi->clks[i] = devm_clk_get(dev, clk_names[i]);
 		if (IS_ERR(dsi->clks[i])) {
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 6d64c7b..cb07bc6 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -43,4 +43,10 @@ config DRM_PANEL_SHARP_LQ101R1SX01
 	  To compile this driver as a module, choose M here: the module
 	  will be called panel-sharp-lq101r1sx01.
 
+config DRM_PANEL_S6E63J0X03
+	tristate "S6E63J0X03 DSI video mode panel"
+	depends on OF
+	select DRM_MIPI_DSI
+	select VIDEOMODE_HELPERS
+
 endmenu
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 4b2a043..27b0a90 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
 obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o
 obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
 obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
+obj-$(CONFIG_DRM_PANEL_S6E63J0X03) += panel-s6e63j0x03.o
-- 
1.9.1

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

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

* [PATCH 2/3] ARM: dts: Add the reference node for syscon to mipi phy for Exynos3250
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                     ` (8 preceding siblings ...)
  2015-06-12 12:59   ` [PATCH 1/2] drm/exynos: ipp: fix wrong index referencing a config element Hyungwon Hwang
@ 2015-06-12 12:59   ` Hyungwon Hwang
  2015-06-12 13:02     ` Hyungwon Hwang
  2015-06-12 12:59   ` [v3,2/3] drm/panel: add s6e63j0x03 LCD panel driver Hyungwon Hwang
  10 siblings, 1 reply; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: inki.dae-Sze3O3UU22JBDgjK7y7TUQ, daniel-rLtY4a/8tF1rovVCs/uTlw,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ, Hyungwon Hwang

Exynos mipi phy driver needs syscon node to be probed successfully.

Signed-off-by: Hyungwon Hwang <human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/boot/dts/exynos3250.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index e3bfb11..f8c02dd 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -140,6 +140,7 @@
 			compatible = "samsung,s5pv210-mipi-video-phy";
 			reg = <0x10020710 8>;
 			#phy-cells = <1>;
+			syscon = <&pmu_system_controller>;
 		};
 
 		pd_cam: cam-power-domain@10023C00 {
-- 
1.9.1

--
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 related	[flat|nested] 50+ messages in thread

* [PATCH 3/3] ARM: dts: fix the clock-frequency of rinato board's panel
  2015-06-12 12:58 [PATCH v6 00/15] Add drivers for Exynos5433 display Hyungwon Hwang
                   ` (10 preceding siblings ...)
  2015-06-12 12:59 ` [PATCH 1/3] drm/panel: add s6e63j0x03 LCD panel driver Hyungwon Hwang
@ 2015-06-12 12:59 ` Hyungwon Hwang
  2015-06-12 13:02   ` Hyungwon Hwang
  11 siblings, 1 reply; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel, devicetree; +Cc: sw0312.kim

After the commit abc0b1447d4974963548777a5ba4a4457c82c426
("drm: Perform basic sanity checks on probed modes"), proper
clock-frequency becomes mandatory for validating the mode of panel.
The display does not work if there is no mode validated. Also, this
clock-frequency must be set appropriately for getting required frame
rate.

Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
---
 arch/arm/boot/dts/exynos3250-rinato.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 0b99068..75aba40 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -181,7 +181,7 @@
 
 		display-timings {
 			timing-0 {
-				clock-frequency = <0>;
+				clock-frequency = <4600000>;
 				hactive = <320>;
 				vactive = <320>;
 				hfront-porch = <1>;
-- 
1.9.1

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

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

* [v3,2/3] drm/panel: add s6e63j0x03 LCD panel driver
       [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                     ` (9 preceding siblings ...)
  2015-06-12 12:59   ` [PATCH 2/3] ARM: dts: Add the reference node for syscon to mipi phy for Exynos3250 Hyungwon Hwang
@ 2015-06-12 12:59   ` Hyungwon Hwang
  10 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 12:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: inki.dae-Sze3O3UU22JBDgjK7y7TUQ, daniel-rLtY4a/8tF1rovVCs/uTlw,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ, Hyungwon Hwang,
	treding-DDmLM1+adcrQT0dZR+AlfA

From: Inki Dae <inki.dae-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>

This patch adds MIPI-DSI based S6E63J0X03 AMOLED LCD panel driver
which uses mipi_dsi bus to communicate with panel. The panel has
320×320 resolution in 1.63-inch physical panel. This panel is used in
Samsung Galaxy Gear 2.

Signed-off-by: Inki Dae <inki.dae-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Hyungwon Hwang <human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>

---
Changes for v2:
- Change the gamma table to 2-dimensional array
- Change the way to make index for brightness
- Make command functions to an array so that it can be called simply
- Change command id for reading device ID
- Change the way to handle the error condition
- Remove power variable, and use the same name variable in bl_dev
- Add the state FB_BLANK_NORMAL to represent the state which the panel
is working but blanked
- Miscellaneous changes to increase the readability and follow the
  coding-style standard
Changes for v3:
- Add DT binding documentation
- Add the code getting DT properties of 'panel-width-mm' and 'panel-height-mm'
- Remove the code getting unnecessary DT properties flip-*
 .../bindings/panel/samsung,s6e63j0x03.txt          |  55 +++
 drivers/gpu/drm/panel/Kconfig                      |   6 +
 drivers/gpu/drm/panel/Makefile                     |   1 +
 drivers/gpu/drm/panel/panel-s6e63j0x03.c           | 546 +++++++++++++++++++++
 4 files changed, 608 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt
 create mode 100644 drivers/gpu/drm/panel/panel-s6e63j0x03.c

--
1.9.1

diff --git a/Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt b/Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt
new file mode 100644
index 0000000..f8215e4
--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt
@@ -0,0 +1,55 @@
+Samsung S6E63J0X03 1.63" 320x320 TFT LCD panel
+
+Required properties:
+  - compatible: "samsung,s6e63j0x03"
+  - reg: the virtual channel number of a DSI peripheral
+  - vdd3-supply: core voltage supply
+  - vci-supply: voltage supply for analog circuits
+  - reset-gpios: a GPIO spec for the reset pin
+  - te-gpios: a GPIO spec for the tearing effect synchronization signal gpio pin
+
+Optional properties:
+  - display-timings: timings for the connected panel as described by [1]
+  - power-on-delay: delay after turning regulators on [ms]
+  - power-off-delay: delay after turning regulators off [ms]
+  - reset-delay: delay after reset sequence [ms]
+  - panel-width-mm: physical panel width [mm]
+  - panel-height-mm: physical panel height [mm]
+
+The device node can contain one 'port' child node with one child
+'endpoint' node, according to the bindings defined in [2]. This
+node should describe panel's video bus.
+
+[1]: Documentation/devicetree/bindings/video/display-timing.txt
+[2]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example:
+
+panel@0 {
+	compatible = "samsung,s6e63j0x03";
+	reg = <0>;
+	vdd3-supply = <&ldo16_reg>;
+	vci-supply = <&ldo20_reg>;
+	reset-gpios = <&gpe0 1 0>;
+	te-gpios = <&gpx0 6 0>;
+	power-on-delay= <30>;
+	power-off-delay= <120>;
+	reset-delay = <5>;
+	init-delay = <100>;
+	panel-width-mm = <29>;
+	panel-height-mm = <29>;
+
+	display-timings {
+		timing-0 {
+			clock-frequency = <0>;
+			hactive = <320>;
+			vactive = <320>;
+			hfront-porch = <1>;
+			hback-porch = <1>;
+			hsync-len = <1>;
+			vfront-porch = <150>;
+			vback-porch = <1>;
+			vsync-len = <2>;
+		};
+	};
+};
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 3df9b9b..8fa7610 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -46,4 +46,10 @@ config DRM_PANEL_S6E3HA2
 	select DRM_MIPI_DSI
 	select VIDEOMODE_HELPERS

+config DRM_PANEL_S6E63J0X03
+	tristate "S6E63J0X03 DSI video mode panel"
+	depends on OF
+	select DRM_MIPI_DSI
+	select VIDEOMODE_HELPERS
+
 endmenu
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 16ff312..9054da1 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o
 obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
 obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
 obj-$(CONFIG_DRM_PANEL_S6E3HA2) += panel-s6e3ha2.o
+obj-$(CONFIG_DRM_PANEL_S6E63J0X03) += panel-s6e63j0x03.o
diff --git a/drivers/gpu/drm/panel/panel-s6e63j0x03.c b/drivers/gpu/drm/panel/panel-s6e63j0x03.c
new file mode 100644
index 0000000..51cf1f6
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-s6e63j0x03.c
@@ -0,0 +1,546 @@
+/*
+ * MIPI-DSI based S6E63J0X03 AMOLED lcd 1.63 inch panel driver.
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd
+ *
+ * Inki Dae, <inki.dae-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *
+ * 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.
+*/
+
+#include <drm/drmP.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/backlight.h>
+
+#include <video/mipi_display.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+#define READ_ID1		0xDA
+#define READ_ID2		0xDB
+#define READ_ID3		0xDC
+
+#define MCS_LEVEL2_KEY		0xf0
+#define MCS_MTP_KEY		0xf1
+#define MCS_MTP_SET3		0xd4
+
+#define MIN_BRIGHTNESS		0
+#define MAX_BRIGHTNESS		100
+#define DEFAULT_BRIGHTNESS	80
+
+#define GAMMA_LEVEL_NUM		30
+#define NUM_GAMMA_STEPS		9
+#define GAMMA_CMD_CNT		28
+
+struct s6e63j0x03 {
+	struct device *dev;
+	struct drm_panel panel;
+	struct backlight_device *bl_dev;
+
+	struct regulator_bulk_data supplies[2];
+	struct gpio_desc *reset_gpio;
+	u32 power_on_delay;
+	u32 power_off_delay;
+	u32 reset_delay;
+	u32 init_delay;
+	struct videomode vm;
+	unsigned int width_mm;
+	unsigned int height_mm;
+};
+
+static const unsigned char gamma_tbl[NUM_GAMMA_STEPS][GAMMA_CMD_CNT] = {
+	{	/* Gamma 10 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x52, 0x6b, 0x6f, 0x26,
+		0x28, 0x2d, 0x28, 0x26, 0x27, 0x33, 0x34, 0x32, 0x36, 0x36,
+		0x35, 0x00, 0xab, 0x00, 0xae, 0x00, 0xbf
+	},
+	{	/* gamma 30 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x70, 0x7f, 0x7f, 0x4e, 0x64, 0x69, 0x26,
+		0x27, 0x2a, 0x28, 0x29, 0x27, 0x31, 0x32, 0x31, 0x35, 0x34,
+		0x35, 0x00, 0xc4, 0x00, 0xca, 0x00, 0xdc
+	},
+	{	/* gamma 60 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x65, 0x7b, 0x7d, 0x5f, 0x67, 0x68, 0x2a,
+		0x28, 0x29, 0x28, 0x2a, 0x27, 0x31, 0x2f, 0x30, 0x34, 0x33,
+		0x34, 0x00, 0xd9, 0x00, 0xe4, 0x00, 0xf5
+	},
+	{	/* gamma 90 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x4d, 0x6f, 0x71, 0x67, 0x6a, 0x6c, 0x29,
+		0x28, 0x28, 0x28, 0x29, 0x27, 0x30, 0x2e, 0x30, 0x32, 0x31,
+		0x31, 0x00, 0xea, 0x00, 0xf6, 0x01, 0x09
+	},
+	{	/* gamma 120 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x3d, 0x66, 0x68, 0x69, 0x69, 0x69, 0x28,
+		0x28, 0x27, 0x28, 0x28, 0x27, 0x30, 0x2e, 0x2f, 0x31, 0x31,
+		0x30, 0x00, 0xf9, 0x01, 0x05, 0x01, 0x1b
+	},
+	{	/* gamma 150 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x31, 0x51, 0x53, 0x66, 0x66, 0x67, 0x28,
+		0x29, 0x27, 0x28, 0x27, 0x27, 0x2e, 0x2d, 0x2e, 0x31, 0x31,
+		0x30, 0x01, 0x04, 0x01, 0x11, 0x01, 0x29
+	},
+	{	/* gamma 200 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x2f, 0x4f, 0x51, 0x67, 0x65, 0x65, 0x29,
+		0x2a, 0x28, 0x27, 0x25, 0x26, 0x2d, 0x2c, 0x2c, 0x30, 0x30,
+		0x30, 0x01, 0x14, 0x01, 0x23, 0x01, 0x3b
+	},
+	{	/* gamma 240 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x2c, 0x4d, 0x50, 0x65, 0x63, 0x64, 0x2a,
+		0x2c, 0x29, 0x26, 0x24, 0x25, 0x2c, 0x2b, 0x2b, 0x30, 0x30,
+		0x30, 0x01, 0x1e, 0x01, 0x2f, 0x01, 0x47
+	},
+	{	/* gamma 300 */
+		MCS_MTP_SET3,
+		0x00, 0x00, 0x00, 0x38, 0x61, 0x64, 0x65, 0x63, 0x64, 0x28,
+		0x2a, 0x27, 0x26, 0x23, 0x25, 0x2b, 0x2b, 0x2a, 0x30, 0x2f,
+		0x30, 0x01, 0x2d, 0x01, 0x3f, 0x01, 0x57
+	}
+};
+
+static const unsigned char prepare_cmds1[][15] = {
+	{ 3, 0xf2, 0x1c, 0x28 },		/* porch_adjustment */
+	{ 4, 0xb5, 0x00, 0x02, 0x00 },		/* frame_freq */
+	{ 5, 0x2a, 0x00, 0x14, 0x01, 0x53 },	/* mem_addr_set_0 */
+	{ 5, 0x2b, 0x00, 0x00, 0x01, 0x3f },	/* mem_addr_set_1 */
+	{ 14, 0xf8, 0x08, 0x08, 0x08, 0x17,	/* ltps_timming_set_0_60hz */
+	      0x00, 0x2a, 0x02, 0x26,
+	      0x00, 0x00, 0x02, 0x00, 0x00 },
+	{ 2, 0xf7, 0x02 },			/* ltps_timming_set_1 */
+	{ 2, 0xb0, 0x01 },			/* param_pos_te_edge */
+	{ 2, 0xe2, 0x0f },			/* te_rising_edge */
+	{ 2, 0xb0, 0x00 },			/* param_pos_default */
+	{ 1, MIPI_DCS_EXIT_SLEEP_MODE },
+};
+
+static const  unsigned char prepare_cmds2[][4] = {
+	{ 3, 0xb1, 0x00, 0x09 },	/* elvss_cond */
+	{ 2, 0x36, 0x40 },		/* set_pos */
+	{ 2, 0x51, 0xff },		/* white_brightness_default */
+	{ 2, 0x53, 0x20 },		/* white_ctrl */
+	{ 2, 0x55, 0x00 },		/* acl_off */
+	{ 1, MIPI_DCS_SET_TEAR_ON },
+};
+
+
+static inline struct s6e63j0x03 *panel_to_s6e63j0x03(struct drm_panel *panel)
+{
+	return container_of(panel, struct s6e63j0x03, panel);
+}
+
+static inline ssize_t s6e63j0x03_dcs_write_seq(struct s6e63j0x03 *ctx,
+					const u8 *seq, const unsigned char len)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+	return mipi_dsi_dcs_write(dsi, seq, len);
+}
+
+static inline int s6e63j0x03_enable_lv2_command(struct s6e63j0x03 *ctx)
+{
+	unsigned char seq[] = { MCS_LEVEL2_KEY, 0x5a, 0x5a };
+
+	return s6e63j0x03_dcs_write_seq(ctx, seq, ARRAY_SIZE(seq));
+}
+
+static inline int s6e63j0x03_apply_mtp_key(struct s6e63j0x03 *ctx, bool on)
+{
+	unsigned char seq1[3] = { MCS_MTP_KEY, 0x5a, 0x5a };
+	unsigned char seq2[3] = { MCS_MTP_KEY, 0xa5, 0xa5 };
+
+	return s6e63j0x03_dcs_write_seq(ctx, on ? seq1 : seq2,
+					ARRAY_SIZE(seq1));
+}
+
+static int s6e63j0x03_read_mtp_id(struct s6e63j0x03 *ctx)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	unsigned char cmds[3] = { READ_ID1, READ_ID2, READ_ID3 };
+	unsigned char id[3];
+	int ret;
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		ret = mipi_dsi_dcs_read(dsi, cmds[i], &id[i], 1);
+
+		if (ret < 0)
+			return ret;
+	}
+
+	dev_info(ctx->dev, "ID: 0x%02x, 0x%02x, 0x%02x\n", id[0], id[1], id[2]);
+
+	return 0;
+}
+
+static int s6e63j0x03_power_on(struct s6e63j0x03 *ctx)
+{
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret < 0)
+		return ret;
+
+	msleep(ctx->power_on_delay);
+
+	gpiod_set_value(ctx->reset_gpio, 0);
+	usleep_range(1000, 2000);
+	gpiod_set_value(ctx->reset_gpio, 1);
+
+	usleep_range(ctx->reset_delay * 1000, (ctx->reset_delay + 1) * 1000);
+
+	return 0;
+}
+
+static int s6e63j0x03_power_off(struct s6e63j0x03 *ctx)
+{
+	int ret;
+
+	gpiod_set_value(ctx->reset_gpio, 0);
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int s6e63j0x03_get_brightness(struct backlight_device *bl_dev)
+{
+	return bl_dev->props.brightness;
+}
+
+static unsigned int s6e63j0x03_get_brightness_index(unsigned int brightness)
+{
+	unsigned int index;
+
+	index = brightness / (MAX_BRIGHTNESS / NUM_GAMMA_STEPS);
+
+	if (index >= NUM_GAMMA_STEPS)
+		index = NUM_GAMMA_STEPS - 1;
+
+	return index;
+}
+
+static int s6e63j0x03_update_gamma(struct s6e63j0x03 *ctx,
+					unsigned int brightness)
+{
+	struct backlight_device *bl_dev = ctx->bl_dev;
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	unsigned int index = s6e63j0x03_get_brightness_index(brightness);
+	int ret;
+
+	ret = s6e63j0x03_apply_mtp_key(ctx, true);
+	if (ret < 0)
+		return ret;
+
+	ret = mipi_dsi_dcs_write(dsi, gamma_tbl[index], GAMMA_CMD_CNT);
+	if (ret < 0)
+		return ret;
+
+	ret = s6e63j0x03_apply_mtp_key(ctx, false);
+	if (ret < 0)
+		return ret;
+
+	bl_dev->props.brightness = brightness;
+
+	return 0;
+}
+
+static int s6e63j0x03_set_brightness(struct backlight_device *bl_dev)
+{
+	struct s6e63j0x03 *ctx = (struct s6e63j0x03 *)bl_get_data(bl_dev);
+	unsigned int brightness = bl_dev->props.brightness;
+	int ret;
+
+	if (brightness < MIN_BRIGHTNESS ||
+		brightness > bl_dev->props.max_brightness) {
+		dev_err(ctx->dev, "Invalid brightness: %u\n", brightness);
+		return -EINVAL;
+	}
+
+	if (bl_dev->props.power > FB_BLANK_NORMAL) {
+		dev_err(ctx->dev,
+			"panel must be at least in fb blank normal state\n");
+		return -EPERM;
+	}
+
+	ret = s6e63j0x03_update_gamma(ctx, brightness);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static const struct backlight_ops s6e63j0x03_bl_ops = {
+	.get_brightness = s6e63j0x03_get_brightness,
+	.update_status = s6e63j0x03_set_brightness,
+};
+
+static int s6e63j0x03_disable(struct drm_panel *panel)
+{
+	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
+	struct backlight_device *bl_dev = ctx->bl_dev;
+	u8 seq[] = { MIPI_DCS_SET_DISPLAY_OFF };
+	int ret;
+
+	ret = s6e63j0x03_dcs_write_seq(ctx, seq, ARRAY_SIZE(seq));
+	if (ret > 0)
+		bl_dev->props.power = FB_BLANK_NORMAL;
+
+	return 0;
+}
+
+static int s6e63j0x03_unprepare(struct drm_panel *panel)
+{
+	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
+	struct backlight_device *bl_dev = ctx->bl_dev;
+	u8 seq[] = { MIPI_DCS_ENTER_SLEEP_MODE };
+	int ret;
+
+	ret = s6e63j0x03_dcs_write_seq(ctx, seq, ARRAY_SIZE(seq));
+	if (ret < 0)
+		return ret;
+
+	msleep(ctx->power_off_delay);
+
+	ret = s6e63j0x03_power_off(ctx);
+	if (ret < 0)
+		return ret;
+
+	bl_dev->props.power = FB_BLANK_POWERDOWN;
+
+	return 0;
+}
+
+static int s6e63j0x03_prepare(struct drm_panel *panel)
+{
+	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
+	struct backlight_device *bl_dev = ctx->bl_dev;
+	int ret;
+	int i;
+
+	ret = s6e63j0x03_power_on(ctx);
+	if (ret < 0)
+		return ret;
+
+	ret = s6e63j0x03_enable_lv2_command(ctx);
+	if (ret < 0)
+		return ret;
+
+	ret = s6e63j0x03_apply_mtp_key(ctx, true);
+	if (ret < 0)
+		return ret;
+
+	ret = s6e63j0x03_read_mtp_id(ctx);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(prepare_cmds1); i++) {
+		ret = s6e63j0x03_dcs_write_seq(ctx, &prepare_cmds1[i][1],
+							prepare_cmds1[i][0]);
+		if (ret < 0)
+			return ret;
+	}
+
+	msleep(120);
+
+	for (i = 0; i < ARRAY_SIZE(prepare_cmds2); i++) {
+		ret = s6e63j0x03_dcs_write_seq(ctx, &prepare_cmds2[i][1],
+							prepare_cmds2[i][0]);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = s6e63j0x03_apply_mtp_key(ctx, false);
+	if (ret < 0)
+		return ret;
+
+	bl_dev->props.power = FB_BLANK_NORMAL;
+
+	return 0;
+}
+
+static int s6e63j0x03_enable(struct drm_panel *panel)
+{
+	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
+	struct backlight_device *bl_dev = ctx->bl_dev;
+	u8 seq[] = { MIPI_DCS_SET_DISPLAY_ON };
+	int ret;
+
+	ret = s6e63j0x03_dcs_write_seq(ctx, seq, ARRAY_SIZE(seq));
+	if (ret > 0)
+		bl_dev->props.power = FB_BLANK_UNBLANK;
+
+	return 0;
+}
+
+static int s6e63j0x03_get_modes(struct drm_panel *panel)
+{
+	struct drm_connector *connector = panel->connector;
+	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
+	struct drm_display_mode *mode;
+
+	mode = drm_mode_create(connector->dev);
+	if (!mode) {
+		DRM_ERROR("failed to create a new display mode\n");
+		return 0;
+	}
+
+	drm_display_mode_from_videomode(&ctx->vm, mode);
+	mode->width_mm = ctx->width_mm;
+	mode->height_mm = ctx->height_mm;
+	connector->display_info.width_mm = mode->width_mm;
+	connector->display_info.height_mm = mode->height_mm;
+
+	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+	drm_mode_probed_add(connector, mode);
+
+	return 1;
+}
+
+static const struct drm_panel_funcs s6e63j0x03_funcs = {
+	.disable = s6e63j0x03_disable,
+	.unprepare = s6e63j0x03_unprepare,
+	.prepare = s6e63j0x03_prepare,
+	.enable = s6e63j0x03_enable,
+	.get_modes = s6e63j0x03_get_modes,
+};
+
+static int s6e63j0x03_parse_dt(struct s6e63j0x03 *ctx)
+{
+	struct device *dev = ctx->dev;
+	struct device_node *np = dev->of_node;
+	int ret;
+
+	ret = of_get_videomode(np, &ctx->vm, 0);
+	if (ret < 0)
+		return ret;
+
+	of_property_read_u32(np, "power-on-delay", &ctx->power_on_delay);
+	of_property_read_u32(np, "power-off-delay", &ctx->power_off_delay);
+	of_property_read_u32(np, "reset-delay", &ctx->reset_delay);
+	of_property_read_u32(np, "init-delay", &ctx->init_delay);
+	of_property_read_u32(np, "panel-width-mm", &ctx->width_mm);
+	of_property_read_u32(np, "panel-height-mm", &ctx->height_mm);
+
+	return ret;
+}
+
+static int s6e63j0x03_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct s6e63j0x03 *ctx;
+	int ret;
+
+	ctx = devm_kzalloc(dev, sizeof(struct s6e63j0x03), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	mipi_dsi_set_drvdata(dsi, ctx);
+
+	ctx->dev = dev;
+
+	dsi->lanes = 1;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+	dsi->mode_flags = MIPI_DSI_MODE_EOT_PACKET | MIPI_DSI_MODE_VIDEO_BURST;
+
+	ret = s6e63j0x03_parse_dt(ctx);
+	if (ret < 0)
+		return ret;
+
+	ctx->supplies[0].supply = "vdd3";
+	ctx->supplies[1].supply = "vci";
+	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
+				      ctx->supplies);
+	if (ret < 0) {
+		dev_err(dev, "failed to get regulators: %d\n", ret);
+		return ret;
+	}
+
+	ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(ctx->reset_gpio)) {
+		dev_err(dev, "cannot get reset-gpio: %ld\n",
+				PTR_ERR(ctx->reset_gpio));
+		return PTR_ERR(ctx->reset_gpio);
+	}
+
+	drm_panel_init(&ctx->panel);
+	ctx->panel.dev = dev;
+	ctx->panel.funcs = &s6e63j0x03_funcs;
+
+	ctx->bl_dev = backlight_device_register("s6e63j0x03", dev, ctx,
+						&s6e63j0x03_bl_ops, NULL);
+	if (IS_ERR(ctx->bl_dev)) {
+		dev_err(dev, "failed to register backlight device\n");
+		return PTR_ERR(ctx->bl_dev);
+	}
+
+	ctx->bl_dev->props.max_brightness = MAX_BRIGHTNESS;
+	ctx->bl_dev->props.brightness = DEFAULT_BRIGHTNESS;
+	ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
+
+
+	ret = drm_panel_add(&ctx->panel);
+	if (ret < 0)
+		goto unregister_backlight;
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret < 0)
+		goto remove_panel;
+
+	return ret;
+
+remove_panel:
+	drm_panel_remove(&ctx->panel);
+
+unregister_backlight:
+	backlight_device_unregister(ctx->bl_dev);
+
+	return ret;
+}
+
+static int s6e63j0x03_remove(struct mipi_dsi_device *dsi)
+{
+	struct s6e63j0x03 *ctx = mipi_dsi_get_drvdata(dsi);
+
+	mipi_dsi_detach(dsi);
+	drm_panel_remove(&ctx->panel);
+
+	backlight_device_unregister(ctx->bl_dev);
+
+	return 0;
+}
+
+static const struct of_device_id s6e63j0x03_of_match[] = {
+	{ .compatible = "samsung,s6e63j0x03" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, s6e63j0x03_of_match);
+
+static struct mipi_dsi_driver s6e63j0x03_driver = {
+	.probe = s6e63j0x03_probe,
+	.remove = s6e63j0x03_remove,
+	.driver = {
+		.name = "panel_s6e63j0x03",
+		.of_match_table = s6e63j0x03_of_match,
+	},
+};
+module_mipi_dsi_driver(s6e63j0x03_driver);
+
+MODULE_AUTHOR("Inki Dae <inki.dae-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>");
+MODULE_DESCRIPTION("MIPI-DSI based s6e8aa0 AMOLED LCD Panel Driver");
+MODULE_LICENSE("GPL v2");
--
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 related	[flat|nested] 50+ messages in thread

* Re: [PATCH 1/2] drm/exynos: ipp: fix wrong index referencing a config element
  2015-06-12 12:59   ` [PATCH 1/2] drm/exynos: ipp: fix wrong index referencing a config element Hyungwon Hwang
@ 2015-06-12 13:02     ` Hyungwon Hwang
  0 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 13:02 UTC (permalink / raw)
  To: Hyungwon Hwang; +Cc: devicetree, sw0312.kim, dri-devel

Please ignore this mail. I didn't know that "git send *" includes all
files in the subdirectories. I am very sorry for disturbing you.

Best regards,
Hyungwon Hwang

On Fri, 12 Jun 2015 21:59:11 +0900
Hyungwon Hwang <human.hwang@samsung.com> wrote:

> Config depends on the opreation. So it must be referenced by an
> operation id, not a property id.
> 
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_ipp.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index b7f1cbc..54c5cf4
> 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> @@ -486,8 +486,7 @@ static int ipp_validate_mem_node(struct
> drm_device *drm_dev, unsigned int bpp;
>  	int i;
>  
> -	/* The property id should already be varified */
> -	ipp_cfg = &c_node->property.config[m_node->prop_id];
> +	ipp_cfg = &c_node->property.config[m_node->ops_id];
>  	num_plane = drm_format_num_planes(ipp_cfg->fmt);
>  
>  	/**

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

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

* Re: [PATCH 2/2] drm/exynos: ipp: validate a GEM handle with multiple planes
  2015-06-12 12:59 ` [PATCH 2/2] drm/exynos: ipp: validate a GEM handle with multiple planes Hyungwon Hwang
@ 2015-06-12 13:02   ` Hyungwon Hwang
  0 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 13:02 UTC (permalink / raw)
  To: Hyungwon Hwang; +Cc: devicetree, sw0312.kim, dri-devel

Please ignore this mail. I didn't know that "git send *" includes all
files in the subdirectories. I am very sorry for disturbing you.

Best regards,
Hyungwon Hwang

On Fri, 12 Jun 2015 21:59:12 +0900
Hyungwon Hwang <human.hwang@samsung.com> wrote:

> FIMC & GSC driver can calculate the offset of planes. So there are
> use cases which IPP receives just one GEM handle of an image with
> multiple plane. This patch extends ipp_validate_mem_node() to validate
> this case.
> 
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_ipp.c | 51
> ++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+),
> 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 54c5cf4..b3dc778
> 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> @@ -482,8 +482,8 @@ static int ipp_validate_mem_node(struct
> drm_device *drm_dev, {
>  	struct drm_exynos_ipp_config *ipp_cfg;
>  	unsigned int num_plane;
> -	unsigned long min_size, size;
> -	unsigned int bpp;
> +	unsigned long size, buf_size = 0, plane_size, img_size = 0;
> +	unsigned int bpp, width, height;
>  	int i;
>  
>  	ipp_cfg = &c_node->property.config[m_node->ops_id];
> @@ -497,20 +497,45 @@ static int ipp_validate_mem_node(struct
> drm_device *drm_dev,
>  	 * but it seems more than enough
>  	 */
>  	for (i = 0; i < num_plane; ++i) {
> -		if (!m_node->buf_info.handles[i]) {
> -			DRM_ERROR("invalid handle for plane %d\n",
> i);
> -			return -EINVAL;
> -		}
> +		width = ipp_cfg->sz.hsize;
> +		height = ipp_cfg->sz.vsize;
>  		bpp = drm_format_plane_cpp(ipp_cfg->fmt, i);
> -		min_size = (ipp_cfg->sz.hsize * ipp_cfg->sz.vsize *
> bpp) >> 3;
> -		size = exynos_drm_gem_get_size(drm_dev,
> -
> m_node->buf_info.handles[i],
> -					       c_node->filp);
> -		if (min_size > size) {
> -			DRM_ERROR("invalid size for plane %d\n", i);
> -			return -EINVAL;
> +
> +		/*
> +		 * The result of drm_format_plane_cpp() for chroma
> planes must
> +		 * be used with drm_format_xxxx_chroma_subsampling()
> for
> +		 * correct result.
> +		 */
> +		if (i > 0) {
> +			width /= drm_format_horz_chroma_subsampling(
> +
> ipp_cfg->fmt);
> +			height /= drm_format_vert_chroma_subsampling(
> +
> ipp_cfg->fmt); }
> +		plane_size = width * height * bpp;
> +		img_size += plane_size;
> +
> +		if (m_node->buf_info.handles[i]) {
> +			size = exynos_drm_gem_get_size(drm_dev,
> +					m_node->buf_info.handles[i],
> +					c_node->filp);
> +			if (plane_size > size) {
> +				DRM_ERROR(
> +					"buffer %d is smaller than
> required\n",
> +					i);
> +				return -EINVAL;
> +			}
> +
> +			buf_size += size;
> +		}
> +	}
> +
> +	if (buf_size < img_size) {
> +		DRM_ERROR("size of buffers(%lu) is smaller than
> image(%lu)\n",
> +			buf_size, img_size);
> +		return -EINVAL;
>  	}
> +
>  	return 0;
>  }
>  

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

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

* Re: [PATCH 1/3] drm/panel: add s6e63j0x03 LCD panel driver
  2015-06-12 12:59 ` [PATCH 1/3] drm/panel: add s6e63j0x03 LCD panel driver Hyungwon Hwang
@ 2015-06-12 13:02   ` Hyungwon Hwang
  0 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 13:02 UTC (permalink / raw)
  To: Hyungwon Hwang; +Cc: devicetree, sw0312.kim, dri-devel

Please ignore this mail. I didn't know that "git send *" includes all
files in the subdirectories. I am very sorry for disturbing you.

Best regards,
Hyungwon Hwang

On Fri, 12 Jun 2015 21:59:14 +0900
Hyungwon Hwang <human.hwang@samsung.com> wrote:

> From: Inki Dae <inki.dae@samsung.com>
> 
> This patch adds MIPI-DSI based S6E63J0X03 AMOLED LCD panel driver
> which uses mipi_dsi bus to communicate with panel. The panel has
> 320×320 resolution in 1.63-inch physical panel. This panel is used in
> Samsung Galaxy Gear 2.
> 
> Signed-off-by: Inki Dae <inki.dae@samsung.com>
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c | 31
> +++++++++++++++++++------------
> drivers/gpu/drm/panel/Kconfig           |  6 ++++++
> drivers/gpu/drm/panel/Makefile          |  1 + 3 files changed, 26
> insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 5576cc3..6cb4887
> 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> @@ -743,6 +743,14 @@ static void exynos_dsi_disable_clock(struct
> exynos_dsi *dsi) DSI_WRITE(dsi, DSIM_PLLCTRL_REG, reg);
>  }
>  
> +static void exynos_dsi_enable_lane(struct exynos_dsi *dsi, u32 lane)
> +{
> +	u32 reg = DSI_READ(dsi, DSIM_CONFIG_REG);
> +	reg |= (DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1) |
> DSIM_LANE_EN_CLK |
> +			DSIM_LANE_EN(lane));
> +	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
> +}
> +
>  static int exynos_dsi_init_link(struct exynos_dsi *dsi)
>  {
>  	struct exynos_dsi_driver_data *driver_data =
> dsi->driver_data; @@ -815,17 +823,6 @@ static int
> exynos_dsi_init_link(struct exynos_dsi *dsi) return -EINVAL;
>  	}
>  
> -	reg |= DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1);
> -
> -	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
> -
> -	reg |= DSIM_LANE_EN_CLK;
> -	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
> -
> -	lanes_mask = BIT(dsi->lanes) - 1;
> -	reg |= DSIM_LANE_EN(lanes_mask);
> -	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
> -
>  	/*
>  	 * Use non-continuous clock mode if the periparal wants and
>  	 * host controller supports
> @@ -837,8 +834,11 @@ static int exynos_dsi_init_link(struct
> exynos_dsi *dsi) if (driver_data->has_clklane_stop &&
>  			dsi->mode_flags &
> MIPI_DSI_CLOCK_NON_CONTINUOUS) { reg |= DSIM_CLKLANE_STOP;
> -		DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
>  	}
> +	DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
> +
> +	lanes_mask = BIT(dsi->lanes) - 1;
> +	exynos_dsi_enable_lane(dsi, lanes_mask);
>  
>  	/* Check clock and data lane state are stop state */
>  	timeout = 100;
> @@ -1301,6 +1301,10 @@ static int exynos_dsi_init(struct exynos_dsi
> *dsi) 
>  	exynos_dsi_reset(dsi);
>  	exynos_dsi_enable_irq(dsi);
> +
> +	if (driver_data->values[RESET_TYPE] == DSIM_FUNCRST)
> +		exynos_dsi_enable_lane(dsi, BIT(dsi->lanes) - 1);
> +
>  	exynos_dsi_enable_clock(dsi);
>  	if (driver_data->wait_for_reset)
>  		exynos_dsi_wait_for_reset(dsi);
> @@ -1893,6 +1897,9 @@ static int exynos_dsi_probe(struct
> platform_device *pdev) dsi->clks = devm_kzalloc(dev,
>  			sizeof(*dsi->clks) *
> dsi->driver_data->num_clks, GFP_KERNEL);
> +	if (!dsi->clks)
> +		goto err_del_component;
> +
>  	for (i = 0; i < dsi->driver_data->num_clks; i++) {
>  		dsi->clks[i] = devm_clk_get(dev, clk_names[i]);
>  		if (IS_ERR(dsi->clks[i])) {
> diff --git a/drivers/gpu/drm/panel/Kconfig
> b/drivers/gpu/drm/panel/Kconfig index 6d64c7b..cb07bc6 100644
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -43,4 +43,10 @@ config DRM_PANEL_SHARP_LQ101R1SX01
>  	  To compile this driver as a module, choose M here: the
> module will be called panel-sharp-lq101r1sx01.
>  
> +config DRM_PANEL_S6E63J0X03
> +	tristate "S6E63J0X03 DSI video mode panel"
> +	depends on OF
> +	select DRM_MIPI_DSI
> +	select VIDEOMODE_HELPERS
> +
>  endmenu
> diff --git a/drivers/gpu/drm/panel/Makefile
> b/drivers/gpu/drm/panel/Makefile index 4b2a043..27b0a90 100644
> --- a/drivers/gpu/drm/panel/Makefile
> +++ b/drivers/gpu/drm/panel/Makefile
> @@ -2,3 +2,4 @@ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
>  obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o
>  obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
>  obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) +=
> panel-sharp-lq101r1sx01.o +obj-$(CONFIG_DRM_PANEL_S6E63J0X03) +=
> panel-s6e63j0x03.o

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

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

* Re: [PATCH 2/3] ARM: dts: Add the reference node for syscon to mipi phy for Exynos3250
  2015-06-12 12:59   ` [PATCH 2/3] ARM: dts: Add the reference node for syscon to mipi phy for Exynos3250 Hyungwon Hwang
@ 2015-06-12 13:02     ` Hyungwon Hwang
  0 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 13:02 UTC (permalink / raw)
  To: Hyungwon Hwang; +Cc: devicetree, sw0312.kim, dri-devel

Please ignore this mail. I didn't know that "git send *" includes all
files in the subdirectories. I am very sorry for disturbing you.

Best regards,
Hyungwon Hwang

On Fri, 12 Jun 2015 21:59:15 +0900
Hyungwon Hwang <human.hwang@samsung.com> wrote:

> Exynos mipi phy driver needs syscon node to be probed successfully.
> 
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> ---
>  arch/arm/boot/dts/exynos3250.dtsi | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/boot/dts/exynos3250.dtsi
> b/arch/arm/boot/dts/exynos3250.dtsi index e3bfb11..f8c02dd 100644
> --- a/arch/arm/boot/dts/exynos3250.dtsi
> +++ b/arch/arm/boot/dts/exynos3250.dtsi
> @@ -140,6 +140,7 @@
>  			compatible =
> "samsung,s5pv210-mipi-video-phy"; reg = <0x10020710 8>;
>  			#phy-cells = <1>;
> +			syscon = <&pmu_system_controller>;
>  		};
>  
>  		pd_cam: cam-power-domain@10023C00 {

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

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

* Re: [PATCH 3/3] ARM: dts: fix the clock-frequency of rinato board's panel
  2015-06-12 12:59 ` [PATCH 3/3] ARM: dts: fix the clock-frequency of rinato board's panel Hyungwon Hwang
@ 2015-06-12 13:02   ` Hyungwon Hwang
  0 siblings, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 13:02 UTC (permalink / raw)
  To: Hyungwon Hwang; +Cc: devicetree, sw0312.kim, dri-devel

Please ignore this mail. I didn't know that "git send *" includes all
files in the subdirectories. I am very sorry for disturbing you.

Best regards,
Hyungwon Hwang

On Fri, 12 Jun 2015 21:59:16 +0900
Hyungwon Hwang <human.hwang@samsung.com> wrote:

> After the commit abc0b1447d4974963548777a5ba4a4457c82c426
> ("drm: Perform basic sanity checks on probed modes"), proper
> clock-frequency becomes mandatory for validating the mode of panel.
> The display does not work if there is no mode validated. Also, this
> clock-frequency must be set appropriately for getting required frame
> rate.
> 
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> ---
>  arch/arm/boot/dts/exynos3250-rinato.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts
> b/arch/arm/boot/dts/exynos3250-rinato.dts index 0b99068..75aba40
> 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts
> +++ b/arch/arm/boot/dts/exynos3250-rinato.dts
> @@ -181,7 +181,7 @@
>  
>  		display-timings {
>  			timing-0 {
> -				clock-frequency = <0>;
> +				clock-frequency = <4600000>;
>  				hactive = <320>;
>  				vactive = <320>;
>  				hfront-porch = <1>;

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

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

* Re: [v3,2/3] drm/panel: add s6e63j0x03 LCD panel driver
  2015-01-19  7:52 ` [PATCH v3 2/3] drm/panel: add s6e63j0x03 LCD panel driver Hyungwon Hwang
  2015-02-03 14:00   ` Thierry Reding
@ 2015-06-12 13:03   ` Hyungwon Hwang
  1 sibling, 0 replies; 50+ messages in thread
From: Hyungwon Hwang @ 2015-06-12 13:03 UTC (permalink / raw)
  To: Hyungwon Hwang; +Cc: devicetree, sw0312.kim, dri-devel, treding

Please ignore this mail. I didn't know that "git send *" includes all
files in the subdirectories. I am very sorry for disturbing you.

Best regards,
Hyungwon Hwang

On Fri, 12 Jun 2015 21:59:17 +0900
Hyungwon Hwang <human.hwang@samsung.com> wrote:

> From: Inki Dae <inki.dae@samsung.com>
> 
> This patch adds MIPI-DSI based S6E63J0X03 AMOLED LCD panel driver
> which uses mipi_dsi bus to communicate with panel. The panel has
> 320×320 resolution in 1.63-inch physical panel. This panel is used in
> Samsung Galaxy Gear 2.
> 
> Signed-off-by: Inki Dae <inki.dae@samsung.com>
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> 
> ---
> Changes for v2:
> - Change the gamma table to 2-dimensional array
> - Change the way to make index for brightness
> - Make command functions to an array so that it can be called simply
> - Change command id for reading device ID
> - Change the way to handle the error condition
> - Remove power variable, and use the same name variable in bl_dev
> - Add the state FB_BLANK_NORMAL to represent the state which the panel
> is working but blanked
> - Miscellaneous changes to increase the readability and follow the
>   coding-style standard
> Changes for v3:
> - Add DT binding documentation
> - Add the code getting DT properties of 'panel-width-mm' and
> 'panel-height-mm'
> - Remove the code getting unnecessary DT properties flip-*
>  .../bindings/panel/samsung,s6e63j0x03.txt          |  55 +++
>  drivers/gpu/drm/panel/Kconfig                      |   6 +
>  drivers/gpu/drm/panel/Makefile                     |   1 +
>  drivers/gpu/drm/panel/panel-s6e63j0x03.c           | 546
> +++++++++++++++++++++ 4 files changed, 608 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt create
> mode 100644 drivers/gpu/drm/panel/panel-s6e63j0x03.c
> 
> --
> 1.9.1
> 
> diff --git
> a/Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt
> b/Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt new
> file mode 100644 index 0000000..f8215e4 --- /dev/null
> +++ b/Documentation/devicetree/bindings/panel/samsung,s6e63j0x03.txt
> @@ -0,0 +1,55 @@
> +Samsung S6E63J0X03 1.63" 320x320 TFT LCD panel
> +
> +Required properties:
> +  - compatible: "samsung,s6e63j0x03"
> +  - reg: the virtual channel number of a DSI peripheral
> +  - vdd3-supply: core voltage supply
> +  - vci-supply: voltage supply for analog circuits
> +  - reset-gpios: a GPIO spec for the reset pin
> +  - te-gpios: a GPIO spec for the tearing effect synchronization
> signal gpio pin +
> +Optional properties:
> +  - display-timings: timings for the connected panel as described by
> [1]
> +  - power-on-delay: delay after turning regulators on [ms]
> +  - power-off-delay: delay after turning regulators off [ms]
> +  - reset-delay: delay after reset sequence [ms]
> +  - panel-width-mm: physical panel width [mm]
> +  - panel-height-mm: physical panel height [mm]
> +
> +The device node can contain one 'port' child node with one child
> +'endpoint' node, according to the bindings defined in [2]. This
> +node should describe panel's video bus.
> +
> +[1]: Documentation/devicetree/bindings/video/display-timing.txt
> +[2]: Documentation/devicetree/bindings/media/video-interfaces.txt
> +
> +Example:
> +
> +panel@0 {
> +	compatible = "samsung,s6e63j0x03";
> +	reg = <0>;
> +	vdd3-supply = <&ldo16_reg>;
> +	vci-supply = <&ldo20_reg>;
> +	reset-gpios = <&gpe0 1 0>;
> +	te-gpios = <&gpx0 6 0>;
> +	power-on-delay= <30>;
> +	power-off-delay= <120>;
> +	reset-delay = <5>;
> +	init-delay = <100>;
> +	panel-width-mm = <29>;
> +	panel-height-mm = <29>;
> +
> +	display-timings {
> +		timing-0 {
> +			clock-frequency = <0>;
> +			hactive = <320>;
> +			vactive = <320>;
> +			hfront-porch = <1>;
> +			hback-porch = <1>;
> +			hsync-len = <1>;
> +			vfront-porch = <150>;
> +			vback-porch = <1>;
> +			vsync-len = <2>;
> +		};
> +	};
> +};
> diff --git a/drivers/gpu/drm/panel/Kconfig
> b/drivers/gpu/drm/panel/Kconfig index 3df9b9b..8fa7610 100644
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -46,4 +46,10 @@ config DRM_PANEL_S6E3HA2
>  	select DRM_MIPI_DSI
>  	select VIDEOMODE_HELPERS
> 
> +config DRM_PANEL_S6E63J0X03
> +	tristate "S6E63J0X03 DSI video mode panel"
> +	depends on OF
> +	select DRM_MIPI_DSI
> +	select VIDEOMODE_HELPERS
> +
>  endmenu
> diff --git a/drivers/gpu/drm/panel/Makefile
> b/drivers/gpu/drm/panel/Makefile index 16ff312..9054da1 100644
> --- a/drivers/gpu/drm/panel/Makefile
> +++ b/drivers/gpu/drm/panel/Makefile
> @@ -3,3 +3,4 @@ obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o
>  obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
>  obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) +=
> panel-sharp-lq101r1sx01.o obj-$(CONFIG_DRM_PANEL_S6E3HA2) +=
> panel-s6e3ha2.o +obj-$(CONFIG_DRM_PANEL_S6E63J0X03) +=
> panel-s6e63j0x03.o diff --git
> a/drivers/gpu/drm/panel/panel-s6e63j0x03.c
> b/drivers/gpu/drm/panel/panel-s6e63j0x03.c new file mode 100644 index
> 0000000..51cf1f6 --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-s6e63j0x03.c
> @@ -0,0 +1,546 @@
> +/*
> + * MIPI-DSI based S6E63J0X03 AMOLED lcd 1.63 inch panel driver.
> + *
> + * Copyright (c) 2014 Samsung Electronics Co., Ltd
> + *
> + * Inki Dae, <inki.dae@samsung.com>
> + *
> + * 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.
> +*/
> +
> +#include <drm/drmP.h>
> +#include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_panel.h>
> +
> +#include <linux/of_gpio.h>
> +#include <linux/gpio.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/backlight.h>
> +
> +#include <video/mipi_display.h>
> +#include <video/of_videomode.h>
> +#include <video/videomode.h>
> +
> +#define READ_ID1		0xDA
> +#define READ_ID2		0xDB
> +#define READ_ID3		0xDC
> +
> +#define MCS_LEVEL2_KEY		0xf0
> +#define MCS_MTP_KEY		0xf1
> +#define MCS_MTP_SET3		0xd4
> +
> +#define MIN_BRIGHTNESS		0
> +#define MAX_BRIGHTNESS		100
> +#define DEFAULT_BRIGHTNESS	80
> +
> +#define GAMMA_LEVEL_NUM		30
> +#define NUM_GAMMA_STEPS		9
> +#define GAMMA_CMD_CNT		28
> +
> +struct s6e63j0x03 {
> +	struct device *dev;
> +	struct drm_panel panel;
> +	struct backlight_device *bl_dev;
> +
> +	struct regulator_bulk_data supplies[2];
> +	struct gpio_desc *reset_gpio;
> +	u32 power_on_delay;
> +	u32 power_off_delay;
> +	u32 reset_delay;
> +	u32 init_delay;
> +	struct videomode vm;
> +	unsigned int width_mm;
> +	unsigned int height_mm;
> +};
> +
> +static const unsigned char gamma_tbl[NUM_GAMMA_STEPS][GAMMA_CMD_CNT]
> = {
> +	{	/* Gamma 10 */
> +		MCS_MTP_SET3,
> +		0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x52, 0x6b,
> 0x6f, 0x26,
> +		0x28, 0x2d, 0x28, 0x26, 0x27, 0x33, 0x34, 0x32,
> 0x36, 0x36,
> +		0x35, 0x00, 0xab, 0x00, 0xae, 0x00, 0xbf
> +	},
> +	{	/* gamma 30 */
> +		MCS_MTP_SET3,
> +		0x00, 0x00, 0x00, 0x70, 0x7f, 0x7f, 0x4e, 0x64,
> 0x69, 0x26,
> +		0x27, 0x2a, 0x28, 0x29, 0x27, 0x31, 0x32, 0x31,
> 0x35, 0x34,
> +		0x35, 0x00, 0xc4, 0x00, 0xca, 0x00, 0xdc
> +	},
> +	{	/* gamma 60 */
> +		MCS_MTP_SET3,
> +		0x00, 0x00, 0x00, 0x65, 0x7b, 0x7d, 0x5f, 0x67,
> 0x68, 0x2a,
> +		0x28, 0x29, 0x28, 0x2a, 0x27, 0x31, 0x2f, 0x30,
> 0x34, 0x33,
> +		0x34, 0x00, 0xd9, 0x00, 0xe4, 0x00, 0xf5
> +	},
> +	{	/* gamma 90 */
> +		MCS_MTP_SET3,
> +		0x00, 0x00, 0x00, 0x4d, 0x6f, 0x71, 0x67, 0x6a,
> 0x6c, 0x29,
> +		0x28, 0x28, 0x28, 0x29, 0x27, 0x30, 0x2e, 0x30,
> 0x32, 0x31,
> +		0x31, 0x00, 0xea, 0x00, 0xf6, 0x01, 0x09
> +	},
> +	{	/* gamma 120 */
> +		MCS_MTP_SET3,
> +		0x00, 0x00, 0x00, 0x3d, 0x66, 0x68, 0x69, 0x69,
> 0x69, 0x28,
> +		0x28, 0x27, 0x28, 0x28, 0x27, 0x30, 0x2e, 0x2f,
> 0x31, 0x31,
> +		0x30, 0x00, 0xf9, 0x01, 0x05, 0x01, 0x1b
> +	},
> +	{	/* gamma 150 */
> +		MCS_MTP_SET3,
> +		0x00, 0x00, 0x00, 0x31, 0x51, 0x53, 0x66, 0x66,
> 0x67, 0x28,
> +		0x29, 0x27, 0x28, 0x27, 0x27, 0x2e, 0x2d, 0x2e,
> 0x31, 0x31,
> +		0x30, 0x01, 0x04, 0x01, 0x11, 0x01, 0x29
> +	},
> +	{	/* gamma 200 */
> +		MCS_MTP_SET3,
> +		0x00, 0x00, 0x00, 0x2f, 0x4f, 0x51, 0x67, 0x65,
> 0x65, 0x29,
> +		0x2a, 0x28, 0x27, 0x25, 0x26, 0x2d, 0x2c, 0x2c,
> 0x30, 0x30,
> +		0x30, 0x01, 0x14, 0x01, 0x23, 0x01, 0x3b
> +	},
> +	{	/* gamma 240 */
> +		MCS_MTP_SET3,
> +		0x00, 0x00, 0x00, 0x2c, 0x4d, 0x50, 0x65, 0x63,
> 0x64, 0x2a,
> +		0x2c, 0x29, 0x26, 0x24, 0x25, 0x2c, 0x2b, 0x2b,
> 0x30, 0x30,
> +		0x30, 0x01, 0x1e, 0x01, 0x2f, 0x01, 0x47
> +	},
> +	{	/* gamma 300 */
> +		MCS_MTP_SET3,
> +		0x00, 0x00, 0x00, 0x38, 0x61, 0x64, 0x65, 0x63,
> 0x64, 0x28,
> +		0x2a, 0x27, 0x26, 0x23, 0x25, 0x2b, 0x2b, 0x2a,
> 0x30, 0x2f,
> +		0x30, 0x01, 0x2d, 0x01, 0x3f, 0x01, 0x57
> +	}
> +};
> +
> +static const unsigned char prepare_cmds1[][15] = {
> +	{ 3, 0xf2, 0x1c, 0x28 },		/* porch_adjustment
> */
> +	{ 4, 0xb5, 0x00, 0x02, 0x00 },		/* frame_freq
> */
> +	{ 5, 0x2a, 0x00, 0x14, 0x01, 0x53 },	/*
> mem_addr_set_0 */
> +	{ 5, 0x2b, 0x00, 0x00, 0x01, 0x3f },	/*
> mem_addr_set_1 */
> +	{ 14, 0xf8, 0x08, 0x08, 0x08, 0x17,	/*
> ltps_timming_set_0_60hz */
> +	      0x00, 0x2a, 0x02, 0x26,
> +	      0x00, 0x00, 0x02, 0x00, 0x00 },
> +	{ 2, 0xf7, 0x02 },			/*
> ltps_timming_set_1 */
> +	{ 2, 0xb0, 0x01 },			/*
> param_pos_te_edge */
> +	{ 2, 0xe2, 0x0f },			/* te_rising_edge
> */
> +	{ 2, 0xb0, 0x00 },			/*
> param_pos_default */
> +	{ 1, MIPI_DCS_EXIT_SLEEP_MODE },
> +};
> +
> +static const  unsigned char prepare_cmds2[][4] = {
> +	{ 3, 0xb1, 0x00, 0x09 },	/* elvss_cond */
> +	{ 2, 0x36, 0x40 },		/* set_pos */
> +	{ 2, 0x51, 0xff },		/*
> white_brightness_default */
> +	{ 2, 0x53, 0x20 },		/* white_ctrl */
> +	{ 2, 0x55, 0x00 },		/* acl_off */
> +	{ 1, MIPI_DCS_SET_TEAR_ON },
> +};
> +
> +
> +static inline struct s6e63j0x03 *panel_to_s6e63j0x03(struct
> drm_panel *panel) +{
> +	return container_of(panel, struct s6e63j0x03, panel);
> +}
> +
> +static inline ssize_t s6e63j0x03_dcs_write_seq(struct s6e63j0x03
> *ctx,
> +					const u8 *seq, const
> unsigned char len) +{
> +	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
> +
> +	return mipi_dsi_dcs_write(dsi, seq, len);
> +}
> +
> +static inline int s6e63j0x03_enable_lv2_command(struct s6e63j0x03
> *ctx) +{
> +	unsigned char seq[] = { MCS_LEVEL2_KEY, 0x5a, 0x5a };
> +
> +	return s6e63j0x03_dcs_write_seq(ctx, seq, ARRAY_SIZE(seq));
> +}
> +
> +static inline int s6e63j0x03_apply_mtp_key(struct s6e63j0x03 *ctx,
> bool on) +{
> +	unsigned char seq1[3] = { MCS_MTP_KEY, 0x5a, 0x5a };
> +	unsigned char seq2[3] = { MCS_MTP_KEY, 0xa5, 0xa5 };
> +
> +	return s6e63j0x03_dcs_write_seq(ctx, on ? seq1 : seq2,
> +					ARRAY_SIZE(seq1));
> +}
> +
> +static int s6e63j0x03_read_mtp_id(struct s6e63j0x03 *ctx)
> +{
> +	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
> +	unsigned char cmds[3] = { READ_ID1, READ_ID2, READ_ID3 };
> +	unsigned char id[3];
> +	int ret;
> +	int i;
> +
> +	for (i = 0; i < 3; i++) {
> +		ret = mipi_dsi_dcs_read(dsi, cmds[i], &id[i], 1);
> +
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	dev_info(ctx->dev, "ID: 0x%02x, 0x%02x, 0x%02x\n", id[0],
> id[1], id[2]); +
> +	return 0;
> +}
> +
> +static int s6e63j0x03_power_on(struct s6e63j0x03 *ctx)
> +{
> +	int ret;
> +
> +	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies),
> ctx->supplies);
> +	if (ret < 0)
> +		return ret;
> +
> +	msleep(ctx->power_on_delay);
> +
> +	gpiod_set_value(ctx->reset_gpio, 0);
> +	usleep_range(1000, 2000);
> +	gpiod_set_value(ctx->reset_gpio, 1);
> +
> +	usleep_range(ctx->reset_delay * 1000, (ctx->reset_delay + 1)
> * 1000); +
> +	return 0;
> +}
> +
> +static int s6e63j0x03_power_off(struct s6e63j0x03 *ctx)
> +{
> +	int ret;
> +
> +	gpiod_set_value(ctx->reset_gpio, 0);
> +
> +	ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies),
> ctx->supplies);
> +	if (ret < 0)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int s6e63j0x03_get_brightness(struct backlight_device *bl_dev)
> +{
> +	return bl_dev->props.brightness;
> +}
> +
> +static unsigned int s6e63j0x03_get_brightness_index(unsigned int
> brightness) +{
> +	unsigned int index;
> +
> +	index = brightness / (MAX_BRIGHTNESS / NUM_GAMMA_STEPS);
> +
> +	if (index >= NUM_GAMMA_STEPS)
> +		index = NUM_GAMMA_STEPS - 1;
> +
> +	return index;
> +}
> +
> +static int s6e63j0x03_update_gamma(struct s6e63j0x03 *ctx,
> +					unsigned int brightness)
> +{
> +	struct backlight_device *bl_dev = ctx->bl_dev;
> +	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
> +	unsigned int index =
> s6e63j0x03_get_brightness_index(brightness);
> +	int ret;
> +
> +	ret = s6e63j0x03_apply_mtp_key(ctx, true);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = mipi_dsi_dcs_write(dsi, gamma_tbl[index],
> GAMMA_CMD_CNT);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = s6e63j0x03_apply_mtp_key(ctx, false);
> +	if (ret < 0)
> +		return ret;
> +
> +	bl_dev->props.brightness = brightness;
> +
> +	return 0;
> +}
> +
> +static int s6e63j0x03_set_brightness(struct backlight_device *bl_dev)
> +{
> +	struct s6e63j0x03 *ctx = (struct s6e63j0x03
> *)bl_get_data(bl_dev);
> +	unsigned int brightness = bl_dev->props.brightness;
> +	int ret;
> +
> +	if (brightness < MIN_BRIGHTNESS ||
> +		brightness > bl_dev->props.max_brightness) {
> +		dev_err(ctx->dev, "Invalid brightness: %u\n",
> brightness);
> +		return -EINVAL;
> +	}
> +
> +	if (bl_dev->props.power > FB_BLANK_NORMAL) {
> +		dev_err(ctx->dev,
> +			"panel must be at least in fb blank normal
> state\n");
> +		return -EPERM;
> +	}
> +
> +	ret = s6e63j0x03_update_gamma(ctx, brightness);
> +	if (ret < 0)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static const struct backlight_ops s6e63j0x03_bl_ops = {
> +	.get_brightness = s6e63j0x03_get_brightness,
> +	.update_status = s6e63j0x03_set_brightness,
> +};
> +
> +static int s6e63j0x03_disable(struct drm_panel *panel)
> +{
> +	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
> +	struct backlight_device *bl_dev = ctx->bl_dev;
> +	u8 seq[] = { MIPI_DCS_SET_DISPLAY_OFF };
> +	int ret;
> +
> +	ret = s6e63j0x03_dcs_write_seq(ctx, seq, ARRAY_SIZE(seq));
> +	if (ret > 0)
> +		bl_dev->props.power = FB_BLANK_NORMAL;
> +
> +	return 0;
> +}
> +
> +static int s6e63j0x03_unprepare(struct drm_panel *panel)
> +{
> +	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
> +	struct backlight_device *bl_dev = ctx->bl_dev;
> +	u8 seq[] = { MIPI_DCS_ENTER_SLEEP_MODE };
> +	int ret;
> +
> +	ret = s6e63j0x03_dcs_write_seq(ctx, seq, ARRAY_SIZE(seq));
> +	if (ret < 0)
> +		return ret;
> +
> +	msleep(ctx->power_off_delay);
> +
> +	ret = s6e63j0x03_power_off(ctx);
> +	if (ret < 0)
> +		return ret;
> +
> +	bl_dev->props.power = FB_BLANK_POWERDOWN;
> +
> +	return 0;
> +}
> +
> +static int s6e63j0x03_prepare(struct drm_panel *panel)
> +{
> +	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
> +	struct backlight_device *bl_dev = ctx->bl_dev;
> +	int ret;
> +	int i;
> +
> +	ret = s6e63j0x03_power_on(ctx);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = s6e63j0x03_enable_lv2_command(ctx);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = s6e63j0x03_apply_mtp_key(ctx, true);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = s6e63j0x03_read_mtp_id(ctx);
> +	if (ret < 0)
> +		return ret;
> +
> +	for (i = 0; i < ARRAY_SIZE(prepare_cmds1); i++) {
> +		ret = s6e63j0x03_dcs_write_seq(ctx,
> &prepare_cmds1[i][1],
> +
> prepare_cmds1[i][0]);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	msleep(120);
> +
> +	for (i = 0; i < ARRAY_SIZE(prepare_cmds2); i++) {
> +		ret = s6e63j0x03_dcs_write_seq(ctx,
> &prepare_cmds2[i][1],
> +
> prepare_cmds2[i][0]);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	ret = s6e63j0x03_apply_mtp_key(ctx, false);
> +	if (ret < 0)
> +		return ret;
> +
> +	bl_dev->props.power = FB_BLANK_NORMAL;
> +
> +	return 0;
> +}
> +
> +static int s6e63j0x03_enable(struct drm_panel *panel)
> +{
> +	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
> +	struct backlight_device *bl_dev = ctx->bl_dev;
> +	u8 seq[] = { MIPI_DCS_SET_DISPLAY_ON };
> +	int ret;
> +
> +	ret = s6e63j0x03_dcs_write_seq(ctx, seq, ARRAY_SIZE(seq));
> +	if (ret > 0)
> +		bl_dev->props.power = FB_BLANK_UNBLANK;
> +
> +	return 0;
> +}
> +
> +static int s6e63j0x03_get_modes(struct drm_panel *panel)
> +{
> +	struct drm_connector *connector = panel->connector;
> +	struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
> +	struct drm_display_mode *mode;
> +
> +	mode = drm_mode_create(connector->dev);
> +	if (!mode) {
> +		DRM_ERROR("failed to create a new display mode\n");
> +		return 0;
> +	}
> +
> +	drm_display_mode_from_videomode(&ctx->vm, mode);
> +	mode->width_mm = ctx->width_mm;
> +	mode->height_mm = ctx->height_mm;
> +	connector->display_info.width_mm = mode->width_mm;
> +	connector->display_info.height_mm = mode->height_mm;
> +
> +	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
> +	drm_mode_probed_add(connector, mode);
> +
> +	return 1;
> +}
> +
> +static const struct drm_panel_funcs s6e63j0x03_funcs = {
> +	.disable = s6e63j0x03_disable,
> +	.unprepare = s6e63j0x03_unprepare,
> +	.prepare = s6e63j0x03_prepare,
> +	.enable = s6e63j0x03_enable,
> +	.get_modes = s6e63j0x03_get_modes,
> +};
> +
> +static int s6e63j0x03_parse_dt(struct s6e63j0x03 *ctx)
> +{
> +	struct device *dev = ctx->dev;
> +	struct device_node *np = dev->of_node;
> +	int ret;
> +
> +	ret = of_get_videomode(np, &ctx->vm, 0);
> +	if (ret < 0)
> +		return ret;
> +
> +	of_property_read_u32(np, "power-on-delay",
> &ctx->power_on_delay);
> +	of_property_read_u32(np, "power-off-delay",
> &ctx->power_off_delay);
> +	of_property_read_u32(np, "reset-delay", &ctx->reset_delay);
> +	of_property_read_u32(np, "init-delay", &ctx->init_delay);
> +	of_property_read_u32(np, "panel-width-mm", &ctx->width_mm);
> +	of_property_read_u32(np, "panel-height-mm", &ctx->height_mm);
> +
> +	return ret;
> +}
> +
> +static int s6e63j0x03_probe(struct mipi_dsi_device *dsi)
> +{
> +	struct device *dev = &dsi->dev;
> +	struct s6e63j0x03 *ctx;
> +	int ret;
> +
> +	ctx = devm_kzalloc(dev, sizeof(struct s6e63j0x03),
> GFP_KERNEL);
> +	if (!ctx)
> +		return -ENOMEM;
> +
> +	mipi_dsi_set_drvdata(dsi, ctx);
> +
> +	ctx->dev = dev;
> +
> +	dsi->lanes = 1;
> +	dsi->format = MIPI_DSI_FMT_RGB888;
> +	dsi->mode_flags = MIPI_DSI_MODE_EOT_PACKET |
> MIPI_DSI_MODE_VIDEO_BURST; +
> +	ret = s6e63j0x03_parse_dt(ctx);
> +	if (ret < 0)
> +		return ret;
> +
> +	ctx->supplies[0].supply = "vdd3";
> +	ctx->supplies[1].supply = "vci";
> +	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
> +				      ctx->supplies);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to get regulators: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ctx->reset_gpio = devm_gpiod_get(dev, "reset",
> GPIOD_OUT_HIGH);
> +	if (IS_ERR(ctx->reset_gpio)) {
> +		dev_err(dev, "cannot get reset-gpio: %ld\n",
> +				PTR_ERR(ctx->reset_gpio));
> +		return PTR_ERR(ctx->reset_gpio);
> +	}
> +
> +	drm_panel_init(&ctx->panel);
> +	ctx->panel.dev = dev;
> +	ctx->panel.funcs = &s6e63j0x03_funcs;
> +
> +	ctx->bl_dev = backlight_device_register("s6e63j0x03", dev,
> ctx,
> +						&s6e63j0x03_bl_ops,
> NULL);
> +	if (IS_ERR(ctx->bl_dev)) {
> +		dev_err(dev, "failed to register backlight
> device\n");
> +		return PTR_ERR(ctx->bl_dev);
> +	}
> +
> +	ctx->bl_dev->props.max_brightness = MAX_BRIGHTNESS;
> +	ctx->bl_dev->props.brightness = DEFAULT_BRIGHTNESS;
> +	ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
> +
> +
> +	ret = drm_panel_add(&ctx->panel);
> +	if (ret < 0)
> +		goto unregister_backlight;
> +
> +	ret = mipi_dsi_attach(dsi);
> +	if (ret < 0)
> +		goto remove_panel;
> +
> +	return ret;
> +
> +remove_panel:
> +	drm_panel_remove(&ctx->panel);
> +
> +unregister_backlight:
> +	backlight_device_unregister(ctx->bl_dev);
> +
> +	return ret;
> +}
> +
> +static int s6e63j0x03_remove(struct mipi_dsi_device *dsi)
> +{
> +	struct s6e63j0x03 *ctx = mipi_dsi_get_drvdata(dsi);
> +
> +	mipi_dsi_detach(dsi);
> +	drm_panel_remove(&ctx->panel);
> +
> +	backlight_device_unregister(ctx->bl_dev);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id s6e63j0x03_of_match[] = {
> +	{ .compatible = "samsung,s6e63j0x03" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, s6e63j0x03_of_match);
> +
> +static struct mipi_dsi_driver s6e63j0x03_driver = {
> +	.probe = s6e63j0x03_probe,
> +	.remove = s6e63j0x03_remove,
> +	.driver = {
> +		.name = "panel_s6e63j0x03",
> +		.of_match_table = s6e63j0x03_of_match,
> +	},
> +};
> +module_mipi_dsi_driver(s6e63j0x03_driver);
> +
> +MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
> +MODULE_DESCRIPTION("MIPI-DSI based s6e8aa0 AMOLED LCD Panel Driver");
> +MODULE_LICENSE("GPL v2");

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

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

* Re: [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi'
  2015-06-12 12:59   ` [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi' Hyungwon Hwang
@ 2015-06-22  9:10     ` Inki Dae
  2015-06-22 11:42       ` Inki Dae
  0 siblings, 1 reply; 50+ messages in thread
From: Inki Dae @ 2015-06-22  9:10 UTC (permalink / raw)
  To: Hyungwon Hwang, Kukjin Kim, Krzysztof Kozlowski
  Cc: devicetree, sw0312.kim, dri-devel

On 2015년 06월 12일 21:59, Hyungwon Hwang wrote:
> The clock which was named as 'pll_clk' is actually not the clock source
> of PLL in MIPI DSI. This patch fixes this disagreement.

Mr. Kukjin and Krzysztof, can you give me Acked-by or Singed-off-by? I'd
like to merge this patch to mainline through drm-next.

Thanks,
Inki Dae

> 
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> ---
> Changes before:
> - Refer https://patchwork.kernel.org/patch/6191811
> Changes for v6:
> - None
> 
>  arch/arm/boot/dts/exynos4.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
> index e20cdc2..1538d7a 100644
> --- a/arch/arm/boot/dts/exynos4.dtsi
> +++ b/arch/arm/boot/dts/exynos4.dtsi
> @@ -167,7 +167,7 @@
>  		phys = <&mipi_phy 1>;
>  		phy-names = "dsim";
>  		clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
> -		clock-names = "bus_clk", "pll_clk";
> +		clock-names = "bus_clk", "sclk_mipi";
>  		status = "disabled";
>  		#address-cells = <1>;
>  		#size-cells = <0>;
> --
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" 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

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

* [PATCH v7 05/15] drm/exynos: add Exynos5433 decon driver
  2015-06-12 12:59   ` [PATCH v6 05/15] drm/exynos: add Exynos5433 decon driver Hyungwon Hwang
@ 2015-06-22 11:16     ` Inki Dae
  2015-06-22 11:41       ` Varka Bhadram
  0 siblings, 1 reply; 50+ messages in thread
From: Inki Dae @ 2015-06-22 11:16 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-samsung-soc

From: Joonyoung Shim <jy0922.shim@samsung.com>

DECON(Display and Enhancement Controller) is new IP replacing FIMD in
Exynos5433. This patch adds Exynos5433 decon driver.

Changelog v7:
- Rebased on top of exynos-drm-next.
- Added runtime pm support.

Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
---
 .../devicetree/bindings/video/exynos5433-decon.txt |   65 ++
 drivers/gpu/drm/exynos/Kconfig                     |    6 +
 drivers/gpu/drm/exynos/Makefile                    |    1 +
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c      |  660 ++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_drv.h            |    1 +
 include/video/exynos5433_decon.h                   |  165 +++++
 6 files changed, 898 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/exynos5433-decon.txt
 create mode 100644 drivers/gpu/drm/exynos/exynos5433_drm_decon.c
 create mode 100644 include/video/exynos5433_decon.h

diff --git a/Documentation/devicetree/bindings/video/exynos5433-decon.txt b/Documentation/devicetree/bindings/video/exynos5433-decon.txt
new file mode 100644
index 0000000..377afbf
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos5433-decon.txt
@@ -0,0 +1,65 @@
+Device-Tree bindings for Samsung Exynos SoC display controller (DECON)
+
+DECON (Display and Enhancement Controller) is the Display Controller for the
+Exynos series of SoCs which transfers the image data from a video memory
+buffer to an external LCD interface.
+
+Required properties:
+- compatible: value should be "samsung,exynos5433-decon";
+- reg: physical base address and length of the DECON registers set.
+- interrupts: should contain a list of all DECON IP block interrupts in the
+	      order: VSYNC, LCD_SYSTEM. The interrupt specifier format
+	      depends on the interrupt controller used.
+- interrupt-names: should contain the interrupt names: "vsync", "lcd_sys"
+		   in the same order as they were listed in the interrupts
+		   property.
+- clocks: must include clock specifiers corresponding to entries in the
+	  clock-names property.
+- clock-names: list of clock names sorted in the same order as the clocks
+	       property. Must contain "aclk_decon", "aclk_smmu_decon0x",
+	       "aclk_xiu_decon0x", "pclk_smmu_decon0x", clk_decon_vclk",
+	       "sclk_decon_eclk"
+- ports: contains a port which is connected to mic node. address-cells and
+	 size-cells must 1 and 0, respectively.
+- port: contains an endpoint node which is connected to the endpoint in the mic
+	node. The reg value muset be 0.
+- i80-if-timings: specify whether the panel which is connected to decon uses
+		  i80 lcd interface or mipi video interface. This node contains
+		  no timing information as that of fimd does. Because there is
+		  no register in decon to specify i80 interface timing value,
+		  it is not needed, but make it remain to use same kind of node
+		  in fimd and exynos7 decon.
+
+Example:
+SoC specific DT entry:
+decon: decon@13800000 {
+	compatible = "samsung,exynos5433-decon";
+	reg = <0x13800000 0x2104>;
+	clocks = <&cmu_disp CLK_ACLK_DECON>, <&cmu_disp CLK_ACLK_SMMU_DECON0X>,
+		<&cmu_disp CLK_ACLK_XIU_DECON0X>,
+		<&cmu_disp CLK_PCLK_SMMU_DECON0X>,
+		<&cmu_disp CLK_SCLK_DECON_VCLK>,
+		<&cmu_disp CLK_SCLK_DECON_ECLK>;
+	clock-names = "aclk_decon", "aclk_smmu_decon0x", "aclk_xiu_decon0x",
+		"pclk_smmu_decon0x", "sclk_decon_vclk", "sclk_decon_eclk";
+	interrupt-names = "vsync", "lcd_sys";
+	interrupts = <0 202 0>, <0 203 0>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			decon_to_mic: endpoint {
+				remote-endpoint = <&mic_to_decon>;
+			};
+		};
+	};
+};
+
+Board specific DT entry:
+&decon {
+	i80-if-timings {
+	};
+};
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index ddb7c8a..51a4eb5 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -24,6 +24,12 @@ config DRM_EXYNOS_FIMD
 	help
 	  Choose this option if you want to use Exynos FIMD for DRM.
 
+config DRM_EXYNOS5433_DECON
+	bool "Exynos5433 DRM DECON"
+	depends on DRM_EXYNOS
+	help
+	  Choose this option if you want to use Exynos5433 DECON for DRM.
+
 config DRM_EXYNOS7_DECON
 	bool "Exynos7 DRM DECON"
 	depends on DRM_EXYNOS && !FB_S3C
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index cc90679..fbd084d 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -10,6 +10,7 @@ exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o \
 
 exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)	+= exynos_drm_fimd.o
+exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON)	+= exynos5433_drm_decon.o
 exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON)	+= exynos7_drm_decon.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_DPI)	+= exynos_drm_dpi.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_DSI)	+= exynos_drm_dsi.o
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
new file mode 100644
index 0000000..8b1225f
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -0,0 +1,660 @@
+/* drivers/gpu/drm/exynos5433_drm_decon.c
+ *
+ * Copyright (C) 2015 Samsung Electronics Co.Ltd
+ * Authors:
+ *	Joonyoung Shim <jy0922.shim@samsung.com>
+ *	Hyungwon Hwang <human.hwang@samsung.com>
+ *
+ * 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 Foundationr
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_gpio.h>
+#include <linux/pm_runtime.h>
+
+#include <video/exynos5433_decon.h>
+
+#include "exynos_drm_drv.h"
+#include "exynos_drm_crtc.h"
+#include "exynos_drm_plane.h"
+#include "exynos_drm_iommu.h"
+
+#define WINDOWS_NR	3
+#define MIN_FB_WIDTH_FOR_16WORD_BURST	128
+
+struct decon_context {
+	struct device			*dev;
+	struct drm_device		*drm_dev;
+	struct exynos_drm_crtc		*crtc;
+	struct exynos_drm_plane		planes[WINDOWS_NR];
+	void __iomem			*addr;
+	struct clk			*clks[6];
+	unsigned int			default_win;
+	unsigned long			irq_flags;
+	int				pipe;
+	bool				suspended;
+
+#define BIT_CLKS_ENABLED		0
+#define BIT_IRQS_ENABLED		1
+	unsigned long			enabled;
+	bool				i80_if;
+	atomic_t			win_updated;
+};
+
+static const char * const decon_clks_name[] = {
+	"aclk_decon",
+	"aclk_smmu_decon0x",
+	"aclk_xiu_decon0x",
+	"pclk_smmu_decon0x",
+	"sclk_decon_vclk",
+	"sclk_decon_eclk",
+};
+
+static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+	u32 val;
+
+	if (ctx->suspended)
+		return -EPERM;
+
+	if (test_and_set_bit(0, &ctx->irq_flags)) {
+		val = VIDINTCON0_INTEN;
+		if (ctx->i80_if)
+			val |= VIDINTCON0_FRAMEDONE;
+		else
+			val |= VIDINTCON0_INTFRMEN;
+
+		writel(val, ctx->addr + DECON_VIDINTCON0);
+	}
+
+	return 0;
+}
+
+static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+
+	if (ctx->suspended)
+		return;
+
+	if (test_and_clear_bit(0, &ctx->irq_flags))
+		writel(0, ctx->addr + DECON_VIDINTCON0);
+}
+
+static void decon_setup_trigger(struct decon_context *ctx)
+{
+	u32 val = TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
+			TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN;
+	writel(val, ctx->addr + DECON_TRIGCON);
+}
+
+static void decon_commit(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+	struct drm_display_mode *mode = &crtc->base.mode;
+	u32 val;
+
+	if (ctx->suspended)
+		return;
+
+	/* enable clock gate */
+	val = CMU_CLKGAGE_MODE_SFR_F | CMU_CLKGAGE_MODE_MEM_F;
+	writel(val, ctx->addr + DECON_CMU);
+
+	/* lcd on and use command if */
+	val = VIDOUT_LCD_ON;
+	if (ctx->i80_if)
+		val |= VIDOUT_COMMAND_IF;
+	else
+		val |= VIDOUT_RGB_IF;
+	writel(val, ctx->addr + DECON_VIDOUTCON0);
+
+	val = VIDTCON2_LINEVAL(mode->vdisplay - 1) |
+		VIDTCON2_HOZVAL(mode->hdisplay - 1);
+	writel(val, ctx->addr + DECON_VIDTCON2);
+
+	if (!ctx->i80_if) {
+		val = VIDTCON00_VBPD_F(
+				mode->crtc_vtotal - mode->crtc_vsync_end) |
+			VIDTCON00_VFPD_F(
+				mode->crtc_vsync_start - mode->crtc_vdisplay);
+		writel(val, ctx->addr + DECON_VIDTCON00);
+
+		val = VIDTCON01_VSPW_F(
+				mode->crtc_vsync_end - mode->crtc_vsync_start);
+		writel(val, ctx->addr + DECON_VIDTCON01);
+
+		val = VIDTCON10_HBPD_F(
+				mode->crtc_htotal - mode->crtc_hsync_end) |
+			VIDTCON10_HFPD_F(
+				mode->crtc_hsync_start - mode->crtc_hdisplay);
+		writel(val, ctx->addr + DECON_VIDTCON10);
+
+		val = VIDTCON11_HSPW_F(
+				mode->crtc_hsync_end - mode->crtc_hsync_start);
+		writel(val, ctx->addr + DECON_VIDTCON11);
+	}
+
+	decon_setup_trigger(ctx);
+
+	/* enable output and display signal */
+	val = VIDCON0_ENVID | VIDCON0_ENVID_F;
+	writel(val, ctx->addr + DECON_VIDCON0);
+}
+
+#define COORDINATE_X(x)		(((x) & 0xfff) << 12)
+#define COORDINATE_Y(x)		((x) & 0xfff)
+#define OFFSIZE(x)		(((x) & 0x3fff) << 14)
+#define PAGEWIDTH(x)		((x) & 0x3fff)
+
+static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win)
+{
+	struct exynos_drm_plane *plane = &ctx->planes[win];
+	unsigned long val;
+
+	val = readl(ctx->addr + DECON_WINCONx(win));
+	val &= ~WINCONx_BPPMODE_MASK;
+
+	switch (plane->pixel_format) {
+	case DRM_FORMAT_XRGB1555:
+		val |= WINCONx_BPPMODE_16BPP_I1555;
+		val |= WINCONx_HAWSWP_F;
+		val |= WINCONx_BURSTLEN_16WORD;
+		break;
+	case DRM_FORMAT_RGB565:
+		val |= WINCONx_BPPMODE_16BPP_565;
+		val |= WINCONx_HAWSWP_F;
+		val |= WINCONx_BURSTLEN_16WORD;
+		break;
+	case DRM_FORMAT_XRGB8888:
+		val |= WINCONx_BPPMODE_24BPP_888;
+		val |= WINCONx_WSWP_F;
+		val |= WINCONx_BURSTLEN_16WORD;
+		break;
+	case DRM_FORMAT_ARGB8888:
+		val |= WINCONx_BPPMODE_32BPP_A8888;
+		val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F;
+		val |= WINCONx_BURSTLEN_16WORD;
+		break;
+	default:
+		DRM_ERROR("Proper pixel format is not set\n");
+		return;
+	}
+
+	DRM_DEBUG_KMS("bpp = %u\n", plane->bpp);
+
+	/*
+	 * In case of exynos, setting dma-burst to 16Word causes permanent
+	 * tearing for very small buffers, e.g. cursor buffer. Burst Mode
+	 * switching which is based on plane size is not recommended as
+	 * plane size varies a lot towards the end of the screen and rapid
+	 * movement causes unstable DMA which results into iommu crash/tear.
+	 */
+
+	if (plane->fb_width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
+		val &= ~WINCONx_BURSTLEN_MASK;
+		val |= WINCONx_BURSTLEN_8WORD;
+	}
+
+	writel(val, ctx->addr + DECON_WINCONx(win));
+}
+
+static void decon_shadow_protect_win(struct decon_context *ctx, int win,
+					bool protect)
+{
+	u32 val;
+
+	val = readl(ctx->addr + DECON_SHADOWCON);
+
+	if (protect)
+		val |= SHADOWCON_Wx_PROTECT(win);
+	else
+		val &= ~SHADOWCON_Wx_PROTECT(win);
+
+	writel(val, ctx->addr + DECON_SHADOWCON);
+}
+
+static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
+{
+	struct decon_context *ctx = crtc->ctx;
+	struct exynos_drm_plane *plane;
+	u32 val;
+
+	if (win < 0 || win >= WINDOWS_NR)
+		return;
+
+	plane = &ctx->planes[win];
+
+	if (ctx->suspended)
+		return;
+
+	decon_shadow_protect_win(ctx, win, true);
+
+	val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y);
+	writel(val, ctx->addr + DECON_VIDOSDxA(win));
+
+	val = COORDINATE_X(plane->crtc_x + plane->crtc_width - 1) |
+		COORDINATE_Y(plane->crtc_y + plane->crtc_height - 1);
+	writel(val, ctx->addr + DECON_VIDOSDxB(win));
+
+	val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
+		VIDOSD_Wx_ALPHA_B_F(0x0);
+	writel(val, ctx->addr + DECON_VIDOSDxC(win));
+
+	val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
+		VIDOSD_Wx_ALPHA_B_F(0x0);
+	writel(val, ctx->addr + DECON_VIDOSDxD(win));
+
+	writel(plane->dma_addr[0], ctx->addr + DECON_VIDW0xADD0B0(win));
+
+	val = plane->dma_addr[0] + plane->pitch * plane->crtc_height;
+	writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
+
+	val = OFFSIZE(plane->pitch - plane->crtc_width * (plane->bpp >> 3))
+		| PAGEWIDTH(plane->crtc_width * (plane->bpp >> 3));
+	writel(val, ctx->addr + DECON_VIDW0xADD2(win));
+
+	decon_win_set_pixfmt(ctx, win);
+
+	/* window enable */
+	val = readl(ctx->addr + DECON_WINCONx(win));
+	val |= WINCONx_ENWIN_F;
+	writel(val, ctx->addr + DECON_WINCONx(win));
+
+	decon_shadow_protect_win(ctx, win, false);
+
+	/* standalone update */
+	val = readl(ctx->addr + DECON_UPDATE);
+	val |= STANDALONE_UPDATE_F;
+	writel(val, ctx->addr + DECON_UPDATE);
+
+	if (ctx->i80_if)
+		atomic_set(&ctx->win_updated, 1);
+}
+
+static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
+{
+	struct decon_context *ctx = crtc->ctx;
+	struct exynos_drm_plane *plane;
+	u32 val;
+
+	if (win < 0 || win >= WINDOWS_NR)
+		return;
+
+	plane = &ctx->planes[win];
+
+	if (ctx->suspended)
+		return;
+
+	decon_shadow_protect_win(ctx, win, true);
+
+	/* window disable */
+	val = readl(ctx->addr + DECON_WINCONx(win));
+	val &= ~WINCONx_ENWIN_F;
+	writel(val, ctx->addr + DECON_WINCONx(win));
+
+	decon_shadow_protect_win(ctx, win, false);
+
+	/* standalone update */
+	val = readl(ctx->addr + DECON_UPDATE);
+	val |= STANDALONE_UPDATE_F;
+	writel(val, ctx->addr + DECON_UPDATE);
+}
+
+static void decon_swreset(struct decon_context *ctx)
+{
+	unsigned int tries;
+
+	writel(0, ctx->addr + DECON_VIDCON0);
+	for (tries = 2000; tries; --tries) {
+		if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_STOP_STATUS)
+			break;
+		udelay(10);
+	}
+
+	WARN(tries == 0, "failed to disable DECON\n");
+
+	writel(VIDCON0_SWRESET, ctx->addr + DECON_VIDCON0);
+	for (tries = 2000; tries; --tries) {
+		if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_SWRESET)
+			break;
+		udelay(10);
+	}
+
+	WARN(tries == 0, "failed to software reset DECON\n");
+}
+
+static void decon_enable(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+	int ret;
+	int i;
+
+	if (!ctx->suspended)
+		return;
+
+	ctx->suspended = false;
+
+	pm_runtime_get_sync(ctx->dev);
+
+	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
+		ret = clk_prepare_enable(ctx->clks[i]);
+		if (ret < 0)
+			goto err;
+	}
+
+	set_bit(BIT_CLKS_ENABLED, &ctx->enabled);
+
+	/* if vblank was enabled status, enable it again. */
+	if (test_and_clear_bit(0, &ctx->irq_flags))
+		decon_enable_vblank(ctx->crtc);
+
+	decon_commit(ctx->crtc);
+
+	return;
+err:
+	while (--i >= 0)
+		clk_disable_unprepare(ctx->clks[i]);
+
+	ctx->suspended = true;
+}
+
+static void decon_disable(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+	int i;
+
+	if (ctx->suspended)
+		return;
+
+	/*
+	 * We need to make sure that all windows are disabled before we
+	 * suspend that connector. Otherwise we might try to scan from
+	 * a destroyed buffer later.
+	 */
+	for (i = 0; i < WINDOWS_NR; i++)
+		decon_win_disable(crtc, i);
+
+	decon_swreset(ctx);
+
+	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++)
+		clk_disable_unprepare(ctx->clks[i]);
+
+	clear_bit(BIT_CLKS_ENABLED, &ctx->enabled);
+
+	pm_runtime_put_sync(ctx->dev);
+
+	ctx->suspended = true;
+}
+
+void decon_te_irq_handler(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+	u32 val;
+
+	if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled))
+		return;
+
+	if (atomic_add_unless(&ctx->win_updated, -1, 0)) {
+		/* trigger */
+		val = readl(ctx->addr + DECON_TRIGCON);
+		val |= TRIGCON_SWTRIGCMD;
+		writel(val, ctx->addr + DECON_TRIGCON);
+	}
+
+	drm_handle_vblank(ctx->drm_dev, ctx->pipe);
+}
+
+static void decon_clear_channels(struct exynos_drm_crtc *crtc)
+{
+	struct decon_context *ctx = crtc->ctx;
+	int win, i, ret;
+	u32 val;
+
+	DRM_DEBUG_KMS("%s\n", __FILE__);
+
+	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
+		ret = clk_prepare_enable(ctx->clks[i]);
+		if (ret < 0)
+			goto err;
+	}
+
+	for (win = 0; win < WINDOWS_NR; win++) {
+		/* shadow update disable */
+		val = readl(ctx->addr + DECON_SHADOWCON);
+		val |= SHADOWCON_Wx_PROTECT(win);
+		writel(val, ctx->addr + DECON_SHADOWCON);
+
+		/* window disable */
+		val = readl(ctx->addr + DECON_WINCONx(win));
+		val &= ~WINCONx_ENWIN_F;
+		writel(val, ctx->addr + DECON_WINCONx(win));
+
+		/* shadow update enable */
+		val = readl(ctx->addr + DECON_SHADOWCON);
+		val &= ~SHADOWCON_Wx_PROTECT(win);
+		writel(val, ctx->addr + DECON_SHADOWCON);
+
+		/* standalone update */
+		val = readl(ctx->addr + DECON_UPDATE);
+		val |= STANDALONE_UPDATE_F;
+		writel(val, ctx->addr + DECON_UPDATE);
+	}
+	/* TODO: wait for possible vsync */
+	msleep(50);
+
+err:
+	while (--i >= 0)
+		clk_disable_unprepare(ctx->clks[i]);
+}
+
+static struct exynos_drm_crtc_ops decon_crtc_ops = {
+	.enable			= decon_enable,
+	.disable		= decon_disable,
+	.commit			= decon_commit,
+	.enable_vblank		= decon_enable_vblank,
+	.disable_vblank		= decon_disable_vblank,
+	.commit			= decon_commit,
+	.win_commit		= decon_win_commit,
+	.win_disable		= decon_win_disable,
+	.te_handler		= decon_te_irq_handler,
+	.clear_channels		= decon_clear_channels,
+};
+
+static int decon_bind(struct device *dev, struct device *master, void *data)
+{
+	struct decon_context *ctx = dev_get_drvdata(dev);
+	struct drm_device *drm_dev = data;
+	struct exynos_drm_private *priv = drm_dev->dev_private;
+	struct exynos_drm_plane *exynos_plane;
+	enum drm_plane_type type;
+	unsigned int zpos;
+	int ret;
+
+	ctx->drm_dev = drm_dev;
+	ctx->pipe = priv->pipe++;
+
+	for (zpos = 0; zpos < WINDOWS_NR; zpos++) {
+		type = (zpos == ctx->default_win) ? DRM_PLANE_TYPE_PRIMARY :
+							DRM_PLANE_TYPE_OVERLAY;
+		ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
+				1 << ctx->pipe, type, zpos);
+		if (ret)
+			return ret;
+	}
+
+	exynos_plane = &ctx->planes[ctx->default_win];
+	ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
+					ctx->pipe, EXYNOS_DISPLAY_TYPE_LCD,
+					&decon_crtc_ops, ctx);
+	if (IS_ERR(ctx->crtc)) {
+		ret = PTR_ERR(ctx->crtc);
+		goto err;
+	}
+
+	ret = drm_iommu_attach_device_if_possible(ctx->crtc, drm_dev, dev);
+	if (ret)
+		goto err;
+
+	return ret;
+err:
+	priv->pipe--;
+	return ret;
+}
+
+static void decon_unbind(struct device *dev, struct device *master, void *data)
+{
+	struct decon_context *ctx = dev_get_drvdata(dev);
+
+	decon_disable(ctx->crtc);
+
+	/* detach this sub driver from iommu mapping if supported. */
+	if (is_drm_iommu_supported(ctx->drm_dev))
+		drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
+}
+
+static const struct component_ops decon_component_ops = {
+	.bind	= decon_bind,
+	.unbind = decon_unbind,
+};
+
+static irqreturn_t decon_vsync_irq_handler(int irq, void *dev_id)
+{
+	struct decon_context *ctx = dev_id;
+	u32 val;
+
+	if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled))
+		goto out;
+
+	val = readl(ctx->addr + DECON_VIDINTCON1);
+	if (val & VIDINTCON1_INTFRMPEND) {
+		drm_handle_vblank(ctx->drm_dev, ctx->pipe);
+
+		/* clear */
+		writel(VIDINTCON1_INTFRMPEND, ctx->addr + DECON_VIDINTCON1);
+	}
+
+out:
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t decon_lcd_sys_irq_handler(int irq, void *dev_id)
+{
+	struct decon_context *ctx = dev_id;
+	u32 val;
+
+	if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled))
+		goto out;
+
+	val = readl(ctx->addr + DECON_VIDINTCON1);
+	if (val & VIDINTCON1_INTFRMDONEPEND) {
+		exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
+
+		/* clear */
+		writel(VIDINTCON1_INTFRMDONEPEND,
+				ctx->addr + DECON_VIDINTCON1);
+	}
+
+out:
+	return IRQ_HANDLED;
+}
+
+static int exynos5433_decon_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct decon_context *ctx;
+	struct resource *res;
+	int ret;
+	int i;
+
+	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->default_win = 0;
+	ctx->suspended = true;
+	ctx->dev = dev;
+	if (of_get_child_by_name(dev->of_node, "i80-if-timings"))
+		ctx->i80_if = true;
+
+	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
+		struct clk *clk;
+
+		clk = devm_clk_get(ctx->dev, decon_clks_name[i]);
+		if (IS_ERR(clk))
+			return PTR_ERR(clk);
+
+		ctx->clks[i] = clk;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "cannot find IO resource\n");
+		return -ENXIO;
+	}
+
+	ctx->addr = devm_ioremap_resource(dev, res);
+	if (IS_ERR(ctx->addr)) {
+		dev_err(dev, "ioremap failed\n");
+		return PTR_ERR(ctx->addr);
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
+			ctx->i80_if ? "lcd_sys" : "vsync");
+	if (!res) {
+		dev_err(dev, "cannot find IRQ resource\n");
+		return -ENXIO;
+	}
+
+	ret = devm_request_irq(dev, res->start, ctx->i80_if ?
+			decon_lcd_sys_irq_handler : decon_vsync_irq_handler, 0,
+			"drm_decon", ctx);
+	if (ret < 0) {
+		dev_err(dev, "lcd_sys irq request failed\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, ctx);
+
+	pm_runtime_enable(dev);
+
+	ret = component_add(dev, &decon_component_ops);
+	if (ret)
+		goto err_disable_pm_runtime;
+
+	return 0;
+
+err_disable_pm_runtime:
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static int exynos5433_decon_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+
+	component_del(&pdev->dev, &decon_component_ops);
+
+	return 0;
+}
+
+static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
+	{ .compatible = "samsung,exynos5433-decon" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match);
+
+struct platform_driver exynos5433_decon_driver = {
+	.probe		= exynos5433_decon_probe,
+	.remove		= exynos5433_decon_remove,
+	.driver		= {
+		.name	= "exynos5433-decon",
+		.of_match_table = exynos5433_decon_driver_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 61a9a9e..819ce3e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -301,6 +301,7 @@ int exynos_drm_create_enc_conn(struct drm_device *dev,
 				struct exynos_drm_display *display);
 
 extern struct platform_driver fimd_driver;
+extern struct platform_driver exynos5433_decon_driver;
 extern struct platform_driver decon_driver;
 extern struct platform_driver dp_driver;
 extern struct platform_driver dsi_driver;
diff --git a/include/video/exynos5433_decon.h b/include/video/exynos5433_decon.h
new file mode 100644
index 0000000..3696575
--- /dev/null
+++ b/include/video/exynos5433_decon.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics Co.Ltd
+ *
+ * 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 Foundationr
+ */
+
+#ifndef EXYNOS_REGS_DECON_H
+#define EXYNOS_REGS_DECON_H
+
+/* Exynos543X DECON */
+#define DECON_VIDCON0			0x0000
+#define DECON_VIDOUTCON0		0x0010
+#define DECON_WINCONx(n)		(0x0020 + ((n) * 4))
+#define DECON_VIDOSDxH(n)		(0x0080 + ((n) * 4))
+#define DECON_SHADOWCON			0x00A0
+#define DECON_VIDOSDxA(n)		(0x00B0 + ((n) * 0x20))
+#define DECON_VIDOSDxB(n)		(0x00B4 + ((n) * 0x20))
+#define DECON_VIDOSDxC(n)		(0x00B8 + ((n) * 0x20))
+#define DECON_VIDOSDxD(n)		(0x00BC + ((n) * 0x20))
+#define DECON_VIDOSDxE(n)		(0x00C0 + ((n) * 0x20))
+#define DECON_VIDW0xADD0B0(n)		(0x0150 + ((n) * 0x10))
+#define DECON_VIDW0xADD0B1(n)		(0x0154 + ((n) * 0x10))
+#define DECON_VIDW0xADD0B2(n)		(0x0158 + ((n) * 0x10))
+#define DECON_VIDW0xADD1B0(n)		(0x01A0 + ((n) * 0x10))
+#define DECON_VIDW0xADD1B1(n)		(0x01A4 + ((n) * 0x10))
+#define DECON_VIDW0xADD1B2(n)		(0x01A8 + ((n) * 0x10))
+#define DECON_VIDW0xADD2(n)		(0x0200 + ((n) * 4))
+#define DECON_LOCALxSIZE(n)		(0x0214 + ((n) * 4))
+#define DECON_VIDINTCON0		0x0220
+#define DECON_VIDINTCON1		0x0224
+#define DECON_WxKEYCON0(n)		(0x0230 + ((n - 1) * 8))
+#define DECON_WxKEYCON1(n)		(0x0234 + ((n - 1) * 8))
+#define DECON_WxKEYALPHA(n)		(0x0250 + ((n - 1) * 4))
+#define DECON_WINxMAP(n)		(0x0270 + ((n) * 4))
+#define DECON_QOSLUT07_00		0x02C0
+#define DECON_QOSLUT15_08		0x02C4
+#define DECON_QOSCTRL			0x02C8
+#define DECON_BLENDERQx(n)		(0x0300 + ((n - 1) * 4))
+#define DECON_BLENDCON			0x0310
+#define DECON_OPE_VIDW0xADD0(n)		(0x0400 + ((n) * 4))
+#define DECON_OPE_VIDW0xADD1(n)		(0x0414 + ((n) * 4))
+#define DECON_FRAMEFIFO_REG7		0x051C
+#define DECON_FRAMEFIFO_REG8		0x0520
+#define DECON_FRAMEFIFO_STATUS		0x0524
+#define DECON_CMU			0x1404
+#define DECON_UPDATE			0x1410
+#define DECON_UPDATE_SCHEME		0x1438
+#define DECON_VIDCON1			0x2000
+#define DECON_VIDCON2			0x2004
+#define DECON_VIDCON3			0x2008
+#define DECON_VIDCON4			0x200C
+#define DECON_VIDTCON2			0x2028
+#define DECON_FRAME_SIZE		0x2038
+#define DECON_LINECNT_OP_THRESHOLD	0x203C
+#define DECON_TRIGCON			0x2040
+#define DECON_TRIGSKIP			0x2050
+#define DECON_CRCRDATA			0x20B0
+#define DECON_CRCCTRL			0x20B4
+
+/* Exynos5430 DECON */
+#define DECON_VIDTCON0			0x2020
+#define DECON_VIDTCON1			0x2024
+
+/* Exynos5433 DECON */
+#define DECON_VIDTCON00			0x2010
+#define DECON_VIDTCON01			0x2014
+#define DECON_VIDTCON10			0x2018
+#define DECON_VIDTCON11			0x201C
+
+/* Exynos543X DECON Internal */
+#define DECON_W013DSTREOCON		0x0320
+#define DECON_W233DSTREOCON		0x0324
+#define DECON_FRAMEFIFO_REG0		0x0500
+#define DECON_ENHANCER_CTRL		0x2100
+
+/* Exynos543X DECON TV */
+#define DECON_VCLKCON0			0x0014
+#define DECON_VIDINTCON2		0x0228
+#define DECON_VIDINTCON3		0x022C
+
+/* VIDCON0 */
+#define VIDCON0_SWRESET			(1 << 28)
+#define VIDCON0_STOP_STATUS		(1 << 2)
+#define VIDCON0_ENVID			(1 << 1)
+#define VIDCON0_ENVID_F			(1 << 0)
+
+/* VIDOUTCON0 */
+#define VIDOUT_LCD_ON			(1 << 24)
+#define VIDOUT_IF_F_MASK		(0x3 << 20)
+#define VIDOUT_RGB_IF			(0x0 << 20)
+#define VIDOUT_COMMAND_IF		(0x2 << 20)
+
+/* WINCONx */
+#define WINCONx_HAWSWP_F		(1 << 16)
+#define WINCONx_WSWP_F			(1 << 15)
+#define WINCONx_BURSTLEN_MASK		(0x3 << 10)
+#define WINCONx_BURSTLEN_16WORD		(0x0 << 10)
+#define WINCONx_BURSTLEN_8WORD		(0x1 << 10)
+#define WINCONx_BURSTLEN_4WORD		(0x2 << 10)
+#define WINCONx_BLD_PIX_F		(1 << 6)
+#define WINCONx_BPPMODE_MASK		(0xf << 2)
+#define WINCONx_BPPMODE_16BPP_565	(0x5 << 2)
+#define WINCONx_BPPMODE_16BPP_A1555	(0x6 << 2)
+#define WINCONx_BPPMODE_16BPP_I1555	(0x7 << 2)
+#define WINCONx_BPPMODE_24BPP_888	(0xb << 2)
+#define WINCONx_BPPMODE_24BPP_A1887	(0xc << 2)
+#define WINCONx_BPPMODE_25BPP_A1888	(0xd << 2)
+#define WINCONx_BPPMODE_32BPP_A8888	(0xd << 2)
+#define WINCONx_BPPMODE_16BPP_A4444	(0xe << 2)
+#define WINCONx_ALPHA_SEL_F		(1 << 1)
+#define WINCONx_ENWIN_F			(1 << 0)
+
+/* SHADOWCON */
+#define SHADOWCON_Wx_PROTECT(n)		(1 << (10 + (n)))
+
+/* VIDOSDxD */
+#define VIDOSD_Wx_ALPHA_R_F(n)		(((n) & 0xff) << 16)
+#define VIDOSD_Wx_ALPHA_G_F(n)		(((n) & 0xff) << 8)
+#define VIDOSD_Wx_ALPHA_B_F(n)		(((n) & 0xff) << 0)
+
+/* VIDINTCON0 */
+#define VIDINTCON0_FRAMEDONE		(1 << 17)
+#define VIDINTCON0_INTFRMEN		(1 << 12)
+#define VIDINTCON0_INTEN		(1 << 0)
+
+/* VIDINTCON1 */
+#define VIDINTCON1_INTFRMDONEPEND	(1 << 2)
+#define VIDINTCON1_INTFRMPEND		(1 << 1)
+#define VIDINTCON1_INTFIFOPEND		(1 << 0)
+
+/* DECON_CMU */
+#define CMU_CLKGAGE_MODE_SFR_F		(1 << 1)
+#define CMU_CLKGAGE_MODE_MEM_F		(1 << 0)
+
+/* DECON_UPDATE */
+#define STANDALONE_UPDATE_F		(1 << 0)
+
+/* DECON_VIDTCON00 */
+#define VIDTCON00_VBPD_F(x)		(((x) & 0xfff) << 16)
+#define VIDTCON00_VFPD_F(x)		((x) & 0xfff)
+
+/* DECON_VIDTCON01 */
+#define VIDTCON01_VSPW_F(x)		(((x) & 0xfff) << 16)
+
+/* DECON_VIDTCON10 */
+#define VIDTCON10_HBPD_F(x)		(((x) & 0xfff) << 16)
+#define VIDTCON10_HFPD_F(x)		((x) & 0xfff)
+
+/* DECON_VIDTCON11 */
+#define VIDTCON11_HSPW_F(x)		(((x) & 0xfff) << 16)
+
+/* DECON_VIDTCON2 */
+#define VIDTCON2_LINEVAL(x)		(((x) & 0xfff) << 16)
+#define VIDTCON2_HOZVAL(x)		((x) & 0xfff)
+
+/* TRIGCON */
+#define TRIGCON_TRIGEN_PER_F		(1 << 31)
+#define TRIGCON_TRIGEN_F		(1 << 30)
+#define TRIGCON_TE_AUTO_MASK		(1 << 29)
+#define TRIGCON_SWTRIGCMD		(1 << 1)
+#define TRIGCON_SWTRIGEN		(1 << 0)
+
+#endif /* EXYNOS_REGS_DECON_H */
-- 
1.7.9.5

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

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

* Re: [PATCH v7 05/15] drm/exynos: add Exynos5433 decon driver
  2015-06-22 11:16     ` [PATCH v7 " Inki Dae
@ 2015-06-22 11:41       ` Varka Bhadram
  2015-06-22 11:57         ` Inki Dae
  0 siblings, 1 reply; 50+ messages in thread
From: Varka Bhadram @ 2015-06-22 11:41 UTC (permalink / raw)
  To: Inki Dae, dri-devel
  Cc: airlied, linux-samsung-soc, Joonyoung Shim, Hyungwon Hwang

Hi,

On 06/22/2015 04:46 PM, Inki Dae wrote:

> From: Joonyoung Shim <jy0922.shim@samsung.com>
>
> DECON(Display and Enhancement Controller) is new IP replacing FIMD in
> Exynos5433. This patch adds Exynos5433 decon driver.
>
> Changelog v7:
> - Rebased on top of exynos-drm-next.
> - Added runtime pm support.
>
> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> Signed-off-by: Inki Dae <inki.dae@samsung.com>
> ---
>   

(...)

> +static int exynos5433_decon_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct decon_context *ctx;
> +	struct resource *res;
> +	int ret;
> +	int i;
> +
> +	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> +	if (!ctx)
> +		return -ENOMEM;
> +
> +	ctx->default_win = 0;
> +	ctx->suspended = true;
> +	ctx->dev = dev;
> +	if (of_get_child_by_name(dev->of_node, "i80-if-timings"))
> +		ctx->i80_if = true;
> +
> +	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
> +		struct clk *clk;
> +
> +		clk = devm_clk_get(ctx->dev, decon_clks_name[i]);
> +		if (IS_ERR(clk))
> +			return PTR_ERR(clk);
> +
> +		ctx->clks[i] = clk;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(dev, "cannot find IO resource\n");
> +		return -ENXIO;
> +	}
> +

You people promised me to remove this check  :-)

http://lists.freedesktop.org/archives/dri-devel/2015-April/081077.html

> +	ctx->addr = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(ctx->addr)) {
> +		dev_err(dev, "ioremap failed\n");
> +		return PTR_ERR(ctx->addr);
> +	}
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
> +			ctx->i80_if ? "lcd_sys" : "vsync");
> +	if (!res) {
> +		dev_err(dev, "cannot find IRQ resource\n");
> +		return -ENXIO;
> +	}
> +
> +	ret = devm_request_irq(dev, res->start, ctx->i80_if ?
> +			decon_lcd_sys_irq_handler : decon_vsync_irq_handler, 0,
> +			"drm_decon", ctx);
> +	if (ret < 0) {
> +		dev_err(dev, "lcd_sys irq request failed\n");
> +		return ret;
> +	}
> +
> +	platform_set_drvdata(pdev, ctx);

You are setting the driver data as ctx..

But no where you are using it...?

Am i missing anything ?

-- 
Best regards,
Varka Bhadram.

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

* Re: [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi'
  2015-06-22  9:10     ` Inki Dae
@ 2015-06-22 11:42       ` Inki Dae
  2015-06-22 11:59         ` Krzysztof Kozlowski
  2015-06-22 12:35         ` Krzysztof Kozlowski
  0 siblings, 2 replies; 50+ messages in thread
From: Inki Dae @ 2015-06-22 11:42 UTC (permalink / raw)
  To: Hyungwon Hwang, Kukjin Kim, Krzysztof Kozlowski, Krzysztof Kozlowski
  Cc: devicetree, sw0312.kim, dri-devel

+ Krzysztof

On 2015년 06월 22일 18:10, Inki Dae wrote:
> On 2015년 06월 12일 21:59, Hyungwon Hwang wrote:
>> The clock which was named as 'pll_clk' is actually not the clock source
>> of PLL in MIPI DSI. This patch fixes this disagreement.
> 
> Mr. Kukjin and Krzysztof, can you give me Acked-by or Singed-off-by? I'd
> like to merge this patch to mainline through drm-next.
> 
> Thanks,
> Inki Dae
> 
>>
>> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
>> ---
>> Changes before:
>> - Refer https://patchwork.kernel.org/patch/6191811
>> Changes for v6:
>> - None
>>
>>  arch/arm/boot/dts/exynos4.dtsi | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
>> index e20cdc2..1538d7a 100644
>> --- a/arch/arm/boot/dts/exynos4.dtsi
>> +++ b/arch/arm/boot/dts/exynos4.dtsi
>> @@ -167,7 +167,7 @@
>>  		phys = <&mipi_phy 1>;
>>  		phy-names = "dsim";
>>  		clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
>> -		clock-names = "bus_clk", "pll_clk";
>> +		clock-names = "bus_clk", "sclk_mipi";
>>  		status = "disabled";
>>  		#address-cells = <1>;
>>  		#size-cells = <0>;
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe devicetree" 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

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

* Re: [PATCH v7 05/15] drm/exynos: add Exynos5433 decon driver
  2015-06-22 11:41       ` Varka Bhadram
@ 2015-06-22 11:57         ` Inki Dae
  2015-06-22 11:59           ` Varka Bhadram
  0 siblings, 1 reply; 50+ messages in thread
From: Inki Dae @ 2015-06-22 11:57 UTC (permalink / raw)
  To: Varka Bhadram; +Cc: linux-samsung-soc, dri-devel

On 2015년 06월 22일 20:41, Varka Bhadram wrote:
> Hi,
> 
> On 06/22/2015 04:46 PM, Inki Dae wrote:
> 
>> From: Joonyoung Shim <jy0922.shim@samsung.com>
>>
>> DECON(Display and Enhancement Controller) is new IP replacing FIMD in
>> Exynos5433. This patch adds Exynos5433 decon driver.
>>
>> Changelog v7:
>> - Rebased on top of exynos-drm-next.
>> - Added runtime pm support.
>>
>> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
>> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
>> Signed-off-by: Inki Dae <inki.dae@samsung.com>
>> ---
>>   
> 
> (...)
> 
>> +static int exynos5433_decon_probe(struct platform_device *pdev)
>> +{
>> +    struct device *dev = &pdev->dev;
>> +    struct decon_context *ctx;
>> +    struct resource *res;
>> +    int ret;
>> +    int i;
>> +
>> +    ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
>> +    if (!ctx)
>> +        return -ENOMEM;
>> +
>> +    ctx->default_win = 0;
>> +    ctx->suspended = true;
>> +    ctx->dev = dev;
>> +    if (of_get_child_by_name(dev->of_node, "i80-if-timings"))
>> +        ctx->i80_if = true;
>> +
>> +    for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
>> +        struct clk *clk;
>> +
>> +        clk = devm_clk_get(ctx->dev, decon_clks_name[i]);
>> +        if (IS_ERR(clk))
>> +            return PTR_ERR(clk);
>> +
>> +        ctx->clks[i] = clk;
>> +    }
>> +
>> +    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +    if (!res) {
>> +        dev_err(dev, "cannot find IO resource\n");
>> +        return -ENXIO;
>> +    }
>> +
> 
> You people promised me to remove this check  :-)

Right but isn't it better to check an error explicitly? Anyway trivial one.

> 
> http://lists.freedesktop.org/archives/dri-devel/2015-April/081077.html
> 
>> +    ctx->addr = devm_ioremap_resource(dev, res);
>> +    if (IS_ERR(ctx->addr)) {
>> +        dev_err(dev, "ioremap failed\n");
>> +        return PTR_ERR(ctx->addr);
>> +    }
>> +
>> +    res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
>> +            ctx->i80_if ? "lcd_sys" : "vsync");
>> +    if (!res) {
>> +        dev_err(dev, "cannot find IRQ resource\n");
>> +        return -ENXIO;
>> +    }
>> +
>> +    ret = devm_request_irq(dev, res->start, ctx->i80_if ?
>> +            decon_lcd_sys_irq_handler : decon_vsync_irq_handler, 0,
>> +            "drm_decon", ctx);
>> +    if (ret < 0) {
>> +        dev_err(dev, "lcd_sys irq request failed\n");
>> +        return ret;
>> +    }
>> +
>> +    platform_set_drvdata(pdev, ctx);
> 
> You are setting the driver data as ctx..
> 
> But no where you are using it...?
> 
> Am i missing anything ?

See decon_bind and decon_unbind functions. :)

Thanks,
Inki Dae

> 

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

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

* Re: [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi'
  2015-06-22 11:42       ` Inki Dae
@ 2015-06-22 11:59         ` Krzysztof Kozlowski
  2015-06-22 12:10           ` Inki Dae
  2015-06-22 12:35         ` Krzysztof Kozlowski
  1 sibling, 1 reply; 50+ messages in thread
From: Krzysztof Kozlowski @ 2015-06-22 11:59 UTC (permalink / raw)
  To: Inki Dae
  Cc: Hyungwon Hwang, Kukjin Kim, Krzysztof Kozlowski, dri-devel,
	devicetree, daniel, sw0312.kim, jy0922.shim, linux-samsung-soc

2015-06-22 20:42 GMT+09:00 Inki Dae <inki.dae@samsung.com>:
> + Krzysztof
>
> On 2015년 06월 22일 18:10, Inki Dae wrote:
>> On 2015년 06월 12일 21:59, Hyungwon Hwang wrote:
>>> The clock which was named as 'pll_clk' is actually not the clock source
>>> of PLL in MIPI DSI. This patch fixes this disagreement.
>>
>> Mr. Kukjin and Krzysztof, can you give me Acked-by or Singed-off-by? I'd
>> like to merge this patch to mainline through drm-next.

Dear Hyungwon Hwang,

Please always CC samsung-soc mailing list on such patches. I won't
receive it on my personal email if you don't CC the list. The
get_maintainers.pl gives necessary addresses.

Comment below,

>>
>> Thanks,
>> Inki Dae
>>
>>>
>>> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
>>> ---
>>> Changes before:
>>> - Refer https://patchwork.kernel.org/patch/6191811
>>> Changes for v6:
>>> - None
>>>
>>>  arch/arm/boot/dts/exynos4.dtsi | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
>>> index e20cdc2..1538d7a 100644
>>> --- a/arch/arm/boot/dts/exynos4.dtsi
>>> +++ b/arch/arm/boot/dts/exynos4.dtsi
>>> @@ -167,7 +167,7 @@
>>>              phys = <&mipi_phy 1>;
>>>              phy-names = "dsim";
>>>              clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
>>> -            clock-names = "bus_clk", "pll_clk";
>>> +            clock-names = "bus_clk", "sclk_mipi";

It seems wrong. The driver fetches reference from a name of "pll_clk",
not "sclk_mipi". Also bindings documentation mentions pll_clk and
bus_clk only.

Best regards,
Krzysztof


>>>              status = "disabled";
>>>              #address-cells = <1>;
>>>              #size-cells = <0>;
>>> --
>>> 1.9.1
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe devicetree" 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] 50+ messages in thread

* Re: [PATCH v7 05/15] drm/exynos: add Exynos5433 decon driver
  2015-06-22 11:57         ` Inki Dae
@ 2015-06-22 11:59           ` Varka Bhadram
  0 siblings, 0 replies; 50+ messages in thread
From: Varka Bhadram @ 2015-06-22 11:59 UTC (permalink / raw)
  To: Inki Dae
  Cc: dri-devel, airlied, linux-samsung-soc, Joonyoung Shim, Hyungwon Hwang

On 06/22/2015 05:27 PM, Inki Dae wrote:

> On 2015년 06월 22일 20:41, Varka Bhadram wrote:
>
(..)

> +    platform_set_drvdata(pdev, ctx);
>> You are setting the driver data as ctx..
>>
>> But no where you are using it...?
>>
>> Am i missing anything ?
> See decon_bind and decon_unbind functions. :)

Cleared. Thanks


-- 
Best regards,
Varka Bhadram.

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

* Re: [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi'
  2015-06-22 11:59         ` Krzysztof Kozlowski
@ 2015-06-22 12:10           ` Inki Dae
  2015-06-22 12:20             ` Krzysztof Kozlowski
  0 siblings, 1 reply; 50+ messages in thread
From: Inki Dae @ 2015-06-22 12:10 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: devicetree, Kukjin Kim, sw0312.kim, dri-devel, linux-samsung-soc

On 2015년 06월 22일 20:59, Krzysztof Kozlowski wrote:
> 2015-06-22 20:42 GMT+09:00 Inki Dae <inki.dae@samsung.com>:
>> + Krzysztof
>>
>> On 2015년 06월 22일 18:10, Inki Dae wrote:
>>> On 2015년 06월 12일 21:59, Hyungwon Hwang wrote:
>>>> The clock which was named as 'pll_clk' is actually not the clock source
>>>> of PLL in MIPI DSI. This patch fixes this disagreement.
>>>
>>> Mr. Kukjin and Krzysztof, can you give me Acked-by or Singed-off-by? I'd
>>> like to merge this patch to mainline through drm-next.
> 
> Dear Hyungwon Hwang,
> 
> Please always CC samsung-soc mailing list on such patches. I won't
> receive it on my personal email if you don't CC the list. The
> get_maintainers.pl gives necessary addresses.
> 
> Comment below,
> 
>>>
>>> Thanks,
>>> Inki Dae
>>>
>>>>
>>>> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
>>>> ---
>>>> Changes before:
>>>> - Refer https://patchwork.kernel.org/patch/6191811
>>>> Changes for v6:
>>>> - None
>>>>
>>>>  arch/arm/boot/dts/exynos4.dtsi | 2 +-
>>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
>>>> index e20cdc2..1538d7a 100644
>>>> --- a/arch/arm/boot/dts/exynos4.dtsi
>>>> +++ b/arch/arm/boot/dts/exynos4.dtsi
>>>> @@ -167,7 +167,7 @@
>>>>              phys = <&mipi_phy 1>;
>>>>              phy-names = "dsim";
>>>>              clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
>>>> -            clock-names = "bus_clk", "pll_clk";
>>>> +            clock-names = "bus_clk", "sclk_mipi";
> 
> It seems wrong. The driver fetches reference from a name of "pll_clk",
> not "sclk_mipi". Also bindings documentation mentions pll_clk and
> bus_clk only.

Krzysztof,

There is your missing point. The driver is already considered for
pll_clk also. See the below codes,

#define OLD_SCLK_MIPI_CLK_NAME "pll_clk"
...

	for (i = 0; i < dsi->driver_data->num_clks; i++) {
		dsi->clks[i] = devm_clk_get(dev, clk_names[i]);
		if (IS_ERR(dsi->clks[i])) {
			if (strcmp(clk_names[i], "sclk_mipi") == 0) {
				strcpy(clk_names[i], OLD_SCLK_MIPI_CLK_NAME);
				i--;
				continue;
			}

			dev_info(dev, "failed to get the clock: %s\n",
					clk_names[i]);
			return PTR_ERR(dsi->clks[i]);
		}
	}

Above codes make the driver to try to get the pll_clk - defined as
OLD_SCLK_MIPI_CLK_NAME macro - again if getting sclk_mipi clock failed
so there is no problem even though a little bit ugly.

As you know, we should guarantee the backward compatibility so this
codes check two clock names.

Thanks,
Inki Dae

> 
> Best regards,
> Krzysztof
> 
> 
>>>>              status = "disabled";
>>>>              #address-cells = <1>;
>>>>              #size-cells = <0>;
>>>> --
>>>> 1.9.1
>>>>
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe devicetree" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>
>>>
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> 

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

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

* Re: [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi'
  2015-06-22 12:10           ` Inki Dae
@ 2015-06-22 12:20             ` Krzysztof Kozlowski
  0 siblings, 0 replies; 50+ messages in thread
From: Krzysztof Kozlowski @ 2015-06-22 12:20 UTC (permalink / raw)
  To: Inki Dae, Hyungwon Hwang
  Cc: devicetree, Krzysztof Kozlowski, Kukjin Kim, sw0312.kim,
	linux-samsung-soc, dri-devel

2015-06-22 21:10 GMT+09:00 Inki Dae <inki.dae@samsung.com>:
> On 2015년 06월 22일 20:59, Krzysztof Kozlowski wrote:
>> 2015-06-22 20:42 GMT+09:00 Inki Dae <inki.dae@samsung.com>:
>>> + Krzysztof
>>>
>>> On 2015년 06월 22일 18:10, Inki Dae wrote:
>>>> On 2015년 06월 12일 21:59, Hyungwon Hwang wrote:
>>>>> The clock which was named as 'pll_clk' is actually not the clock source
>>>>> of PLL in MIPI DSI. This patch fixes this disagreement.
>>>>
>>>> Mr. Kukjin and Krzysztof, can you give me Acked-by or Singed-off-by? I'd
>>>> like to merge this patch to mainline through drm-next.
>>
>> Dear Hyungwon Hwang,
>>
>> Please always CC samsung-soc mailing list on such patches. I won't
>> receive it on my personal email if you don't CC the list. The
>> get_maintainers.pl gives necessary addresses.
>>
>> Comment below,
>>
>>>>
>>>> Thanks,
>>>> Inki Dae
>>>>
>>>>>
>>>>> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
>>>>> ---
>>>>> Changes before:
>>>>> - Refer https://patchwork.kernel.org/patch/6191811
>>>>> Changes for v6:
>>>>> - None
>>>>>
>>>>>  arch/arm/boot/dts/exynos4.dtsi | 2 +-
>>>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
>>>>> index e20cdc2..1538d7a 100644
>>>>> --- a/arch/arm/boot/dts/exynos4.dtsi
>>>>> +++ b/arch/arm/boot/dts/exynos4.dtsi
>>>>> @@ -167,7 +167,7 @@
>>>>>              phys = <&mipi_phy 1>;
>>>>>              phy-names = "dsim";
>>>>>              clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
>>>>> -            clock-names = "bus_clk", "pll_clk";
>>>>> +            clock-names = "bus_clk", "sclk_mipi";
>>
>> It seems wrong. The driver fetches reference from a name of "pll_clk",
>> not "sclk_mipi". Also bindings documentation mentions pll_clk and
>> bus_clk only.
>
> Krzysztof,
>
> There is your missing point. The driver is already considered for
> pll_clk also. See the below codes,
>
> #define OLD_SCLK_MIPI_CLK_NAME "pll_clk"
> ...
>
>         for (i = 0; i < dsi->driver_data->num_clks; i++) {
>                 dsi->clks[i] = devm_clk_get(dev, clk_names[i]);
>                 if (IS_ERR(dsi->clks[i])) {
>                         if (strcmp(clk_names[i], "sclk_mipi") == 0) {
>                                 strcpy(clk_names[i], OLD_SCLK_MIPI_CLK_NAME);
>                                 i--;
>                                 continue;
>                         }
>
>                         dev_info(dev, "failed to get the clock: %s\n",
>                                         clk_names[i]);
>                         return PTR_ERR(dsi->clks[i]);
>                 }
>         }
>
> Above codes make the driver to try to get the pll_clk - defined as
> OLD_SCLK_MIPI_CLK_NAME macro - again if getting sclk_mipi clock failed
> so there is no problem even though a little bit ugly.
>
> As you know, we should guarantee the backward compatibility so this
> codes check two clock names.

I am looking at next-20150622 and file
drivers/gpu/drm/exynos/exynos_drm_dsi.c. There is no such code there.
There is only pll_clk. No sclk_mipi.

Maybe it was changed by other patch... but I haven't received it. Also
I cannot find such patch on linux-kernel, linux-arm-kernel and
linux-samsung-soc. I cannot ack something that I cannot see :) .

If you sent whole patchset to my office address, then I will look at
it tomorrow. From home I can only look at LKML patches.

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

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

* Re: [PATCH v6 08/15] drm/exynos: dsi: rename pll_clk to sclk_clk
  2015-06-12 12:59   ` [PATCH v6 08/15] drm/exynos: dsi: rename pll_clk to sclk_clk Hyungwon Hwang
@ 2015-06-22 12:25     ` Inki Dae
  0 siblings, 0 replies; 50+ messages in thread
From: Inki Dae @ 2015-06-22 12:25 UTC (permalink / raw)
  To: Hyungwon Hwang; +Cc: devicetree, linux-samsung-soc, sw0312.kim, dri-devel

+ Samsung SoC mailing list.

On 2015년 06월 12일 21:59, Hyungwon Hwang wrote:
> This patch renames pll_clk to sclk_clk. The clock referenced by pll_clk
> is actually not the pll input clock for dsi. The pll input clock comes
> from the board's oscillator directly. But for the backward
> compatibility, the old clock name "pll_clk" is also OK.
> 
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> ---
> Changes before:
> - Refer https://patchwork.kernel.org/patch/6191721
> Changes for v6:
> - Merged 2 patches
>    drm/exynos: dsi: add the backward compatibility for the renamed clock
>    drm/exynos: dsi: rename pll_clk to sclk_clk
> 
>  .../devicetree/bindings/video/exynos_dsim.txt      |  7 +++--
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c            | 36 ++++++++++------------
>  2 files changed, 20 insertions(+), 23 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/video/exynos_dsim.txt b/Documentation/devicetree/bindings/video/exynos_dsim.txt
> index 802aa7e..44659dd 100644
> --- a/Documentation/devicetree/bindings/video/exynos_dsim.txt
> +++ b/Documentation/devicetree/bindings/video/exynos_dsim.txt
> @@ -10,13 +10,14 @@ Required properties:
>    - interrupts: should contain DSI interrupt
>    - clocks: list of clock specifiers, must contain an entry for each required
>      entry in clock-names
> -  - clock-names: should include "bus_clk"and "pll_clk" entries
> +  - clock-names: should include "bus_clk"and "sclk_mipi" entries
> +		 the use of "pll_clk" is deprecated
>    - phys: list of phy specifiers, must contain an entry for each required
>      entry in phy-names
>    - phy-names: should include "dsim" entry
>    - vddcore-supply: MIPI DSIM Core voltage supply (e.g. 1.1V)
>    - vddio-supply: MIPI DSIM I/O and PLL voltage supply (e.g. 1.8V)
> -  - samsung,pll-clock-frequency: specifies frequency of the "pll_clk" clock
> +  - samsung,pll-clock-frequency: specifies frequency of the oscillator clock
>    - #address-cells, #size-cells: should be set respectively to <1> and <0>
>      according to DSI host bindings (see MIPI DSI bindings [1])
> 
> @@ -48,7 +49,7 @@ Example:
>  		reg = <0x11C80000 0x10000>;
>  		interrupts = <0 79 0>;
>  		clocks = <&clock 286>, <&clock 143>;
> -		clock-names = "bus_clk", "pll_clk";
> +		clock-names = "bus_clk", "sclk_mipi";
>  		phys = <&mipi_phy 1>;
>  		phy-names = "dsim";
>  		vddcore-supply = <&vusb_reg>;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> index c1999ad..a3bfac2 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> @@ -235,6 +235,8 @@
>  #define DSI_XFER_TIMEOUT_MS		100
>  #define DSI_RX_FIFO_EMPTY		0x30800002
> 
> +#define OLD_SCLK_MIPI_CLK_NAME "pll_clk"
> +
>  enum exynos_dsi_transfer_type {
>  	EXYNOS_DSI_TX,
>  	EXYNOS_DSI_RX,
> @@ -279,7 +281,7 @@ struct exynos_dsi {
> 
>  	void __iomem *reg_base;
>  	struct phy *phy;
> -	struct clk *pll_clk;
> +	struct clk *sclk_clk;
>  	struct clk *bus_clk;
>  	struct regulator_bulk_data supplies[2];
>  	int irq;
> @@ -433,16 +435,7 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
>  	u16 m;
>  	u32 reg;
> 
> -	clk_set_rate(dsi->pll_clk, dsi->pll_clk_rate);
> -
> -	fin = clk_get_rate(dsi->pll_clk);
> -	if (!fin) {
> -		dev_err(dsi->dev, "failed to get PLL clock frequency\n");
> -		return 0;
> -	}
> -
> -	dev_dbg(dsi->dev, "PLL input frequency: %lu\n", fin);
> -
> +	fin = dsi->pll_clk_rate;
>  	fout = exynos_dsi_pll_find_pms(dsi, fin, freq, &p, &m, &s);
>  	if (!fout) {
>  		dev_err(dsi->dev,
> @@ -1313,10 +1306,10 @@ static int exynos_dsi_poweron(struct exynos_dsi *dsi)
>  		goto err_bus_clk;
>  	}
> 
> -	ret = clk_prepare_enable(dsi->pll_clk);
> +	ret = clk_prepare_enable(dsi->sclk_clk);
>  	if (ret < 0) {
>  		dev_err(dsi->dev, "cannot enable pll clock %d\n", ret);
> -		goto err_pll_clk;
> +		goto err_sclk_clk;
>  	}
> 
>  	ret = phy_power_on(dsi->phy);
> @@ -1328,8 +1321,8 @@ static int exynos_dsi_poweron(struct exynos_dsi *dsi)
>  	return 0;
> 
>  err_phy:
> -	clk_disable_unprepare(dsi->pll_clk);
> -err_pll_clk:
> +	clk_disable_unprepare(dsi->sclk_clk);
> +err_sclk_clk:
>  	clk_disable_unprepare(dsi->bus_clk);
>  err_bus_clk:
>  	regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
> @@ -1355,7 +1348,7 @@ static void exynos_dsi_poweroff(struct exynos_dsi *dsi)
> 
>  	phy_power_off(dsi->phy);
> 
> -	clk_disable_unprepare(dsi->pll_clk);
> +	clk_disable_unprepare(dsi->sclk_clk);
>  	clk_disable_unprepare(dsi->bus_clk);
> 
>  	ret = regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
> @@ -1722,10 +1715,13 @@ static int exynos_dsi_probe(struct platform_device *pdev)
>  		return -EPROBE_DEFER;
>  	}
> 
> -	dsi->pll_clk = devm_clk_get(dev, "pll_clk");
> -	if (IS_ERR(dsi->pll_clk)) {
> -		dev_info(dev, "failed to get dsi pll input clock\n");
> -		return PTR_ERR(dsi->pll_clk);
> +	dsi->sclk_clk = devm_clk_get(dev, "sclk_mipi");
> +	if (IS_ERR(dsi->sclk_clk)) {
> +		dsi->sclk_clk = devm_clk_get(dev, OLD_SCLK_MIPI_CLK_NAME);
> +		if (IS_ERR(dsi->sclk_clk)) {
> +			dev_info(dev, "failed to get dsi sclk clock\n");
> +			eturn PTR_ERR(dsi->sclk_clk);
> +		}
>  	}
> 
>  	dsi->bus_clk = devm_clk_get(dev, "bus_clk");
> --
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" 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

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

* Re: [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi'
  2015-06-22 11:42       ` Inki Dae
  2015-06-22 11:59         ` Krzysztof Kozlowski
@ 2015-06-22 12:35         ` Krzysztof Kozlowski
  2015-06-23  2:10           ` Krzysztof Kozlowski
  1 sibling, 1 reply; 50+ messages in thread
From: Krzysztof Kozlowski @ 2015-06-22 12:35 UTC (permalink / raw)
  To: Inki Dae
  Cc: Hyungwon Hwang, Kukjin Kim, Krzysztof Kozlowski, dri-devel,
	devicetree, daniel, sw0312.kim, jy0922.shim, linux-samsung-soc

2015-06-22 20:42 GMT+09:00 Inki Dae <inki.dae@samsung.com>:
> + Krzysztof
>
> On 2015년 06월 22일 18:10, Inki Dae wrote:
>> On 2015년 06월 12일 21:59, Hyungwon Hwang wrote:
>>> The clock which was named as 'pll_clk' is actually not the clock source
>>> of PLL in MIPI DSI. This patch fixes this disagreement.
>>
>> Mr. Kukjin and Krzysztof, can you give me Acked-by or Singed-off-by? I'd
>> like to merge this patch to mainline through drm-next.

Thanks for forwarding me other necessary patch. All that burden could
be easily avoided by sending everything to samsung-soc anyway.

The patch itself looks good:
Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

>>
>> Thanks,
>> Inki Dae
>>
>>>
>>> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
>>> ---
>>> Changes before:
>>> - Refer https://patchwork.kernel.org/patch/6191811
>>> Changes for v6:
>>> - None
>>>
>>>  arch/arm/boot/dts/exynos4.dtsi | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
>>> index e20cdc2..1538d7a 100644
>>> --- a/arch/arm/boot/dts/exynos4.dtsi
>>> +++ b/arch/arm/boot/dts/exynos4.dtsi
>>> @@ -167,7 +167,7 @@
>>>              phys = <&mipi_phy 1>;
>>>              phy-names = "dsim";
>>>              clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
>>> -            clock-names = "bus_clk", "pll_clk";
>>> +            clock-names = "bus_clk", "sclk_mipi";
>>>              status = "disabled";
>>>              #address-cells = <1>;
>>>              #size-cells = <0>;
>>> --
>>> 1.9.1
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe devicetree" 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] 50+ messages in thread

* Re: [PATCH v6 06/15] of: add helper for getting endpoint node of specific identifiers
  2015-06-12 12:59 ` [PATCH v6 06/15] of: add helper for getting endpoint node of specific identifiers Hyungwon Hwang
@ 2015-06-23  0:19   ` Dave Airlie
  2015-06-23  2:29     ` Inki Dae
  0 siblings, 1 reply; 50+ messages in thread
From: Dave Airlie @ 2015-06-23  0:19 UTC (permalink / raw)
  To: Hyungwon Hwang, Inki Dae; +Cc: devicetree, sw0312.kim, dri-devel

On 12 June 2015 at 22:59, Hyungwon Hwang <human.hwang@samsung.com> wrote:
> When there are multiple ports or multiple endpoints in a port, they have to be
> distinguished by the value of reg property. It is common. The drivers can get
> the specific endpoint in the specific port via this function. Now the drivers
> have to implement this code in themselves or have to force the order of dt nodes
> to get the right node.
>
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> Acked-by: Rob Herring <robh+dt@kernel.org>

FYI, Since I'm merging this via exynos-next into my tree, it broke
module builds of exynos, because it doesn't export the symbol it adds,
I've added a patch to my -next tree to fix it up.

Inki, in future can you add a modular build to pre-pull testing.

Dave.

> ---
> Changes before:
> - Refer https://patchwork.kernel.org/patch/6191751/
> Changes for v6:
> - None
>  drivers/of/base.c        | 33 +++++++++++++++++++++++++++++++++
>  include/linux/of_graph.h |  8 ++++++++
>  2 files changed, 41 insertions(+)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 99764db..f3b583b 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -2233,6 +2233,39 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
>  EXPORT_SYMBOL(of_graph_get_next_endpoint);
>
>  /**
> + * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers
> + * @parent: pointer to the parent device node
> + * @port_reg: identifier (value of reg property) of the parent port node
> + * @reg: identifier (value of reg property) of the endpoint node
> + *
> + * Return: An 'endpoint' node pointer which is identified by reg and at the same
> + * is the child of a port node identified by port_reg. reg and port_reg are
> + * ignored when they are -1.
> + */
> +struct device_node *of_graph_get_endpoint_by_regs(
> +       const struct device_node *parent, int port_reg, int reg)
> +{
> +       struct of_endpoint endpoint;
> +       struct device_node *node, *prev_node = NULL;
> +
> +       while (1) {
> +               node = of_graph_get_next_endpoint(parent, prev_node);
> +               of_node_put(prev_node);
> +               if (!node)
> +                       break;
> +
> +               of_graph_parse_endpoint(node, &endpoint);
> +               if (((port_reg == -1) || (endpoint.port == port_reg)) &&
> +                       ((reg == -1) || (endpoint.id == reg)))
> +                       return node;
> +
> +               prev_node = node;
> +       }
> +
> +       return NULL;
> +}
> +
> +/**
>   * of_graph_get_remote_port_parent() - get remote port's parent node
>   * @node: pointer to a local endpoint device_node
>   *
> diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
> index 7bc92e0..1c1d5b9 100644
> --- a/include/linux/of_graph.h
> +++ b/include/linux/of_graph.h
> @@ -45,6 +45,8 @@ int of_graph_parse_endpoint(const struct device_node *node,
>  struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
>  struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
>                                         struct device_node *previous);
> +struct device_node *of_graph_get_endpoint_by_regs(
> +               const struct device_node *parent, int port_reg, int reg);
>  struct device_node *of_graph_get_remote_port_parent(
>                                         const struct device_node *node);
>  struct device_node *of_graph_get_remote_port(const struct device_node *node);
> @@ -69,6 +71,12 @@ static inline struct device_node *of_graph_get_next_endpoint(
>         return NULL;
>  }
>
> +struct device_node *of_graph_get_endpoint_by_regs(
> +               const struct device_node *parent, int port_reg, int reg)
> +{
> +       return NULL;
> +}
> +
>  static inline struct device_node *of_graph_get_remote_port_parent(
>                                         const struct device_node *node)
>  {
> --
> 1.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi'
  2015-06-22 12:35         ` Krzysztof Kozlowski
@ 2015-06-23  2:10           ` Krzysztof Kozlowski
  2015-06-23  2:28             ` Inki Dae
  0 siblings, 1 reply; 50+ messages in thread
From: Krzysztof Kozlowski @ 2015-06-23  2:10 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Inki Dae, Hyungwon Hwang, Kukjin Kim, dri-devel, devicetree,
	daniel, sw0312.kim, jy0922.shim, linux-samsung-soc, Rob Herring

2015-06-22 21:35 GMT+09:00 Krzysztof Kozlowski <k.kozlowski@samsung.com>:
> 2015-06-22 20:42 GMT+09:00 Inki Dae <inki.dae@samsung.com>:
>> + Krzysztof
>>
>> On 2015년 06월 22일 18:10, Inki Dae wrote:
>>> On 2015년 06월 12일 21:59, Hyungwon Hwang wrote:
>>>> The clock which was named as 'pll_clk' is actually not the clock source
>>>> of PLL in MIPI DSI. This patch fixes this disagreement.
>>>
>>> Mr. Kukjin and Krzysztof, can you give me Acked-by or Singed-off-by? I'd
>>> like to merge this patch to mainline through drm-next.
>
> Thanks for forwarding me other necessary patch. All that burden could
> be easily avoided by sending everything to samsung-soc anyway.
>
> The patch itself looks good:
> Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
>
> Best regards,
> Krzysztof

To clarify. There were seven versions of this patch and none of them
were sent to samsung-soc list, to Kukjin Kim or to me.

I also wonder about patch 2: "of: add helper for getting endpoint node
with specific identifiers"
for which I can't find respective ack from Rob Herring (+Cc). I only found this:
http://www.spinics.net/lists/devicetree/msg69336.html
but there are only comments, not an ack.

Best regards,
Krzysztof

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

* Re: [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi'
  2015-06-23  2:10           ` Krzysztof Kozlowski
@ 2015-06-23  2:28             ` Inki Dae
  2015-06-23  4:00               ` Krzysztof Kozlowski
  0 siblings, 1 reply; 50+ messages in thread
From: Inki Dae @ 2015-06-23  2:28 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: devicetree, Kukjin Kim, sw0312.kim, dri-devel, Rob Herring,
	linux-samsung-soc

On 2015년 06월 23일 11:10, Krzysztof Kozlowski wrote:
> 2015-06-22 21:35 GMT+09:00 Krzysztof Kozlowski <k.kozlowski@samsung.com>:
>> 2015-06-22 20:42 GMT+09:00 Inki Dae <inki.dae@samsung.com>:
>>> + Krzysztof
>>>
>>> On 2015년 06월 22일 18:10, Inki Dae wrote:
>>>> On 2015년 06월 12일 21:59, Hyungwon Hwang wrote:
>>>>> The clock which was named as 'pll_clk' is actually not the clock source
>>>>> of PLL in MIPI DSI. This patch fixes this disagreement.
>>>>
>>>> Mr. Kukjin and Krzysztof, can you give me Acked-by or Singed-off-by? I'd
>>>> like to merge this patch to mainline through drm-next.
>>
>> Thanks for forwarding me other necessary patch. All that burden could
>> be easily avoided by sending everything to samsung-soc anyway.
>>
>> The patch itself looks good:
>> Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
>>
>> Best regards,
>> Krzysztof
> 
> To clarify. There were seven versions of this patch and none of them
> were sent to samsung-soc list, to Kukjin Kim or to me.
> 
> I also wonder about patch 2: "of: add helper for getting endpoint node
> with specific identifiers"
> for which I can't find respective ack from Rob Herring (+Cc). I only found this:
> http://www.spinics.net/lists/devicetree/msg69336.html
> but there are only comments, not an ack.

Below is the comments from Rob Herring. How about subscribing device
tree mainling list? You are a maintainer of Exynos SoC. This patch was
posted to device tree mailing list ccing Grant and Rob. If you listen to
only Samsung SoC mailing list then you couldn't find this patch in your
email box.

"On Sun, Feb 22, 2015 at 7:41 PM, Hyungwon Hwang
<human.hwang@samsung.com> wrote:
 > When there are multiple ports or multiple endpoints in a port, they
have to be
 > distinguished by the value of reg property. It is common. The drivers
can get
 > the specific endpoint in the specific port via this function. Now the
drivers
 > have to implement this code in themselves or have to force the order
of dt nodes
 > to get the right node.
 >
 > Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>

Acked-by: Rob Herring <robh@kernel.org>

 I'm not applying as there is no user, so apply this patch along with a
 user of the function."

That is why I merged this patch to exynos-drm-next.

Thanks,
Inki Dae

> 
> Best regards,
> Krzysztof
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> 

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

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

* Re: [PATCH v6 06/15] of: add helper for getting endpoint node of specific identifiers
  2015-06-23  0:19   ` Dave Airlie
@ 2015-06-23  2:29     ` Inki Dae
  0 siblings, 0 replies; 50+ messages in thread
From: Inki Dae @ 2015-06-23  2:29 UTC (permalink / raw)
  To: Dave Airlie; +Cc: devicetree, sw0312.kim, dri-devel

On 2015년 06월 23일 09:19, Dave Airlie wrote:
> On 12 June 2015 at 22:59, Hyungwon Hwang <human.hwang@samsung.com> wrote:
>> When there are multiple ports or multiple endpoints in a port, they have to be
>> distinguished by the value of reg property. It is common. The drivers can get
>> the specific endpoint in the specific port via this function. Now the drivers
>> have to implement this code in themselves or have to force the order of dt nodes
>> to get the right node.
>>
>> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
>> Acked-by: Rob Herring <robh+dt@kernel.org>
> 
> FYI, Since I'm merging this via exynos-next into my tree, it broke
> module builds of exynos, because it doesn't export the symbol it adds,
> I've added a patch to my -next tree to fix it up.
> 
> Inki, in future can you add a modular build to pre-pull testing.

Yes I do. I should have tested the modular build. Sorry for this.

Thanks,
Inki Dae

> 
> Dave.
> 
>> ---
>> Changes before:
>> - Refer https://patchwork.kernel.org/patch/6191751/
>> Changes for v6:
>> - None
>>  drivers/of/base.c        | 33 +++++++++++++++++++++++++++++++++
>>  include/linux/of_graph.h |  8 ++++++++
>>  2 files changed, 41 insertions(+)
>>
>> diff --git a/drivers/of/base.c b/drivers/of/base.c
>> index 99764db..f3b583b 100644
>> --- a/drivers/of/base.c
>> +++ b/drivers/of/base.c
>> @@ -2233,6 +2233,39 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
>>  EXPORT_SYMBOL(of_graph_get_next_endpoint);
>>
>>  /**
>> + * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers
>> + * @parent: pointer to the parent device node
>> + * @port_reg: identifier (value of reg property) of the parent port node
>> + * @reg: identifier (value of reg property) of the endpoint node
>> + *
>> + * Return: An 'endpoint' node pointer which is identified by reg and at the same
>> + * is the child of a port node identified by port_reg. reg and port_reg are
>> + * ignored when they are -1.
>> + */
>> +struct device_node *of_graph_get_endpoint_by_regs(
>> +       const struct device_node *parent, int port_reg, int reg)
>> +{
>> +       struct of_endpoint endpoint;
>> +       struct device_node *node, *prev_node = NULL;
>> +
>> +       while (1) {
>> +               node = of_graph_get_next_endpoint(parent, prev_node);
>> +               of_node_put(prev_node);
>> +               if (!node)
>> +                       break;
>> +
>> +               of_graph_parse_endpoint(node, &endpoint);
>> +               if (((port_reg == -1) || (endpoint.port == port_reg)) &&
>> +                       ((reg == -1) || (endpoint.id == reg)))
>> +                       return node;
>> +
>> +               prev_node = node;
>> +       }
>> +
>> +       return NULL;
>> +}
>> +
>> +/**
>>   * of_graph_get_remote_port_parent() - get remote port's parent node
>>   * @node: pointer to a local endpoint device_node
>>   *
>> diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
>> index 7bc92e0..1c1d5b9 100644
>> --- a/include/linux/of_graph.h
>> +++ b/include/linux/of_graph.h
>> @@ -45,6 +45,8 @@ int of_graph_parse_endpoint(const struct device_node *node,
>>  struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
>>  struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
>>                                         struct device_node *previous);
>> +struct device_node *of_graph_get_endpoint_by_regs(
>> +               const struct device_node *parent, int port_reg, int reg);
>>  struct device_node *of_graph_get_remote_port_parent(
>>                                         const struct device_node *node);
>>  struct device_node *of_graph_get_remote_port(const struct device_node *node);
>> @@ -69,6 +71,12 @@ static inline struct device_node *of_graph_get_next_endpoint(
>>         return NULL;
>>  }
>>
>> +struct device_node *of_graph_get_endpoint_by_regs(
>> +               const struct device_node *parent, int port_reg, int reg)
>> +{
>> +       return NULL;
>> +}
>> +
>>  static inline struct device_node *of_graph_get_remote_port_parent(
>>                                         const struct device_node *node)
>>  {
>> --
>> 1.9.1
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> 

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

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

* Re: [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi'
  2015-06-23  2:28             ` Inki Dae
@ 2015-06-23  4:00               ` Krzysztof Kozlowski
  0 siblings, 0 replies; 50+ messages in thread
From: Krzysztof Kozlowski @ 2015-06-23  4:00 UTC (permalink / raw)
  To: Inki Dae
  Cc: devicetree, Kukjin Kim, sw0312.kim, dri-devel, Rob Herring,
	linux-samsung-soc

On 23.06.2015 11:28, Inki Dae wrote:
> On 2015년 06월 23일 11:10, Krzysztof Kozlowski wrote:
>> 2015-06-22 21:35 GMT+09:00 Krzysztof Kozlowski <k.kozlowski@samsung.com>:
>>> 2015-06-22 20:42 GMT+09:00 Inki Dae <inki.dae@samsung.com>:
>>>> + Krzysztof
>>>>
>>>> On 2015년 06월 22일 18:10, Inki Dae wrote:
>>>>> On 2015년 06월 12일 21:59, Hyungwon Hwang wrote:
>>>>>> The clock which was named as 'pll_clk' is actually not the clock source
>>>>>> of PLL in MIPI DSI. This patch fixes this disagreement.
>>>>>
>>>>> Mr. Kukjin and Krzysztof, can you give me Acked-by or Singed-off-by? I'd
>>>>> like to merge this patch to mainline through drm-next.
>>>
>>> Thanks for forwarding me other necessary patch. All that burden could
>>> be easily avoided by sending everything to samsung-soc anyway.
>>>
>>> The patch itself looks good:
>>> Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
>>>
>>> Best regards,
>>> Krzysztof
>>
>> To clarify. There were seven versions of this patch and none of them
>> were sent to samsung-soc list, to Kukjin Kim or to me.
>>
>> I also wonder about patch 2: "of: add helper for getting endpoint node
>> with specific identifiers"
>> for which I can't find respective ack from Rob Herring (+Cc). I only found this:
>> http://www.spinics.net/lists/devicetree/msg69336.html
>> but there are only comments, not an ack.
> 
> Below is the comments from Rob Herring. How about subscribing device
> tree mainling list? You are a maintainer of Exynos SoC. This patch was
> posted to device tree mailing list ccing Grant and Rob. If you listen to
> only Samsung SoC mailing list then you couldn't find this patch in your
> email box.

Some time ago I was subscribing devicetree, but as I am not device tree
maintainer and the traffic there is really huge, I unsubscribed.

> 
> "On Sun, Feb 22, 2015 at 7:41 PM, Hyungwon Hwang
> <human.hwang@samsung.com> wrote:
>  > When there are multiple ports or multiple endpoints in a port, they
> have to be
>  > distinguished by the value of reg property. It is common. The drivers
> can get
>  > the specific endpoint in the specific port via this function. Now the
> drivers
>  > have to implement this code in themselves or have to force the order
> of dt nodes
>  > to get the right node.
>  >
>  > Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> 
> Acked-by: Rob Herring <robh@kernel.org>
> 
>  I'm not applying as there is no user, so apply this patch along with a
>  user of the function."

Thanks! That helped me finding it in the archives.

Best regards,
Krzysztof

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

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

end of thread, other threads:[~2015-06-23  4:00 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-12 12:58 [PATCH v6 00/15] Add drivers for Exynos5433 display Hyungwon Hwang
2015-06-12 12:58 ` [PATCH v6 02/15] drm/exynos: Add the dependency for DRM_EXYNOS to DPI/DSI/DP Hyungwon Hwang
2015-06-12 12:58 ` [PATCH v6 03/15] drm/exynos: add drm_iommu_attach_device_if_possible() Hyungwon Hwang
2015-06-12 12:58 ` [PATCH v6 04/15] drm/exynos: fix the input prompt of Exynos7 DECON Hyungwon Hwang
2015-06-12 12:59 ` [PATCH v6 06/15] of: add helper for getting endpoint node of specific identifiers Hyungwon Hwang
2015-06-23  0:19   ` Dave Airlie
2015-06-23  2:29     ` Inki Dae
2015-06-12 12:59 ` [PATCH v6 07/15] drm/exynos: mic: add MIC driver Hyungwon Hwang
2015-06-12 12:59 ` [PATCH v6 12/15] drm/exynos: dsi: add support for Exynos5433 Hyungwon Hwang
2015-06-12 12:59 ` [PATCH v6 14/15] drm/exynos: dsi: do not set TE GPIO direction by input Hyungwon Hwang
     [not found] ` <1434113958-15877-1-git-send-email-human.hwang-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-06-12 12:58   ` [PATCH v6 01/15] drm/exynos: remove the dependency of DP driver for ARCH_EXYNOS Hyungwon Hwang
2015-06-12 12:59   ` [PATCH v6 05/15] drm/exynos: add Exynos5433 decon driver Hyungwon Hwang
2015-06-22 11:16     ` [PATCH v7 " Inki Dae
2015-06-22 11:41       ` Varka Bhadram
2015-06-22 11:57         ` Inki Dae
2015-06-22 11:59           ` Varka Bhadram
2015-06-12 12:59   ` [PATCH v6 08/15] drm/exynos: dsi: rename pll_clk to sclk_clk Hyungwon Hwang
2015-06-22 12:25     ` Inki Dae
2015-06-12 12:59   ` [PATCH v6 09/15] drm/exynos: dsi: add macros for register access Hyungwon Hwang
2015-06-12 12:59   ` [PATCH v6 10/15] drm/exynos: dsi: make use of driver data for static values Hyungwon Hwang
2015-06-12 12:59   ` [PATCH v6 11/15] drm/exynos: dsi: make use of array for clock access Hyungwon Hwang
2015-06-12 12:59   ` [PATCH v6 13/15] drm/exynos: dsi: add support for MIC driver as a bridge Hyungwon Hwang
2015-06-12 12:59   ` [PATCH v6 15/15] ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi' Hyungwon Hwang
2015-06-22  9:10     ` Inki Dae
2015-06-22 11:42       ` Inki Dae
2015-06-22 11:59         ` Krzysztof Kozlowski
2015-06-22 12:10           ` Inki Dae
2015-06-22 12:20             ` Krzysztof Kozlowski
2015-06-22 12:35         ` Krzysztof Kozlowski
2015-06-23  2:10           ` Krzysztof Kozlowski
2015-06-23  2:28             ` Inki Dae
2015-06-23  4:00               ` Krzysztof Kozlowski
2015-06-12 12:59   ` [PATCH 1/2] drm/exynos: ipp: fix wrong index referencing a config element Hyungwon Hwang
2015-06-12 13:02     ` Hyungwon Hwang
2015-06-12 12:59   ` [PATCH 2/3] ARM: dts: Add the reference node for syscon to mipi phy for Exynos3250 Hyungwon Hwang
2015-06-12 13:02     ` Hyungwon Hwang
2015-06-12 12:59   ` [v3,2/3] drm/panel: add s6e63j0x03 LCD panel driver Hyungwon Hwang
2015-06-12 12:59 ` [PATCH 2/2] drm/exynos: ipp: validate a GEM handle with multiple planes Hyungwon Hwang
2015-06-12 13:02   ` Hyungwon Hwang
2015-06-12 12:59 ` [PATCH] ARM: dts: set display clock correctly for exynos4412-trats2 Hyungwon Hwang
2015-06-12 12:59   ` Hyungwon Hwang
2015-06-12 12:59 ` [PATCH 1/3] drm/panel: add s6e63j0x03 LCD panel driver Hyungwon Hwang
2015-06-12 13:02   ` Hyungwon Hwang
2015-06-12 12:59 ` [PATCH 3/3] ARM: dts: fix the clock-frequency of rinato board's panel Hyungwon Hwang
2015-06-12 13:02   ` Hyungwon Hwang
  -- strict thread matches above, loose matches on Subject: below --
2015-01-19  7:52 [PATCH v3 1/3] ARM: dts: add fimd device support for exynos3250-rinato Hyungwon Hwang
2015-01-19  7:52 ` [PATCH v3 2/3] drm/panel: add s6e63j0x03 LCD panel driver Hyungwon Hwang
2015-02-03 14:00   ` Thierry Reding
2015-06-12 13:03   ` [v3,2/3] " Hyungwon Hwang
2015-01-19  7:52 ` [PATCH v3 3/3] ARM: dts: add Panel device support for exynos3250-rinato Hyungwon Hwang

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.