2015-08-19 14:49:18

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver


Hi all,
The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
share the same IP, so a lot of parts can be re-used. I split the common
code into bridge directory, then rk3288 and exynos only need to keep
some platform code. Cause I can't find the exact IP name of exynos dp
controller, so I decide to name dp core driver with "analogix" which I
find in rk3288 eDP TRM ;)

Beyond that, there are three light registers setting differents bewteen
exynos and rk3288.
1. RK3288 have five special pll resigters which not indicata in exynos
dp controller.
2. The address of DP_PHY_PD(dp phy power manager register) are different
between rk3288 and exynos.
3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
register).

I have verified this series on two kinds of rockchip platform board, one
is rk3288 sdk board which connect with a 2K display port monitor, the other
is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
both of them works rightlly.

I haven't verified the dp function on samsung platform, cause I haven't got
exynos boards. I can only ensure that there are no build error on samsung
platform, wish some samsung guys help to test. ;)

Thanks,
- Yakir

Changes in v3:
- Take Thierry Reding suggest, move exynos's video_timing code
to analogix_dp-exynos platform driver, add get_modes method
to struct analogix_dp_plat_data.
- Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
- Take Thierry Reding suggest, dynamic parse video timing info from
struct drm_display_mode and struct drm_display_info.
- Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
the DT property value directly, but we can take those as hardware limite.
For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
so DT property would like "link-rate = 0x0a" "lane-count = 4".
- Take Heiko suggest, add devicetree binding documents.
- Take Thierry Reding suggest, remove sync pol & colorimetry properies
from the new analogix dp driver devicetree binding.
- Update the exist exynos dtsi file with the latest DP DT properies.
- Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
driver which name to "pclk".
- Take Heiko suggest, add devicetree binding document.
- Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
point to get panel node.
- Add the new function point analogix_dp_platdata.get_modes init.
- Take Heiko suggest, add rockchip dp phy driver,
collect the phy clocks and power control.
- Add "analogix,need-force-hpd" to indicate whether driver need foce
hpd when hpd detect failed.
- move dp hpd detect to connector detect function.
- Add edid modes parse support

Changes in v2:
- Take Joe Preches advise, improved commit message more readable, and
avoid using some uncommon style like bellow:
- retval = exynos_dp_read_bytes_from_i2c(...
...)
+ retval =
+ exynos_dp_read_bytes_from_i2c(......);
- Take Jingoo Han suggest, just remove my name from author list.
- Take Jingoo Han suggest, remove new copyright
- Fix compiled failed dut to analogix_dp_device misspell
- Take Heiko suggest, get panel node with remote-endpoint method,
and create devicetree binding for driver.
- Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
leave those clock to rockchip dp phy driver.
- Add GNU license v2 declared and samsung copyright
- Fix compile failed dut to phy_pd_addr variable misspell error

Yakir Yang (14):
drm: exynos/dp: fix code style
drm: exynos/dp: convert to drm bridge mode
drm: bridge: analogix_dp: split exynos dp driver to bridge dir
drm: bridge/analogix_dp: dynamic parse sync_pol & interlace &
colorimetry
drm: bridge/analogix_dp: fix link_rate & lane_count bug
Documentation: drm/bridge: add document for analogix_dp
drm: rockchip/dp: add rockchip platform dp driver
phy: Add driver for rockchip Display Port PHY
drm: bridge/analogix_dp: add platform device type support
drm: bridge: analogix_dp: add some rk3288 special registers setting
drm: bridge: analogix_dp: try force hpd after plug in lookup failed
drm: bridge/analogix_dp: expand the delay time for hpd detect
drm: bridge/analogix_dp: move hpd detect to connector detect function
drm: bridge/analogix_dp: add edid modes parse in get_modes method

.../devicetree/bindings/drm/bridge/analogix_dp.txt | 73 +
.../devicetree/bindings/phy/rockchip-dp-phy.txt | 26 +
.../bindings/video/analogix_dp-rockchip.txt | 83 ++
.../devicetree/bindings/video/exynos_dp.txt | 51 +-
arch/arm/boot/dts/exynos5250-arndale.dts | 10 +-
arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 +-
arch/arm/boot/dts/exynos5250-snow.dts | 12 +-
arch/arm/boot/dts/exynos5250-spring.dts | 12 +-
arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 +-
arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 +-
arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 +-
drivers/gpu/drm/bridge/Kconfig | 5 +
drivers/gpu/drm/bridge/Makefile | 1 +
drivers/gpu/drm/bridge/analogix_dp_core.c | 1382 +++++++++++++++++++
drivers/gpu/drm/bridge/analogix_dp_core.h | 286 ++++
drivers/gpu/drm/bridge/analogix_dp_reg.c | 1294 ++++++++++++++++++
.../exynos_dp_reg.h => bridge/analogix_dp_reg.h} | 270 ++--
drivers/gpu/drm/exynos/Kconfig | 5 +-
drivers/gpu/drm/exynos/Makefile | 2 +-
drivers/gpu/drm/exynos/analogix_dp-exynos.c | 347 +++++
drivers/gpu/drm/exynos/exynos_dp_core.c | 1416 --------------------
drivers/gpu/drm/exynos/exynos_dp_core.h | 282 ----
drivers/gpu/drm/exynos/exynos_dp_reg.c | 1263 -----------------
drivers/gpu/drm/rockchip/Kconfig | 9 +
drivers/gpu/drm/rockchip/Makefile | 1 +
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 390 ++++++
drivers/phy/Kconfig | 7 +
drivers/phy/Makefile | 1 +
drivers/phy/phy-rockchip-dp.c | 185 +++
include/drm/bridge/analogix_dp.h | 40 +
30 files changed, 4325 insertions(+), 3172 deletions(-)
create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
rename drivers/gpu/drm/{exynos/exynos_dp_reg.h => bridge/analogix_dp_reg.h} (62%)
create mode 100644 drivers/gpu/drm/exynos/analogix_dp-exynos.c
delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.c
delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.h
delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_reg.c
create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
create mode 100644 drivers/phy/phy-rockchip-dp.c
create mode 100644 include/drm/bridge/analogix_dp.h

--
1.9.1


2015-08-19 14:49:53

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 01/14] drm: exynos/dp: fix code style

After run "checkpatch.pl -f --subjective" command, I see there
are lots of alignment problem in exynos_dp driver, so let just
fix them.

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3: None
Changes in v2:
- Take Joe Preches advise, improved commit message more readable, and
avoid using some uncommon style like bellow:
- retval = exynos_dp_read_bytes_from_i2c(...
...)
+ retval =
+ exynos_dp_read_bytes_from_i2c(......);

drivers/gpu/drm/exynos/exynos_dp_core.c | 219 ++++++++++++++++----------------
drivers/gpu/drm/exynos/exynos_dp_core.h | 53 ++++----
drivers/gpu/drm/exynos/exynos_dp_reg.c | 100 +++++++--------
3 files changed, 182 insertions(+), 190 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 172b800..562f4a8 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -114,8 +114,8 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)

/* Read Extension Flag, Number of 128-byte EDID extension blocks */
retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
- EDID_EXTENSION_FLAG,
- &extend_block);
+ EDID_EXTENSION_FLAG,
+ &extend_block);
if (retval)
return retval;

@@ -123,10 +123,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
dev_dbg(dp->dev, "EDID data includes a single extension!\n");

/* Read EDID data */
- retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
- EDID_HEADER_PATTERN,
- EDID_BLOCK_LENGTH,
- &edid[EDID_HEADER_PATTERN]);
+ retval = exynos_dp_read_bytes_from_i2c(
+ dp, I2C_EDID_DEVICE_ADDR,
+ EDID_HEADER_PATTERN,
+ EDID_BLOCK_LENGTH,
+ &edid[EDID_HEADER_PATTERN]);
if (retval != 0) {
dev_err(dp->dev, "EDID Read failed!\n");
return -EIO;
@@ -138,11 +139,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
}

/* Read additional EDID data */
- retval = exynos_dp_read_bytes_from_i2c(dp,
- I2C_EDID_DEVICE_ADDR,
- EDID_BLOCK_LENGTH,
- EDID_BLOCK_LENGTH,
- &edid[EDID_BLOCK_LENGTH]);
+ retval = exynos_dp_read_bytes_from_i2c(
+ dp, I2C_EDID_DEVICE_ADDR,
+ EDID_BLOCK_LENGTH,
+ EDID_BLOCK_LENGTH,
+ &edid[EDID_BLOCK_LENGTH]);
if (retval != 0) {
dev_err(dp->dev, "EDID Read failed!\n");
return -EIO;
@@ -154,24 +155,22 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
}

exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
- &test_vector);
+ &test_vector);
if (test_vector & DP_TEST_LINK_EDID_READ) {
- exynos_dp_write_byte_to_dpcd(dp,
- DP_TEST_EDID_CHECKSUM,
+ exynos_dp_write_byte_to_dpcd(
+ dp, DP_TEST_EDID_CHECKSUM,
edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
- exynos_dp_write_byte_to_dpcd(dp,
- DP_TEST_RESPONSE,
+ exynos_dp_write_byte_to_dpcd(
+ dp, DP_TEST_RESPONSE,
DP_TEST_EDID_CHECKSUM_WRITE);
}
} else {
dev_info(dp->dev, "EDID data does not include any extensions.\n");

/* Read EDID data */
- retval = exynos_dp_read_bytes_from_i2c(dp,
- I2C_EDID_DEVICE_ADDR,
- EDID_HEADER_PATTERN,
- EDID_BLOCK_LENGTH,
- &edid[EDID_HEADER_PATTERN]);
+ retval = exynos_dp_read_bytes_from_i2c(
+ dp, I2C_EDID_DEVICE_ADDR, EDID_HEADER_PATTERN,
+ EDID_BLOCK_LENGTH, &edid[EDID_HEADER_PATTERN]);
if (retval != 0) {
dev_err(dp->dev, "EDID Read failed!\n");
return -EIO;
@@ -182,16 +181,15 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
return -EIO;
}

- exynos_dp_read_byte_from_dpcd(dp,
- DP_TEST_REQUEST,
- &test_vector);
+ exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
+ &test_vector);
if (test_vector & DP_TEST_LINK_EDID_READ) {
- exynos_dp_write_byte_to_dpcd(dp,
- DP_TEST_EDID_CHECKSUM,
- edid[EDID_CHECKSUM]);
- exynos_dp_write_byte_to_dpcd(dp,
- DP_TEST_RESPONSE,
- DP_TEST_EDID_CHECKSUM_WRITE);
+ exynos_dp_write_byte_to_dpcd(
+ dp, DP_TEST_EDID_CHECKSUM,
+ edid[EDID_CHECKSUM]);
+ exynos_dp_write_byte_to_dpcd(
+ dp, DP_TEST_RESPONSE,
+ DP_TEST_EDID_CHECKSUM_WRITE);
}
}

@@ -206,8 +204,7 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
int retval;

/* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */
- retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV,
- 12, buf);
+ retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, 12, buf);
if (retval)
return retval;

@@ -222,19 +219,21 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
}

static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
- bool enable)
+ bool enable)
{
u8 data;

exynos_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data);

if (enable)
- exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
- DP_LANE_COUNT_ENHANCED_FRAME_EN |
- DPCD_LANE_COUNT_SET(data));
+ exynos_dp_write_byte_to_dpcd(
+ dp, DP_LANE_COUNT_SET,
+ DP_LANE_COUNT_ENHANCED_FRAME_EN |
+ DPCD_LANE_COUNT_SET(data));
else
- exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
- DPCD_LANE_COUNT_SET(data));
+ exynos_dp_write_byte_to_dpcd(
+ dp, DP_LANE_COUNT_SET,
+ DPCD_LANE_COUNT_SET(data));
}

static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp)
@@ -261,13 +260,12 @@ static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
{
exynos_dp_set_training_pattern(dp, DP_NONE);

- exynos_dp_write_byte_to_dpcd(dp,
- DP_TRAINING_PATTERN_SET,
- DP_TRAINING_PATTERN_DISABLE);
+ exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+ DP_TRAINING_PATTERN_DISABLE);
}

static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
- int pre_emphasis, int lane)
+ int pre_emphasis, int lane)
{
switch (lane) {
case 0:
@@ -307,15 +305,14 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
/* Setup RX configuration */
buf[0] = dp->link_train.link_rate;
buf[1] = dp->link_train.lane_count;
- retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET,
- 2, buf);
+ retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, 2, buf);
if (retval)
return retval;

/* Set TX pre-emphasis to minimum */
for (lane = 0; lane < lane_count; lane++)
- exynos_dp_set_lane_lane_pre_emphasis(dp,
- PRE_EMPHASIS_LEVEL_0, lane);
+ exynos_dp_set_lane_lane_pre_emphasis(dp, PRE_EMPHASIS_LEVEL_0,
+ lane);

/* Wait for PLL lock */
pll_tries = 0;
@@ -333,9 +330,9 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
exynos_dp_set_training_pattern(dp, TRAINING_PTN1);

/* Set RX training pattern */
- retval = exynos_dp_write_byte_to_dpcd(dp,
- DP_TRAINING_PATTERN_SET,
- DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1);
+ retval = exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+ DP_LINK_SCRAMBLING_DISABLE |
+ DP_TRAINING_PATTERN_1);
if (retval)
return retval;

@@ -344,7 +341,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
DP_TRAIN_VOLTAGE_SWING_LEVEL_0;

retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
- lane_count, buf);
+ lane_count, buf);

return retval;
}
@@ -352,7 +349,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
{
int shift = (lane & 1) * 4;
- u8 link_value = link_status[lane>>1];
+ u8 link_value = link_status[lane >> 1];

return (link_value >> shift) & 0xf;
}
@@ -371,7 +368,7 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
}

static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
- int lane_count)
+ int lane_count)
{
int lane;
u8 lane_status;
@@ -390,10 +387,10 @@ static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
}

static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2],
- int lane)
+ int lane)
{
int shift = (lane & 1) * 4;
- u8 link_value = adjust_request[lane>>1];
+ u8 link_value = adjust_request[lane >> 1];

return (link_value >> shift) & 0x3;
}
@@ -403,13 +400,13 @@ static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
int lane)
{
int shift = (lane & 1) * 4;
- u8 link_value = adjust_request[lane>>1];
+ u8 link_value = adjust_request[lane >> 1];

return ((link_value >> shift) & 0xc) >> 2;
}

static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
- u8 training_lane_set, int lane)
+ u8 training_lane_set, int lane)
{
switch (lane) {
case 0:
@@ -465,7 +462,7 @@ static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
}

static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
- u8 adjust_request[2])
+ u8 adjust_request[2])
{
int lane, lane_count;
u8 voltage_swing, pre_emphasis, training_lane;
@@ -498,13 +495,13 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)

lane_count = dp->link_train.lane_count;

- retval = exynos_dp_read_bytes_from_dpcd(dp,
- DP_LANE0_1_STATUS, 2, link_status);
+ retval = exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+ 2, link_status);
if (retval)
return retval;

- retval = exynos_dp_read_bytes_from_dpcd(dp,
- DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+ retval = exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+ 2, adjust_request);
if (retval)
return retval;

@@ -512,8 +509,8 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
/* set training pattern 2 for EQ */
exynos_dp_set_training_pattern(dp, TRAINING_PTN2);

- retval = exynos_dp_write_byte_to_dpcd(dp,
- DP_TRAINING_PATTERN_SET,
+ retval = exynos_dp_write_byte_to_dpcd(
+ dp, DP_TRAINING_PATTERN_SET,
DP_LINK_SCRAMBLING_DISABLE |
DP_TRAINING_PATTERN_2);
if (retval)
@@ -551,11 +548,11 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
exynos_dp_get_adjust_training_lane(dp, adjust_request);

for (lane = 0; lane < lane_count; lane++)
- exynos_dp_set_lane_link_training(dp,
- dp->link_train.training_lane[lane], lane);
+ exynos_dp_set_lane_link_training(
+ dp, dp->link_train.training_lane[lane], lane);

- retval = exynos_dp_write_bytes_to_dpcd(dp,
- DP_TRAINING_LANE0_SET, lane_count,
+ retval = exynos_dp_write_bytes_to_dpcd(
+ dp, DP_TRAINING_LANE0_SET, lane_count,
dp->link_train.training_lane);
if (retval)
return retval;
@@ -573,8 +570,8 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)

lane_count = dp->link_train.lane_count;

- retval = exynos_dp_read_bytes_from_dpcd(dp,
- DP_LANE0_1_STATUS, 2, link_status);
+ retval = exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+ 2, link_status);
if (retval)
return retval;

@@ -583,13 +580,13 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
return -EIO;
}

- retval = exynos_dp_read_bytes_from_dpcd(dp,
- DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+ retval = exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+ 2, adjust_request);
if (retval)
return retval;

- retval = exynos_dp_read_byte_from_dpcd(dp,
- DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
+ retval = exynos_dp_read_byte_from_dpcd(
+ dp, DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
if (retval)
return retval;

@@ -628,17 +625,18 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
}

for (lane = 0; lane < lane_count; lane++)
- exynos_dp_set_lane_link_training(dp,
- dp->link_train.training_lane[lane], lane);
+ exynos_dp_set_lane_link_training(
+ dp, dp->link_train.training_lane[lane], lane);

retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
- lane_count, dp->link_train.training_lane);
+ lane_count,
+ dp->link_train.training_lane);

return retval;
}

static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
- u8 *bandwidth)
+ u8 *bandwidth)
{
u8 data;

@@ -651,7 +649,7 @@ static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
}

static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
- u8 *lane_count)
+ u8 *lane_count)
{
u8 data;

@@ -664,8 +662,8 @@ static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
}

static void exynos_dp_init_training(struct exynos_dp_device *dp,
- enum link_lane_count_type max_lane,
- enum link_rate_type max_rate)
+ enum link_lane_count_type max_lane,
+ enum link_rate_type max_rate)
{
/*
* MACRO_RST must be applied after the PLL_LOCK to avoid
@@ -678,7 +676,7 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);

if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
- (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
+ (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
dp->link_train.link_rate);
dp->link_train.link_rate = LINK_RATE_1_62GBPS;
@@ -738,8 +736,7 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
}

static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
- u32 count,
- u32 bwtype)
+ u32 count, u32 bwtype)
{
int i;
int retval;
@@ -830,21 +827,19 @@ static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable)
if (enable) {
exynos_dp_enable_scrambling(dp);

- exynos_dp_read_byte_from_dpcd(dp,
- DP_TRAINING_PATTERN_SET,
- &data);
- exynos_dp_write_byte_to_dpcd(dp,
- DP_TRAINING_PATTERN_SET,
+ exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+ &data);
+ exynos_dp_write_byte_to_dpcd(
+ dp, DP_TRAINING_PATTERN_SET,
(u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
} else {
exynos_dp_disable_scrambling(dp);

- exynos_dp_read_byte_from_dpcd(dp,
- DP_TRAINING_PATTERN_SET,
- &data);
- exynos_dp_write_byte_to_dpcd(dp,
- DP_TRAINING_PATTERN_SET,
- (u8)(data | DP_LINK_SCRAMBLING_DISABLE));
+ exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+ &data);
+ exynos_dp_write_byte_to_dpcd(
+ dp, DP_TRAINING_PATTERN_SET,
+ (u8)(data | DP_LINK_SCRAMBLING_DISABLE));
}
}

@@ -915,7 +910,7 @@ static void exynos_dp_commit(struct exynos_drm_display *display)
}

ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
- dp->video_info->link_rate);
+ dp->video_info->link_rate);
if (ret) {
dev_err(dp->dev, "unable to do link train\n");
return;
@@ -1004,7 +999,7 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {

/* returns the number of bridges attached */
static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
- struct drm_encoder *encoder)
+ struct drm_encoder *encoder)
{
int ret;

@@ -1020,7 +1015,7 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
}

static int exynos_dp_create_connector(struct exynos_drm_display *display,
- struct drm_encoder *encoder)
+ struct drm_encoder *encoder)
{
struct exynos_dp_device *dp = display_to_dp(display);
struct drm_connector *connector = &dp->connector;
@@ -1038,7 +1033,8 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display,
connector->polled = DRM_CONNECTOR_POLL_HPD;

ret = drm_connector_init(dp->drm_dev, connector,
- &exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
+ &exynos_dp_connector_funcs,
+ DRM_MODE_CONNECTOR_eDP);
if (ret) {
DRM_ERROR("Failed to initialize connector with drm\n");
return ret;
@@ -1148,8 +1144,8 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
struct device_node *dp_node = dev->of_node;
struct video_info *dp_video_config;

- dp_video_config = devm_kzalloc(dev,
- sizeof(*dp_video_config), GFP_KERNEL);
+ dp_video_config = devm_kzalloc(dev, sizeof(*dp_video_config),
+ GFP_KERNEL);
if (!dp_video_config)
return ERR_PTR(-ENOMEM);

@@ -1163,37 +1159,37 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
of_property_read_bool(dp_node, "interlaced");

if (of_property_read_u32(dp_node, "samsung,color-space",
- &dp_video_config->color_space)) {
+ &dp_video_config->color_space)) {
dev_err(dev, "failed to get color-space\n");
return ERR_PTR(-EINVAL);
}

if (of_property_read_u32(dp_node, "samsung,dynamic-range",
- &dp_video_config->dynamic_range)) {
+ &dp_video_config->dynamic_range)) {
dev_err(dev, "failed to get dynamic-range\n");
return ERR_PTR(-EINVAL);
}

if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
- &dp_video_config->ycbcr_coeff)) {
+ &dp_video_config->ycbcr_coeff)) {
dev_err(dev, "failed to get ycbcr-coeff\n");
return ERR_PTR(-EINVAL);
}

if (of_property_read_u32(dp_node, "samsung,color-depth",
- &dp_video_config->color_depth)) {
+ &dp_video_config->color_depth)) {
dev_err(dev, "failed to get color-depth\n");
return ERR_PTR(-EINVAL);
}

if (of_property_read_u32(dp_node, "samsung,link-rate",
- &dp_video_config->link_rate)) {
+ &dp_video_config->link_rate)) {
dev_err(dev, "failed to get link-rate\n");
return ERR_PTR(-EINVAL);
}

if (of_property_read_u32(dp_node, "samsung,lane-count",
- &dp_video_config->lane_count)) {
+ &dp_video_config->lane_count)) {
dev_err(dev, "failed to get lane-count\n");
return ERR_PTR(-EINVAL);
}
@@ -1206,7 +1202,7 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
int ret;

ret = of_get_videomode(dp->dev->of_node, &dp->priv.vm,
- OF_USE_NATIVE_MODE);
+ OF_USE_NATIVE_MODE);
if (ret) {
DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
return ret;
@@ -1302,7 +1298,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
exynos_dp_init_dp(dp);

ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
- irq_flags, "exynos-dp", dp);
+ irq_flags, "exynos-dp", dp);
if (ret) {
dev_err(&pdev->dev, "failed to request irq\n");
return ret;
@@ -1315,7 +1311,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
}

static void exynos_dp_unbind(struct device *dev, struct device *master,
- void *data)
+ void *data)
{
struct exynos_dp_device *dp = dev_get_drvdata(dev);

@@ -1334,7 +1330,7 @@ static int exynos_dp_probe(struct platform_device *pdev)
struct exynos_dp_device *dp;

dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
- GFP_KERNEL);
+ GFP_KERNEL);
if (!dp)
return -ENOMEM;

@@ -1358,8 +1354,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
of_node_put(bridge_node);
if (!dp->bridge)
return -EPROBE_DEFER;
- } else
+ } else {
return -EPROBE_DEFER;
+ }
}

return component_add(&pdev->dev, &exynos_dp_ops);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index a4e7996..c321ad5 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -180,8 +180,8 @@ void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
- enum analog_power_block block,
- bool enable);
+ enum analog_power_block block,
+ bool enable);
void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
void exynos_dp_init_hpd(struct exynos_dp_device *dp);
enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
@@ -192,50 +192,50 @@ int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
void exynos_dp_enable_sw_function(struct exynos_dp_device *dp);
int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp);
int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned char data);
+ unsigned int reg_addr,
+ unsigned char data);
int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned char *data);
+ unsigned int reg_addr,
+ unsigned char *data);
int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned int count,
- unsigned char data[]);
+ unsigned int reg_addr,
+ unsigned int count,
+ unsigned char data[]);
int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned int count,
- unsigned char data[]);
+ unsigned int reg_addr,
+ unsigned int count,
+ unsigned char data[]);
int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
unsigned int device_addr,
unsigned int reg_addr);
int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
- unsigned int device_addr,
- unsigned int reg_addr,
- unsigned int *data);
+ unsigned int device_addr,
+ unsigned int reg_addr,
+ unsigned int *data);
int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
- unsigned int device_addr,
- unsigned int reg_addr,
- unsigned int count,
- unsigned char edid[]);
+ unsigned int device_addr,
+ unsigned int reg_addr,
+ unsigned int count,
+ unsigned char edid[]);
void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable);
void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
- enum pattern_set pattern);
+ enum pattern_set pattern);
void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level);
void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level);
void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level);
void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level);
void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
- u32 training_lane);
+ u32 training_lane);
void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
- u32 training_lane);
+ u32 training_lane);
void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
- u32 training_lane);
+ u32 training_lane);
void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
- u32 training_lane);
+ u32 training_lane);
u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp);
u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
@@ -246,9 +246,8 @@ void exynos_dp_init_video(struct exynos_dp_device *dp);
void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
- enum clock_recovery_m_value_type type,
- u32 m_value,
- u32 n_value);
+ enum clock_recovery_m_value_type type,
+ u32 m_value, u32 n_value);
void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type);
void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable);
void exynos_dp_start_video(struct exynos_dp_device *dp);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.c b/drivers/gpu/drm/exynos/exynos_dp_reg.c
index c1f87a2..9aa483d 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_reg.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_reg.c
@@ -202,8 +202,8 @@ void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable)
}

void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
- enum analog_power_block block,
- bool enable)
+ enum analog_power_block block,
+ bool enable)
{
u32 reg;

@@ -399,8 +399,8 @@ void exynos_dp_init_aux(struct exynos_dp_device *dp)
exynos_dp_reset_aux(dp);

/* Disable AUX transaction H/W retry */
- reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
- AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+ reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
+ AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL);

/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
@@ -483,8 +483,8 @@ int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
}

int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned char data)
+ unsigned int reg_addr,
+ unsigned char data)
{
u32 reg;
int i;
@@ -519,17 +519,16 @@ int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
retval = exynos_dp_start_aux_transaction(dp);
if (retval == 0)
break;
- else
- dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
- __func__);
+
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
}

return retval;
}

int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned char *data)
+ unsigned int reg_addr,
+ unsigned char *data)
{
u32 reg;
int i;
@@ -560,9 +559,8 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
retval = exynos_dp_start_aux_transaction(dp);
if (retval == 0)
break;
- else
- dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
- __func__);
+
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
}

/* Read data buffer */
@@ -573,9 +571,9 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
}

int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned int count,
- unsigned char data[])
+ unsigned int reg_addr,
+ unsigned int count,
+ unsigned char data[])
{
u32 reg;
unsigned int start_offset;
@@ -625,9 +623,9 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
retval = exynos_dp_start_aux_transaction(dp);
if (retval == 0)
break;
- else
- dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
- __func__);
+
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}

start_offset += cur_data_count;
@@ -637,9 +635,9 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
}

int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned int count,
- unsigned char data[])
+ unsigned int reg_addr,
+ unsigned int count,
+ unsigned char data[])
{
u32 reg;
unsigned int start_offset;
@@ -683,9 +681,9 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
retval = exynos_dp_start_aux_transaction(dp);
if (retval == 0)
break;
- else
- dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
- __func__);
+
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}

for (cur_data_idx = 0; cur_data_idx < cur_data_count;
@@ -736,9 +734,9 @@ int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
}

int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
- unsigned int device_addr,
- unsigned int reg_addr,
- unsigned int *data)
+ unsigned int device_addr,
+ unsigned int reg_addr,
+ unsigned int *data)
{
u32 reg;
int i;
@@ -767,9 +765,8 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
retval = exynos_dp_start_aux_transaction(dp);
if (retval == 0)
break;
- else
- dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
- __func__);
+
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
}

/* Read data */
@@ -780,10 +777,10 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
}

int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
- unsigned int device_addr,
- unsigned int reg_addr,
- unsigned int count,
- unsigned char edid[])
+ unsigned int device_addr,
+ unsigned int reg_addr,
+ unsigned int count,
+ unsigned char edid[])
{
u32 reg;
unsigned int i, j;
@@ -807,8 +804,8 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
* request without sending address
*/
if (!defer)
- retval = exynos_dp_select_i2c_device(dp,
- device_addr, reg_addr + i);
+ retval = exynos_dp_select_i2c_device(
+ dp, device_addr, reg_addr + i);
else
defer = 0;

@@ -828,15 +825,14 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
retval = exynos_dp_start_aux_transaction(dp);
if (retval == 0)
break;
- else
- dev_dbg(dp->dev,
- "%s: Aux Transaction fail!\n",
- __func__);
+
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}
/* Check if Rx sends defer */
reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
if (reg == AUX_RX_COMM_AUX_DEFER ||
- reg == AUX_RX_COMM_I2C_DEFER) {
+ reg == AUX_RX_COMM_I2C_DEFER) {
dev_err(dp->dev, "Defer: %d\n\n", reg);
defer = 1;
}
@@ -901,7 +897,7 @@ void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable)
}

void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
- enum pattern_set pattern)
+ enum pattern_set pattern)
{
u32 reg;

@@ -974,7 +970,7 @@ void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
}

void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
- u32 training_lane)
+ u32 training_lane)
{
u32 reg;

@@ -983,7 +979,7 @@ void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
}

void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
- u32 training_lane)
+ u32 training_lane)
{
u32 reg;

@@ -992,7 +988,7 @@ void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
}

void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
- u32 training_lane)
+ u32 training_lane)
{
u32 reg;

@@ -1001,7 +997,7 @@ void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
}

void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
- u32 training_lane)
+ u32 training_lane)
{
u32 reg;

@@ -1125,9 +1121,9 @@ int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
}

void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
- enum clock_recovery_m_value_type type,
- u32 m_value,
- u32 n_value)
+ enum clock_recovery_m_value_type type,
+ u32 m_value,
+ u32 n_value)
{
u32 reg;

@@ -1221,7 +1217,7 @@ void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
u32 reg;

reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
- reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
+ reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
reg |= MASTER_VID_FUNC_EN_N;
writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);

--
1.9.1

2015-08-19 14:50:09

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 02/14] drm: exynos/dp: convert to drm bridge mode

In order to move exynos dp code to bridge directory,
we need to convert driver drm bridge mode first. As
dp driver already have a ptn3460 bridge, so we need
to move ptn bridge to the next bridge of dp bridge.

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3: None
Changes in v2:
- Take Jingoo Han suggest, just remove my name from author list.

drivers/gpu/drm/exynos/exynos_dp_core.c | 194 ++++++++++++++++++++------------
drivers/gpu/drm/exynos/exynos_dp_core.h | 1 +
2 files changed, 123 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 562f4a8..2b87406 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -997,59 +997,6 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
.best_encoder = exynos_dp_best_encoder,
};

-/* returns the number of bridges attached */
-static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
- struct drm_encoder *encoder)
-{
- int ret;
-
- encoder->bridge = dp->bridge;
- dp->bridge->encoder = encoder;
- ret = drm_bridge_attach(encoder->dev, dp->bridge);
- if (ret) {
- DRM_ERROR("Failed to attach bridge to drm\n");
- return ret;
- }
-
- return 0;
-}
-
-static int exynos_dp_create_connector(struct exynos_drm_display *display,
- struct drm_encoder *encoder)
-{
- struct exynos_dp_device *dp = display_to_dp(display);
- struct drm_connector *connector = &dp->connector;
- int ret;
-
- dp->encoder = encoder;
-
- /* Pre-empt DP connector creation if there's a bridge */
- if (dp->bridge) {
- ret = exynos_drm_attach_lcd_bridge(dp, encoder);
- if (!ret)
- return 0;
- }
-
- connector->polled = DRM_CONNECTOR_POLL_HPD;
-
- ret = drm_connector_init(dp->drm_dev, connector,
- &exynos_dp_connector_funcs,
- DRM_MODE_CONNECTOR_eDP);
- if (ret) {
- DRM_ERROR("Failed to initialize connector with drm\n");
- return ret;
- }
-
- drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
- drm_connector_register(connector);
- drm_mode_connector_attach_encoder(connector, encoder);
-
- if (dp->panel)
- ret = drm_panel_attach(dp->panel, &dp->connector);
-
- return ret;
-}
-
static void exynos_dp_phy_init(struct exynos_dp_device *dp)
{
if (dp->phy)
@@ -1114,23 +1061,126 @@ static void exynos_dp_poweroff(struct exynos_dp_device *dp)
}
}

-static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
+/* returns the number of bridges attached */
+static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
+ struct drm_encoder *encoder)
+{
+ int ret;
+
+ dp->bridge->next = dp->ptn_bridge;
+ dp->bridge->encoder = encoder;
+ ret = drm_bridge_attach(encoder->dev, dp->bridge);
+ if (ret) {
+ DRM_ERROR("Failed to attach ptn bridge to drm\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int exynos_dp_bridge_attach(struct drm_bridge *bridge)
+{
+
+ struct exynos_dp_device *dp = bridge->driver_private;
+ struct drm_encoder *encoder = dp->encoder;
+ struct drm_connector *connector = &dp->connector;
+ int ret;
+
+ if (!bridge->encoder) {
+ DRM_ERROR("Parent encoder object not found");
+ return -ENODEV;
+ }
+
+ encoder->bridge = bridge;
+
+ /* Pre-empt DP connector creation if there's a bridge */
+ if (dp->ptn_bridge) {
+ ret = exynos_drm_attach_lcd_bridge(dp, encoder);
+ if (ret)
+ return -ENODEV;
+ }
+
+ connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+ ret = drm_connector_init(dp->drm_dev, connector,
+ &exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
+ if (ret) {
+ DRM_ERROR("Failed to initialize connector with drm\n");
+ return ret;
+ }
+
+ drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
+ drm_connector_register(connector);
+ drm_mode_connector_attach_encoder(connector, encoder);
+
+ if (dp->panel)
+ ret = drm_panel_attach(dp->panel, &dp->connector);
+
+ return ret;
+}
+
+static void exynos_dp_bridge_nop(struct drm_bridge *bridge)
+{
+ /* do nothing */
+}
+
+static void exynos_dp_bridge_enable(struct drm_bridge *bridge)
+{
+ struct exynos_dp_device *dp = bridge->driver_private;
+
+ exynos_dp_poweron(dp);
+ dp->dpms_mode = DRM_MODE_DPMS_ON;
+}
+
+static void exynos_dp_bridge_disable(struct drm_bridge *bridge)
+{
+ struct exynos_dp_device *dp = bridge->driver_private;
+
+ exynos_dp_poweroff(dp);
+ dp->dpms_mode = DRM_MODE_DPMS_OFF;
+}
+
+static const struct drm_bridge_funcs exynos_dp_bridge_funcs = {
+ .enable = exynos_dp_bridge_enable,
+ .disable = exynos_dp_bridge_disable,
+ .pre_enable = exynos_dp_bridge_nop,
+ .post_disable = exynos_dp_bridge_nop,
+ .attach = exynos_dp_bridge_attach,
+};
+
+static int exynos_dp_create_connector(struct exynos_drm_display *display,
+ struct drm_encoder *encoder)
{
struct exynos_dp_device *dp = display_to_dp(display);
+ struct drm_device *drm_dev = dp->drm_dev;
+ struct drm_bridge *bridge;
+ int ret;

- switch (mode) {
- case DRM_MODE_DPMS_ON:
- exynos_dp_poweron(dp);
- break;
- case DRM_MODE_DPMS_STANDBY:
- case DRM_MODE_DPMS_SUSPEND:
- case DRM_MODE_DPMS_OFF:
- exynos_dp_poweroff(dp);
- break;
- default:
- break;
+ bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL);
+ if (!bridge) {
+ DRM_ERROR("failed to allocate for drm bridge\n");
+ return -ENOMEM;
}
- dp->dpms_mode = mode;
+
+ dp->bridge = bridge;
+ dp->encoder = encoder;
+
+ bridge->driver_private = dp;
+ bridge->encoder = dp->encoder;
+ bridge->funcs = &exynos_dp_bridge_funcs;
+
+ ret = drm_bridge_attach(drm_dev, bridge);
+ if (ret) {
+ DRM_ERROR("failed to attach drm bridge\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
+{
+ /* do nothing */
}

static struct exynos_drm_display_ops exynos_dp_display_ops = {
@@ -1242,7 +1292,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
}
}

- if (!dp->panel && !dp->bridge) {
+ if (!dp->panel && !dp->ptn_bridge) {
ret = exynos_dp_dt_parse_panel(dp);
if (ret)
return ret;
@@ -1315,7 +1365,7 @@ static void exynos_dp_unbind(struct device *dev, struct device *master,
{
struct exynos_dp_device *dp = dev_get_drvdata(dev);

- exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
+ exynos_dp_bridge_disable(dp->bridge);
}

static const struct component_ops exynos_dp_ops = {
@@ -1350,9 +1400,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
if (endpoint) {
bridge_node = of_graph_get_remote_port_parent(endpoint);
if (bridge_node) {
- dp->bridge = of_drm_find_bridge(bridge_node);
+ dp->ptn_bridge = of_drm_find_bridge(bridge_node);
of_node_put(bridge_node);
- if (!dp->bridge)
+ if (!dp->ptn_bridge)
return -EPROBE_DEFER;
} else {
return -EPROBE_DEFER;
@@ -1374,7 +1424,7 @@ static int exynos_dp_suspend(struct device *dev)
{
struct exynos_dp_device *dp = dev_get_drvdata(dev);

- exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
+ exynos_dp_bridge_disable(dp->bridge);
return 0;
}

@@ -1382,7 +1432,7 @@ static int exynos_dp_resume(struct device *dev)
{
struct exynos_dp_device *dp = dev_get_drvdata(dev);

- exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_ON);
+ exynos_dp_bridge_enable(dp->bridge);
return 0;
}
#endif
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index c321ad5..29bd56e 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -154,6 +154,7 @@ struct exynos_dp_device {
struct drm_encoder *encoder;
struct drm_panel *panel;
struct drm_bridge *bridge;
+ struct drm_bridge *ptn_bridge;
struct clk *clock;
unsigned int irq;
void __iomem *reg_base;
--
1.9.1

2015-08-19 14:51:29

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 03/14] drm: bridge: analogix_dp: split exynos dp driver to bridge dir

Split the dp core driver from exynos directory to bridge
directory, and rename the core driver to analogix_dp_*,
leave the platform code to analogix_dp-exynos.

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3:
- Take Thierry Reding suggest, move exynos's video_timing code
to analogix_dp-exynos platform driver, add get_modes method
to struct analogix_dp_plat_data.
- Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".

Changes in v2:
- Take Jingoo Han suggest, remove new copyright
- Fix compiled failed dut to analogix_dp_device misspell

drivers/gpu/drm/bridge/Kconfig | 5 +
drivers/gpu/drm/bridge/Makefile | 1 +
.../exynos_dp_core.c => bridge/analogix_dp_core.c} | 816 ++++++-------
drivers/gpu/drm/bridge/analogix_dp_core.h | 282 +++++
drivers/gpu/drm/bridge/analogix_dp_reg.c | 1265 ++++++++++++++++++++
.../exynos_dp_reg.h => bridge/analogix_dp_reg.h} | 258 ++--
drivers/gpu/drm/exynos/Kconfig | 5 +-
drivers/gpu/drm/exynos/Makefile | 2 +-
drivers/gpu/drm/exynos/analogix_dp-exynos.c | 291 +++++
drivers/gpu/drm/exynos/exynos_dp_core.h | 282 -----
drivers/gpu/drm/exynos/exynos_dp_reg.c | 1259 -------------------
include/drm/bridge/analogix_dp.h | 24 +
12 files changed, 2350 insertions(+), 2140 deletions(-)
rename drivers/gpu/drm/{exynos/exynos_dp_core.c => bridge/analogix_dp_core.c} (50%)
create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
rename drivers/gpu/drm/{exynos/exynos_dp_reg.h => bridge/analogix_dp_reg.h} (64%)
create mode 100644 drivers/gpu/drm/exynos/analogix_dp-exynos.c
delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.h
delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_reg.c
create mode 100644 include/drm/bridge/analogix_dp.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index acef322..c7638b5 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -3,6 +3,11 @@ config DRM_DW_HDMI
depends on DRM
select DRM_KMS_HELPER

+config DRM_ANALOGIX_DP
+ tristate
+ depends on DRM
+ select DRM_KMS_HELPER
+
config DRM_PTN3460
tristate "PTN3460 DP/LVDS bridge"
depends on DRM
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 8dfebd9..a7ee559 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -3,3 +3,4 @@ ccflags-y := -Iinclude/drm
obj-$(CONFIG_DRM_PS8622) += ps8622.o
obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
+obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix_dp_core.o analogix_dp_reg.o
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
similarity index 50%
rename from drivers/gpu/drm/exynos/exynos_dp_core.c
rename to drivers/gpu/drm/bridge/analogix_dp_core.c
index 2b87406..6c15e20 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -1,5 +1,5 @@
/*
- * Samsung SoC DP (Display Port) interface driver.
+ * Analogix Core DP (Display Port) interface driver.
*
* Copyright (C) 2012 Samsung Electronics Co., Ltd.
* Author: Jingoo Han <[email protected]>
@@ -18,12 +18,9 @@
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
-#include <linux/of_graph.h>
#include <linux/gpio.h>
#include <linux/component.h>
#include <linux/phy/phy.h>
-#include <video/of_display_timing.h>
-#include <video/of_videomode.h>

#include <drm/drmP.h>
#include <drm/drm_crtc.h>
@@ -31,51 +28,42 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_panel.h>

-#include "exynos_dp_core.h"
+#include <drm/bridge/analogix_dp.h>

-#define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \
- connector)
+#include "analogix_dp_core.h"

-static inline struct exynos_drm_crtc *dp_to_crtc(struct exynos_dp_device *dp)
-{
- return to_exynos_crtc(dp->encoder->crtc);
-}
-
-static inline struct exynos_dp_device *
-display_to_dp(struct exynos_drm_display *d)
-{
- return container_of(d, struct exynos_dp_device, display);
-}
+#define connector_to_dp(c) \
+ container_of(c, struct analogix_dp_device, connector)

struct bridge_init {
struct i2c_client *client;
struct device_node *node;
};

-static void exynos_dp_init_dp(struct exynos_dp_device *dp)
+static void analogix_dp_init_dp(struct analogix_dp_device *dp)
{
- exynos_dp_reset(dp);
+ analogix_dp_reset(dp);

- exynos_dp_swreset(dp);
+ analogix_dp_swreset(dp);

- exynos_dp_init_analog_param(dp);
- exynos_dp_init_interrupt(dp);
+ analogix_dp_init_analog_param(dp);
+ analogix_dp_init_interrupt(dp);

/* SW defined function Normal operation */
- exynos_dp_enable_sw_function(dp);
+ analogix_dp_enable_sw_function(dp);

- exynos_dp_config_interrupt(dp);
- exynos_dp_init_analog_func(dp);
+ analogix_dp_config_interrupt(dp);
+ analogix_dp_init_analog_func(dp);

- exynos_dp_init_hpd(dp);
- exynos_dp_init_aux(dp);
+ analogix_dp_init_hpd(dp);
+ analogix_dp_init_aux(dp);
}

-static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
+static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
{
int timeout_loop = 0;

- while (exynos_dp_get_plug_in_status(dp) != 0) {
+ while (analogix_dp_get_plug_in_status(dp) != 0) {
timeout_loop++;
if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
dev_err(dp->dev, "failed to get hpd plug status\n");
@@ -87,7 +75,7 @@ static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
return 0;
}

-static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data)
+static unsigned char analogix_dp_calc_edid_check_sum(unsigned char *edid_data)
{
int i;
unsigned char sum = 0;
@@ -98,7 +86,7 @@ static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data)
return sum;
}

-static int exynos_dp_read_edid(struct exynos_dp_device *dp)
+static int analogix_dp_read_edid(struct analogix_dp_device *dp)
{
unsigned char edid[EDID_BLOCK_LENGTH * 2];
unsigned int extend_block = 0;
@@ -113,9 +101,9 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
*/

/* Read Extension Flag, Number of 128-byte EDID extension blocks */
- retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
- EDID_EXTENSION_FLAG,
- &extend_block);
+ retval = analogix_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
+ EDID_EXTENSION_FLAG,
+ &extend_block);
if (retval)
return retval;

@@ -123,44 +111,44 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
dev_dbg(dp->dev, "EDID data includes a single extension!\n");

/* Read EDID data */
- retval = exynos_dp_read_bytes_from_i2c(
- dp, I2C_EDID_DEVICE_ADDR,
- EDID_HEADER_PATTERN,
- EDID_BLOCK_LENGTH,
- &edid[EDID_HEADER_PATTERN]);
+ retval = analogix_dp_read_bytes_from_i2c(
+ dp, I2C_EDID_DEVICE_ADDR,
+ EDID_HEADER_PATTERN,
+ EDID_BLOCK_LENGTH,
+ &edid[EDID_HEADER_PATTERN]);
if (retval != 0) {
dev_err(dp->dev, "EDID Read failed!\n");
return -EIO;
}
- sum = exynos_dp_calc_edid_check_sum(edid);
+ sum = analogix_dp_calc_edid_check_sum(edid);
if (sum != 0) {
dev_err(dp->dev, "EDID bad checksum!\n");
return -EIO;
}

/* Read additional EDID data */
- retval = exynos_dp_read_bytes_from_i2c(
- dp, I2C_EDID_DEVICE_ADDR,
- EDID_BLOCK_LENGTH,
- EDID_BLOCK_LENGTH,
- &edid[EDID_BLOCK_LENGTH]);
+ retval = analogix_dp_read_bytes_from_i2c(
+ dp, I2C_EDID_DEVICE_ADDR,
+ EDID_BLOCK_LENGTH,
+ EDID_BLOCK_LENGTH,
+ &edid[EDID_BLOCK_LENGTH]);
if (retval != 0) {
dev_err(dp->dev, "EDID Read failed!\n");
return -EIO;
}
- sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
+ sum = analogix_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
if (sum != 0) {
dev_err(dp->dev, "EDID bad checksum!\n");
return -EIO;
}

- exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
- &test_vector);
+ analogix_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
+ &test_vector);
if (test_vector & DP_TEST_LINK_EDID_READ) {
- exynos_dp_write_byte_to_dpcd(
+ analogix_dp_write_byte_to_dpcd(
dp, DP_TEST_EDID_CHECKSUM,
edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
- exynos_dp_write_byte_to_dpcd(
+ analogix_dp_write_byte_to_dpcd(
dp, DP_TEST_RESPONSE,
DP_TEST_EDID_CHECKSUM_WRITE);
}
@@ -168,26 +156,28 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
dev_info(dp->dev, "EDID data does not include any extensions.\n");

/* Read EDID data */
- retval = exynos_dp_read_bytes_from_i2c(
- dp, I2C_EDID_DEVICE_ADDR, EDID_HEADER_PATTERN,
- EDID_BLOCK_LENGTH, &edid[EDID_HEADER_PATTERN]);
+ retval = analogix_dp_read_bytes_from_i2c(
+ dp, I2C_EDID_DEVICE_ADDR,
+ EDID_HEADER_PATTERN,
+ EDID_BLOCK_LENGTH,
+ &edid[EDID_HEADER_PATTERN]);
if (retval != 0) {
dev_err(dp->dev, "EDID Read failed!\n");
return -EIO;
}
- sum = exynos_dp_calc_edid_check_sum(edid);
+ sum = analogix_dp_calc_edid_check_sum(edid);
if (sum != 0) {
dev_err(dp->dev, "EDID bad checksum!\n");
return -EIO;
}

- exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
- &test_vector);
+ analogix_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
+ &test_vector);
if (test_vector & DP_TEST_LINK_EDID_READ) {
- exynos_dp_write_byte_to_dpcd(
+ analogix_dp_write_byte_to_dpcd(
dp, DP_TEST_EDID_CHECKSUM,
edid[EDID_CHECKSUM]);
- exynos_dp_write_byte_to_dpcd(
+ analogix_dp_write_byte_to_dpcd(
dp, DP_TEST_RESPONSE,
DP_TEST_EDID_CHECKSUM_WRITE);
}
@@ -197,20 +187,20 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
return 0;
}

-static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
+static int analogix_dp_handle_edid(struct analogix_dp_device *dp)
{
u8 buf[12];
int i;
int retval;

/* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */
- retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, 12, buf);
+ retval = analogix_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, 12, buf);
if (retval)
return retval;

/* Read EDID */
for (i = 0; i < 3; i++) {
- retval = exynos_dp_read_edid(dp);
+ retval = analogix_dp_read_edid(dp);
if (!retval)
break;
}
@@ -218,74 +208,76 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
return retval;
}

-static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
- bool enable)
+static void
+analogix_dp_enable_rx_to_enhanced_mode(struct analogix_dp_device *dp,
+ bool enable)
{
u8 data;

- exynos_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data);
+ analogix_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data);

if (enable)
- exynos_dp_write_byte_to_dpcd(
+ analogix_dp_write_byte_to_dpcd(
dp, DP_LANE_COUNT_SET,
DP_LANE_COUNT_ENHANCED_FRAME_EN |
DPCD_LANE_COUNT_SET(data));
else
- exynos_dp_write_byte_to_dpcd(
+ analogix_dp_write_byte_to_dpcd(
dp, DP_LANE_COUNT_SET,
DPCD_LANE_COUNT_SET(data));
}

-static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp)
+static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device *dp)
{
u8 data;
int retval;

- exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data);
+ analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data);
retval = DPCD_ENHANCED_FRAME_CAP(data);

return retval;
}

-static void exynos_dp_set_enhanced_mode(struct exynos_dp_device *dp)
+static void analogix_dp_set_enhanced_mode(struct analogix_dp_device *dp)
{
u8 data;

- data = exynos_dp_is_enhanced_mode_available(dp);
- exynos_dp_enable_rx_to_enhanced_mode(dp, data);
- exynos_dp_enable_enhanced_mode(dp, data);
+ data = analogix_dp_is_enhanced_mode_available(dp);
+ analogix_dp_enable_rx_to_enhanced_mode(dp, data);
+ analogix_dp_enable_enhanced_mode(dp, data);
}

-static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
+static void analogix_dp_training_pattern_dis(struct analogix_dp_device *dp)
{
- exynos_dp_set_training_pattern(dp, DP_NONE);
+ analogix_dp_set_training_pattern(dp, DP_NONE);

- exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
- DP_TRAINING_PATTERN_DISABLE);
+ analogix_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+ DP_TRAINING_PATTERN_DISABLE);
}

-static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
- int pre_emphasis, int lane)
+static void
+analogix_dp_set_lane_lane_pre_emphasis(struct analogix_dp_device *dp,
+ int pre_emphasis, int lane)
{
switch (lane) {
case 0:
- exynos_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
+ analogix_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
break;
case 1:
- exynos_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
+ analogix_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
break;

case 2:
- exynos_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
+ analogix_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
break;

case 3:
- exynos_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
+ analogix_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
break;
}
}

-static int exynos_dp_link_start(struct exynos_dp_device *dp)
+static int analogix_dp_link_start(struct analogix_dp_device *dp)
{
u8 buf[4];
int lane, lane_count, pll_tries, retval;
@@ -299,24 +291,24 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
dp->link_train.cr_loop[lane] = 0;

/* Set link rate and count as you want to establish*/
- exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
- exynos_dp_set_lane_count(dp, dp->link_train.lane_count);
+ analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
+ analogix_dp_set_lane_count(dp, dp->link_train.lane_count);

/* Setup RX configuration */
buf[0] = dp->link_train.link_rate;
buf[1] = dp->link_train.lane_count;
- retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, 2, buf);
+ retval = analogix_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, 2, buf);
if (retval)
return retval;

/* Set TX pre-emphasis to minimum */
for (lane = 0; lane < lane_count; lane++)
- exynos_dp_set_lane_lane_pre_emphasis(dp, PRE_EMPHASIS_LEVEL_0,
- lane);
+ analogix_dp_set_lane_lane_pre_emphasis(
+ dp, PRE_EMPHASIS_LEVEL_0, lane);

/* Wait for PLL lock */
pll_tries = 0;
- while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
+ while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
if (pll_tries == DP_TIMEOUT_LOOP_COUNT) {
dev_err(dp->dev, "Wait for PLL lock timed out\n");
return -ETIMEDOUT;
@@ -327,12 +319,12 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
}

/* Set training pattern 1 */
- exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
+ analogix_dp_set_training_pattern(dp, TRAINING_PTN1);

/* Set RX training pattern */
- retval = exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
- DP_LINK_SCRAMBLING_DISABLE |
- DP_TRAINING_PATTERN_1);
+ retval = analogix_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+ DP_LINK_SCRAMBLING_DISABLE |
+ DP_TRAINING_PATTERN_1);
if (retval)
return retval;

@@ -340,13 +332,13 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
buf[lane] = DP_TRAIN_PRE_EMPH_LEVEL_0 |
DP_TRAIN_VOLTAGE_SWING_LEVEL_0;

- retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
- lane_count, buf);
+ retval = analogix_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
+ lane_count, buf);

return retval;
}

-static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
+static unsigned char analogix_dp_get_lane_status(u8 link_status[2], int lane)
{
int shift = (lane & 1) * 4;
u8 link_value = link_status[lane >> 1];
@@ -354,21 +346,21 @@ static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
return (link_value >> shift) & 0xf;
}

-static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
+static int analogix_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
{
int lane;
u8 lane_status;

for (lane = 0; lane < lane_count; lane++) {
- lane_status = exynos_dp_get_lane_status(link_status, lane);
+ lane_status = analogix_dp_get_lane_status(link_status, lane);
if ((lane_status & DP_LANE_CR_DONE) == 0)
return -EINVAL;
}
return 0;
}

-static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
- int lane_count)
+static int analogix_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
+ int lane_count)
{
int lane;
u8 lane_status;
@@ -377,7 +369,7 @@ static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
return -EINVAL;

for (lane = 0; lane < lane_count; lane++) {
- lane_status = exynos_dp_get_lane_status(link_status, lane);
+ lane_status = analogix_dp_get_lane_status(link_status, lane);
lane_status &= DP_CHANNEL_EQ_BITS;
if (lane_status != DP_CHANNEL_EQ_BITS)
return -EINVAL;
@@ -386,8 +378,8 @@ static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
return 0;
}

-static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2],
- int lane)
+static unsigned char
+analogix_dp_get_adjust_request_voltage(u8 adjust_request[2], int lane)
{
int shift = (lane & 1) * 4;
u8 link_value = adjust_request[lane >> 1];
@@ -395,7 +387,7 @@ static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2],
return (link_value >> shift) & 0x3;
}

-static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
+static unsigned char analogix_dp_get_adjust_request_pre_emphasis(
u8 adjust_request[2],
int lane)
{
@@ -405,45 +397,45 @@ static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
return ((link_value >> shift) & 0xc) >> 2;
}

-static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
- u8 training_lane_set, int lane)
+static void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp,
+ u8 training_lane_set, int lane)
{
switch (lane) {
case 0:
- exynos_dp_set_lane0_link_training(dp, training_lane_set);
+ analogix_dp_set_lane0_link_training(dp, training_lane_set);
break;
case 1:
- exynos_dp_set_lane1_link_training(dp, training_lane_set);
+ analogix_dp_set_lane1_link_training(dp, training_lane_set);
break;

case 2:
- exynos_dp_set_lane2_link_training(dp, training_lane_set);
+ analogix_dp_set_lane2_link_training(dp, training_lane_set);
break;

case 3:
- exynos_dp_set_lane3_link_training(dp, training_lane_set);
+ analogix_dp_set_lane3_link_training(dp, training_lane_set);
break;
}
}

-static unsigned int exynos_dp_get_lane_link_training(
- struct exynos_dp_device *dp,
+static unsigned int analogix_dp_get_lane_link_training(
+ struct analogix_dp_device *dp,
int lane)
{
u32 reg;

switch (lane) {
case 0:
- reg = exynos_dp_get_lane0_link_training(dp);
+ reg = analogix_dp_get_lane0_link_training(dp);
break;
case 1:
- reg = exynos_dp_get_lane1_link_training(dp);
+ reg = analogix_dp_get_lane1_link_training(dp);
break;
case 2:
- reg = exynos_dp_get_lane2_link_training(dp);
+ reg = analogix_dp_get_lane2_link_training(dp);
break;
case 3:
- reg = exynos_dp_get_lane3_link_training(dp);
+ reg = analogix_dp_get_lane3_link_training(dp);
break;
default:
WARN_ON(1);
@@ -453,25 +445,25 @@ static unsigned int exynos_dp_get_lane_link_training(
return reg;
}

-static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
+static void analogix_dp_reduce_link_rate(struct analogix_dp_device *dp)
{
- exynos_dp_training_pattern_dis(dp);
- exynos_dp_set_enhanced_mode(dp);
+ analogix_dp_training_pattern_dis(dp);
+ analogix_dp_set_enhanced_mode(dp);

dp->link_train.lt_state = FAILED;
}

-static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
- u8 adjust_request[2])
+static void analogix_dp_get_adjust_training_lane(struct analogix_dp_device *dp,
+ u8 adjust_request[2])
{
int lane, lane_count;
u8 voltage_swing, pre_emphasis, training_lane;

lane_count = dp->link_train.lane_count;
for (lane = 0; lane < lane_count; lane++) {
- voltage_swing = exynos_dp_get_adjust_request_voltage(
+ voltage_swing = analogix_dp_get_adjust_request_voltage(
adjust_request, lane);
- pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+ pre_emphasis = analogix_dp_get_adjust_request_pre_emphasis(
adjust_request, lane);
training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
DPCD_PRE_EMPHASIS_SET(pre_emphasis);
@@ -485,7 +477,7 @@ static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
}
}

-static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
+static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp)
{
int lane, lane_count, retval;
u8 voltage_swing, pre_emphasis, training_lane;
@@ -495,24 +487,24 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)

lane_count = dp->link_train.lane_count;

- retval = exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
- 2, link_status);
+ retval = analogix_dp_read_bytes_from_dpcd(
+ dp, DP_LANE0_1_STATUS, 2, link_status);
if (retval)
return retval;

- retval = exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
- 2, adjust_request);
+ retval = analogix_dp_read_bytes_from_dpcd(
+ dp, DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
if (retval)
return retval;

- if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
+ if (analogix_dp_clock_recovery_ok(link_status, lane_count) == 0) {
/* set training pattern 2 for EQ */
- exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
+ analogix_dp_set_training_pattern(dp, TRAINING_PTN2);

- retval = exynos_dp_write_byte_to_dpcd(
- dp, DP_TRAINING_PATTERN_SET,
- DP_LINK_SCRAMBLING_DISABLE |
- DP_TRAINING_PATTERN_2);
+ retval = analogix_dp_write_byte_to_dpcd(
+ dp, DP_TRAINING_PATTERN_SET,
+ DP_LINK_SCRAMBLING_DISABLE |
+ DP_TRAINING_PATTERN_2);
if (retval)
return retval;

@@ -520,12 +512,12 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
dp->link_train.lt_state = EQUALIZER_TRAINING;
} else {
for (lane = 0; lane < lane_count; lane++) {
- training_lane = exynos_dp_get_lane_link_training(
+ training_lane = analogix_dp_get_lane_link_training(
dp, lane);
- voltage_swing = exynos_dp_get_adjust_request_voltage(
- adjust_request, lane);
- pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+ voltage_swing = analogix_dp_get_adjust_request_voltage(
adjust_request, lane);
+ pre_emphasis = analogix_dp_get_adjust_request_pre_emphasis(
+ adjust_request, lane);

if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
voltage_swing &&
@@ -539,19 +531,19 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n",
dp->link_train.cr_loop[lane],
voltage_swing, pre_emphasis);
- exynos_dp_reduce_link_rate(dp);
+ analogix_dp_reduce_link_rate(dp);
return -EIO;
}
}
}

- exynos_dp_get_adjust_training_lane(dp, adjust_request);
+ analogix_dp_get_adjust_training_lane(dp, adjust_request);

for (lane = 0; lane < lane_count; lane++)
- exynos_dp_set_lane_link_training(
+ analogix_dp_set_lane_link_training(
dp, dp->link_train.training_lane[lane], lane);

- retval = exynos_dp_write_bytes_to_dpcd(
+ retval = analogix_dp_write_bytes_to_dpcd(
dp, DP_TRAINING_LANE0_SET, lane_count,
dp->link_train.training_lane);
if (retval)
@@ -560,7 +552,7 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
return retval;
}

-static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
+static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
{
int lane, lane_count, retval;
u32 reg;
@@ -570,46 +562,46 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)

lane_count = dp->link_train.lane_count;

- retval = exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
- 2, link_status);
+ retval = analogix_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+ 2, link_status);
if (retval)
return retval;

- if (exynos_dp_clock_recovery_ok(link_status, lane_count)) {
- exynos_dp_reduce_link_rate(dp);
+ if (analogix_dp_clock_recovery_ok(link_status, lane_count)) {
+ analogix_dp_reduce_link_rate(dp);
return -EIO;
}

- retval = exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
- 2, adjust_request);
+ retval = analogix_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+ 2, adjust_request);
if (retval)
return retval;

- retval = exynos_dp_read_byte_from_dpcd(
+ retval = analogix_dp_read_byte_from_dpcd(
dp, DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
if (retval)
return retval;

- exynos_dp_get_adjust_training_lane(dp, adjust_request);
+ analogix_dp_get_adjust_training_lane(dp, adjust_request);

- if (!exynos_dp_channel_eq_ok(link_status, link_align, lane_count)) {
+ if (!analogix_dp_channel_eq_ok(link_status, link_align, lane_count)) {
/* traing pattern Set to Normal */
- exynos_dp_training_pattern_dis(dp);
+ analogix_dp_training_pattern_dis(dp);

dev_info(dp->dev, "Link Training success!\n");

- exynos_dp_get_link_bandwidth(dp, &reg);
+ analogix_dp_get_link_bandwidth(dp, &reg);
dp->link_train.link_rate = reg;
dev_dbg(dp->dev, "final bandwidth = %.2x\n",
dp->link_train.link_rate);

- exynos_dp_get_lane_count(dp, &reg);
+ analogix_dp_get_lane_count(dp, &reg);
dp->link_train.lane_count = reg;
dev_dbg(dp->dev, "final lane count = %.2x\n",
dp->link_train.lane_count);

/* set enhanced mode if available */
- exynos_dp_set_enhanced_mode(dp);
+ analogix_dp_set_enhanced_mode(dp);
dp->link_train.lt_state = FINISHED;

return 0;
@@ -620,23 +612,23 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)

if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
dev_err(dp->dev, "EQ Max loop\n");
- exynos_dp_reduce_link_rate(dp);
+ analogix_dp_reduce_link_rate(dp);
return -EIO;
}

for (lane = 0; lane < lane_count; lane++)
- exynos_dp_set_lane_link_training(
+ analogix_dp_set_lane_link_training(
dp, dp->link_train.training_lane[lane], lane);

- retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
- lane_count,
- dp->link_train.training_lane);
+ retval = analogix_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
+ lane_count,
+ dp->link_train.training_lane);

return retval;
}

-static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
- u8 *bandwidth)
+static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
+ u8 *bandwidth)
{
u8 data;

@@ -644,12 +636,12 @@ static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
* For DP rev.1.1, Maximum link rate of Main Link lanes
* 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
*/
- exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
+ analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
*bandwidth = data;
}

-static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
- u8 *lane_count)
+static void analogix_dp_get_max_rx_lane_count(struct analogix_dp_device *dp,
+ u8 *lane_count)
{
u8 data;

@@ -657,23 +649,23 @@ static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
* For DP rev.1.1, Maximum number of Main Link lanes
* 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
*/
- exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data);
+ analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data);
*lane_count = DPCD_MAX_LANE_COUNT(data);
}

-static void exynos_dp_init_training(struct exynos_dp_device *dp,
- enum link_lane_count_type max_lane,
- enum link_rate_type max_rate)
+static void analogix_dp_init_training(struct analogix_dp_device *dp,
+ enum link_lane_count_type max_lane,
+ enum link_rate_type max_rate)
{
/*
* MACRO_RST must be applied after the PLL_LOCK to avoid
* the DP inter pair skew issue for at least 10 us
*/
- exynos_dp_reset_macro(dp);
+ analogix_dp_reset_macro(dp);

/* Initialize by reading RX's DPCD */
- exynos_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
- exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
+ analogix_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
+ analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);

if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
(dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
@@ -695,10 +687,10 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
dp->link_train.link_rate = max_rate;

/* All DP analog module power up */
- exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
+ analogix_dp_set_analog_power_down(dp, POWER_ALL, 0);
}

-static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
+static int analogix_dp_sw_link_training(struct analogix_dp_device *dp)
{
int retval = 0, training_finished = 0;

@@ -708,17 +700,17 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
while (!retval && !training_finished) {
switch (dp->link_train.lt_state) {
case START:
- retval = exynos_dp_link_start(dp);
+ retval = analogix_dp_link_start(dp);
if (retval)
dev_err(dp->dev, "LT link start failed!\n");
break;
case CLOCK_RECOVERY:
- retval = exynos_dp_process_clock_recovery(dp);
+ retval = analogix_dp_process_clock_recovery(dp);
if (retval)
dev_err(dp->dev, "LT CR failed!\n");
break;
case EQUALIZER_TRAINING:
- retval = exynos_dp_process_equalizer_training(dp);
+ retval = analogix_dp_process_equalizer_training(dp);
if (retval)
dev_err(dp->dev, "LT EQ failed!\n");
break;
@@ -735,15 +727,15 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
return retval;
}

-static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
- u32 count, u32 bwtype)
+static int analogix_dp_set_link_train(struct analogix_dp_device *dp,
+ u32 count, u32 bwtype)
{
int i;
int retval;

for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) {
- exynos_dp_init_training(dp, count, bwtype);
- retval = exynos_dp_sw_link_training(dp);
+ analogix_dp_init_training(dp, count, bwtype);
+ retval = analogix_dp_sw_link_training(dp);
if (retval == 0)
break;

@@ -753,24 +745,24 @@ static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
return retval;
}

-static int exynos_dp_config_video(struct exynos_dp_device *dp)
+static int analogix_dp_config_video(struct analogix_dp_device *dp)
{
int retval = 0;
int timeout_loop = 0;
int done_count = 0;

- exynos_dp_config_video_slave_mode(dp);
+ analogix_dp_config_video_slave_mode(dp);

- exynos_dp_set_video_color_format(dp);
+ analogix_dp_set_video_color_format(dp);

- if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
+ if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
dev_err(dp->dev, "PLL is not locked yet.\n");
return -EINVAL;
}

for (;;) {
timeout_loop++;
- if (exynos_dp_is_slave_video_stream_clock_on(dp) == 0)
+ if (analogix_dp_is_slave_video_stream_clock_on(dp) == 0)
break;
if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
dev_err(dp->dev, "Timeout of video streamclk ok\n");
@@ -781,25 +773,25 @@ static int exynos_dp_config_video(struct exynos_dp_device *dp)
}

/* Set to use the register calculated M/N video */
- exynos_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);
+ analogix_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);

/* For video bist, Video timing must be generated by register */
- exynos_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE);
+ analogix_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE);

/* Disable video mute */
- exynos_dp_enable_video_mute(dp, 0);
+ analogix_dp_enable_video_mute(dp, 0);

/* Configure video slave mode */
- exynos_dp_enable_video_master(dp, 0);
+ analogix_dp_enable_video_master(dp, 0);

/* Enable video */
- exynos_dp_start_video(dp);
+ analogix_dp_start_video(dp);

timeout_loop = 0;

for (;;) {
timeout_loop++;
- if (exynos_dp_is_video_stream_on(dp) == 0) {
+ if (analogix_dp_is_video_stream_on(dp) == 0) {
done_count++;
if (done_count > 10)
break;
@@ -820,45 +812,46 @@ static int exynos_dp_config_video(struct exynos_dp_device *dp)
return retval;
}

-static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable)
+static void analogix_dp_enable_scramble(struct analogix_dp_device *dp,
+ bool enable)
{
u8 data;

if (enable) {
- exynos_dp_enable_scrambling(dp);
+ analogix_dp_enable_scrambling(dp);

- exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
- &data);
- exynos_dp_write_byte_to_dpcd(
- dp, DP_TRAINING_PATTERN_SET,
- (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
+ analogix_dp_read_byte_from_dpcd(
+ dp, DP_TRAINING_PATTERN_SET, &data);
+ analogix_dp_write_byte_to_dpcd(
+ dp, DP_TRAINING_PATTERN_SET,
+ (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
} else {
- exynos_dp_disable_scrambling(dp);
+ analogix_dp_disable_scrambling(dp);

- exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
- &data);
- exynos_dp_write_byte_to_dpcd(
+ analogix_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+ &data);
+ analogix_dp_write_byte_to_dpcd(
dp, DP_TRAINING_PATTERN_SET,
(u8)(data | DP_LINK_SCRAMBLING_DISABLE));
}
}

-static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
+static irqreturn_t analogix_dp_irq_handler(int irq, void *arg)
{
- struct exynos_dp_device *dp = arg;
+ struct analogix_dp_device *dp = arg;

enum dp_irq_type irq_type;

- irq_type = exynos_dp_get_irq_type(dp);
+ irq_type = analogix_dp_get_irq_type(dp);
switch (irq_type) {
case DP_IRQ_TYPE_HP_CABLE_IN:
dev_dbg(dp->dev, "Received irq - cable in\n");
schedule_work(&dp->hotplug_work);
- exynos_dp_clear_hotplug_interrupts(dp);
+ analogix_dp_clear_hotplug_interrupts(dp);
break;
case DP_IRQ_TYPE_HP_CABLE_OUT:
dev_dbg(dp->dev, "Received irq - cable out\n");
- exynos_dp_clear_hotplug_interrupts(dp);
+ analogix_dp_clear_hotplug_interrupts(dp);
break;
case DP_IRQ_TYPE_HP_CHANGE:
/*
@@ -867,7 +860,7 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
* only handle cable changes.
*/
dev_dbg(dp->dev, "Received irq - hotplug change; ignoring.\n");
- exynos_dp_clear_hotplug_interrupts(dp);
+ analogix_dp_clear_hotplug_interrupts(dp);
break;
default:
dev_err(dp->dev, "Received irq - unknown type!\n");
@@ -876,172 +869,155 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
return IRQ_HANDLED;
}

-static void exynos_dp_hotplug(struct work_struct *work)
+static void analogix_dp_hotplug(struct work_struct *work)
{
- struct exynos_dp_device *dp;
+ struct analogix_dp_device *dp;

- dp = container_of(work, struct exynos_dp_device, hotplug_work);
+ dp = container_of(work, struct analogix_dp_device, hotplug_work);

if (dp->drm_dev)
drm_helper_hpd_irq_event(dp->drm_dev);
}

-static void exynos_dp_commit(struct exynos_drm_display *display)
+static void analogix_dp_commit(struct analogix_dp_device *dp)
{
- struct exynos_dp_device *dp = display_to_dp(display);
int ret;

/* Keep the panel disabled while we configure video */
- if (dp->panel) {
- if (drm_panel_disable(dp->panel))
+ if (dp->plat_data && dp->plat_data->panel) {
+ if (drm_panel_disable(dp->plat_data->panel))
DRM_ERROR("failed to disable the panel\n");
}

- ret = exynos_dp_detect_hpd(dp);
+ ret = analogix_dp_detect_hpd(dp);
if (ret) {
/* Cable has been disconnected, we're done */
return;
}

- ret = exynos_dp_handle_edid(dp);
+ ret = analogix_dp_handle_edid(dp);
if (ret) {
dev_err(dp->dev, "unable to handle edid\n");
return;
}

- ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
- dp->video_info->link_rate);
+ ret = analogix_dp_set_link_train(dp, dp->video_info->lane_count,
+ dp->video_info->link_rate);
if (ret) {
dev_err(dp->dev, "unable to do link train\n");
return;
}

- exynos_dp_enable_scramble(dp, 1);
- exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
- exynos_dp_enable_enhanced_mode(dp, 1);
+ analogix_dp_enable_scramble(dp, 1);
+ analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
+ analogix_dp_enable_enhanced_mode(dp, 1);

- exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
- exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
+ analogix_dp_set_lane_count(dp, dp->video_info->lane_count);
+ analogix_dp_set_link_bandwidth(dp, dp->video_info->link_rate);

- exynos_dp_init_video(dp);
- ret = exynos_dp_config_video(dp);
+ analogix_dp_init_video(dp);
+ ret = analogix_dp_config_video(dp);
if (ret)
dev_err(dp->dev, "unable to config video\n");

/* Safe to enable the panel now */
- if (dp->panel) {
- if (drm_panel_enable(dp->panel))
+ if (dp->plat_data && dp->plat_data->panel) {
+ if (drm_panel_enable(dp->plat_data->panel))
DRM_ERROR("failed to enable the panel\n");
}
}

-static enum drm_connector_status exynos_dp_detect(
+static enum drm_connector_status analogix_dp_detect(
struct drm_connector *connector, bool force)
{
return connector_status_connected;
}

-static void exynos_dp_connector_destroy(struct drm_connector *connector)
+static void analogix_dp_connector_destroy(struct drm_connector *connector)
{
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
}

-static struct drm_connector_funcs exynos_dp_connector_funcs = {
+static struct drm_connector_funcs analogix_dp_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
- .detect = exynos_dp_detect,
- .destroy = exynos_dp_connector_destroy,
+ .detect = analogix_dp_detect,
+ .destroy = analogix_dp_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

-static int exynos_dp_get_modes(struct drm_connector *connector)
+static int analogix_dp_get_modes(struct drm_connector *connector)
{
- struct exynos_dp_device *dp = ctx_from_connector(connector);
- struct drm_display_mode *mode;
+ struct analogix_dp_device *dp = connector_to_dp(connector);
+ struct analogix_dp_plat_data *plat_data = dp->plat_data;
+ int num_modes = 0;

- if (dp->panel)
- return drm_panel_get_modes(dp->panel);
-
- mode = drm_mode_create(connector->dev);
- if (!mode) {
- DRM_ERROR("failed to create a new display mode.\n");
- return 0;
- }
+ if (plat_data && plat_data->panel)
+ num_modes += drm_panel_get_modes(plat_data->panel);

- drm_display_mode_from_videomode(&dp->priv.vm, mode);
- mode->width_mm = dp->priv.width_mm;
- mode->height_mm = dp->priv.height_mm;
- connector->display_info.width_mm = mode->width_mm;
- connector->display_info.height_mm = mode->height_mm;
+ if (plat_data && plat_data->get_modes)
+ num_modes += plat_data->get_modes(plat_data, connector);

- mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
- drm_mode_set_name(mode);
- drm_mode_probed_add(connector, mode);
-
- return 1;
+ return num_modes;
}

-static struct drm_encoder *exynos_dp_best_encoder(
+static struct drm_encoder *analogix_dp_best_encoder(
struct drm_connector *connector)
{
- struct exynos_dp_device *dp = ctx_from_connector(connector);
+ struct analogix_dp_device *dp = connector_to_dp(connector);

return dp->encoder;
}

-static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
- .get_modes = exynos_dp_get_modes,
- .best_encoder = exynos_dp_best_encoder,
+static struct drm_connector_helper_funcs analogix_dp_connector_helper_funcs = {
+ .get_modes = analogix_dp_get_modes,
+ .best_encoder = analogix_dp_best_encoder,
};

-static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+static void analogix_dp_phy_init(struct analogix_dp_device *dp)
{
if (dp->phy)
phy_power_on(dp->phy);
}

-static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+static void analogix_dp_phy_exit(struct analogix_dp_device *dp)
{
if (dp->phy)
phy_power_off(dp->phy);
}

-static void exynos_dp_poweron(struct exynos_dp_device *dp)
+static void analogix_dp_poweron(struct analogix_dp_device *dp)
{
- struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
-
if (dp->dpms_mode == DRM_MODE_DPMS_ON)
return;

- if (dp->panel) {
- if (drm_panel_prepare(dp->panel)) {
+ if (dp->plat_data && dp->plat_data->panel) {
+ if (drm_panel_prepare(dp->plat_data->panel)) {
DRM_ERROR("failed to setup the panel\n");
return;
}
}

- if (crtc->ops->clock_enable)
- crtc->ops->clock_enable(dp_to_crtc(dp), true);
+ if (dp->plat_data && dp->plat_data->power_on)
+ dp->plat_data->power_on(dp->plat_data);

clk_prepare_enable(dp->clock);
- exynos_dp_phy_init(dp);
- exynos_dp_init_dp(dp);
+ analogix_dp_phy_init(dp);
+ analogix_dp_init_dp(dp);
enable_irq(dp->irq);
- exynos_dp_commit(&dp->display);
+ analogix_dp_commit(dp);
}

-static void exynos_dp_poweroff(struct exynos_dp_device *dp)
+static void analogix_dp_poweroff(struct analogix_dp_device *dp)
{
- struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
-
if (dp->dpms_mode != DRM_MODE_DPMS_ON)
return;

- if (dp->panel) {
- if (drm_panel_disable(dp->panel)) {
+ if (dp->plat_data && dp->plat_data->panel) {
+ if (drm_panel_disable(dp->plat_data->panel)) {
DRM_ERROR("failed to disable the panel\n");
return;
}
@@ -1049,39 +1025,21 @@ static void exynos_dp_poweroff(struct exynos_dp_device *dp)

disable_irq(dp->irq);
flush_work(&dp->hotplug_work);
- exynos_dp_phy_exit(dp);
+ analogix_dp_phy_exit(dp);
clk_disable_unprepare(dp->clock);

- if (crtc->ops->clock_enable)
- crtc->ops->clock_enable(dp_to_crtc(dp), false);
+ if (dp->plat_data && dp->plat_data->power_off)
+ dp->plat_data->power_off(dp->plat_data);

- if (dp->panel) {
- if (drm_panel_unprepare(dp->panel))
+ if (dp->plat_data && dp->plat_data->panel) {
+ if (drm_panel_unprepare(dp->plat_data->panel))
DRM_ERROR("failed to turnoff the panel\n");
}
}

-/* returns the number of bridges attached */
-static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
- struct drm_encoder *encoder)
+static int analogix_dp_bridge_attach(struct drm_bridge *bridge)
{
- int ret;
-
- dp->bridge->next = dp->ptn_bridge;
- dp->bridge->encoder = encoder;
- ret = drm_bridge_attach(encoder->dev, dp->bridge);
- if (ret) {
- DRM_ERROR("Failed to attach ptn bridge to drm\n");
- return ret;
- }
-
- return 0;
-}
-
-static int exynos_dp_bridge_attach(struct drm_bridge *bridge)
-{
-
- struct exynos_dp_device *dp = bridge->driver_private;
+ struct analogix_dp_device *dp = bridge->driver_private;
struct drm_encoder *encoder = dp->encoder;
struct drm_connector *connector = &dp->connector;
int ret;
@@ -1093,66 +1051,77 @@ static int exynos_dp_bridge_attach(struct drm_bridge *bridge)

encoder->bridge = bridge;

- /* Pre-empt DP connector creation if there's a bridge */
- if (dp->ptn_bridge) {
- ret = exynos_drm_attach_lcd_bridge(dp, encoder);
- if (ret)
- return -ENODEV;
- }
-
connector->polled = DRM_CONNECTOR_POLL_HPD;

ret = drm_connector_init(dp->drm_dev, connector,
- &exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
+ &analogix_dp_connector_funcs,
+ DRM_MODE_CONNECTOR_eDP);
if (ret) {
DRM_ERROR("Failed to initialize connector with drm\n");
return ret;
}

- drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
+ drm_connector_helper_add(connector,
+ &analogix_dp_connector_helper_funcs);
drm_connector_register(connector);
drm_mode_connector_attach_encoder(connector, encoder);

- if (dp->panel)
- ret = drm_panel_attach(dp->panel, &dp->connector);
+ if (dp->plat_data && dp->plat_data->panel) {
+ ret = drm_panel_attach(dp->plat_data->panel, &dp->connector);
+ if (ret) {
+ DRM_ERROR("Failed to attach panel\n");
+ return ret;
+ }
+ }
+
+ /*
+ * This should be the end of attach function, caused
+ * we should ensure dp bridge could attach first.
+ */
+ if (dp->plat_data && dp->plat_data->attach) {
+ ret = dp->plat_data->attach(dp->plat_data, bridge);
+ if (ret) {
+ DRM_ERROR("Failed at platform attch func\n");
+ return ret;
+ }
+ }

- return ret;
+ return 0;
}

-static void exynos_dp_bridge_nop(struct drm_bridge *bridge)
+static void analogix_dp_bridge_nop(struct drm_bridge *bridge)
{
/* do nothing */
}

-static void exynos_dp_bridge_enable(struct drm_bridge *bridge)
+static void analogix_dp_bridge_enable(struct drm_bridge *bridge)
{
- struct exynos_dp_device *dp = bridge->driver_private;
+ struct analogix_dp_device *dp = bridge->driver_private;

- exynos_dp_poweron(dp);
+ analogix_dp_poweron(dp);
dp->dpms_mode = DRM_MODE_DPMS_ON;
}

-static void exynos_dp_bridge_disable(struct drm_bridge *bridge)
+static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
{
- struct exynos_dp_device *dp = bridge->driver_private;
+ struct analogix_dp_device *dp = bridge->driver_private;

- exynos_dp_poweroff(dp);
+ analogix_dp_poweroff(dp);
dp->dpms_mode = DRM_MODE_DPMS_OFF;
}

-static const struct drm_bridge_funcs exynos_dp_bridge_funcs = {
- .enable = exynos_dp_bridge_enable,
- .disable = exynos_dp_bridge_disable,
- .pre_enable = exynos_dp_bridge_nop,
- .post_disable = exynos_dp_bridge_nop,
- .attach = exynos_dp_bridge_attach,
+static const struct drm_bridge_funcs analogix_dp_bridge_funcs = {
+ .enable = analogix_dp_bridge_enable,
+ .disable = analogix_dp_bridge_disable,
+ .pre_enable = analogix_dp_bridge_nop,
+ .post_disable = analogix_dp_bridge_nop,
+ .attach = analogix_dp_bridge_attach,
};

-static int exynos_dp_create_connector(struct exynos_drm_display *display,
- struct drm_encoder *encoder)
+static int analogix_dp_bridge_register(struct drm_device *drm_dev,
+ struct analogix_dp_device *dp)
+
{
- struct exynos_dp_device *dp = display_to_dp(display);
- struct drm_device *drm_dev = dp->drm_dev;
struct drm_bridge *bridge;
int ret;

@@ -1163,11 +1132,10 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display,
}

dp->bridge = bridge;
- dp->encoder = encoder;

bridge->driver_private = dp;
bridge->encoder = dp->encoder;
- bridge->funcs = &exynos_dp_bridge_funcs;
+ bridge->funcs = &analogix_dp_bridge_funcs;

ret = drm_bridge_attach(drm_dev, bridge);
if (ret) {
@@ -1178,18 +1146,7 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display,
return 0;
}

-static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
-{
- /* do nothing */
-}
-
-static struct exynos_drm_display_ops exynos_dp_display_ops = {
- .create_connector = exynos_dp_create_connector,
- .dpms = exynos_dp_dpms,
- .commit = exynos_dp_commit,
-};
-
-static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
+static struct video_info *analogix_dp_dt_parse_pdata(struct device *dev)
{
struct device_node *dp_node = dev->of_node;
struct video_info *dp_video_config;
@@ -1208,37 +1165,37 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
dp_video_config->interlaced =
of_property_read_bool(dp_node, "interlaced");

- if (of_property_read_u32(dp_node, "samsung,color-space",
+ if (of_property_read_u32(dp_node, "analogix,color-space",
&dp_video_config->color_space)) {
dev_err(dev, "failed to get color-space\n");
return ERR_PTR(-EINVAL);
}

- if (of_property_read_u32(dp_node, "samsung,dynamic-range",
+ if (of_property_read_u32(dp_node, "analogix,dynamic-range",
&dp_video_config->dynamic_range)) {
dev_err(dev, "failed to get dynamic-range\n");
return ERR_PTR(-EINVAL);
}

- if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
+ if (of_property_read_u32(dp_node, "analogix,ycbcr-coeff",
&dp_video_config->ycbcr_coeff)) {
dev_err(dev, "failed to get ycbcr-coeff\n");
return ERR_PTR(-EINVAL);
}

- if (of_property_read_u32(dp_node, "samsung,color-depth",
+ if (of_property_read_u32(dp_node, "analogix,color-depth",
&dp_video_config->color_depth)) {
dev_err(dev, "failed to get color-depth\n");
return ERR_PTR(-EINVAL);
}

- if (of_property_read_u32(dp_node, "samsung,link-rate",
+ if (of_property_read_u32(dp_node, "analogix,link-rate",
&dp_video_config->link_rate)) {
dev_err(dev, "failed to get link-rate\n");
return ERR_PTR(-EINVAL);
}

- if (of_property_read_u32(dp_node, "samsung,lane-count",
+ if (of_property_read_u32(dp_node, "analogix,lane-count",
&dp_video_config->lane_count)) {
dev_err(dev, "failed to get lane-count\n");
return ERR_PTR(-EINVAL);
@@ -1247,32 +1204,33 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
return dp_video_config;
}

-static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
+int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
+ struct drm_encoder *encoder,
+ struct analogix_dp_plat_data *plat_data)
{
- int ret;
-
- ret = of_get_videomode(dp->dev->of_node, &dp->priv.vm,
- OF_USE_NATIVE_MODE);
- if (ret) {
- DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
- return ret;
- }
- return 0;
-}
-
-static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
-{
- struct exynos_dp_device *dp = dev_get_drvdata(dev);
struct platform_device *pdev = to_platform_device(dev);
- struct drm_device *drm_dev = data;
+ struct analogix_dp_device *dp;
struct resource *res;
unsigned int irq_flags;
int ret = 0;

+ dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL);
+ if (!dp)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, dp);
+
dp->dev = &pdev->dev;
dp->dpms_mode = DRM_MODE_DPMS_OFF;

- dp->video_info = exynos_dp_dt_parse_pdata(&pdev->dev);
+ /*
+ * platform dp driver need containor_of the plat_data to get
+ * the driver private data, so we need to store the point of
+ * plat_data, not the context of plat_data.
+ */
+ dp->plat_data = plat_data;
+
+ dp->video_info = analogix_dp_dt_parse_pdata(&pdev->dev);
if (IS_ERR(dp->video_info))
return PTR_ERR(dp->video_info);

@@ -1292,12 +1250,6 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
}
}

- if (!dp->panel && !dp->ptn_bridge) {
- ret = exynos_dp_dt_parse_panel(dp);
- if (ret)
- return ret;
- }
-
dp->clock = devm_clk_get(&pdev->dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(&pdev->dev, "failed to get clock\n");
@@ -1312,7 +1264,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
if (IS_ERR(dp->reg_base))
return PTR_ERR(dp->reg_base);

- dp->hpd_gpio = of_get_named_gpio(dev->of_node, "samsung,hpd-gpio", 0);
+ dp->hpd_gpio = of_get_named_gpio(dev->of_node, "analogix,hpd-gpio", 0);

if (gpio_is_valid(dp->hpd_gpio)) {
/*
@@ -1341,14 +1293,14 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
return -ENODEV;
}

- INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
+ INIT_WORK(&dp->hotplug_work, analogix_dp_hotplug);

- exynos_dp_phy_init(dp);
+ analogix_dp_phy_init(dp);

- exynos_dp_init_dp(dp);
+ analogix_dp_init_dp(dp);

- ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
- irq_flags, "exynos-dp", dp);
+ ret = devm_request_irq(&pdev->dev, dp->irq, analogix_dp_irq_handler,
+ irq_flags, "analogix-dp", dp);
if (ret) {
dev_err(&pdev->dev, "failed to request irq\n");
return ret;
@@ -1356,108 +1308,38 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
disable_irq(dp->irq);

dp->drm_dev = drm_dev;
+ dp->encoder = encoder;

- return exynos_drm_create_enc_conn(drm_dev, &dp->display);
-}
-
-static void exynos_dp_unbind(struct device *dev, struct device *master,
- void *data)
-{
- struct exynos_dp_device *dp = dev_get_drvdata(dev);
-
- exynos_dp_bridge_disable(dp->bridge);
-}
-
-static const struct component_ops exynos_dp_ops = {
- .bind = exynos_dp_bind,
- .unbind = exynos_dp_unbind,
-};
-
-static int exynos_dp_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct device_node *panel_node, *bridge_node, *endpoint;
- struct exynos_dp_device *dp;
-
- dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
- GFP_KERNEL);
- if (!dp)
- return -ENOMEM;
-
- dp->display.type = EXYNOS_DISPLAY_TYPE_LCD;
- dp->display.ops = &exynos_dp_display_ops;
- platform_set_drvdata(pdev, dp);
-
- panel_node = of_parse_phandle(dev->of_node, "panel", 0);
- if (panel_node) {
- dp->panel = of_drm_find_panel(panel_node);
- of_node_put(panel_node);
- if (!dp->panel)
- return -EPROBE_DEFER;
- }
-
- endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
- if (endpoint) {
- bridge_node = of_graph_get_remote_port_parent(endpoint);
- if (bridge_node) {
- dp->ptn_bridge = of_drm_find_bridge(bridge_node);
- of_node_put(bridge_node);
- if (!dp->ptn_bridge)
- return -EPROBE_DEFER;
- } else {
- return -EPROBE_DEFER;
- }
- }
-
- return component_add(&pdev->dev, &exynos_dp_ops);
+ return analogix_dp_bridge_register(drm_dev, dp);
}
+EXPORT_SYMBOL_GPL(analogix_dp_bind);

-static int exynos_dp_remove(struct platform_device *pdev)
+void analogix_dp_unbind(struct device *dev, struct device *master, void *data)
{
- component_del(&pdev->dev, &exynos_dp_ops);
+ struct analogix_dp_device *dp = dev_get_drvdata(dev);

- return 0;
+ analogix_dp_bridge_disable(dp->bridge);
}
+EXPORT_SYMBOL_GPL(analogix_dp_unbind);

-#ifdef CONFIG_PM_SLEEP
-static int exynos_dp_suspend(struct device *dev)
+int analogix_dp_suspend(struct device *dev)
{
- struct exynos_dp_device *dp = dev_get_drvdata(dev);
+ struct analogix_dp_device *dp = dev_get_drvdata(dev);

- exynos_dp_bridge_disable(dp->bridge);
+ analogix_dp_bridge_disable(dp->bridge);
return 0;
}
+EXPORT_SYMBOL_GPL(analogix_dp_suspend);

-static int exynos_dp_resume(struct device *dev)
+int analogix_dp_resume(struct device *dev)
{
- struct exynos_dp_device *dp = dev_get_drvdata(dev);
+ struct analogix_dp_device *dp = dev_get_drvdata(dev);

- exynos_dp_bridge_enable(dp->bridge);
+ analogix_dp_bridge_enable(dp->bridge);
return 0;
}
-#endif
-
-static const struct dev_pm_ops exynos_dp_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
-};
-
-static const struct of_device_id exynos_dp_match[] = {
- { .compatible = "samsung,exynos5-dp" },
- {},
-};
-MODULE_DEVICE_TABLE(of, exynos_dp_match);
-
-struct platform_driver dp_driver = {
- .probe = exynos_dp_probe,
- .remove = exynos_dp_remove,
- .driver = {
- .name = "exynos-dp",
- .owner = THIS_MODULE,
- .pm = &exynos_dp_pm_ops,
- .of_match_table = exynos_dp_match,
- },
-};
+EXPORT_SYMBOL_GPL(analogix_dp_resume);

MODULE_AUTHOR("Jingoo Han <[email protected]>");
-MODULE_DESCRIPTION("Samsung SoC DP Driver");
+MODULE_DESCRIPTION("Analogix Core DP Driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
new file mode 100644
index 0000000..2cefde9
--- /dev/null
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
@@ -0,0 +1,282 @@
+/*
+ * Header file for Samsung DP (Display Port) interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef _ANALOGIX_DP_CORE_H
+#define _ANALOGIX_DP_CORE_H
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_dp_helper.h>
+
+#define DP_TIMEOUT_LOOP_COUNT 100
+#define MAX_CR_LOOP 5
+#define MAX_EQ_LOOP 5
+
+enum link_rate_type {
+ LINK_RATE_1_62GBPS = 0x06,
+ LINK_RATE_2_70GBPS = 0x0a
+};
+
+enum link_lane_count_type {
+ LANE_COUNT1 = 1,
+ LANE_COUNT2 = 2,
+ LANE_COUNT4 = 4
+};
+
+enum link_training_state {
+ START,
+ CLOCK_RECOVERY,
+ EQUALIZER_TRAINING,
+ FINISHED,
+ FAILED
+};
+
+enum voltage_swing_level {
+ VOLTAGE_LEVEL_0,
+ VOLTAGE_LEVEL_1,
+ VOLTAGE_LEVEL_2,
+ VOLTAGE_LEVEL_3,
+};
+
+enum pre_emphasis_level {
+ PRE_EMPHASIS_LEVEL_0,
+ PRE_EMPHASIS_LEVEL_1,
+ PRE_EMPHASIS_LEVEL_2,
+ PRE_EMPHASIS_LEVEL_3,
+};
+
+enum pattern_set {
+ PRBS7,
+ D10_2,
+ TRAINING_PTN1,
+ TRAINING_PTN2,
+ DP_NONE
+};
+
+enum color_space {
+ COLOR_RGB,
+ COLOR_YCBCR422,
+ COLOR_YCBCR444
+};
+
+enum color_depth {
+ COLOR_6,
+ COLOR_8,
+ COLOR_10,
+ COLOR_12
+};
+
+enum color_coefficient {
+ COLOR_YCBCR601,
+ COLOR_YCBCR709
+};
+
+enum dynamic_range {
+ VESA,
+ CEA
+};
+
+enum pll_status {
+ PLL_UNLOCKED,
+ PLL_LOCKED
+};
+
+enum clock_recovery_m_value_type {
+ CALCULATED_M,
+ REGISTER_M
+};
+
+enum video_timing_recognition_type {
+ VIDEO_TIMING_FROM_CAPTURE,
+ VIDEO_TIMING_FROM_REGISTER
+};
+
+enum analog_power_block {
+ AUX_BLOCK,
+ CH0_BLOCK,
+ CH1_BLOCK,
+ CH2_BLOCK,
+ CH3_BLOCK,
+ ANALOG_TOTAL,
+ POWER_ALL
+};
+
+enum dp_irq_type {
+ DP_IRQ_TYPE_HP_CABLE_IN,
+ DP_IRQ_TYPE_HP_CABLE_OUT,
+ DP_IRQ_TYPE_HP_CHANGE,
+ DP_IRQ_TYPE_UNKNOWN,
+};
+
+struct video_info {
+ char *name;
+
+ bool h_sync_polarity;
+ bool v_sync_polarity;
+ bool interlaced;
+
+ enum color_space color_space;
+ enum dynamic_range dynamic_range;
+ enum color_coefficient ycbcr_coeff;
+ enum color_depth color_depth;
+
+ enum link_rate_type link_rate;
+ enum link_lane_count_type lane_count;
+};
+
+struct link_train {
+ int eq_loop;
+ int cr_loop[4];
+
+ u8 link_rate;
+ u8 lane_count;
+ u8 training_lane[4];
+
+ enum link_training_state lt_state;
+};
+
+struct analogix_dp_device {
+ struct device *dev;
+ struct drm_device *drm_dev;
+ struct drm_connector connector;
+ struct drm_encoder *encoder;
+ struct drm_bridge *bridge;
+ struct clk *clock;
+ unsigned int irq;
+ void __iomem *reg_base;
+
+ struct video_info *video_info;
+ struct link_train link_train;
+ struct work_struct hotplug_work;
+ struct phy *phy;
+ int dpms_mode;
+ int hpd_gpio;
+
+ struct analogix_dp_plat_data *plat_data;
+};
+
+/* analogix_dp_reg.c */
+void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable);
+void analogix_dp_stop_video(struct analogix_dp_device *dp);
+void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable);
+void analogix_dp_init_analog_param(struct analogix_dp_device *dp);
+void analogix_dp_init_interrupt(struct analogix_dp_device *dp);
+void analogix_dp_reset(struct analogix_dp_device *dp);
+void analogix_dp_swreset(struct analogix_dp_device *dp);
+void analogix_dp_config_interrupt(struct analogix_dp_device *dp);
+enum pll_status analogix_dp_get_pll_lock_status(struct analogix_dp_device *dp);
+void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable);
+void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
+ enum analog_power_block block,
+ bool enable);
+void analogix_dp_init_analog_func(struct analogix_dp_device *dp);
+void analogix_dp_init_hpd(struct analogix_dp_device *dp);
+enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp);
+void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp);
+void analogix_dp_reset_aux(struct analogix_dp_device *dp);
+void analogix_dp_init_aux(struct analogix_dp_device *dp);
+int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp);
+void analogix_dp_enable_sw_function(struct analogix_dp_device *dp);
+int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp);
+int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp,
+ unsigned int reg_addr,
+ unsigned char data);
+int analogix_dp_read_byte_from_dpcd(struct analogix_dp_device *dp,
+ unsigned int reg_addr,
+ unsigned char *data);
+int analogix_dp_write_bytes_to_dpcd(struct analogix_dp_device *dp,
+ unsigned int reg_addr,
+ unsigned int count,
+ unsigned char data[]);
+int analogix_dp_read_bytes_from_dpcd(struct analogix_dp_device *dp,
+ unsigned int reg_addr,
+ unsigned int count,
+ unsigned char data[]);
+int analogix_dp_select_i2c_device(struct analogix_dp_device *dp,
+ unsigned int device_addr,
+ unsigned int reg_addr);
+int analogix_dp_read_byte_from_i2c(struct analogix_dp_device *dp,
+ unsigned int device_addr,
+ unsigned int reg_addr,
+ unsigned int *data);
+int analogix_dp_read_bytes_from_i2c(struct analogix_dp_device *dp,
+ unsigned int device_addr,
+ unsigned int reg_addr,
+ unsigned int count,
+ unsigned char edid[]);
+void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype);
+void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype);
+void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count);
+void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count);
+void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp,
+ bool enable);
+void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
+ enum pattern_set pattern);
+void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
+ u32 level);
+void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
+ u32 level);
+void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
+ u32 level);
+void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
+ u32 level);
+void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
+ u32 training_lane);
+void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
+ u32 training_lane);
+void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
+ u32 training_lane);
+void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
+ u32 training_lane);
+u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp);
+u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp);
+u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp);
+u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp);
+void analogix_dp_reset_macro(struct analogix_dp_device *dp);
+void analogix_dp_init_video(struct analogix_dp_device *dp);
+
+void analogix_dp_set_video_color_format(struct analogix_dp_device *dp);
+int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp);
+void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp,
+ enum clock_recovery_m_value_type type,
+ u32 m_value, u32 n_value);
+void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type);
+void analogix_dp_enable_video_master(struct analogix_dp_device *dp,
+ bool enable);
+void analogix_dp_start_video(struct analogix_dp_device *dp);
+int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp);
+void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp);
+void analogix_dp_enable_scrambling(struct analogix_dp_device *dp);
+void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
+
+/* I2C EDID Chip ID, Slave Address */
+#define I2C_EDID_DEVICE_ADDR 0x50
+#define I2C_E_EDID_DEVICE_ADDR 0x30
+
+#define EDID_BLOCK_LENGTH 0x80
+#define EDID_HEADER_PATTERN 0x00
+#define EDID_EXTENSION_FLAG 0x7e
+#define EDID_CHECKSUM 0x7f
+
+/* DP_MAX_LANE_COUNT */
+#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
+#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
+
+/* DP_LANE_COUNT_SET */
+#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f)
+
+/* DP_TRAINING_LANE0_SET */
+#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3)
+#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3)
+#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0)
+#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3)
+
+#endif /* _ANALOGIX_DP_CORE_H */
diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix_dp_reg.c
new file mode 100644
index 0000000..cc5cdbf
--- /dev/null
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.c
@@ -0,0 +1,1265 @@
+/*
+ * Samsung DP (Display port) register interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include "analogix_dp_core.h"
+#include "analogix_dp_reg.h"
+
+#define COMMON_INT_MASK_1 0
+#define COMMON_INT_MASK_2 0
+#define COMMON_INT_MASK_3 0
+#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
+#define INT_STA_MASK INT_HPD
+
+void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable)
+{
+ u32 reg;
+
+ if (enable) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
+ reg |= HDCP_VIDEO_MUTE;
+ writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
+ reg &= ~HDCP_VIDEO_MUTE;
+ writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
+ }
+}
+
+void analogix_dp_stop_video(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
+ reg &= ~VIDEO_EN;
+ writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
+}
+
+void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable)
+{
+ u32 reg;
+
+ if (enable)
+ reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
+ LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
+ else
+ reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
+ LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
+
+ writel(reg, dp->reg_base + ANALOGIX_DP_LANE_MAP);
+}
+
+void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = TX_TERMINAL_CTRL_50_OHM;
+ writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_1);
+
+ reg = SEL_24M | TX_DVDD_BIT_1_0625V;
+ writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
+
+ reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
+ writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3);
+
+ reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
+ TX_CUR1_2X | TX_CUR_16_MA;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PLL_FILTER_CTL_1);
+
+ reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
+ CH1_AMP_400_MV | CH0_AMP_400_MV;
+ writel(reg, dp->reg_base + ANALOGIX_DP_TX_AMP_TUNING_CTL);
+}
+
+void analogix_dp_init_interrupt(struct analogix_dp_device *dp)
+{
+ /* Set interrupt pin assertion polarity as high */
+ writel(INT_POL1 | INT_POL0, dp->reg_base + ANALOGIX_DP_INT_CTL);
+
+ /* Clear pending regisers */
+ writel(0xff, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
+ writel(0x4f, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_2);
+ writel(0xe0, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_3);
+ writel(0xe7, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
+ writel(0x63, dp->reg_base + ANALOGIX_DP_INT_STA);
+
+ /* 0:mask,1: unmask */
+ writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
+ writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
+ writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
+ writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
+ writel(0x00, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
+}
+
+void analogix_dp_reset(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ analogix_dp_stop_video(dp);
+ analogix_dp_enable_video_mute(dp, 0);
+
+ reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
+ AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
+ HDCP_FUNC_EN_N | SW_FUNC_EN_N;
+ writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
+
+ reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
+ SERDES_FIFO_FUNC_EN_N |
+ LS_CLK_DOMAIN_FUNC_EN_N;
+ writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
+
+ usleep_range(20, 30);
+
+ analogix_dp_lane_swap(dp, 0);
+
+ writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
+ writel(0x40, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
+ writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+ writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
+
+ writel(0x0, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
+ writel(0x0, dp->reg_base + ANALOGIX_DP_HDCP_CTL);
+
+ writel(0x5e, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_L);
+ writel(0x1a, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_H);
+
+ writel(0x10, dp->reg_base + ANALOGIX_DP_LINK_DEBUG_CTL);
+
+ writel(0x0, dp->reg_base + ANALOGIX_DP_PHY_TEST);
+
+ writel(0x0, dp->reg_base + ANALOGIX_DP_VIDEO_FIFO_THRD);
+ writel(0x20, dp->reg_base + ANALOGIX_DP_AUDIO_MARGIN);
+
+ writel(0x4, dp->reg_base + ANALOGIX_DP_M_VID_GEN_FILTER_TH);
+ writel(0x2, dp->reg_base + ANALOGIX_DP_M_AUD_GEN_FILTER_TH);
+
+ writel(0x00000101, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
+}
+
+void analogix_dp_swreset(struct analogix_dp_device *dp)
+{
+ writel(RESET_DP_TX, dp->reg_base + ANALOGIX_DP_TX_SW_RESET);
+}
+
+void analogix_dp_config_interrupt(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ /* 0: mask, 1: unmask */
+ reg = COMMON_INT_MASK_1;
+ writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
+
+ reg = COMMON_INT_MASK_2;
+ writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
+
+ reg = COMMON_INT_MASK_3;
+ writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
+
+ reg = COMMON_INT_MASK_4;
+ writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
+
+ reg = INT_STA_MASK;
+ writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
+}
+
+enum pll_status analogix_dp_get_pll_lock_status(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
+ if (reg & PLL_LOCK)
+ return PLL_LOCKED;
+ else
+ return PLL_UNLOCKED;
+}
+
+void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable)
+{
+ u32 reg;
+
+ if (enable) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
+ reg |= DP_PLL_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
+ reg &= ~DP_PLL_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
+ }
+}
+
+void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
+ enum analog_power_block block,
+ bool enable)
+{
+ u32 reg;
+
+ switch (block) {
+ case AUX_BLOCK:
+ if (enable) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg |= AUX_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg &= ~AUX_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ }
+ break;
+ case CH0_BLOCK:
+ if (enable) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg |= CH0_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg &= ~CH0_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ }
+ break;
+ case CH1_BLOCK:
+ if (enable) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg |= CH1_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg &= ~CH1_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ }
+ break;
+ case CH2_BLOCK:
+ if (enable) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg |= CH2_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg &= ~CH2_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ }
+ break;
+ case CH3_BLOCK:
+ if (enable) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg |= CH3_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg &= ~CH3_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ }
+ break;
+ case ANALOG_TOTAL:
+ if (enable) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg |= DP_PHY_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg &= ~DP_PHY_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ }
+ break;
+ case POWER_ALL:
+ if (enable) {
+ reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
+ CH1_PD | CH0_PD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ } else {
+ writel(0x00, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void analogix_dp_init_analog_func(struct analogix_dp_device *dp)
+{
+ u32 reg;
+ int timeout_loop = 0;
+
+ analogix_dp_set_analog_power_down(dp, POWER_ALL, 0);
+
+ reg = PLL_LOCK_CHG;
+ writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
+ reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
+ writel(reg, dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
+
+ /* Power up PLL */
+ if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
+ analogix_dp_set_pll_power_down(dp, 0);
+
+ while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
+ timeout_loop++;
+ if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
+ dev_err(dp->dev, "failed to get pll lock status\n");
+ return;
+ }
+ usleep_range(10, 20);
+ }
+ }
+
+ /* Enable Serdes FIFO function and Link symbol clock domain module */
+ reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
+ reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
+ | AUX_FUNC_EN_N);
+ writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
+}
+
+void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ if (gpio_is_valid(dp->hpd_gpio))
+ return;
+
+ reg = HOTPLUG_CHG | HPD_LOST | PLUG;
+ writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
+
+ reg = INT_HPD;
+ writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
+}
+
+void analogix_dp_init_hpd(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ if (gpio_is_valid(dp->hpd_gpio))
+ return;
+
+ analogix_dp_clear_hotplug_interrupts(dp);
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+ reg &= ~(F_HPD | HPD_CTRL);
+ writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+}
+
+enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ if (gpio_is_valid(dp->hpd_gpio)) {
+ reg = gpio_get_value(dp->hpd_gpio);
+ if (reg)
+ return DP_IRQ_TYPE_HP_CABLE_IN;
+ else
+ return DP_IRQ_TYPE_HP_CABLE_OUT;
+ } else {
+ /* Parse hotplug interrupt status register */
+ reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
+
+ if (reg & PLUG)
+ return DP_IRQ_TYPE_HP_CABLE_IN;
+
+ if (reg & HPD_LOST)
+ return DP_IRQ_TYPE_HP_CABLE_OUT;
+
+ if (reg & HOTPLUG_CHG)
+ return DP_IRQ_TYPE_HP_CHANGE;
+
+ return DP_IRQ_TYPE_UNKNOWN;
+ }
+}
+
+void analogix_dp_reset_aux(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ /* Disable AUX channel module */
+ reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
+ reg |= AUX_FUNC_EN_N;
+ writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
+}
+
+void analogix_dp_init_aux(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ /* Clear inerrupts related to AUX channel */
+ reg = RPLY_RECEIV | AUX_ERR;
+ writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
+
+ analogix_dp_reset_aux(dp);
+
+ /* Disable AUX transaction H/W retry */
+ reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
+ AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
+
+ /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
+ reg = DEFER_CTRL_EN | DEFER_COUNT(1);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_DEFER_CTL);
+
+ /* Enable AUX channel module */
+ reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
+ reg &= ~AUX_FUNC_EN_N;
+ writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
+}
+
+int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ if (gpio_is_valid(dp->hpd_gpio)) {
+ if (gpio_get_value(dp->hpd_gpio))
+ return 0;
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+ if (reg & HPD_STATUS)
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
+ reg &= ~SW_FUNC_EN_N;
+ writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
+}
+
+int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp)
+{
+ int reg;
+ int retval = 0;
+ int timeout_loop = 0;
+
+ /* Enable AUX CH operation */
+ reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
+ reg |= AUX_EN;
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
+
+ /* Is AUX CH command reply received? */
+ reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
+ while (!(reg & RPLY_RECEIV)) {
+ timeout_loop++;
+ if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
+ dev_err(dp->dev, "AUX CH command reply failed!\n");
+ return -ETIMEDOUT;
+ }
+ reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
+ usleep_range(10, 11);
+ }
+
+ /* Clear interrupt source for AUX CH command reply */
+ writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
+
+ /* Clear interrupt source for AUX CH access error */
+ reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
+ if (reg & AUX_ERR) {
+ writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
+ return -EREMOTEIO;
+ }
+
+ /* Check AUX CH error access status */
+ reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
+ if ((reg & AUX_STATUS_MASK) != 0) {
+ dev_err(dp->dev, "AUX CH error happens: %d\n\n",
+ reg & AUX_STATUS_MASK);
+ return -EREMOTEIO;
+ }
+
+ return retval;
+}
+
+int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp,
+ unsigned int reg_addr,
+ unsigned char data)
+{
+ u32 reg;
+ int i;
+ int retval;
+
+ for (i = 0; i < 3; i++) {
+ /* Clear AUX CH data buffer */
+ reg = BUF_CLR;
+ writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
+
+ /* Select DPCD device address */
+ reg = AUX_ADDR_7_0(reg_addr);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
+ reg = AUX_ADDR_15_8(reg_addr);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
+ reg = AUX_ADDR_19_16(reg_addr);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
+
+ /* Write data buffer */
+ reg = (unsigned int)data;
+ writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
+
+ /*
+ * Set DisplayPort transaction and write 1 byte
+ * If bit 3 is 1, DisplayPort transaction.
+ * If Bit 3 is 0, I2C transaction.
+ */
+ reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
+
+ /* Start AUX transaction */
+ retval = analogix_dp_start_aux_transaction(dp);
+ if (retval == 0)
+ break;
+
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
+ }
+
+ return retval;
+}
+
+int analogix_dp_read_byte_from_dpcd(struct analogix_dp_device *dp,
+ unsigned int reg_addr,
+ unsigned char *data)
+{
+ u32 reg;
+ int i;
+ int retval;
+
+ for (i = 0; i < 3; i++) {
+ /* Clear AUX CH data buffer */
+ reg = BUF_CLR;
+ writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
+
+ /* Select DPCD device address */
+ reg = AUX_ADDR_7_0(reg_addr);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
+ reg = AUX_ADDR_15_8(reg_addr);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
+ reg = AUX_ADDR_19_16(reg_addr);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
+
+ /*
+ * Set DisplayPort transaction and read 1 byte
+ * If bit 3 is 1, DisplayPort transaction.
+ * If Bit 3 is 0, I2C transaction.
+ */
+ reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
+
+ /* Start AUX transaction */
+ retval = analogix_dp_start_aux_transaction(dp);
+ if (retval == 0)
+ break;
+
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
+ }
+
+ /* Read data buffer */
+ reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
+ *data = (unsigned char)(reg & 0xff);
+
+ return retval;
+}
+
+int analogix_dp_write_bytes_to_dpcd(struct analogix_dp_device *dp,
+ unsigned int reg_addr,
+ unsigned int count,
+ unsigned char data[])
+{
+ u32 reg;
+ unsigned int start_offset;
+ unsigned int cur_data_count;
+ unsigned int cur_data_idx;
+ int i;
+ int retval = 0;
+
+ /* Clear AUX CH data buffer */
+ reg = BUF_CLR;
+ writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
+
+ start_offset = 0;
+ while (start_offset < count) {
+ /* Buffer size of AUX CH is 16 * 4bytes */
+ if ((count - start_offset) > 16)
+ cur_data_count = 16;
+ else
+ cur_data_count = count - start_offset;
+
+ for (i = 0; i < 3; i++) {
+ /* Select DPCD device address */
+ reg = AUX_ADDR_7_0(reg_addr + start_offset);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
+ reg = AUX_ADDR_15_8(reg_addr + start_offset);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
+ reg = AUX_ADDR_19_16(reg_addr + start_offset);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
+
+ for (cur_data_idx = 0; cur_data_idx < cur_data_count;
+ cur_data_idx++) {
+ reg = data[start_offset + cur_data_idx];
+ writel(reg, dp->reg_base +
+ ANALOGIX_DP_BUF_DATA_0 +
+ 4 * cur_data_idx);
+ }
+
+ /*
+ * Set DisplayPort transaction and write
+ * If bit 3 is 1, DisplayPort transaction.
+ * If Bit 3 is 0, I2C transaction.
+ */
+ reg = AUX_LENGTH(cur_data_count) |
+ AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
+
+ /* Start AUX transaction */
+ retval = analogix_dp_start_aux_transaction(dp);
+ if (retval == 0)
+ break;
+
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
+ }
+
+ start_offset += cur_data_count;
+ }
+
+ return retval;
+}
+
+int analogix_dp_read_bytes_from_dpcd(struct analogix_dp_device *dp,
+ unsigned int reg_addr,
+ unsigned int count,
+ unsigned char data[])
+{
+ u32 reg;
+ unsigned int start_offset;
+ unsigned int cur_data_count;
+ unsigned int cur_data_idx;
+ int i;
+ int retval = 0;
+
+ /* Clear AUX CH data buffer */
+ reg = BUF_CLR;
+ writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
+
+ start_offset = 0;
+ while (start_offset < count) {
+ /* Buffer size of AUX CH is 16 * 4bytes */
+ if ((count - start_offset) > 16)
+ cur_data_count = 16;
+ else
+ cur_data_count = count - start_offset;
+
+ /* AUX CH Request Transaction process */
+ for (i = 0; i < 3; i++) {
+ /* Select DPCD device address */
+ reg = AUX_ADDR_7_0(reg_addr + start_offset);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
+ reg = AUX_ADDR_15_8(reg_addr + start_offset);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
+ reg = AUX_ADDR_19_16(reg_addr + start_offset);
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
+
+ /*
+ * Set DisplayPort transaction and read
+ * If bit 3 is 1, DisplayPort transaction.
+ * If Bit 3 is 0, I2C transaction.
+ */
+ reg = AUX_LENGTH(cur_data_count) |
+ AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
+
+ /* Start AUX transaction */
+ retval = analogix_dp_start_aux_transaction(dp);
+ if (retval == 0)
+ break;
+
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
+ }
+
+ for (cur_data_idx = 0; cur_data_idx < cur_data_count;
+ cur_data_idx++) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0
+ + 4 * cur_data_idx);
+ data[start_offset + cur_data_idx] =
+ (unsigned char)reg;
+ }
+
+ start_offset += cur_data_count;
+ }
+
+ return retval;
+}
+
+int analogix_dp_select_i2c_device(struct analogix_dp_device *dp,
+ unsigned int device_addr,
+ unsigned int reg_addr)
+{
+ u32 reg;
+ int retval;
+
+ /* Set EDID device address */
+ reg = device_addr;
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
+ writel(0x0, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
+ writel(0x0, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
+
+ /* Set offset from base address of EDID device */
+ writel(reg_addr, dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
+
+ /*
+ * Set I2C transaction and write address
+ * If bit 3 is 1, DisplayPort transaction.
+ * If Bit 3 is 0, I2C transaction.
+ */
+ reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT |
+ AUX_TX_COMM_WRITE;
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
+
+ /* Start AUX transaction */
+ retval = analogix_dp_start_aux_transaction(dp);
+ if (retval != 0)
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
+
+ return retval;
+}
+
+int analogix_dp_read_byte_from_i2c(struct analogix_dp_device *dp,
+ unsigned int device_addr,
+ unsigned int reg_addr,
+ unsigned int *data)
+{
+ u32 reg;
+ int i;
+ int retval;
+
+ for (i = 0; i < 3; i++) {
+ /* Clear AUX CH data buffer */
+ reg = BUF_CLR;
+ writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
+
+ /* Select EDID device */
+ retval = analogix_dp_select_i2c_device(dp, device_addr,
+ reg_addr);
+ if (retval != 0)
+ continue;
+
+ /*
+ * Set I2C transaction and read data
+ * If bit 3 is 1, DisplayPort transaction.
+ * If Bit 3 is 0, I2C transaction.
+ */
+ reg = AUX_TX_COMM_I2C_TRANSACTION |
+ AUX_TX_COMM_READ;
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
+
+ /* Start AUX transaction */
+ retval = analogix_dp_start_aux_transaction(dp);
+ if (retval == 0)
+ break;
+
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
+ }
+
+ /* Read data */
+ if (retval == 0)
+ *data = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
+
+ return retval;
+}
+
+int analogix_dp_read_bytes_from_i2c(struct analogix_dp_device *dp,
+ unsigned int device_addr,
+ unsigned int reg_addr,
+ unsigned int count,
+ unsigned char edid[])
+{
+ u32 reg;
+ unsigned int i, j;
+ unsigned int cur_data_idx;
+ unsigned int defer = 0;
+ int retval = 0;
+
+ for (i = 0; i < count; i += 16) {
+ for (j = 0; j < 3; j++) {
+ /* Clear AUX CH data buffer */
+ reg = BUF_CLR;
+ writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
+
+ /* Set normal AUX CH command */
+ reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
+ reg &= ~ADDR_ONLY;
+ writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
+
+ /*
+ * If Rx sends defer, Tx sends only reads
+ * request without sending address
+ */
+ if (!defer)
+ retval = analogix_dp_select_i2c_device(
+ dp, device_addr, reg_addr + i);
+ else
+ defer = 0;
+
+ if (retval == 0) {
+ /*
+ * Set I2C transaction and write data
+ * If bit 3 is 1, DisplayPort transaction.
+ * If Bit 3 is 0, I2C transaction.
+ */
+ reg = AUX_LENGTH(16) |
+ AUX_TX_COMM_I2C_TRANSACTION |
+ AUX_TX_COMM_READ;
+ writel(reg, dp->reg_base +
+ ANALOGIX_DP_AUX_CH_CTL_1);
+
+ /* Start AUX transaction */
+ retval = analogix_dp_start_aux_transaction(dp);
+ if (retval == 0)
+ break;
+
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
+ }
+ /* Check if Rx sends defer */
+ reg = readl(dp->reg_base + ANALOGIX_DP_AUX_RX_COMM);
+ if (reg == AUX_RX_COMM_AUX_DEFER ||
+ reg == AUX_RX_COMM_I2C_DEFER) {
+ dev_err(dp->dev, "Defer: %d\n\n", reg);
+ defer = 1;
+ }
+ }
+
+ for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0
+ + 4 * cur_data_idx);
+ edid[i + cur_data_idx] = (unsigned char)reg;
+ }
+ }
+
+ return retval;
+}
+
+void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
+{
+ u32 reg;
+
+ reg = bwtype;
+ if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype == LINK_RATE_1_62GBPS))
+ writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
+}
+
+void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
+ *bwtype = reg;
+}
+
+void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
+{
+ u32 reg;
+
+ reg = count;
+ writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
+}
+
+void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
+ *count = reg;
+}
+
+void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp,
+ bool enable)
+{
+ u32 reg;
+
+ if (enable) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
+ reg |= ENHANCED;
+ writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
+ reg &= ~ENHANCED;
+ writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
+ }
+}
+
+void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
+ enum pattern_set pattern)
+{
+ u32 reg;
+
+ switch (pattern) {
+ case PRBS7:
+ reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
+ writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
+ break;
+ case D10_2:
+ reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
+ writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
+ break;
+ case TRAINING_PTN1:
+ reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
+ writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
+ break;
+ case TRAINING_PTN2:
+ reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
+ writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
+ break;
+ case DP_NONE:
+ reg = SCRAMBLING_ENABLE |
+ LINK_QUAL_PATTERN_SET_DISABLE |
+ SW_TRAINING_PATTERN_SET_NORMAL;
+ writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
+ break;
+ default:
+ break;
+ }
+}
+
+void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
+ u32 level)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
+ reg &= ~PRE_EMPHASIS_SET_MASK;
+ reg |= level << PRE_EMPHASIS_SET_SHIFT;
+ writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
+}
+
+void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
+ u32 level)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
+ reg &= ~PRE_EMPHASIS_SET_MASK;
+ reg |= level << PRE_EMPHASIS_SET_SHIFT;
+ writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
+}
+
+void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
+ u32 level)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
+ reg &= ~PRE_EMPHASIS_SET_MASK;
+ reg |= level << PRE_EMPHASIS_SET_SHIFT;
+ writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
+}
+
+void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
+ u32 level)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
+ reg &= ~PRE_EMPHASIS_SET_MASK;
+ reg |= level << PRE_EMPHASIS_SET_SHIFT;
+ writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
+}
+
+void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
+ u32 training_lane)
+{
+ u32 reg;
+
+ reg = training_lane;
+ writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
+}
+
+void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
+ u32 training_lane)
+{
+ u32 reg;
+
+ reg = training_lane;
+ writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
+}
+
+void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
+ u32 training_lane)
+{
+ u32 reg;
+
+ reg = training_lane;
+ writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
+}
+
+void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
+ u32 training_lane)
+{
+ u32 reg;
+
+ reg = training_lane;
+ writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
+}
+
+u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
+ return reg;
+}
+
+u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
+ return reg;
+}
+
+u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
+ return reg;
+}
+
+u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
+ return reg;
+}
+
+void analogix_dp_reset_macro(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_PHY_TEST);
+ reg |= MACRO_RST;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
+
+ /* 10 us is the minimum reset time. */
+ usleep_range(10, 20);
+
+ reg &= ~MACRO_RST;
+ writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
+}
+
+void analogix_dp_init_video(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
+ writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
+
+ reg = 0x0;
+ writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
+
+ reg = CHA_CRI(4) | CHA_CTRL;
+ writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
+
+ reg = 0x0;
+ writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+
+ reg = VID_HRES_TH(2) | VID_VRES_TH(0);
+ writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_8);
+}
+
+void analogix_dp_set_video_color_format(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ /* Configure the input color depth, color space, dynamic range */
+ reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) |
+ (dp->video_info->color_depth << IN_BPC_SHIFT) |
+ (dp->video_info->color_space << IN_COLOR_F_SHIFT);
+ writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_2);
+
+ /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
+ reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
+ reg &= ~IN_YC_COEFFI_MASK;
+ if (dp->video_info->ycbcr_coeff)
+ reg |= IN_YC_COEFFI_ITU709;
+ else
+ reg |= IN_YC_COEFFI_ITU601;
+ writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
+}
+
+int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
+ writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
+
+ if (!(reg & DET_STA)) {
+ dev_dbg(dp->dev, "Input stream clock not detected.\n");
+ return -EINVAL;
+ }
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
+ writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
+ dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
+
+ if (reg & CHA_STA) {
+ dev_dbg(dp->dev, "Input stream clk is changing\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp,
+ enum clock_recovery_m_value_type type,
+ u32 m_value, u32 n_value)
+{
+ u32 reg;
+
+ if (type == REGISTER_M) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
+ reg |= FIX_M_VID;
+ writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
+ reg = m_value & 0xff;
+ writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_0);
+ reg = (m_value >> 8) & 0xff;
+ writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_1);
+ reg = (m_value >> 16) & 0xff;
+ writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_2);
+
+ reg = n_value & 0xff;
+ writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_0);
+ reg = (n_value >> 8) & 0xff;
+ writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_1);
+ reg = (n_value >> 16) & 0xff;
+ writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_2);
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
+ reg &= ~FIX_M_VID;
+ writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
+
+ writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_0);
+ writel(0x80, dp->reg_base + ANALOGIX_DP_N_VID_1);
+ writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_2);
+ }
+}
+
+void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type)
+{
+ u32 reg;
+
+ if (type == VIDEO_TIMING_FROM_CAPTURE) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
+ reg &= ~FORMAT_SEL;
+ writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
+ reg |= FORMAT_SEL;
+ writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
+ }
+}
+
+void analogix_dp_enable_video_master(struct analogix_dp_device *dp, bool enable)
+{
+ u32 reg;
+
+ if (enable) {
+ reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
+ reg &= ~VIDEO_MODE_MASK;
+ reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
+ writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
+ } else {
+ reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
+ reg &= ~VIDEO_MODE_MASK;
+ reg |= VIDEO_MODE_SLAVE_MODE;
+ writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
+ }
+}
+
+void analogix_dp_start_video(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
+ reg |= VIDEO_EN;
+ writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
+}
+
+int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+ writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+ if (!(reg & STRM_VALID)) {
+ dev_dbg(dp->dev, "Input video stream is not detected.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
+ reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
+ reg |= MASTER_VID_FUNC_EN_N;
+ writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
+ reg &= ~INTERACE_SCAN_CFG;
+ reg |= (dp->video_info->interlaced << 2);
+ writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
+ reg &= ~VSYNC_POLARITY_CFG;
+ reg |= (dp->video_info->v_sync_polarity << 1);
+ writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
+ reg &= ~HSYNC_POLARITY_CFG;
+ reg |= (dp->video_info->h_sync_polarity << 0);
+ writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
+
+ reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
+ writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
+}
+
+void analogix_dp_enable_scrambling(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
+ reg &= ~SCRAMBLING_DISABLE;
+ writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
+}
+
+void analogix_dp_disable_scrambling(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
+ reg |= SCRAMBLING_DISABLE;
+ writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
+}
diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.h b/drivers/gpu/drm/bridge/analogix_dp_reg.h
similarity index 64%
rename from drivers/gpu/drm/exynos/exynos_dp_reg.h
rename to drivers/gpu/drm/bridge/analogix_dp_reg.h
index 2e9bd0e..bed226f 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.h
@@ -1,5 +1,5 @@
/*
- * Register definition file for Samsung DP driver
+ * Register definition file for Analogix Core DP driver
*
* Copyright (C) 2012 Samsung Electronics Co., Ltd.
* Author: Jingoo Han <[email protected]>
@@ -9,96 +9,96 @@
* published by the Free Software Foundation.
*/

-#ifndef _EXYNOS_DP_REG_H
-#define _EXYNOS_DP_REG_H
-
-#define EXYNOS_DP_TX_SW_RESET 0x14
-#define EXYNOS_DP_FUNC_EN_1 0x18
-#define EXYNOS_DP_FUNC_EN_2 0x1C
-#define EXYNOS_DP_VIDEO_CTL_1 0x20
-#define EXYNOS_DP_VIDEO_CTL_2 0x24
-#define EXYNOS_DP_VIDEO_CTL_3 0x28
-
-#define EXYNOS_DP_VIDEO_CTL_8 0x3C
-#define EXYNOS_DP_VIDEO_CTL_10 0x44
-
-#define EXYNOS_DP_LANE_MAP 0x35C
-
-#define EXYNOS_DP_ANALOG_CTL_1 0x370
-#define EXYNOS_DP_ANALOG_CTL_2 0x374
-#define EXYNOS_DP_ANALOG_CTL_3 0x378
-#define EXYNOS_DP_PLL_FILTER_CTL_1 0x37C
-#define EXYNOS_DP_TX_AMP_TUNING_CTL 0x380
-
-#define EXYNOS_DP_AUX_HW_RETRY_CTL 0x390
-
-#define EXYNOS_DP_COMMON_INT_STA_1 0x3C4
-#define EXYNOS_DP_COMMON_INT_STA_2 0x3C8
-#define EXYNOS_DP_COMMON_INT_STA_3 0x3CC
-#define EXYNOS_DP_COMMON_INT_STA_4 0x3D0
-#define EXYNOS_DP_INT_STA 0x3DC
-#define EXYNOS_DP_COMMON_INT_MASK_1 0x3E0
-#define EXYNOS_DP_COMMON_INT_MASK_2 0x3E4
-#define EXYNOS_DP_COMMON_INT_MASK_3 0x3E8
-#define EXYNOS_DP_COMMON_INT_MASK_4 0x3EC
-#define EXYNOS_DP_INT_STA_MASK 0x3F8
-#define EXYNOS_DP_INT_CTL 0x3FC
-
-#define EXYNOS_DP_SYS_CTL_1 0x600
-#define EXYNOS_DP_SYS_CTL_2 0x604
-#define EXYNOS_DP_SYS_CTL_3 0x608
-#define EXYNOS_DP_SYS_CTL_4 0x60C
-
-#define EXYNOS_DP_PKT_SEND_CTL 0x640
-#define EXYNOS_DP_HDCP_CTL 0x648
-
-#define EXYNOS_DP_LINK_BW_SET 0x680
-#define EXYNOS_DP_LANE_COUNT_SET 0x684
-#define EXYNOS_DP_TRAINING_PTN_SET 0x688
-#define EXYNOS_DP_LN0_LINK_TRAINING_CTL 0x68C
-#define EXYNOS_DP_LN1_LINK_TRAINING_CTL 0x690
-#define EXYNOS_DP_LN2_LINK_TRAINING_CTL 0x694
-#define EXYNOS_DP_LN3_LINK_TRAINING_CTL 0x698
-
-#define EXYNOS_DP_DEBUG_CTL 0x6C0
-#define EXYNOS_DP_HPD_DEGLITCH_L 0x6C4
-#define EXYNOS_DP_HPD_DEGLITCH_H 0x6C8
-#define EXYNOS_DP_LINK_DEBUG_CTL 0x6E0
-
-#define EXYNOS_DP_M_VID_0 0x700
-#define EXYNOS_DP_M_VID_1 0x704
-#define EXYNOS_DP_M_VID_2 0x708
-#define EXYNOS_DP_N_VID_0 0x70C
-#define EXYNOS_DP_N_VID_1 0x710
-#define EXYNOS_DP_N_VID_2 0x714
-
-#define EXYNOS_DP_PLL_CTL 0x71C
-#define EXYNOS_DP_PHY_PD 0x720
-#define EXYNOS_DP_PHY_TEST 0x724
-
-#define EXYNOS_DP_VIDEO_FIFO_THRD 0x730
-#define EXYNOS_DP_AUDIO_MARGIN 0x73C
-
-#define EXYNOS_DP_M_VID_GEN_FILTER_TH 0x764
-#define EXYNOS_DP_M_AUD_GEN_FILTER_TH 0x778
-#define EXYNOS_DP_AUX_CH_STA 0x780
-#define EXYNOS_DP_AUX_CH_DEFER_CTL 0x788
-#define EXYNOS_DP_AUX_RX_COMM 0x78C
-#define EXYNOS_DP_BUFFER_DATA_CTL 0x790
-#define EXYNOS_DP_AUX_CH_CTL_1 0x794
-#define EXYNOS_DP_AUX_ADDR_7_0 0x798
-#define EXYNOS_DP_AUX_ADDR_15_8 0x79C
-#define EXYNOS_DP_AUX_ADDR_19_16 0x7A0
-#define EXYNOS_DP_AUX_CH_CTL_2 0x7A4
-
-#define EXYNOS_DP_BUF_DATA_0 0x7C0
-
-#define EXYNOS_DP_SOC_GENERAL_CTL 0x800
-
-/* EXYNOS_DP_TX_SW_RESET */
+#ifndef _ANALOGIX_DP_REG_H
+#define _ANALOGIX_DP_REG_H
+
+#define ANALOGIX_DP_TX_SW_RESET 0x14
+#define ANALOGIX_DP_FUNC_EN_1 0x18
+#define ANALOGIX_DP_FUNC_EN_2 0x1C
+#define ANALOGIX_DP_VIDEO_CTL_1 0x20
+#define ANALOGIX_DP_VIDEO_CTL_2 0x24
+#define ANALOGIX_DP_VIDEO_CTL_3 0x28
+
+#define ANALOGIX_DP_VIDEO_CTL_8 0x3C
+#define ANALOGIX_DP_VIDEO_CTL_10 0x44
+
+#define ANALOGIX_DP_LANE_MAP 0x35C
+
+#define ANALOGIX_DP_ANALOG_CTL_1 0x370
+#define ANALOGIX_DP_ANALOG_CTL_2 0x374
+#define ANALOGIX_DP_ANALOG_CTL_3 0x378
+#define ANALOGIX_DP_PLL_FILTER_CTL_1 0x37C
+#define ANALOGIX_DP_TX_AMP_TUNING_CTL 0x380
+
+#define ANALOGIX_DP_AUX_HW_RETRY_CTL 0x390
+
+#define ANALOGIX_DP_COMMON_INT_STA_1 0x3C4
+#define ANALOGIX_DP_COMMON_INT_STA_2 0x3C8
+#define ANALOGIX_DP_COMMON_INT_STA_3 0x3CC
+#define ANALOGIX_DP_COMMON_INT_STA_4 0x3D0
+#define ANALOGIX_DP_INT_STA 0x3DC
+#define ANALOGIX_DP_COMMON_INT_MASK_1 0x3E0
+#define ANALOGIX_DP_COMMON_INT_MASK_2 0x3E4
+#define ANALOGIX_DP_COMMON_INT_MASK_3 0x3E8
+#define ANALOGIX_DP_COMMON_INT_MASK_4 0x3EC
+#define ANALOGIX_DP_INT_STA_MASK 0x3F8
+#define ANALOGIX_DP_INT_CTL 0x3FC
+
+#define ANALOGIX_DP_SYS_CTL_1 0x600
+#define ANALOGIX_DP_SYS_CTL_2 0x604
+#define ANALOGIX_DP_SYS_CTL_3 0x608
+#define ANALOGIX_DP_SYS_CTL_4 0x60C
+
+#define ANALOGIX_DP_PKT_SEND_CTL 0x640
+#define ANALOGIX_DP_HDCP_CTL 0x648
+
+#define ANALOGIX_DP_LINK_BW_SET 0x680
+#define ANALOGIX_DP_LANE_COUNT_SET 0x684
+#define ANALOGIX_DP_TRAINING_PTN_SET 0x688
+#define ANALOGIX_DP_LN0_LINK_TRAINING_CTL 0x68C
+#define ANALOGIX_DP_LN1_LINK_TRAINING_CTL 0x690
+#define ANALOGIX_DP_LN2_LINK_TRAINING_CTL 0x694
+#define ANALOGIX_DP_LN3_LINK_TRAINING_CTL 0x698
+
+#define ANALOGIX_DP_DEBUG_CTL 0x6C0
+#define ANALOGIX_DP_HPD_DEGLITCH_L 0x6C4
+#define ANALOGIX_DP_HPD_DEGLITCH_H 0x6C8
+#define ANALOGIX_DP_LINK_DEBUG_CTL 0x6E0
+
+#define ANALOGIX_DP_M_VID_0 0x700
+#define ANALOGIX_DP_M_VID_1 0x704
+#define ANALOGIX_DP_M_VID_2 0x708
+#define ANALOGIX_DP_N_VID_0 0x70C
+#define ANALOGIX_DP_N_VID_1 0x710
+#define ANALOGIX_DP_N_VID_2 0x714
+
+#define ANALOGIX_DP_PLL_CTL 0x71C
+#define ANALOGIX_DP_PHY_PD 0x720
+#define ANALOGIX_DP_PHY_TEST 0x724
+
+#define ANALOGIX_DP_VIDEO_FIFO_THRD 0x730
+#define ANALOGIX_DP_AUDIO_MARGIN 0x73C
+
+#define ANALOGIX_DP_M_VID_GEN_FILTER_TH 0x764
+#define ANALOGIX_DP_M_AUD_GEN_FILTER_TH 0x778
+#define ANALOGIX_DP_AUX_CH_STA 0x780
+#define ANALOGIX_DP_AUX_CH_DEFER_CTL 0x788
+#define ANALOGIX_DP_AUX_RX_COMM 0x78C
+#define ANALOGIX_DP_BUFFER_DATA_CTL 0x790
+#define ANALOGIX_DP_AUX_CH_CTL_1 0x794
+#define ANALOGIX_DP_AUX_ADDR_7_0 0x798
+#define ANALOGIX_DP_AUX_ADDR_15_8 0x79C
+#define ANALOGIX_DP_AUX_ADDR_19_16 0x7A0
+#define ANALOGIX_DP_AUX_CH_CTL_2 0x7A4
+
+#define ANALOGIX_DP_BUF_DATA_0 0x7C0
+
+#define ANALOGIX_DP_SOC_GENERAL_CTL 0x800
+
+/* ANALOGIX_DP_TX_SW_RESET */
#define RESET_DP_TX (0x1 << 0)

-/* EXYNOS_DP_FUNC_EN_1 */
+/* ANALOGIX_DP_FUNC_EN_1 */
#define MASTER_VID_FUNC_EN_N (0x1 << 7)
#define SLAVE_VID_FUNC_EN_N (0x1 << 5)
#define AUD_FIFO_FUNC_EN_N (0x1 << 4)
@@ -107,17 +107,17 @@
#define CRC_FUNC_EN_N (0x1 << 1)
#define SW_FUNC_EN_N (0x1 << 0)

-/* EXYNOS_DP_FUNC_EN_2 */
+/* ANALOGIX_DP_FUNC_EN_2 */
#define SSC_FUNC_EN_N (0x1 << 7)
#define AUX_FUNC_EN_N (0x1 << 2)
#define SERDES_FIFO_FUNC_EN_N (0x1 << 1)
#define LS_CLK_DOMAIN_FUNC_EN_N (0x1 << 0)

-/* EXYNOS_DP_VIDEO_CTL_1 */
+/* ANALOGIX_DP_VIDEO_CTL_1 */
#define VIDEO_EN (0x1 << 7)
#define HDCP_VIDEO_MUTE (0x1 << 6)

-/* EXYNOS_DP_VIDEO_CTL_1 */
+/* ANALOGIX_DP_VIDEO_CTL_1 */
#define IN_D_RANGE_MASK (0x1 << 7)
#define IN_D_RANGE_SHIFT (7)
#define IN_D_RANGE_CEA (0x1 << 7)
@@ -134,7 +134,7 @@
#define IN_COLOR_F_YCBCR422 (0x1 << 0)
#define IN_COLOR_F_RGB (0x0 << 0)

-/* EXYNOS_DP_VIDEO_CTL_3 */
+/* ANALOGIX_DP_VIDEO_CTL_3 */
#define IN_YC_COEFFI_MASK (0x1 << 7)
#define IN_YC_COEFFI_SHIFT (7)
#define IN_YC_COEFFI_ITU709 (0x1 << 7)
@@ -144,17 +144,17 @@
#define VID_CHK_UPDATE_TYPE_1 (0x1 << 4)
#define VID_CHK_UPDATE_TYPE_0 (0x0 << 4)

-/* EXYNOS_DP_VIDEO_CTL_8 */
+/* ANALOGIX_DP_VIDEO_CTL_8 */
#define VID_HRES_TH(x) (((x) & 0xf) << 4)
#define VID_VRES_TH(x) (((x) & 0xf) << 0)

-/* EXYNOS_DP_VIDEO_CTL_10 */
+/* ANALOGIX_DP_VIDEO_CTL_10 */
#define FORMAT_SEL (0x1 << 4)
#define INTERACE_SCAN_CFG (0x1 << 2)
#define VSYNC_POLARITY_CFG (0x1 << 1)
#define HSYNC_POLARITY_CFG (0x1 << 0)

-/* EXYNOS_DP_LANE_MAP */
+/* ANALOGIX_DP_LANE_MAP */
#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6)
#define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6)
#define LANE3_MAP_LOGIC_LANE_2 (0x2 << 6)
@@ -172,30 +172,30 @@
#define LANE0_MAP_LOGIC_LANE_2 (0x2 << 0)
#define LANE0_MAP_LOGIC_LANE_3 (0x3 << 0)

-/* EXYNOS_DP_ANALOG_CTL_1 */
+/* ANALOGIX_DP_ANALOG_CTL_1 */
#define TX_TERMINAL_CTRL_50_OHM (0x1 << 4)

-/* EXYNOS_DP_ANALOG_CTL_2 */
+/* ANALOGIX_DP_ANALOG_CTL_2 */
#define SEL_24M (0x1 << 3)
#define TX_DVDD_BIT_1_0625V (0x4 << 0)

-/* EXYNOS_DP_ANALOG_CTL_3 */
+/* ANALOGIX_DP_ANALOG_CTL_3 */
#define DRIVE_DVDD_BIT_1_0625V (0x4 << 5)
#define VCO_BIT_600_MICRO (0x5 << 0)

-/* EXYNOS_DP_PLL_FILTER_CTL_1 */
+/* ANALOGIX_DP_PLL_FILTER_CTL_1 */
#define PD_RING_OSC (0x1 << 6)
#define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4)
#define TX_CUR1_2X (0x1 << 2)
#define TX_CUR_16_MA (0x3 << 0)

-/* EXYNOS_DP_TX_AMP_TUNING_CTL */
+/* ANALOGIX_DP_TX_AMP_TUNING_CTL */
#define CH3_AMP_400_MV (0x0 << 24)
#define CH2_AMP_400_MV (0x0 << 16)
#define CH1_AMP_400_MV (0x0 << 8)
#define CH0_AMP_400_MV (0x0 << 0)

-/* EXYNOS_DP_AUX_HW_RETRY_CTL */
+/* ANALOGIX_DP_AUX_HW_RETRY_CTL */
#define AUX_BIT_PERIOD_EXPECTED_DELAY(x) (((x) & 0x7) << 8)
#define AUX_HW_RETRY_INTERVAL_MASK (0x3 << 3)
#define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS (0x0 << 3)
@@ -204,7 +204,7 @@
#define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS (0x3 << 3)
#define AUX_HW_RETRY_COUNT_SEL(x) (((x) & 0x7) << 0)

-/* EXYNOS_DP_COMMON_INT_STA_1 */
+/* ANALOGIX_DP_COMMON_INT_STA_1 */
#define VSYNC_DET (0x1 << 7)
#define PLL_LOCK_CHG (0x1 << 6)
#define SPDIF_ERR (0x1 << 5)
@@ -214,19 +214,19 @@
#define VID_CLK_CHG (0x1 << 1)
#define SW_INT (0x1 << 0)

-/* EXYNOS_DP_COMMON_INT_STA_2 */
+/* ANALOGIX_DP_COMMON_INT_STA_2 */
#define ENC_EN_CHG (0x1 << 6)
#define HW_BKSV_RDY (0x1 << 3)
#define HW_SHA_DONE (0x1 << 2)
#define HW_AUTH_STATE_CHG (0x1 << 1)
#define HW_AUTH_DONE (0x1 << 0)

-/* EXYNOS_DP_COMMON_INT_STA_3 */
+/* ANALOGIX_DP_COMMON_INT_STA_3 */
#define AFIFO_UNDER (0x1 << 7)
#define AFIFO_OVER (0x1 << 6)
#define R0_CHK_FLAG (0x1 << 5)

-/* EXYNOS_DP_COMMON_INT_STA_4 */
+/* ANALOGIX_DP_COMMON_INT_STA_4 */
#define PSR_ACTIVE (0x1 << 7)
#define PSR_INACTIVE (0x1 << 6)
#define SPDIF_BI_PHASE_ERR (0x1 << 5)
@@ -234,29 +234,29 @@
#define HPD_LOST (0x1 << 1)
#define PLUG (0x1 << 0)

-/* EXYNOS_DP_INT_STA */
+/* ANALOGIX_DP_INT_STA */
#define INT_HPD (0x1 << 6)
#define HW_TRAINING_FINISH (0x1 << 5)
#define RPLY_RECEIV (0x1 << 1)
#define AUX_ERR (0x1 << 0)

-/* EXYNOS_DP_INT_CTL */
+/* ANALOGIX_DP_INT_CTL */
#define SOFT_INT_CTRL (0x1 << 2)
#define INT_POL1 (0x1 << 1)
#define INT_POL0 (0x1 << 0)

-/* EXYNOS_DP_SYS_CTL_1 */
+/* ANALOGIX_DP_SYS_CTL_1 */
#define DET_STA (0x1 << 2)
#define FORCE_DET (0x1 << 1)
#define DET_CTRL (0x1 << 0)

-/* EXYNOS_DP_SYS_CTL_2 */
+/* ANALOGIX_DP_SYS_CTL_2 */
#define CHA_CRI(x) (((x) & 0xf) << 4)
#define CHA_STA (0x1 << 2)
#define FORCE_CHA (0x1 << 1)
#define CHA_CTRL (0x1 << 0)

-/* EXYNOS_DP_SYS_CTL_3 */
+/* ANALOGIX_DP_SYS_CTL_3 */
#define HPD_STATUS (0x1 << 6)
#define F_HPD (0x1 << 5)
#define HPD_CTRL (0x1 << 4)
@@ -265,13 +265,13 @@
#define F_VALID (0x1 << 1)
#define VALID_CTRL (0x1 << 0)

-/* EXYNOS_DP_SYS_CTL_4 */
+/* ANALOGIX_DP_SYS_CTL_4 */
#define FIX_M_AUD (0x1 << 4)
#define ENHANCED (0x1 << 3)
#define FIX_M_VID (0x1 << 2)
#define M_VID_UPDATE_CTRL (0x3 << 0)

-/* EXYNOS_DP_TRAINING_PTN_SET */
+/* ANALOGIX_DP_TRAINING_PTN_SET */
#define SCRAMBLER_TYPE (0x1 << 9)
#define HW_LINK_TRAINING_PATTERN (0x1 << 8)
#define SCRAMBLING_DISABLE (0x1 << 5)
@@ -285,24 +285,24 @@
#define SW_TRAINING_PATTERN_SET_PTN1 (0x1 << 0)
#define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0)

-/* EXYNOS_DP_LN0_LINK_TRAINING_CTL */
+/* ANALOGIX_DP_LN0_LINK_TRAINING_CTL */
#define PRE_EMPHASIS_SET_MASK (0x3 << 3)
#define PRE_EMPHASIS_SET_SHIFT (3)

-/* EXYNOS_DP_DEBUG_CTL */
+/* ANALOGIX_DP_DEBUG_CTL */
#define PLL_LOCK (0x1 << 4)
#define F_PLL_LOCK (0x1 << 3)
#define PLL_LOCK_CTRL (0x1 << 2)
#define PN_INV (0x1 << 0)

-/* EXYNOS_DP_PLL_CTL */
+/* ANALOGIX_DP_PLL_CTL */
#define DP_PLL_PD (0x1 << 7)
#define DP_PLL_RESET (0x1 << 6)
#define DP_PLL_LOOP_BIT_DEFAULT (0x1 << 4)
#define DP_PLL_REF_BIT_1_1250V (0x5 << 0)
#define DP_PLL_REF_BIT_1_2500V (0x7 << 0)

-/* EXYNOS_DP_PHY_PD */
+/* ANALOGIX_DP_PHY_PD */
#define DP_PHY_PD (0x1 << 5)
#define AUX_PD (0x1 << 4)
#define CH3_PD (0x1 << 3)
@@ -310,28 +310,28 @@
#define CH1_PD (0x1 << 1)
#define CH0_PD (0x1 << 0)

-/* EXYNOS_DP_PHY_TEST */
+/* ANALOGIX_DP_PHY_TEST */
#define MACRO_RST (0x1 << 5)
#define CH1_TEST (0x1 << 1)
#define CH0_TEST (0x1 << 0)

-/* EXYNOS_DP_AUX_CH_STA */
+/* ANALOGIX_DP_AUX_CH_STA */
#define AUX_BUSY (0x1 << 4)
#define AUX_STATUS_MASK (0xf << 0)

-/* EXYNOS_DP_AUX_CH_DEFER_CTL */
+/* ANALOGIX_DP_AUX_CH_DEFER_CTL */
#define DEFER_CTRL_EN (0x1 << 7)
#define DEFER_COUNT(x) (((x) & 0x7f) << 0)

-/* EXYNOS_DP_AUX_RX_COMM */
+/* ANALOGIX_DP_AUX_RX_COMM */
#define AUX_RX_COMM_I2C_DEFER (0x2 << 2)
#define AUX_RX_COMM_AUX_DEFER (0x2 << 0)

-/* EXYNOS_DP_BUFFER_DATA_CTL */
+/* ANALOGIX_DP_BUFFER_DATA_CTL */
#define BUF_CLR (0x1 << 7)
#define BUF_DATA_COUNT(x) (((x) & 0x1f) << 0)

-/* EXYNOS_DP_AUX_CH_CTL_1 */
+/* ANALOGIX_DP_AUX_CH_CTL_1 */
#define AUX_LENGTH(x) (((x - 1) & 0xf) << 4)
#define AUX_TX_COMM_MASK (0xf << 0)
#define AUX_TX_COMM_DP_TRANSACTION (0x1 << 3)
@@ -340,20 +340,20 @@
#define AUX_TX_COMM_WRITE (0x0 << 0)
#define AUX_TX_COMM_READ (0x1 << 0)

-/* EXYNOS_DP_AUX_ADDR_7_0 */
+/* ANALOGIX_DP_AUX_ADDR_7_0 */
#define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff)

-/* EXYNOS_DP_AUX_ADDR_15_8 */
+/* ANALOGIX_DP_AUX_ADDR_15_8 */
#define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff)

-/* EXYNOS_DP_AUX_ADDR_19_16 */
+/* ANALOGIX_DP_AUX_ADDR_19_16 */
#define AUX_ADDR_19_16(x) (((x) >> 16) & 0x0f)

-/* EXYNOS_DP_AUX_CH_CTL_2 */
+/* ANALOGIX_DP_AUX_CH_CTL_2 */
#define ADDR_ONLY (0x1 << 1)
#define AUX_EN (0x1 << 0)

-/* EXYNOS_DP_SOC_GENERAL_CTL */
+/* ANALOGIX_DP_SOC_GENERAL_CTL */
#define AUDIO_MODE_SPDIF_MODE (0x1 << 8)
#define AUDIO_MODE_MASTER_MODE (0x0 << 8)
#define MASTER_VIDEO_INTERLACE_EN (0x1 << 4)
@@ -363,4 +363,4 @@
#define VIDEO_MODE_SLAVE_MODE (0x1 << 0)
#define VIDEO_MODE_MASTER_MODE (0x0 << 0)

-#endif /* _EXYNOS_DP_REG_H */
+#endif /* _ANALOGIX_DP_REG_H */
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 43003c4..b33549c 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -54,9 +54,10 @@ config DRM_EXYNOS_DSI
help
This enables support for Exynos MIPI-DSI device.

-config DRM_EXYNOS_DP
- bool "EXYNOS DRM DP driver support"
+config DRM_EXYNOS_ANALOGIX_DP
+ bool "EXYNOS specific extensions for Analogix DP driver"
depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
+ select DRM_ANALOGIX_DP
default DRM_EXYNOS
select DRM_PANEL
help
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 7de0b10..cda4d26 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -14,7 +14,7 @@ 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
-exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp_core.o exynos_dp_reg.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_ANALOGIX_DP) += analogix_dp-exynos.o
exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynos_mixer.o
exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o
exynosdrm-$(CONFIG_DRM_EXYNOS_G2D) += exynos_drm_g2d.o
diff --git a/drivers/gpu/drm/exynos/analogix_dp-exynos.c b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
new file mode 100644
index 0000000..d5631c2
--- /dev/null
+++ b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
@@ -0,0 +1,291 @@
+/*
+ * Samsung SoC DP (Display Port) interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_graph.h>
+#include <video/of_display_timing.h>
+#include <video/of_videomode.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_panel.h>
+#include <drm/bridge/ptn3460.h>
+#include <drm/bridge/analogix_dp.h>
+
+#include <drm/exynos_drm.h>
+#include "exynos_drm_drv.h"
+
+#define plat_data_to_dp(pd) \
+ container_of(pd, struct exynos_dp_device, plat_data)
+
+struct exynos_dp_device {
+ struct exynos_drm_display display;
+ struct drm_bridge *ptn_bridge;
+ struct drm_device *drm_dev;
+ struct device *dev;
+
+ struct exynos_drm_panel_info priv;
+ struct analogix_dp_plat_data plat_data;
+};
+
+int exynos_dp_crtc_clock_enable(struct analogix_dp_plat_data *plat_data,
+ bool enable)
+{
+ struct exynos_dp_device *dp = plat_data_to_dp(plat_data);
+ struct drm_encoder *encoder = dp->display.encoder;
+ struct exynos_drm_crtc *crtc;
+
+ if (!encoder)
+ return -1;
+
+ crtc = to_exynos_crtc(encoder->crtc);
+ if (crtc && crtc->ops && crtc->ops->clock_enable)
+ crtc->ops->clock_enable(crtc, enable);
+
+ return 0;
+}
+
+static int exynos_dp_poweron(struct analogix_dp_plat_data *plat_data)
+{
+ return exynos_dp_crtc_clock_enable(plat_data, true);
+}
+
+static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data)
+{
+ return exynos_dp_crtc_clock_enable(plat_data, false);
+}
+
+static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data,
+ struct drm_connector *connector)
+{
+ struct exynos_dp_device *dp = plat_data_to_dp(plat_data);
+ struct drm_display_mode *mode;
+
+ if (dp->plat_data.panel)
+ return 0;
+
+ 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(&dp->priv.vm, mode);
+ mode->width_mm = dp->priv.width_mm;
+ mode->height_mm = dp->priv.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_set_name(mode);
+ drm_mode_probed_add(connector, mode);
+
+ return 1;
+}
+
+static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
+ struct drm_bridge *bridge)
+{
+ struct exynos_dp_device *dp = plat_data_to_dp(plat_data);
+ struct drm_encoder *encoder = dp->display.encoder;
+ int ret;
+
+ /* Pre-empt DP connector creation if there's a bridge */
+ if (dp->ptn_bridge) {
+ bridge->next = dp->ptn_bridge;
+ dp->ptn_bridge->encoder = encoder;
+ ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge);
+ if (ret) {
+ DRM_ERROR("Failed to attach bridge to drm\n");
+ bridge->next = NULL;
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
+{
+ /* do nothing */
+}
+
+static int exynos_dp_create_connector(struct exynos_drm_display *display,
+ struct drm_encoder *encoder)
+{
+ /* do nothing */
+ return 0;
+}
+
+static void exynos_dp_commit(struct exynos_drm_display *display)
+{
+ /* do nothing */
+}
+
+static struct exynos_drm_display_ops exynos_dp_display_ops = {
+ .create_connector = exynos_dp_create_connector,
+ .dpms = exynos_dp_dpms,
+ .commit = exynos_dp_commit,
+};
+
+static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
+{
+ int ret;
+
+ ret = of_get_videomode(dp->dev->of_node, &dp->priv.vm,
+ OF_USE_NATIVE_MODE);
+ if (ret) {
+ DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
+{
+ struct exynos_dp_device *dp = dev_get_drvdata(dev);
+ struct drm_device *drm_dev = data;
+ int ret;
+
+ /*
+ * Just like the probe function said, we don't need the
+ * device drvrate anymore, we should leave the charge to
+ * analogix dp driver, set the device drvdata to NULL.
+ */
+ dev_set_drvdata(dev, NULL);
+
+ dp->dev = dev;
+ dp->drm_dev = drm_dev;
+
+ dp->plat_data.power_on = exynos_dp_poweron;
+ dp->plat_data.power_off = exynos_dp_poweroff;
+ dp->plat_data.get_modes = exynos_dp_get_modes;
+ dp->plat_data.attach = exynos_dp_bridge_attach;
+
+ if (!dp->plat_data.panel || !dp->ptn_bridge) {
+ ret = exynos_dp_dt_parse_panel(dp);
+ if (ret)
+ return ret;
+ }
+
+ ret = exynos_drm_create_enc_conn(dp->drm_dev, &dp->display);
+ if (ret) {
+ DRM_ERROR("exynos dp create enc_conn failed\n");
+ return ret;
+ }
+
+ return analogix_dp_bind(dev, dp->drm_dev, dp->display.encoder,
+ &dp->plat_data);
+}
+
+static void exynos_dp_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ return analogix_dp_unbind(dev, master, data);
+}
+
+static const struct component_ops exynos_dp_ops = {
+ .bind = exynos_dp_bind,
+ .unbind = exynos_dp_unbind,
+};
+
+static int exynos_dp_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *panel_node, *bridge_node, *endpoint;
+ struct exynos_dp_device *dp;
+
+ dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
+ GFP_KERNEL);
+ if (!dp)
+ return -ENOMEM;
+
+ /*
+ * We just use the drvdata until driver run into component
+ * add function, and then we would set drvdata to null, so
+ * that analogix dp driver would take charge of the drvdata.
+ */
+ platform_set_drvdata(pdev, dp);
+
+ dp->display.type = EXYNOS_DISPLAY_TYPE_LCD;
+ dp->display.ops = &exynos_dp_display_ops;
+
+ panel_node = of_parse_phandle(dev->of_node, "panel", 0);
+ if (panel_node) {
+ dp->plat_data.panel = of_drm_find_panel(panel_node);
+ of_node_put(panel_node);
+ if (!dp->plat_data.panel)
+ return -EPROBE_DEFER;
+ }
+
+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+ if (endpoint) {
+ bridge_node = of_graph_get_remote_port_parent(endpoint);
+ if (bridge_node) {
+ dp->ptn_bridge = of_drm_find_bridge(bridge_node);
+ of_node_put(bridge_node);
+ if (!dp->ptn_bridge)
+ return -EPROBE_DEFER;
+ } else {
+ return -EPROBE_DEFER;
+ }
+ }
+
+ return component_add(&pdev->dev, &exynos_dp_ops);
+}
+
+static int exynos_dp_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &exynos_dp_ops);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos_dp_suspend(struct device *dev)
+{
+ return analogix_dp_suspend(dev);
+}
+
+static int exynos_dp_resume(struct device *dev)
+{
+ return analogix_dp_resume(dev);
+}
+#endif
+
+static const struct dev_pm_ops exynos_dp_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
+};
+
+static const struct of_device_id exynos_dp_match[] = {
+ { .compatible = "samsung,exynos5-dp" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
+
+struct platform_driver dp_driver = {
+ .probe = exynos_dp_probe,
+ .remove = exynos_dp_remove,
+ .driver = {
+ .name = "exynos-dp",
+ .owner = THIS_MODULE,
+ .pm = &exynos_dp_pm_ops,
+ .of_match_table = exynos_dp_match,
+ },
+};
+
+MODULE_AUTHOR("Jingoo Han <[email protected]>");
+MODULE_DESCRIPTION("Samsung Specific Analogix-DP Driver Extension");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
deleted file mode 100644
index 29bd56e..0000000
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Header file for Samsung DP (Display Port) interface driver.
- *
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Author: Jingoo Han <[email protected]>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef _EXYNOS_DP_CORE_H
-#define _EXYNOS_DP_CORE_H
-
-#include <drm/drm_crtc.h>
-#include <drm/drm_dp_helper.h>
-#include <drm/exynos_drm.h>
-
-#include "exynos_drm_drv.h"
-
-#define DP_TIMEOUT_LOOP_COUNT 100
-#define MAX_CR_LOOP 5
-#define MAX_EQ_LOOP 5
-
-enum link_rate_type {
- LINK_RATE_1_62GBPS = 0x06,
- LINK_RATE_2_70GBPS = 0x0a
-};
-
-enum link_lane_count_type {
- LANE_COUNT1 = 1,
- LANE_COUNT2 = 2,
- LANE_COUNT4 = 4
-};
-
-enum link_training_state {
- START,
- CLOCK_RECOVERY,
- EQUALIZER_TRAINING,
- FINISHED,
- FAILED
-};
-
-enum voltage_swing_level {
- VOLTAGE_LEVEL_0,
- VOLTAGE_LEVEL_1,
- VOLTAGE_LEVEL_2,
- VOLTAGE_LEVEL_3,
-};
-
-enum pre_emphasis_level {
- PRE_EMPHASIS_LEVEL_0,
- PRE_EMPHASIS_LEVEL_1,
- PRE_EMPHASIS_LEVEL_2,
- PRE_EMPHASIS_LEVEL_3,
-};
-
-enum pattern_set {
- PRBS7,
- D10_2,
- TRAINING_PTN1,
- TRAINING_PTN2,
- DP_NONE
-};
-
-enum color_space {
- COLOR_RGB,
- COLOR_YCBCR422,
- COLOR_YCBCR444
-};
-
-enum color_depth {
- COLOR_6,
- COLOR_8,
- COLOR_10,
- COLOR_12
-};
-
-enum color_coefficient {
- COLOR_YCBCR601,
- COLOR_YCBCR709
-};
-
-enum dynamic_range {
- VESA,
- CEA
-};
-
-enum pll_status {
- PLL_UNLOCKED,
- PLL_LOCKED
-};
-
-enum clock_recovery_m_value_type {
- CALCULATED_M,
- REGISTER_M
-};
-
-enum video_timing_recognition_type {
- VIDEO_TIMING_FROM_CAPTURE,
- VIDEO_TIMING_FROM_REGISTER
-};
-
-enum analog_power_block {
- AUX_BLOCK,
- CH0_BLOCK,
- CH1_BLOCK,
- CH2_BLOCK,
- CH3_BLOCK,
- ANALOG_TOTAL,
- POWER_ALL
-};
-
-enum dp_irq_type {
- DP_IRQ_TYPE_HP_CABLE_IN,
- DP_IRQ_TYPE_HP_CABLE_OUT,
- DP_IRQ_TYPE_HP_CHANGE,
- DP_IRQ_TYPE_UNKNOWN,
-};
-
-struct video_info {
- char *name;
-
- bool h_sync_polarity;
- bool v_sync_polarity;
- bool interlaced;
-
- enum color_space color_space;
- enum dynamic_range dynamic_range;
- enum color_coefficient ycbcr_coeff;
- enum color_depth color_depth;
-
- enum link_rate_type link_rate;
- enum link_lane_count_type lane_count;
-};
-
-struct link_train {
- int eq_loop;
- int cr_loop[4];
-
- u8 link_rate;
- u8 lane_count;
- u8 training_lane[4];
-
- enum link_training_state lt_state;
-};
-
-struct exynos_dp_device {
- struct exynos_drm_display display;
- struct device *dev;
- struct drm_device *drm_dev;
- struct drm_connector connector;
- struct drm_encoder *encoder;
- struct drm_panel *panel;
- struct drm_bridge *bridge;
- struct drm_bridge *ptn_bridge;
- struct clk *clock;
- unsigned int irq;
- void __iomem *reg_base;
-
- struct video_info *video_info;
- struct link_train link_train;
- struct work_struct hotplug_work;
- struct phy *phy;
- int dpms_mode;
- int hpd_gpio;
-
- struct exynos_drm_panel_info priv;
-};
-
-/* exynos_dp_reg.c */
-void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable);
-void exynos_dp_stop_video(struct exynos_dp_device *dp);
-void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable);
-void exynos_dp_init_analog_param(struct exynos_dp_device *dp);
-void exynos_dp_init_interrupt(struct exynos_dp_device *dp);
-void exynos_dp_reset(struct exynos_dp_device *dp);
-void exynos_dp_swreset(struct exynos_dp_device *dp);
-void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
-enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
-void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
-void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
- enum analog_power_block block,
- bool enable);
-void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
-void exynos_dp_init_hpd(struct exynos_dp_device *dp);
-enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
-void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp);
-void exynos_dp_reset_aux(struct exynos_dp_device *dp);
-void exynos_dp_init_aux(struct exynos_dp_device *dp);
-int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
-void exynos_dp_enable_sw_function(struct exynos_dp_device *dp);
-int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp);
-int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned char data);
-int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned char *data);
-int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned int count,
- unsigned char data[]);
-int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned int count,
- unsigned char data[]);
-int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
- unsigned int device_addr,
- unsigned int reg_addr);
-int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
- unsigned int device_addr,
- unsigned int reg_addr,
- unsigned int *data);
-int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
- unsigned int device_addr,
- unsigned int reg_addr,
- unsigned int count,
- unsigned char edid[]);
-void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
-void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
-void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
-void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
-void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable);
-void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
- enum pattern_set pattern);
-void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level);
-void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level);
-void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level);
-void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level);
-void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
- u32 training_lane);
-void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
- u32 training_lane);
-void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
- u32 training_lane);
-void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
- u32 training_lane);
-u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp);
-u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
-u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
-u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp);
-void exynos_dp_reset_macro(struct exynos_dp_device *dp);
-void exynos_dp_init_video(struct exynos_dp_device *dp);
-
-void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
-int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
-void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
- enum clock_recovery_m_value_type type,
- u32 m_value, u32 n_value);
-void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type);
-void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable);
-void exynos_dp_start_video(struct exynos_dp_device *dp);
-int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp);
-void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp);
-void exynos_dp_enable_scrambling(struct exynos_dp_device *dp);
-void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
-
-/* I2C EDID Chip ID, Slave Address */
-#define I2C_EDID_DEVICE_ADDR 0x50
-#define I2C_E_EDID_DEVICE_ADDR 0x30
-
-#define EDID_BLOCK_LENGTH 0x80
-#define EDID_HEADER_PATTERN 0x00
-#define EDID_EXTENSION_FLAG 0x7e
-#define EDID_CHECKSUM 0x7f
-
-/* DP_MAX_LANE_COUNT */
-#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
-#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
-
-/* DP_LANE_COUNT_SET */
-#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f)
-
-/* DP_TRAINING_LANE0_SET */
-#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3)
-#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3)
-#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0)
-#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3)
-
-#endif /* _EXYNOS_DP_CORE_H */
diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.c b/drivers/gpu/drm/exynos/exynos_dp_reg.c
deleted file mode 100644
index 9aa483d..0000000
--- a/drivers/gpu/drm/exynos/exynos_dp_reg.c
+++ /dev/null
@@ -1,1259 +0,0 @@
-/*
- * Samsung DP (Display port) register interface driver.
- *
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Author: Jingoo Han <[email protected]>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-
-#include "exynos_dp_core.h"
-#include "exynos_dp_reg.h"
-
-#define COMMON_INT_MASK_1 0
-#define COMMON_INT_MASK_2 0
-#define COMMON_INT_MASK_3 0
-#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
-#define INT_STA_MASK INT_HPD
-
-void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable)
-{
- u32 reg;
-
- if (enable) {
- reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
- reg |= HDCP_VIDEO_MUTE;
- writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
- reg &= ~HDCP_VIDEO_MUTE;
- writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
- }
-}
-
-void exynos_dp_stop_video(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
- reg &= ~VIDEO_EN;
- writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
-}
-
-void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable)
-{
- u32 reg;
-
- if (enable)
- reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
- LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
- else
- reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
- LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
-
- writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP);
-}
-
-void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = TX_TERMINAL_CTRL_50_OHM;
- writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1);
-
- reg = SEL_24M | TX_DVDD_BIT_1_0625V;
- writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2);
-
- reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
- writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3);
-
- reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
- TX_CUR1_2X | TX_CUR_16_MA;
- writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1);
-
- reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
- CH1_AMP_400_MV | CH0_AMP_400_MV;
- writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL);
-}
-
-void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
-{
- /* Set interrupt pin assertion polarity as high */
- writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL);
-
- /* Clear pending regisers */
- writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
- writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2);
- writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3);
- writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
- writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA);
-
- /* 0:mask,1: unmask */
- writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
- writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
- writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
- writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
- writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
-}
-
-void exynos_dp_reset(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- exynos_dp_stop_video(dp);
- exynos_dp_enable_video_mute(dp, 0);
-
- reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
- AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
- HDCP_FUNC_EN_N | SW_FUNC_EN_N;
- writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
-
- reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
- SERDES_FIFO_FUNC_EN_N |
- LS_CLK_DOMAIN_FUNC_EN_N;
- writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
-
- usleep_range(20, 30);
-
- exynos_dp_lane_swap(dp, 0);
-
- writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
- writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
- writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
- writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
-
- writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL);
- writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL);
-
- writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L);
- writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H);
-
- writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL);
-
- writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST);
-
- writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD);
- writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN);
-
- writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH);
- writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH);
-
- writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
-}
-
-void exynos_dp_swreset(struct exynos_dp_device *dp)
-{
- writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET);
-}
-
-void exynos_dp_config_interrupt(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- /* 0: mask, 1: unmask */
- reg = COMMON_INT_MASK_1;
- writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
-
- reg = COMMON_INT_MASK_2;
- writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
-
- reg = COMMON_INT_MASK_3;
- writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
-
- reg = COMMON_INT_MASK_4;
- writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
-
- reg = INT_STA_MASK;
- writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
-}
-
-enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
- if (reg & PLL_LOCK)
- return PLL_LOCKED;
- else
- return PLL_UNLOCKED;
-}
-
-void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable)
-{
- u32 reg;
-
- if (enable) {
- reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
- reg |= DP_PLL_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
- reg &= ~DP_PLL_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
- }
-}
-
-void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
- enum analog_power_block block,
- bool enable)
-{
- u32 reg;
-
- switch (block) {
- case AUX_BLOCK:
- if (enable) {
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
- reg |= AUX_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
- reg &= ~AUX_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- }
- break;
- case CH0_BLOCK:
- if (enable) {
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
- reg |= CH0_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
- reg &= ~CH0_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- }
- break;
- case CH1_BLOCK:
- if (enable) {
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
- reg |= CH1_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
- reg &= ~CH1_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- }
- break;
- case CH2_BLOCK:
- if (enable) {
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
- reg |= CH2_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
- reg &= ~CH2_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- }
- break;
- case CH3_BLOCK:
- if (enable) {
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
- reg |= CH3_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
- reg &= ~CH3_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- }
- break;
- case ANALOG_TOTAL:
- if (enable) {
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
- reg |= DP_PHY_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
- reg &= ~DP_PHY_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- }
- break;
- case POWER_ALL:
- if (enable) {
- reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
- CH1_PD | CH0_PD;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
- } else {
- writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD);
- }
- break;
- default:
- break;
- }
-}
-
-void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
-{
- u32 reg;
- int timeout_loop = 0;
-
- exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
-
- reg = PLL_LOCK_CHG;
- writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
-
- reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
- reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
- writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL);
-
- /* Power up PLL */
- if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
- exynos_dp_set_pll_power_down(dp, 0);
-
- while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
- timeout_loop++;
- if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
- dev_err(dp->dev, "failed to get pll lock status\n");
- return;
- }
- usleep_range(10, 20);
- }
- }
-
- /* Enable Serdes FIFO function and Link symbol clock domain module */
- reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
- reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
- | AUX_FUNC_EN_N);
- writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
-}
-
-void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- if (gpio_is_valid(dp->hpd_gpio))
- return;
-
- reg = HOTPLUG_CHG | HPD_LOST | PLUG;
- writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
-
- reg = INT_HPD;
- writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
-}
-
-void exynos_dp_init_hpd(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- if (gpio_is_valid(dp->hpd_gpio))
- return;
-
- exynos_dp_clear_hotplug_interrupts(dp);
-
- reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
- reg &= ~(F_HPD | HPD_CTRL);
- writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
-}
-
-enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- if (gpio_is_valid(dp->hpd_gpio)) {
- reg = gpio_get_value(dp->hpd_gpio);
- if (reg)
- return DP_IRQ_TYPE_HP_CABLE_IN;
- else
- return DP_IRQ_TYPE_HP_CABLE_OUT;
- } else {
- /* Parse hotplug interrupt status register */
- reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
-
- if (reg & PLUG)
- return DP_IRQ_TYPE_HP_CABLE_IN;
-
- if (reg & HPD_LOST)
- return DP_IRQ_TYPE_HP_CABLE_OUT;
-
- if (reg & HOTPLUG_CHG)
- return DP_IRQ_TYPE_HP_CHANGE;
-
- return DP_IRQ_TYPE_UNKNOWN;
- }
-}
-
-void exynos_dp_reset_aux(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- /* Disable AUX channel module */
- reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
- reg |= AUX_FUNC_EN_N;
- writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
-}
-
-void exynos_dp_init_aux(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- /* Clear inerrupts related to AUX channel */
- reg = RPLY_RECEIV | AUX_ERR;
- writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
-
- exynos_dp_reset_aux(dp);
-
- /* Disable AUX transaction H/W retry */
- reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
- AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL);
-
- /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
- reg = DEFER_CTRL_EN | DEFER_COUNT(1);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL);
-
- /* Enable AUX channel module */
- reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
- reg &= ~AUX_FUNC_EN_N;
- writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
-}
-
-int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- if (gpio_is_valid(dp->hpd_gpio)) {
- if (gpio_get_value(dp->hpd_gpio))
- return 0;
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
- if (reg & HPD_STATUS)
- return 0;
- }
-
- return -EINVAL;
-}
-
-void exynos_dp_enable_sw_function(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
- reg &= ~SW_FUNC_EN_N;
- writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
-}
-
-int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
-{
- int reg;
- int retval = 0;
- int timeout_loop = 0;
-
- /* Enable AUX CH operation */
- reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
- reg |= AUX_EN;
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
-
- /* Is AUX CH command reply received? */
- reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
- while (!(reg & RPLY_RECEIV)) {
- timeout_loop++;
- if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
- dev_err(dp->dev, "AUX CH command reply failed!\n");
- return -ETIMEDOUT;
- }
- reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
- usleep_range(10, 11);
- }
-
- /* Clear interrupt source for AUX CH command reply */
- writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA);
-
- /* Clear interrupt source for AUX CH access error */
- reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
- if (reg & AUX_ERR) {
- writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA);
- return -EREMOTEIO;
- }
-
- /* Check AUX CH error access status */
- reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA);
- if ((reg & AUX_STATUS_MASK) != 0) {
- dev_err(dp->dev, "AUX CH error happens: %d\n\n",
- reg & AUX_STATUS_MASK);
- return -EREMOTEIO;
- }
-
- return retval;
-}
-
-int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned char data)
-{
- u32 reg;
- int i;
- int retval;
-
- for (i = 0; i < 3; i++) {
- /* Clear AUX CH data buffer */
- reg = BUF_CLR;
- writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
-
- /* Select DPCD device address */
- reg = AUX_ADDR_7_0(reg_addr);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
- reg = AUX_ADDR_15_8(reg_addr);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
- reg = AUX_ADDR_19_16(reg_addr);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
-
- /* Write data buffer */
- reg = (unsigned int)data;
- writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
-
- /*
- * Set DisplayPort transaction and write 1 byte
- * If bit 3 is 1, DisplayPort transaction.
- * If Bit 3 is 0, I2C transaction.
- */
- reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
-
- /* Start AUX transaction */
- retval = exynos_dp_start_aux_transaction(dp);
- if (retval == 0)
- break;
-
- dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
- }
-
- return retval;
-}
-
-int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned char *data)
-{
- u32 reg;
- int i;
- int retval;
-
- for (i = 0; i < 3; i++) {
- /* Clear AUX CH data buffer */
- reg = BUF_CLR;
- writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
-
- /* Select DPCD device address */
- reg = AUX_ADDR_7_0(reg_addr);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
- reg = AUX_ADDR_15_8(reg_addr);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
- reg = AUX_ADDR_19_16(reg_addr);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
-
- /*
- * Set DisplayPort transaction and read 1 byte
- * If bit 3 is 1, DisplayPort transaction.
- * If Bit 3 is 0, I2C transaction.
- */
- reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
-
- /* Start AUX transaction */
- retval = exynos_dp_start_aux_transaction(dp);
- if (retval == 0)
- break;
-
- dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
- }
-
- /* Read data buffer */
- reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
- *data = (unsigned char)(reg & 0xff);
-
- return retval;
-}
-
-int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned int count,
- unsigned char data[])
-{
- u32 reg;
- unsigned int start_offset;
- unsigned int cur_data_count;
- unsigned int cur_data_idx;
- int i;
- int retval = 0;
-
- /* Clear AUX CH data buffer */
- reg = BUF_CLR;
- writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
-
- start_offset = 0;
- while (start_offset < count) {
- /* Buffer size of AUX CH is 16 * 4bytes */
- if ((count - start_offset) > 16)
- cur_data_count = 16;
- else
- cur_data_count = count - start_offset;
-
- for (i = 0; i < 3; i++) {
- /* Select DPCD device address */
- reg = AUX_ADDR_7_0(reg_addr + start_offset);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
- reg = AUX_ADDR_15_8(reg_addr + start_offset);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
- reg = AUX_ADDR_19_16(reg_addr + start_offset);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
-
- for (cur_data_idx = 0; cur_data_idx < cur_data_count;
- cur_data_idx++) {
- reg = data[start_offset + cur_data_idx];
- writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0
- + 4 * cur_data_idx);
- }
-
- /*
- * Set DisplayPort transaction and write
- * If bit 3 is 1, DisplayPort transaction.
- * If Bit 3 is 0, I2C transaction.
- */
- reg = AUX_LENGTH(cur_data_count) |
- AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
-
- /* Start AUX transaction */
- retval = exynos_dp_start_aux_transaction(dp);
- if (retval == 0)
- break;
-
- dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
- __func__);
- }
-
- start_offset += cur_data_count;
- }
-
- return retval;
-}
-
-int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
- unsigned int reg_addr,
- unsigned int count,
- unsigned char data[])
-{
- u32 reg;
- unsigned int start_offset;
- unsigned int cur_data_count;
- unsigned int cur_data_idx;
- int i;
- int retval = 0;
-
- /* Clear AUX CH data buffer */
- reg = BUF_CLR;
- writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
-
- start_offset = 0;
- while (start_offset < count) {
- /* Buffer size of AUX CH is 16 * 4bytes */
- if ((count - start_offset) > 16)
- cur_data_count = 16;
- else
- cur_data_count = count - start_offset;
-
- /* AUX CH Request Transaction process */
- for (i = 0; i < 3; i++) {
- /* Select DPCD device address */
- reg = AUX_ADDR_7_0(reg_addr + start_offset);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
- reg = AUX_ADDR_15_8(reg_addr + start_offset);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
- reg = AUX_ADDR_19_16(reg_addr + start_offset);
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
-
- /*
- * Set DisplayPort transaction and read
- * If bit 3 is 1, DisplayPort transaction.
- * If Bit 3 is 0, I2C transaction.
- */
- reg = AUX_LENGTH(cur_data_count) |
- AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
-
- /* Start AUX transaction */
- retval = exynos_dp_start_aux_transaction(dp);
- if (retval == 0)
- break;
-
- dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
- __func__);
- }
-
- for (cur_data_idx = 0; cur_data_idx < cur_data_count;
- cur_data_idx++) {
- reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
- + 4 * cur_data_idx);
- data[start_offset + cur_data_idx] =
- (unsigned char)reg;
- }
-
- start_offset += cur_data_count;
- }
-
- return retval;
-}
-
-int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
- unsigned int device_addr,
- unsigned int reg_addr)
-{
- u32 reg;
- int retval;
-
- /* Set EDID device address */
- reg = device_addr;
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
- writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
- writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
-
- /* Set offset from base address of EDID device */
- writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
-
- /*
- * Set I2C transaction and write address
- * If bit 3 is 1, DisplayPort transaction.
- * If Bit 3 is 0, I2C transaction.
- */
- reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT |
- AUX_TX_COMM_WRITE;
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
-
- /* Start AUX transaction */
- retval = exynos_dp_start_aux_transaction(dp);
- if (retval != 0)
- dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
-
- return retval;
-}
-
-int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
- unsigned int device_addr,
- unsigned int reg_addr,
- unsigned int *data)
-{
- u32 reg;
- int i;
- int retval;
-
- for (i = 0; i < 3; i++) {
- /* Clear AUX CH data buffer */
- reg = BUF_CLR;
- writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
-
- /* Select EDID device */
- retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr);
- if (retval != 0)
- continue;
-
- /*
- * Set I2C transaction and read data
- * If bit 3 is 1, DisplayPort transaction.
- * If Bit 3 is 0, I2C transaction.
- */
- reg = AUX_TX_COMM_I2C_TRANSACTION |
- AUX_TX_COMM_READ;
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
-
- /* Start AUX transaction */
- retval = exynos_dp_start_aux_transaction(dp);
- if (retval == 0)
- break;
-
- dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
- }
-
- /* Read data */
- if (retval == 0)
- *data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
-
- return retval;
-}
-
-int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
- unsigned int device_addr,
- unsigned int reg_addr,
- unsigned int count,
- unsigned char edid[])
-{
- u32 reg;
- unsigned int i, j;
- unsigned int cur_data_idx;
- unsigned int defer = 0;
- int retval = 0;
-
- for (i = 0; i < count; i += 16) {
- for (j = 0; j < 3; j++) {
- /* Clear AUX CH data buffer */
- reg = BUF_CLR;
- writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
-
- /* Set normal AUX CH command */
- reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
- reg &= ~ADDR_ONLY;
- writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
-
- /*
- * If Rx sends defer, Tx sends only reads
- * request without sending address
- */
- if (!defer)
- retval = exynos_dp_select_i2c_device(
- dp, device_addr, reg_addr + i);
- else
- defer = 0;
-
- if (retval == 0) {
- /*
- * Set I2C transaction and write data
- * If bit 3 is 1, DisplayPort transaction.
- * If Bit 3 is 0, I2C transaction.
- */
- reg = AUX_LENGTH(16) |
- AUX_TX_COMM_I2C_TRANSACTION |
- AUX_TX_COMM_READ;
- writel(reg, dp->reg_base +
- EXYNOS_DP_AUX_CH_CTL_1);
-
- /* Start AUX transaction */
- retval = exynos_dp_start_aux_transaction(dp);
- if (retval == 0)
- break;
-
- dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
- __func__);
- }
- /* Check if Rx sends defer */
- reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
- if (reg == AUX_RX_COMM_AUX_DEFER ||
- reg == AUX_RX_COMM_I2C_DEFER) {
- dev_err(dp->dev, "Defer: %d\n\n", reg);
- defer = 1;
- }
- }
-
- for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) {
- reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
- + 4 * cur_data_idx);
- edid[i + cur_data_idx] = (unsigned char)reg;
- }
- }
-
- return retval;
-}
-
-void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype)
-{
- u32 reg;
-
- reg = bwtype;
- if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype == LINK_RATE_1_62GBPS))
- writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET);
-}
-
-void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET);
- *bwtype = reg;
-}
-
-void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count)
-{
- u32 reg;
-
- reg = count;
- writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
-}
-
-void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
- *count = reg;
-}
-
-void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable)
-{
- u32 reg;
-
- if (enable) {
- reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
- reg |= ENHANCED;
- writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
- reg &= ~ENHANCED;
- writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
- }
-}
-
-void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
- enum pattern_set pattern)
-{
- u32 reg;
-
- switch (pattern) {
- case PRBS7:
- reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
- writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
- break;
- case D10_2:
- reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
- writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
- break;
- case TRAINING_PTN1:
- reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
- writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
- break;
- case TRAINING_PTN2:
- reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
- writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
- break;
- case DP_NONE:
- reg = SCRAMBLING_ENABLE |
- LINK_QUAL_PATTERN_SET_DISABLE |
- SW_TRAINING_PATTERN_SET_NORMAL;
- writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
- break;
- default:
- break;
- }
-}
-
-void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
- reg &= ~PRE_EMPHASIS_SET_MASK;
- reg |= level << PRE_EMPHASIS_SET_SHIFT;
- writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
-}
-
-void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
- reg &= ~PRE_EMPHASIS_SET_MASK;
- reg |= level << PRE_EMPHASIS_SET_SHIFT;
- writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
-}
-
-void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
- reg &= ~PRE_EMPHASIS_SET_MASK;
- reg |= level << PRE_EMPHASIS_SET_SHIFT;
- writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
-}
-
-void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
- reg &= ~PRE_EMPHASIS_SET_MASK;
- reg |= level << PRE_EMPHASIS_SET_SHIFT;
- writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
-}
-
-void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
- u32 training_lane)
-{
- u32 reg;
-
- reg = training_lane;
- writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
-}
-
-void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
- u32 training_lane)
-{
- u32 reg;
-
- reg = training_lane;
- writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
-}
-
-void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
- u32 training_lane)
-{
- u32 reg;
-
- reg = training_lane;
- writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
-}
-
-void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
- u32 training_lane)
-{
- u32 reg;
-
- reg = training_lane;
- writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
-}
-
-u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
- return reg;
-}
-
-u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
- return reg;
-}
-
-u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
- return reg;
-}
-
-u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
- return reg;
-}
-
-void exynos_dp_reset_macro(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST);
- reg |= MACRO_RST;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
-
- /* 10 us is the minimum reset time. */
- usleep_range(10, 20);
-
- reg &= ~MACRO_RST;
- writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
-}
-
-void exynos_dp_init_video(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
- writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
-
- reg = 0x0;
- writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
-
- reg = CHA_CRI(4) | CHA_CTRL;
- writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
-
- reg = 0x0;
- writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
-
- reg = VID_HRES_TH(2) | VID_VRES_TH(0);
- writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
-}
-
-void exynos_dp_set_video_color_format(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- /* Configure the input color depth, color space, dynamic range */
- reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) |
- (dp->video_info->color_depth << IN_BPC_SHIFT) |
- (dp->video_info->color_space << IN_COLOR_F_SHIFT);
- writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2);
-
- /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
- reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
- reg &= ~IN_YC_COEFFI_MASK;
- if (dp->video_info->ycbcr_coeff)
- reg |= IN_YC_COEFFI_ITU709;
- else
- reg |= IN_YC_COEFFI_ITU601;
- writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
-}
-
-int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
- writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
-
- reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
-
- if (!(reg & DET_STA)) {
- dev_dbg(dp->dev, "Input stream clock not detected.\n");
- return -EINVAL;
- }
-
- reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
- writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
-
- reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
- dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
-
- if (reg & CHA_STA) {
- dev_dbg(dp->dev, "Input stream clk is changing\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
- enum clock_recovery_m_value_type type,
- u32 m_value,
- u32 n_value)
-{
- u32 reg;
-
- if (type == REGISTER_M) {
- reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
- reg |= FIX_M_VID;
- writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
- reg = m_value & 0xff;
- writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0);
- reg = (m_value >> 8) & 0xff;
- writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1);
- reg = (m_value >> 16) & 0xff;
- writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2);
-
- reg = n_value & 0xff;
- writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0);
- reg = (n_value >> 8) & 0xff;
- writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1);
- reg = (n_value >> 16) & 0xff;
- writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2);
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
- reg &= ~FIX_M_VID;
- writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
-
- writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0);
- writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1);
- writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2);
- }
-}
-
-void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type)
-{
- u32 reg;
-
- if (type == VIDEO_TIMING_FROM_CAPTURE) {
- reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
- reg &= ~FORMAT_SEL;
- writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
- reg |= FORMAT_SEL;
- writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
- }
-}
-
-void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable)
-{
- u32 reg;
-
- if (enable) {
- reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
- reg &= ~VIDEO_MODE_MASK;
- reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
- writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
- } else {
- reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
- reg &= ~VIDEO_MODE_MASK;
- reg |= VIDEO_MODE_SLAVE_MODE;
- writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
- }
-}
-
-void exynos_dp_start_video(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
- reg |= VIDEO_EN;
- writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
-}
-
-int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
- writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
-
- reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
- if (!(reg & STRM_VALID)) {
- dev_dbg(dp->dev, "Input video stream is not detected.\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
- reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
- reg |= MASTER_VID_FUNC_EN_N;
- writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
-
- reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
- reg &= ~INTERACE_SCAN_CFG;
- reg |= (dp->video_info->interlaced << 2);
- writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
-
- reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
- reg &= ~VSYNC_POLARITY_CFG;
- reg |= (dp->video_info->v_sync_polarity << 1);
- writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
-
- reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
- reg &= ~HSYNC_POLARITY_CFG;
- reg |= (dp->video_info->h_sync_polarity << 0);
- writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
-
- reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
- writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
-}
-
-void exynos_dp_enable_scrambling(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
- reg &= ~SCRAMBLING_DISABLE;
- writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
-}
-
-void exynos_dp_disable_scrambling(struct exynos_dp_device *dp)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
- reg |= SCRAMBLING_DISABLE;
- writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
-}
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
new file mode 100644
index 0000000..8b4ffad
--- /dev/null
+++ b/include/drm/bridge/analogix_dp.h
@@ -0,0 +1,24 @@
+#ifndef _ANALOGIX_DP_H_
+#define _ANALOGIX_DP_H_
+
+#include <drm/drm_crtc.h>
+
+struct analogix_dp_plat_data {
+ struct drm_panel *panel;
+
+ int (*power_on)(struct analogix_dp_plat_data *);
+ int (*power_off)(struct analogix_dp_plat_data *);
+ int (*attach)(struct analogix_dp_plat_data *, struct drm_bridge *);
+ int (*get_modes)(struct analogix_dp_plat_data *,
+ struct drm_connector *);
+};
+
+int analogix_dp_resume(struct device *dev);
+int analogix_dp_suspend(struct device *dev);
+
+int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
+ struct drm_encoder *encoder,
+ struct analogix_dp_plat_data *plat_data);
+void analogix_dp_unbind(struct device *dev, struct device *master, void *data);
+
+#endif /* _ANALOGIX_DP_H_ */
--
1.9.1

2015-08-19 14:50:32

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 04/14] drm: bridge/analogix_dp: dynamic parse sync_pol & interlace & colorimetry

Both hsync/vsync polarity and interlace mode can be parsed from
drm display mode, and dynamic_range and ycbcr_coeff can be judge
by the video code.

But presumably Exynos still relaies on the DT properties, so take
good use of mode_fixup() in to achieve the compatibility hacks.

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3:
- Take Thierry Reding suggest, dynamic parse video timing info from
struct drm_display_mode and struct drm_display_info.

Changes in v2: None

drivers/gpu/drm/bridge/analogix_dp_core.c | 50 ++++++++++++----------
drivers/gpu/drm/exynos/analogix_dp-exynos.c | 65 ++++++++++++++++++++++++++---
2 files changed, 89 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 6c15e20..480cc13 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -1110,11 +1110,40 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
dp->dpms_mode = DRM_MODE_DPMS_OFF;
}

+static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
+ struct drm_display_mode *orig_mode,
+ struct drm_display_mode *mode)
+{
+ struct analogix_dp_device *dp = bridge->driver_private;
+ struct video_info *video_info = dp->video_info;
+ int vic;
+
+ /* interlaces & hsync pol & vsync pol */
+ video_info->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
+ video_info->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
+ video_info->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
+
+ /* dynamic_range & colorimetry */
+ vic = drm_match_cea_mode(mode);
+ if ((vic == 6) || (vic == 7) || (vic == 21) || (vic == 22) ||
+ (vic == 2) || (vic == 3) || (vic == 17) || (vic == 18)) {
+ video_info->dynamic_range = CEA;
+ video_info->ycbcr_coeff = COLOR_YCBCR601;
+ } else if (vic) {
+ video_info->dynamic_range = CEA;
+ video_info->ycbcr_coeff = COLOR_YCBCR709;
+ } else {
+ video_info->dynamic_range = VESA;
+ video_info->ycbcr_coeff = COLOR_YCBCR709;
+ }
+}
+
static const struct drm_bridge_funcs analogix_dp_bridge_funcs = {
.enable = analogix_dp_bridge_enable,
.disable = analogix_dp_bridge_disable,
.pre_enable = analogix_dp_bridge_nop,
.post_disable = analogix_dp_bridge_nop,
+ .mode_set = analogix_dp_bridge_mode_set,
.attach = analogix_dp_bridge_attach,
};

@@ -1156,33 +1185,12 @@ static struct video_info *analogix_dp_dt_parse_pdata(struct device *dev)
if (!dp_video_config)
return ERR_PTR(-ENOMEM);

- dp_video_config->h_sync_polarity =
- of_property_read_bool(dp_node, "hsync-active-high");
-
- dp_video_config->v_sync_polarity =
- of_property_read_bool(dp_node, "vsync-active-high");
-
- dp_video_config->interlaced =
- of_property_read_bool(dp_node, "interlaced");
-
if (of_property_read_u32(dp_node, "analogix,color-space",
&dp_video_config->color_space)) {
dev_err(dev, "failed to get color-space\n");
return ERR_PTR(-EINVAL);
}

- if (of_property_read_u32(dp_node, "analogix,dynamic-range",
- &dp_video_config->dynamic_range)) {
- dev_err(dev, "failed to get dynamic-range\n");
- return ERR_PTR(-EINVAL);
- }
-
- if (of_property_read_u32(dp_node, "analogix,ycbcr-coeff",
- &dp_video_config->ycbcr_coeff)) {
- dev_err(dev, "failed to get ycbcr-coeff\n");
- return ERR_PTR(-EINVAL);
- }
-
if (of_property_read_u32(dp_node, "analogix,color-depth",
&dp_video_config->color_depth)) {
dev_err(dev, "failed to get color-depth\n");
diff --git a/drivers/gpu/drm/exynos/analogix_dp-exynos.c b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
index d5631c2..17da2c8 100644
--- a/drivers/gpu/drm/exynos/analogix_dp-exynos.c
+++ b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
@@ -26,11 +26,17 @@
#include <drm/exynos_drm.h>
#include "exynos_drm_drv.h"

-#define plat_data_to_dp(pd) \
- container_of(pd, struct exynos_dp_device, plat_data)
+#define to_dp(nm) container_of(nm, struct exynos_dp_device, nm)
+
+struct video_info {
+ bool h_sync_polarity;
+ bool v_sync_polarity;
+ bool interlaced;
+};

struct exynos_dp_device {
struct exynos_drm_display display;
+ struct video_info video_info;
struct drm_bridge *ptn_bridge;
struct drm_device *drm_dev;
struct device *dev;
@@ -42,7 +48,7 @@ struct exynos_dp_device {
int exynos_dp_crtc_clock_enable(struct analogix_dp_plat_data *plat_data,
bool enable)
{
- struct exynos_dp_device *dp = plat_data_to_dp(plat_data);
+ struct exynos_dp_device *dp = to_dp(plat_data);
struct drm_encoder *encoder = dp->display.encoder;
struct exynos_drm_crtc *crtc;

@@ -69,7 +75,7 @@ static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data)
static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data,
struct drm_connector *connector)
{
- struct exynos_dp_device *dp = plat_data_to_dp(plat_data);
+ struct exynos_dp_device *dp = to_dp(plat_data);
struct drm_display_mode *mode;

if (dp->plat_data.panel)
@@ -97,7 +103,7 @@ static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data,
static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
struct drm_bridge *bridge)
{
- struct exynos_dp_device *dp = plat_data_to_dp(plat_data);
+ struct exynos_dp_device *dp = to_dp(plat_data);
struct drm_encoder *encoder = dp->display.encoder;
int ret;

@@ -116,6 +122,34 @@ static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
return 0;
}

+static void exynos_dp_mode_fixup(struct exynos_drm_display *display,
+ struct drm_connector *connector,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct exynos_dp_device *dp = to_dp(display);
+ int flags = adjusted_mode->flags;
+
+ flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
+ DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE);
+
+ if (dp->video_info.h_sync_polarity)
+ flags |= DRM_MODE_FLAG_PHSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NHSYNC;
+
+ if (dp->video_info.v_sync_polarity)
+ flags |= DRM_MODE_FLAG_PVSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NVSYNC;
+
+ if (dp->video_info.interlaced)
+ flags |= DRM_MODE_FLAG_INTERLACE;
+
+ adjusted_mode->flags = flags;
+}
+
static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
{
/* do nothing */
@@ -137,6 +171,7 @@ static struct exynos_drm_display_ops exynos_dp_display_ops = {
.create_connector = exynos_dp_create_connector,
.dpms = exynos_dp_dpms,
.commit = exynos_dp_commit,
+ .mode_fixup = exynos_dp_mode_fixup,
};

static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
@@ -153,6 +188,22 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
return 0;
}

+static int exynos_dp_dt_parse_video_info(struct exynos_dp_device *dp)
+{
+ struct device_node *dp_node = dp->dev->of_node;
+
+ dp->video_info.h_sync_polarity =
+ of_property_read_bool(dp_node, "hsync-active-high");
+
+ dp->video_info.v_sync_polarity =
+ of_property_read_bool(dp_node, "vsync-active-high");
+
+ dp->video_info.interlaced =
+ of_property_read_bool(dp_node, "interlaced");
+
+ return 0;
+}
+
static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
{
struct exynos_dp_device *dp = dev_get_drvdata(dev);
@@ -180,6 +231,10 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
return ret;
}

+ ret = exynos_dp_dt_parse_video_info(dp);
+ if (ret)
+ return ret;
+
ret = exynos_drm_create_enc_conn(dp->drm_dev, &dp->display);
if (ret) {
DRM_ERROR("exynos dp create enc_conn failed\n");
--
1.9.1

2015-08-19 14:50:42

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 05/14] drm: bridge/analogix_dp: fix link_rate & lane_count bug

link_rate and lane_count already configed in analogix_dp_set_link_train(),
so we don't need to config those repeatly after training finished, just
remove them out.

Beside Display Port 1.2 already support 5.4Gbps link rate, the maximum sets
would change from {1.62Gbps, 2.7Gbps} to {1.62Gbps, 2.7Gbps, 5.4Gbps}.

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3:
- Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
the DT property value directly, but we can take those as hardware limite.
For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
so DT property would like "link-rate = 0x0a" "lane-count = 4".

Changes in v2: None

drivers/gpu/drm/bridge/analogix_dp_core.c | 16 ++++++++--------
drivers/gpu/drm/bridge/analogix_dp_core.h | 9 +++++----
2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 480cc13..1778e0a 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -635,6 +635,8 @@ static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
/*
* For DP rev.1.1, Maximum link rate of Main Link lanes
* 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
+ * For DP rev.1.2, Maximum link rate of Main Link lanes
+ * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps, 0x14 = 5.4Gbps
*/
analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
*bandwidth = data;
@@ -668,7 +670,8 @@ static void analogix_dp_init_training(struct analogix_dp_device *dp,
analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);

if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
- (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
+ (dp->link_train.link_rate != LINK_RATE_2_70GBPS) &&
+ (dp->link_train.link_rate != LINK_RATE_5_40GBPS)) {
dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
dp->link_train.link_rate);
dp->link_train.link_rate = LINK_RATE_1_62GBPS;
@@ -901,8 +904,8 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
return;
}

- ret = analogix_dp_set_link_train(dp, dp->video_info->lane_count,
- dp->video_info->link_rate);
+ ret = analogix_dp_set_link_train(dp, dp->video_info->max_lane_count,
+ dp->video_info->max_link_rate);
if (ret) {
dev_err(dp->dev, "unable to do link train\n");
return;
@@ -912,9 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
analogix_dp_enable_enhanced_mode(dp, 1);

- analogix_dp_set_lane_count(dp, dp->video_info->lane_count);
- analogix_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
-
analogix_dp_init_video(dp);
ret = analogix_dp_config_video(dp);
if (ret)
@@ -1198,13 +1198,13 @@ static struct video_info *analogix_dp_dt_parse_pdata(struct device *dev)
}

if (of_property_read_u32(dp_node, "analogix,link-rate",
- &dp_video_config->link_rate)) {
+ &dp_video_config->max_link_rate)) {
dev_err(dev, "failed to get link-rate\n");
return ERR_PTR(-EINVAL);
}

if (of_property_read_u32(dp_node, "analogix,lane-count",
- &dp_video_config->lane_count)) {
+ &dp_video_config->max_lane_count)) {
dev_err(dev, "failed to get lane-count\n");
return ERR_PTR(-EINVAL);
}
diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
index 2cefde9..941b34f 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
@@ -21,8 +21,9 @@
#define MAX_EQ_LOOP 5

enum link_rate_type {
- LINK_RATE_1_62GBPS = 0x06,
- LINK_RATE_2_70GBPS = 0x0a
+ LINK_RATE_1_62GBPS = DP_LINK_BW_1_62,
+ LINK_RATE_2_70GBPS = DP_LINK_BW_2_7,
+ LINK_RATE_5_40GBPS = DP_LINK_BW_5_4,
};

enum link_lane_count_type {
@@ -128,8 +129,8 @@ struct video_info {
enum color_coefficient ycbcr_coeff;
enum color_depth color_depth;

- enum link_rate_type link_rate;
- enum link_lane_count_type lane_count;
+ enum link_rate_type max_link_rate;
+ enum link_lane_count_type max_lane_count;
};

struct link_train {
--
1.9.1

2015-08-19 14:50:54

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Analogix dp driver is split from exynos dp driver, so we just
make an copy of exynos_dp.txt, and then simplify exynos_dp.txt

Beside update some exynos dtsi file with the latest change
according to the devicetree binding documents.

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3:
- Take Heiko suggest, add devicetree binding documents.
- Take Thierry Reding suggest, remove sync pol & colorimetry properies
from the new analogix dp driver devicetree binding.
- Update the exist exynos dtsi file with the latest DP DT properies.

Changes in v2: None

.../devicetree/bindings/drm/bridge/analogix_dp.txt | 70 ++++++++++++++++++++++
.../devicetree/bindings/video/exynos_dp.txt | 50 ++++++----------
arch/arm/boot/dts/exynos5250-arndale.dts | 10 ++--
arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 ++--
arch/arm/boot/dts/exynos5250-snow.dts | 12 ++--
arch/arm/boot/dts/exynos5250-spring.dts | 12 ++--
arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 ++--
arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 ++--
arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 ++--
9 files changed, 119 insertions(+), 79 deletions(-)
create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt

diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
new file mode 100644
index 0000000..6127018
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
@@ -0,0 +1,70 @@
+Analogix Display Port bridge bindings
+
+Required properties for dp-controller:
+ -compatible:
+ platform specific such as:
+ * "samsung,exynos5-dp"
+ * "rockchip,rk3288-dp"
+ -reg:
+ physical base address of the controller and length
+ of memory mapped region.
+ -interrupts:
+ interrupt combiner values.
+ -clocks:
+ from common clock binding: handle to dp clock.
+ -clock-names:
+ from common clock binding: Shall be "dp".
+ -interrupt-parent:
+ phandle to Interrupt combiner node.
+ -phys:
+ from general PHY binding: the phandle for the PHY device.
+ -phy-names:
+ from general PHY binding: Should be "dp".
+ -analogix,color-space:
+ input video data format.
+ COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
+ -analogix,color-depth:
+ number of bits per colour component.
+ COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
+ -analogix,link-rate:
+ max link rate supported by the eDP controller.
+ LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
+ LINK_RATE_5_40GBPS = 0x14
+ -analogix,lane-count:
+ max number of lanes supported by the eDP contoller.
+ LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
+ -port@[X]: SoC specific port nodes with endpoint definitions as defined
+ in Documentation/devicetree/bindings/media/video-interfaces.txt,
+ please refer to the SoC specific binding document:
+ * Documentation/devicetree/bindings/video/exynos_dp.txt
+ * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
+
+Optional properties for dp-controller:
+ -analogix,hpd-gpio:
+ Hotplug detect GPIO.
+ Indicates which GPIO should be used for hotplug
+ detection
+ -video interfaces: Device node can contain video interface port
+ nodes according to [1].
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+-------------------------------------------------------------------------------
+
+Example:
+
+ dp-controller {
+ compatible = "samsung,exynos5-dp";
+ reg = <0x145b0000 0x10000>;
+ interrupts = <10 3>;
+ interrupt-parent = <&combiner>;
+ clocks = <&clock 342>;
+ clock-names = "dp";
+
+ phys = <&dp_phy>;
+ phy-names = "dp";
+
+ analogix,color-space = <0>;
+ analogix,color-depth = <1>;
+ analogix,link-rate = <0x0a>;
+ analogix,lane-count = <4>;
+ };
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
index 7a3a9cd..177506f 100644
--- a/Documentation/devicetree/bindings/video/exynos_dp.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -31,28 +31,10 @@ Required properties for dp-controller:
from general PHY binding: the phandle for the PHY device.
-phy-names:
from general PHY binding: Should be "dp".
- -samsung,color-space:
- input video data format.
- COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
- -samsung,dynamic-range:
- dynamic range for input video data.
- VESA = 0, CEA = 1
- -samsung,ycbcr-coeff:
- YCbCr co-efficients for input video.
- COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
- -samsung,color-depth:
- number of bits per colour component.
- COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
- -samsung,link-rate:
- link rate supported by the panel.
- LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
- -samsung,lane-count:
- number of lanes supported by the panel.
- LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
- - display-timings: timings for the connected panel as described by
- Documentation/devicetree/bindings/video/display-timing.txt

Optional properties for dp-controller:
+ - display-timings: timings for the connected panel as described by
+ Documentation/devicetree/bindings/video/display-timing.txt
-interlaced:
interlace scan mode.
Progressive if defined, Interlaced if not defined
@@ -62,14 +44,18 @@ Optional properties for dp-controller:
-hsync-active-high:
HSYNC polarity configuration.
High if defined, Low if not defined
- -samsung,hpd-gpio:
- Hotplug detect GPIO.
- Indicates which GPIO should be used for hotplug
- detection
- -video interfaces: Device node can contain video interface port
- nodes according to [1].

-[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+For the below properties, please refer to Analogix DP binding document:
+ * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
+ -phys (required)
+ -phy-names (required)
+ -analogix,color-space (required)
+ -analogix,color-depth (required)
+ -analogix,link-rate (required)
+ -analogix,lane-count (required)
+ -analogix,hpd-gpio (optional)
+ -video interfaces (optional)
+-------------------------------------------------------------------------------

Example:

@@ -88,12 +74,10 @@ SOC specific portion:

Board Specific portion:
dp-controller {
- samsung,color-space = <0>;
- samsung,dynamic-range = <0>;
- samsung,ycbcr-coeff = <0>;
- samsung,color-depth = <1>;
- samsung,link-rate = <0x0a>;
- samsung,lane-count = <4>;
+ analogix,color-space = <0>;
+ analogix,color-depth = <1>;
+ analogix,link-rate = <0x0a>;
+ analogix,lane-count = <4>;

display-timings {
native-mode = <&lcd_timing>;
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index 7e728a1..e48798d 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -119,12 +119,10 @@

&dp {
status = "okay";
- samsung,color-space = <0>;
- samsung,dynamic-range = <0>;
- samsung,ycbcr-coeff = <0>;
- samsung,color-depth = <1>;
- samsung,link-rate = <0x0a>;
- samsung,lane-count = <4>;
+ analogix,color-space = <0>;
+ analogix,color-depth = <1>;
+ analogix,link-rate = <0x0a>;
+ analogix,lane-count = <4>;
};

&fimd {
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 4fe186d..b8c6b8b 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -75,12 +75,10 @@
};

&dp {
- samsung,color-space = <0>;
- samsung,dynamic-range = <0>;
- samsung,ycbcr-coeff = <0>;
- samsung,color-depth = <1>;
- samsung,link-rate = <0x0a>;
- samsung,lane-count = <4>;
+ analogix,color-space = <0>;
+ analogix,color-depth = <1>;
+ analogix,link-rate = <0x0a>;
+ analogix,lane-count = <4>;

pinctrl-names = "default";
pinctrl-0 = <&dp_hpd>;
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
index b7f4122..9ce2b89 100644
--- a/arch/arm/boot/dts/exynos5250-snow.dts
+++ b/arch/arm/boot/dts/exynos5250-snow.dts
@@ -239,13 +239,11 @@
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&dp_hpd>;
- samsung,color-space = <0>;
- samsung,dynamic-range = <0>;
- samsung,ycbcr-coeff = <0>;
- samsung,color-depth = <1>;
- samsung,link-rate = <0x0a>;
- samsung,lane-count = <2>;
- samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
+ analogix,color-space = <0>;
+ analogix,color-depth = <1>;
+ analogix,link-rate = <0x0a>;
+ analogix,lane-count = <2>;
+ analogix,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;

ports {
port@0 {
diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
index d03f9b8..9288ae6 100644
--- a/arch/arm/boot/dts/exynos5250-spring.dts
+++ b/arch/arm/boot/dts/exynos5250-spring.dts
@@ -69,13 +69,11 @@
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&dp_hpd_gpio>;
- samsung,color-space = <0>;
- samsung,dynamic-range = <0>;
- samsung,ycbcr-coeff = <0>;
- samsung,color-depth = <1>;
- samsung,link-rate = <0x0a>;
- samsung,lane-count = <1>;
- samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
+ analogix,color-space = <0>;
+ analogix,color-depth = <1>;
+ analogix,link-rate = <0x0a>;
+ analogix,lane-count = <1>;
+ analogix,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
};

&ehci {
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 8f4d76c..695a380 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -147,13 +147,11 @@
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&dp_hpd_gpio>;
- samsung,color-space = <0>;
- samsung,dynamic-range = <0>;
- samsung,ycbcr-coeff = <0>;
- samsung,color-depth = <1>;
- samsung,link-rate = <0x06>;
- samsung,lane-count = <2>;
- samsung,hpd-gpio = <&gpx2 6 0>;
+ analogix,color-space = <0>;
+ analogix,color-depth = <1>;
+ analogix,link-rate = <0x06>;
+ analogix,lane-count = <2>;
+ analogix,hpd-gpio = <&gpx2 6 0>;

ports {
port@0 {
diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
index 98871f9..fd46714 100644
--- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
@@ -91,12 +91,10 @@
&dp {
pinctrl-names = "default";
pinctrl-0 = <&dp_hpd>;
- samsung,color-space = <0>;
- samsung,dynamic-range = <0>;
- samsung,ycbcr-coeff = <0>;
- samsung,color-depth = <1>;
- samsung,link-rate = <0x0a>;
- samsung,lane-count = <4>;
+ analogix,color-space = <0>;
+ analogix,color-depth = <1>;
+ analogix,link-rate = <0x0a>;
+ analogix,lane-count = <4>;
status = "okay";
};

diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 7d5b386..54b4c63 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -141,13 +141,11 @@
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&dp_hpd_gpio>;
- samsung,color-space = <0>;
- samsung,dynamic-range = <0>;
- samsung,ycbcr-coeff = <0>;
- samsung,color-depth = <1>;
- samsung,link-rate = <0x0a>;
- samsung,lane-count = <2>;
- samsung,hpd-gpio = <&gpx2 6 0>;
+ analogix,color-space = <0>;
+ analogix,color-depth = <1>;
+ analogix,link-rate = <0x0a>;
+ analogix,lane-count = <2>;
+ analogix,hpd-gpio = <&gpx2 6 0>;
panel = <&panel>;
};

--
1.9.1

2015-08-19 14:54:42

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 07/14] drm: rockchip/dp: add rockchip platform dp driver

Rockchip have three clocks for dp controller, we leave pclk_edp
to analogix_dp driver control, and keep the sclk_edp_24m and
sclk_edp in platform driver.

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3:
- Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
driver which name to "pclk".
- Take Heiko suggest, add devicetree binding document.
- Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
point to get panel node.
- Add the new function point analogix_dp_platdata.get_modes init.

Changes in v2:
- Take Heiko suggest, get panel node with remote-endpoint method,
and create devicetree binding for driver.
- Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
leave those clock to rockchip dp phy driver.

.../bindings/video/analogix_dp-rockchip.txt | 82 +++++
drivers/gpu/drm/rockchip/Kconfig | 9 +
drivers/gpu/drm/rockchip/Makefile | 1 +
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 389 +++++++++++++++++++++
4 files changed, 481 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c

diff --git a/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt b/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
new file mode 100644
index 0000000..99fd421
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
@@ -0,0 +1,82 @@
+Rockchip RK3288 specific extensions to the Analogix Display Port
+================================
+
+Required properties:
+- compatible: "rockchip,rk3288-edp";
+
+- reg: physical base address of the controller and length
+- clocks: from common clock binding: handle to dp clock.
+ of memory mapped region.
+- clock-names: from common clock binding:
+ Required elements: "dp" "pclk"
+- resets: Must contain an entry for each entry in reset-names.
+ See ../reset/reset.txt for details.
+- reset-names: Must include the name "dp"
+
+- rockchip,grf: this soc should set GRF regs, so need get grf here.
+
+- ports: contain a port node with endpoint definitions as defined in
+ Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+
+For the below properties, please refer to Analogix DP binding document:
+ * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
+- phys (required)
+- phy-names (required)
+- analogix,color-space (required)
+- analogix,color-depth (required)
+- analogix,link-rate (required)
+- analogix,lane-count (required)
+- analogix,hpd-gpio (optional)
+- video interfaces (optional)
+-------------------------------------------------------------------------------
+
+Example:
+ dp-controller: dp@ff970000 {
+ compatible = "rockchip,rk3288-dp";
+ reg = <0xff970000 0x4000>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>;
+ clock-names = "dp", "pclk";
+ phys = <&dp_phy>;
+ phy-names = "dp";
+
+ rockchip,grf = <&grf>;
+ resets = <&cru 111>;
+ reset-names = "dp";
+
+ hsync-active-high = <0>;
+ vsync-active-high = <0>;
+ interlaced = <0>;
+ analogix,color-space = <0>;
+ analogix,color-depth = <1>;
+ analogix,link-rate = <0x0a>;
+ analogix,lane-count = <4>;
+ status = "disabled";
+
+ ports {
+ edp_in: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ edp_in_vopb: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vopb_out_edp>;
+ };
+ edp_in_vopl: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&vopl_out_edp>;
+ };
+ };
+
+ edp_out: port@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ edp_out_panel: endpoint {
+ reg = <0>;
+ remote-endpoint = <&panel_in_edp>
+ };
+ };
+ };
+ };
+
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 35215f6..c2ba945 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -25,3 +25,12 @@ config ROCKCHIP_DW_HDMI
for the Synopsys DesignWare HDMI driver. If you want to
enable HDMI on RK3288 based SoC, you should selet this
option.
+
+config ROCKCHIP_ANALOGIX_DP
+ tristate "Rockchip specific extensions for Analogix DP driver"
+ depends on DRM_ROCKCHIP
+ select DRM_ANALOGIX_DP
+ help
+ This selects support for Rockchip SoC specific extensions
+ for the Analogix Core DP driver. If you want to enable DP
+ on RK3288 based SoC, you should selet this option.
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index f3d8a19..8ad01fb 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -6,5 +6,6 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o rockchip_drm_fbdev.o \
rockchip_drm_gem.o

obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
+obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o

obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_drm_vop.o
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
new file mode 100644
index 0000000..cebff9e
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -0,0 +1,389 @@
+/*
+ * Rockchip SoC DP (Display Port) interface driver.
+ *
+ * Copyright (C) Fuzhou Rockchip Electronics Co., Ltd.
+ * Author: Andy Yan <[email protected]>
+ * Yakir Yang <[email protected]>
+ * Jeff Chen <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_of.h>
+#include <drm/drm_dp_helper.h>
+
+#include <linux/component.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_graph.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+#include <drm/bridge/analogix_dp.h>
+
+#include "rockchip_drm_drv.h"
+#include "rockchip_drm_vop.h"
+
+#define encoder_to_dp(c) \
+ container_of(c, struct rockchip_dp_device, encoder)
+
+#define plat_data_to_dp(pd) \
+ container_of(pd, struct rockchip_dp_device, plat_data)
+
+/* dp grf register offset */
+#define GRF_GPIO7B_IOMUX 0x0070
+#define GPIO7B3_SEL_MASK (0x03 << 6)
+#define GPIO7B3_SEL_EDP_HOTPLUG BIT(7)
+
+#define GRF_SOC_CON6 0x025c
+#define GRF_EDP_LCD_SEL_MASK BIT(5)
+#define GRF_EDP_SEL_VOP_LIT BIT(5)
+#define GRF_EDP_SEL_VOP_BIG 0
+
+struct rockchip_dp_device {
+ struct drm_device *drm_dev;
+ struct device *dev;
+ struct drm_encoder encoder;
+ struct drm_display_mode mode;
+
+ struct clk *pclk;
+ struct regmap *grf;
+ struct reset_control *rst;
+
+ struct analogix_dp_plat_data plat_data;
+};
+
+static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
+{
+ u32 val;
+ int ret;
+
+ val = GPIO7B3_SEL_EDP_HOTPLUG | (GPIO7B3_SEL_MASK << 16);
+ ret = regmap_write(dp->grf, GRF_GPIO7B_IOMUX, val);
+ if (ret != 0) {
+ dev_err(dp->dev, "Could not config GRF edp hpd: %d\n", ret);
+ return ret;
+ }
+
+ reset_control_assert(dp->rst);
+ usleep_range(10, 20);
+ reset_control_deassert(dp->rst);
+
+ return 0;
+}
+
+static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
+{
+ struct rockchip_dp_device *dp = plat_data_to_dp(plat_data);
+ int ret;
+
+ ret = clk_prepare_enable(dp->pclk);
+ if (ret < 0) {
+ dev_err(dp->dev, "failed to enable pclk %d\n", ret);
+ return ret;
+ }
+
+ ret = rockchip_dp_pre_init(dp);
+ if (ret < 0) {
+ dev_err(dp->dev, "failed to dp pre init %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
+{
+ struct rockchip_dp_device *dp = plat_data_to_dp(plat_data);
+
+ clk_disable_unprepare(dp->pclk);
+
+ return 0;
+}
+
+static bool
+rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ /* do nothing */
+ return true;
+}
+
+static void rockchip_dp_drm_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted)
+{
+ /* do nothing */
+}
+
+static void rockchip_dp_drm_encoder_prepare(struct drm_encoder *encoder)
+{
+ struct rockchip_dp_device *dp = encoder_to_dp(encoder);
+ u32 val;
+ int ret;
+
+ ret = rockchip_drm_crtc_mode_config(encoder->crtc,
+ DRM_MODE_CONNECTOR_eDP,
+ ROCKCHIP_OUT_MODE_AAAA);
+ if (ret < 0) {
+ dev_err(dp->dev, "Could not set crtc mode config: %d.\n", ret);
+ return;
+ }
+
+ ret = rockchip_drm_encoder_get_mux_id(dp->dev->of_node, encoder);
+ if (ret < 0)
+ return;
+
+ if (ret)
+ val = GRF_EDP_SEL_VOP_LIT | (GRF_EDP_LCD_SEL_MASK << 16);
+ else
+ val = GRF_EDP_SEL_VOP_BIG | (GRF_EDP_LCD_SEL_MASK << 16);
+
+ dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
+
+ ret = regmap_write(dp->grf, GRF_SOC_CON6, val);
+ if (ret != 0) {
+ dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
+ return;
+ }
+}
+
+static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
+{
+ /* do nothing */
+}
+
+static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
+ .mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
+ .mode_set = rockchip_dp_drm_encoder_mode_set,
+ .prepare = rockchip_dp_drm_encoder_prepare,
+ .commit = rockchip_dp_drm_encoder_nop,
+ .disable = rockchip_dp_drm_encoder_nop,
+};
+
+static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder)
+{
+ drm_encoder_cleanup(encoder);
+}
+
+static struct drm_encoder_funcs rockchip_dp_encoder_funcs = {
+ .destroy = rockchip_dp_drm_encoder_destroy,
+};
+
+static int rockchip_dp_init(struct rockchip_dp_device *dp)
+{
+ struct device *dev = dp->dev;
+ struct device_node *np = dev->of_node;
+ int ret;
+
+ dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+ if (IS_ERR(dp->grf)) {
+ dev_err(dev, "failed to get rockchip,grf property\n");
+ return PTR_ERR(dp->grf);
+ }
+
+ dp->pclk = devm_clk_get(dev, "pclk");
+ if (IS_ERR(dp->pclk)) {
+ dev_err(dev, "failed to get pclk property\n");
+ return PTR_ERR(dp->pclk);
+ }
+
+ dp->rst = devm_reset_control_get(dev, "dp");
+ if (IS_ERR(dp->rst)) {
+ dev_err(dev, "failed to get dp reset control\n");
+ return PTR_ERR(dp->rst);
+ }
+
+ ret = clk_prepare_enable(dp->pclk);
+ if (ret < 0) {
+ dev_err(dp->dev, "failed to enable pclk %d\n", ret);
+ return ret;
+ }
+
+ ret = rockchip_dp_pre_init(dp);
+ if (ret < 0) {
+ dev_err(dp->dev, "failed to pre init %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
+{
+ struct drm_encoder *encoder = &dp->encoder;
+ struct drm_device *drm_dev = dp->drm_dev;
+ struct device *dev = dp->dev;
+ int ret;
+
+ encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
+ dev->of_node);
+ DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+ ret = drm_encoder_init(drm_dev, encoder, &rockchip_dp_encoder_funcs,
+ DRM_MODE_ENCODER_TMDS);
+ if (ret) {
+ DRM_ERROR("failed to initialize encoder with drm\n");
+ return ret;
+ }
+
+ drm_encoder_helper_add(encoder, &rockchip_dp_encoder_helper_funcs);
+
+ return 0;
+}
+
+static int rockchip_dp_bind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct rockchip_dp_device *dp = dev_get_drvdata(dev);
+ struct drm_device *drm_dev = data;
+ int ret;
+
+ /*
+ * Just like the probe function said, we don't need the
+ * device drvrate anymore, we should leave the charge to
+ * analogix dp driver, set the device drvdata to NULL.
+ */
+ dev_set_drvdata(dev, NULL);
+
+ ret = rockchip_dp_init(dp);
+ if (ret < 0)
+ return ret;
+
+ dp->drm_dev = drm_dev;
+
+ ret = rockchip_dp_drm_create_encoder(dp);
+ if (ret) {
+ DRM_ERROR("failed to create drm encoder\n");
+ return ret;
+ }
+
+ dp->plat_data.attach = NULL;
+ dp->plat_data.get_modes = NULL;
+ dp->plat_data.power_on = rockchip_dp_poweron;
+ dp->plat_data.power_off = rockchip_dp_powerdown;
+
+ return analogix_dp_bind(dev, dp->drm_dev, &dp->encoder,
+ &dp->plat_data);
+}
+
+static void rockchip_dp_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ return analogix_dp_unbind(dev, master, data);
+}
+
+static const struct component_ops rockchip_dp_component_ops = {
+ .bind = rockchip_dp_bind,
+ .unbind = rockchip_dp_unbind,
+};
+
+static int rockchip_dp_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *panel_node, *port, *endpoint;
+ struct rockchip_dp_device *dp;
+ struct drm_panel *panel;
+
+ port = of_graph_get_port_by_id(dev->of_node, 1);
+ if (!port) {
+ dev_err(dev, "can't find output port\n");
+ return -EINVAL;
+ }
+
+ endpoint = of_get_child_by_name(port, "endpoint");
+ of_node_put(port);
+ if (!endpoint) {
+ dev_err(dev, "no output endpoint found\n");
+ return -EINVAL;
+ }
+
+ panel_node = of_graph_get_remote_port_parent(endpoint);
+ of_node_put(endpoint);
+ if (!panel_node) {
+ dev_err(dev, "no output node found\n");
+ return -EINVAL;
+ }
+
+ panel = of_drm_find_panel(panel_node);
+ if (!panel) {
+ DRM_ERROR("failed to find panel\n");
+ of_node_put(panel_node);
+ return -EPROBE_DEFER;
+ }
+
+ of_node_put(panel_node);
+
+ dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+ if (!dp)
+ return -ENOMEM;
+
+ dp->dev = dev;
+
+ dp->plat_data.panel = panel;
+
+ /*
+ * We just use the drvdata until driver run into component
+ * add function, and then we would set drvdata to null, so
+ * that analogix dp driver could take charge of the drvdata.
+ */
+ platform_set_drvdata(pdev, dp);
+
+ return component_add(dev, &rockchip_dp_component_ops);
+}
+
+static int rockchip_dp_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &rockchip_dp_component_ops);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int rockchip_dp_suspend(struct device *dev)
+{
+ return analogix_dp_suspend(dev);
+}
+
+static int rockchip_dp_resume(struct device *dev)
+{
+ return analogix_dp_resume(dev);
+}
+#endif
+
+static const struct dev_pm_ops rockchip_dp_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(rockchip_dp_suspend, rockchip_dp_resume)
+};
+
+static const struct of_device_id rockchip_dp_dt_ids[] = {
+ {.compatible = "rockchip,rk3288-dp",},
+ {}
+};
+MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
+
+static struct platform_driver rockchip_dp_driver = {
+ .probe = rockchip_dp_probe,
+ .remove = rockchip_dp_remove,
+ .driver = {
+ .name = "rockchip-dp",
+ .owner = THIS_MODULE,
+ .pm = &rockchip_dp_pm_ops,
+ .of_match_table = of_match_ptr(rockchip_dp_dt_ids),
+ },
+};
+
+module_platform_driver(rockchip_dp_driver);
+
+MODULE_AUTHOR("Yakir Yang <[email protected]>");
+MODULE_AUTHOR("Jeff chen <[email protected]>");
+MODULE_DESCRIPTION("Rockchip Specific Analogix-DP Driver Extension");
+MODULE_LICENSE("GPL v2");
--
1.9.1

2015-08-19 14:51:40

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 08/14] phy: Add driver for rockchip Display Port PHY

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3:
- Take Heiko suggest, add rockchip dp phy driver,
collect the phy clocks and power control.

Changes in v2: None

.../devicetree/bindings/phy/rockchip-dp-phy.txt | 26 +++
drivers/phy/Kconfig | 7 +
drivers/phy/Makefile | 1 +
drivers/phy/phy-rockchip-dp.c | 185 +++++++++++++++++++++
4 files changed, 219 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
create mode 100644 drivers/phy/phy-rockchip-dp.c

diff --git a/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
new file mode 100644
index 0000000..5de1088
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
@@ -0,0 +1,26 @@
+Rockchip Soc Seroes Display Port PHY
+------------------------------------
+
+Required properties:
+- compatible : should be one of the following supported values:
+ - "rockchip.rk3288-dp-phy"
+
+- reg : a list of registers used by phy driver
+- clocks: from common clock binding: handle to dp clock.
+ of memory mapped region.
+- clock-names: from common clock binding:
+ Required elements: "sclk_dp" "sclk_dp_24m"
+
+- rockchip,grf: this soc should set GRF regs, so need get grf here.
+- #phy-cells : from the generic PHY bindings, must be 0;
+
+Example:
+
+edp_phy: phy@ff770274 {
+ compatilble = "rockchip,rk3288-dp-phy";
+ reg = <0xff770274 4>;
+ rockchip,grf = <&grf>;
+ clocks = <&cru SCLK_EDP_24M>;
+ clock-names = "24m";
+ #phy-cells = <0>;
+}
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 6b8dd16..da00440 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -297,6 +297,13 @@ config PHY_ROCKCHIP_USB
help
Enable this to support the Rockchip USB 2.0 PHY.

+config PHY_ROCKCHIP_DP
+ tristate "Rockchip Display Port PHY Driver"
+ depends on ARCH_ROCKCHIP && OF
+ select GENERIC_PHY
+ help
+ Enable this to support the Rockchip Display Port PHY.
+
config PHY_ST_SPEAR1310_MIPHY
tristate "ST SPEAR1310-MIPHY driver"
select GENERIC_PHY
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index f344e1b..35e3ce6 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -33,6 +33,7 @@ phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
+obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
diff --git a/drivers/phy/phy-rockchip-dp.c b/drivers/phy/phy-rockchip-dp.c
new file mode 100644
index 0000000..4759111
--- /dev/null
+++ b/drivers/phy/phy-rockchip-dp.c
@@ -0,0 +1,185 @@
+/*
+ * Rockchip DP PHY driver
+ *
+ * Copyright (C) 2015 FuZhou Rockchip Co., Ltd.
+ * Author: Yakir Yang <ykk@@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+
+#define GRF_SOC_CON12 0x0274
+#define GRF_EDP_REF_CLK_SEL_INTER BIT(4)
+
+#define DP_PHY_SIDDQ_WRITE_EN BIT(21)
+#define DP_PHY_SIDDQ_ON 0
+#define DP_PHY_SIDDQ_OFF BIT(5)
+
+struct rockchip_dp_phy {
+ struct device *dev;
+ struct regmap *grf;
+ void __iomem *regs;
+ struct clk *phy_24m;
+};
+
+static int rockchip_dp_phy_clk_enable(struct rockchip_dp_phy *dp)
+{
+ int ret = 0;
+
+ ret = clk_set_rate(dp->phy_24m, 24000000);
+ if (ret < 0) {
+ dev_err(dp->dev, "cannot set clock phy_24m %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(dp->phy_24m);
+ if (ret < 0) {
+ dev_err(dp->dev, "cannot enable clock phy_24m %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rockchip_dp_phy_clk_disable(struct rockchip_dp_phy *dp)
+{
+ clk_disable_unprepare(dp->phy_24m);
+
+ return 0;
+}
+
+static int rockchip_set_phy_state(struct phy *phy, bool enable)
+{
+ struct rockchip_dp_phy *dp = phy_get_drvdata(phy);
+
+ if (enable) {
+ rockchip_dp_phy_clk_enable(dp);
+ writel(DP_PHY_SIDDQ_WRITE_EN | DP_PHY_SIDDQ_ON, dp->regs);
+ } else {
+ rockchip_dp_phy_clk_disable(dp);
+ writel(DP_PHY_SIDDQ_WRITE_EN | DP_PHY_SIDDQ_OFF, dp->regs);
+ }
+
+ return 0;
+}
+
+static int rockchip_dp_phy_power_on(struct phy *phy)
+{
+ return rockchip_set_phy_state(phy, true);
+}
+
+static int rockchip_dp_phy_power_off(struct phy *phy)
+{
+ return rockchip_set_phy_state(phy, false);
+}
+
+static struct phy_ops rockchip_dp_phy_ops = {
+ .power_on = rockchip_dp_phy_power_on,
+ .power_off = rockchip_dp_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static int rockchip_dp_phy_init(struct rockchip_dp_phy *dp)
+{
+ struct device *dev = dp->dev;
+ struct device_node *np = dev->of_node;
+ int ret;
+
+ dp->phy_24m = devm_clk_get(dev, "24m");
+ if (IS_ERR(dp->phy_24m)) {
+ dev_err(dev, "cannot get clock 24m\n");
+ return PTR_ERR(dp->phy_24m);
+ }
+
+ ret = rockchip_dp_phy_clk_enable(dp);
+ if (ret < 0) {
+ dev_err(dp->dev, "cannot enable dp phy clk %d\n", ret);
+ return ret;
+ }
+
+ dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+ if (IS_ERR(dp->grf)) {
+ dev_err(dev, "rk3288-dp needs rockchip,grf property\n");
+ return PTR_ERR(dp->grf);
+ }
+
+ ret = regmap_write(dp->grf, GRF_SOC_CON12,
+ GRF_EDP_REF_CLK_SEL_INTER |
+ (GRF_EDP_REF_CLK_SEL_INTER << 16));
+ if (ret != 0) {
+ dev_err(dp->dev, "Could not config GRF edp ref clk: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rockchip_dp_phy_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct phy_provider *phy_provider;
+ struct rockchip_dp_phy *dp;
+ struct resource *res;
+ struct phy *phy;
+ int ret;
+
+ dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+ if (IS_ERR(dp))
+ return -ENOMEM;
+
+ dp->dev = dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dp->regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(dp->regs))
+ return PTR_ERR(dp->regs);
+
+ ret = rockchip_dp_phy_init(dp);
+ if (ret)
+ return ret;
+
+ phy = devm_phy_create(dev, NULL, &rockchip_dp_phy_ops, NULL);
+ if (IS_ERR(phy)) {
+ dev_err(dev, "failed to create phy\n");
+ return PTR_ERR(phy);
+ }
+ phy_set_drvdata(phy, dp);
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id rockchip_dp_phy_dt_ids[] = {
+ { .compatible = "rockchip,rk3288-dp-phy" },
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, rockchip_dp_phy_dt_ids);
+
+static struct platform_driver rockchip_dp_phy_driver = {
+ .probe = rockchip_dp_phy_probe,
+ .driver = {
+ .name = "rockchip-dp-phy",
+ .owner = THIS_MODULE,
+ .of_match_table = rockchip_dp_phy_dt_ids,
+ },
+};
+
+module_platform_driver(rockchip_dp_phy_driver);
+
+MODULE_AUTHOR("Yakir Yang <[email protected]>");
+MODULE_DESCRIPTION("Rockchip DP PHY driver");
+MODULE_LICENSE("GPL v2");
--
1.9.1

2015-08-19 14:53:59

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 09/14] drm: bridge/analogix_dp: add platform device type support

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3: None
Changes in v2:
- Add GNU license v2 declared and samsung copyright

drivers/gpu/drm/exynos/analogix_dp-exynos.c | 1 +
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 1 +
include/drm/bridge/analogix_dp.h | 16 ++++++++++++++++
3 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/exynos/analogix_dp-exynos.c b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
index 17da2c8..b160159 100644
--- a/drivers/gpu/drm/exynos/analogix_dp-exynos.c
+++ b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
@@ -220,6 +220,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
dp->dev = dev;
dp->drm_dev = drm_dev;

+ dp->plat_data.dev_type = EXYNOS_DP;
dp->plat_data.power_on = exynos_dp_poweron;
dp->plat_data.power_off = exynos_dp_poweroff;
dp->plat_data.get_modes = exynos_dp_get_modes;
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index cebff9e..f2c5c26 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -267,6 +267,7 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
return ret;
}

+ dp->plat_data.dev_type = RK3288_DP;
dp->plat_data.attach = NULL;
dp->plat_data.get_modes = NULL;
dp->plat_data.power_on = rockchip_dp_poweron;
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 8b4ffad..7209a64 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -1,9 +1,25 @@
+/*
+ * Analogix Core DP (Display Port) interface driver.
+ *
+ * Copyright (C) 2012 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 as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
#ifndef _ANALOGIX_DP_H_
#define _ANALOGIX_DP_H_

#include <drm/drm_crtc.h>

+enum analogix_dp_devtype {
+ EXYNOS_DP,
+ RK3288_DP,
+};
+
struct analogix_dp_plat_data {
+ enum analogix_dp_devtype dev_type;
struct drm_panel *panel;

int (*power_on)(struct analogix_dp_plat_data *);
--
1.9.1

2015-08-19 14:52:03

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 10/14] drm: bridge: analogix_dp: add some rk3288 special registers setting

RK3288 need some special registers setting, we can separate
them out by the dev_type of plat_data.

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3: None
Changes in v2:
- Fix compile failed dut to phy_pd_addr variable misspell error

drivers/gpu/drm/bridge/analogix_dp_reg.c | 76 ++++++++++++++++++++------------
drivers/gpu/drm/bridge/analogix_dp_reg.h | 12 +++++
2 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix_dp_reg.c
index cc5cdbf..a0fc1fb 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.c
@@ -15,6 +15,8 @@
#include <linux/delay.h>
#include <linux/gpio.h>

+#include <drm/bridge/analogix_dp.h>
+
#include "analogix_dp_core.h"
#include "analogix_dp_reg.h"

@@ -72,6 +74,14 @@ void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
reg = SEL_24M | TX_DVDD_BIT_1_0625V;
writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);

+ if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) {
+ writel(REF_CLK_24M, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
+ writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
+ writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
+ writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
+ writel(0x22, dp->reg_base + ANALOGIX_DP_PLL_REG_5);
+ }
+
reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3);

@@ -206,81 +216,85 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
bool enable)
{
u32 reg;
+ u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
+
+ if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
+ phy_pd_addr = ANALOGIX_DP_PD;

switch (block) {
case AUX_BLOCK:
if (enable) {
- reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg = readl(dp->reg_base + phy_pd_addr);
reg |= AUX_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
} else {
- reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg = readl(dp->reg_base + phy_pd_addr);
reg &= ~AUX_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
}
break;
case CH0_BLOCK:
if (enable) {
- reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg = readl(dp->reg_base + phy_pd_addr);
reg |= CH0_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
} else {
- reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg = readl(dp->reg_base + phy_pd_addr);
reg &= ~CH0_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
}
break;
case CH1_BLOCK:
if (enable) {
- reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg = readl(dp->reg_base + phy_pd_addr);
reg |= CH1_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
} else {
- reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg = readl(dp->reg_base + phy_pd_addr);
reg &= ~CH1_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
}
break;
case CH2_BLOCK:
if (enable) {
- reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg = readl(dp->reg_base + phy_pd_addr);
reg |= CH2_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
} else {
- reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg = readl(dp->reg_base + phy_pd_addr);
reg &= ~CH2_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
}
break;
case CH3_BLOCK:
if (enable) {
- reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg = readl(dp->reg_base + phy_pd_addr);
reg |= CH3_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
} else {
- reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg = readl(dp->reg_base + phy_pd_addr);
reg &= ~CH3_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
}
break;
case ANALOG_TOTAL:
if (enable) {
- reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg = readl(dp->reg_base + phy_pd_addr);
reg |= DP_PHY_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
} else {
- reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+ reg = readl(dp->reg_base + phy_pd_addr);
reg &= ~DP_PHY_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
}
break;
case POWER_ALL:
if (enable) {
reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
CH1_PD | CH0_PD;
- writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(reg, dp->reg_base + phy_pd_addr);
} else {
- writel(0x00, dp->reg_base + ANALOGIX_DP_PHY_PD);
+ writel(0x00, dp->reg_base + phy_pd_addr);
}
break;
default:
@@ -399,8 +413,14 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
analogix_dp_reset_aux(dp);

/* Disable AUX transaction H/W retry */
- reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
- AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+ if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
+ reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
+ AUX_HW_RETRY_COUNT_SEL(3) |
+ AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+ else
+ reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) |
+ AUX_HW_RETRY_COUNT_SEL(0) |
+ AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);

/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix_dp_reg.h
index bed226f..e38af21 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.h
@@ -22,6 +22,14 @@
#define ANALOGIX_DP_VIDEO_CTL_8 0x3C
#define ANALOGIX_DP_VIDEO_CTL_10 0x44

+#define ANALOGIX_DP_PLL_REG_1 0xfc
+#define ANALOGIX_DP_PLL_REG_2 0x9e4
+#define ANALOGIX_DP_PLL_REG_3 0x9e8
+#define ANALOGIX_DP_PLL_REG_4 0x9ec
+#define ANALOGIX_DP_PLL_REG_5 0xa00
+
+#define ANALOGIX_DP_PD 0x12c
+
#define ANALOGIX_DP_LANE_MAP 0x35C

#define ANALOGIX_DP_ANALOG_CTL_1 0x370
@@ -154,6 +162,10 @@
#define VSYNC_POLARITY_CFG (0x1 << 1)
#define HSYNC_POLARITY_CFG (0x1 << 0)

+/* ANALOGIX_DP_PLL_REG_1 */
+#define REF_CLK_24M (0x1 << 1)
+#define REF_CLK_27M (0x0 << 1)
+
/* ANALOGIX_DP_LANE_MAP */
#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6)
#define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6)
--
1.9.1

2015-08-19 14:52:18

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 11/14] drm: bridge: analogix_dp: try force hpd after plug in lookup failed

Some edp screen do not have hpd signal, so we can't just return
failed when hpd plug in detect failed.

This is an hardware property, so we need add a devicetree property
"analogix,need-force-hpd" to indicate this sutiation.

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3:
- Add "analogix,need-force-hpd" to indicate whether driver need foce
hpd when hpd detect failed.

Changes in v2: None

.../devicetree/bindings/drm/bridge/analogix_dp.txt | 3 ++
.../bindings/video/analogix_dp-rockchip.txt | 1 +
.../devicetree/bindings/video/exynos_dp.txt | 1 +
drivers/gpu/drm/bridge/analogix_dp_core.c | 36 +++++++++++++++++++---
drivers/gpu/drm/bridge/analogix_dp_core.h | 2 ++
drivers/gpu/drm/bridge/analogix_dp_reg.c | 9 ++++++
6 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
index 6127018..b043200 100644
--- a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
+++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
@@ -40,6 +40,9 @@ Required properties for dp-controller:
* Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt

Optional properties for dp-controller:
+ -analogix,need-force-hpd:
+ Indicate driver need force hpd when hpd detect failed, this
+ is used for some eDP screen which don't have hpd signal.
-analogix,hpd-gpio:
Hotplug detect GPIO.
Indicates which GPIO should be used for hotplug
diff --git a/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt b/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
index 99fd421..752005e 100644
--- a/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
+++ b/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
@@ -27,6 +27,7 @@ For the below properties, please refer to Analogix DP binding document:
- analogix,color-depth (required)
- analogix,link-rate (required)
- analogix,lane-count (required)
+- analogix,need-force-hpd (optional)
- analogix,hpd-gpio (optional)
- video interfaces (optional)
-------------------------------------------------------------------------------
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
index 177506f..ba20416 100644
--- a/Documentation/devicetree/bindings/video/exynos_dp.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -53,6 +53,7 @@ For the below properties, please refer to Analogix DP binding document:
-analogix,color-depth (required)
-analogix,link-rate (required)
-analogix,lane-count (required)
+ -analogix,need-force-hpd (optional)
-analogix,hpd-gpio (optional)
-video interfaces (optional)
-------------------------------------------------------------------------------
diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 1778e0a..99870f7 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -63,15 +63,38 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
{
int timeout_loop = 0;

- while (analogix_dp_get_plug_in_status(dp) != 0) {
+ while (timeout_loop < DP_TIMEOUT_LOOP_COUNT) {
+ if (analogix_dp_get_plug_in_status(dp) == 0)
+ return 0;
+
timeout_loop++;
- if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
- dev_err(dp->dev, "failed to get hpd plug status\n");
- return -ETIMEDOUT;
- }
usleep_range(10, 11);
}

+ /*
+ * Some edp screen do not have hpd signal, so we can't just
+ * return failed when hpd plug in detect failed, DT property
+ * "need-force-hpd" would indicate whether driver need this.
+ */
+ if (!dp->need_force_hpd)
+ return -ETIMEDOUT;
+
+ /*
+ * The eDP TRM indicate that if HPD_STATUS(RO) is 0, AUX CH
+ * will not work, so we need to give a force hpd action to
+ * set HPD_STATUS manually.
+ */
+ dev_dbg(dp->dev, "failed to get hpd plug status, try to force hpd\n");
+
+ analogix_dp_force_hpd(dp);
+
+ if (analogix_dp_get_plug_in_status(dp) != 0) {
+ dev_err(dp->dev, "failed to get hpd plug in status\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(dp->dev, "success to get plug in status after force hpd\n");
+
return 0;
}

@@ -1272,6 +1295,9 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
if (IS_ERR(dp->reg_base))
return PTR_ERR(dp->reg_base);

+ dp->need_force_hpd =
+ of_property_read_bool(dev->of_node, "analogix,need-force-hpd");
+
dp->hpd_gpio = of_get_named_gpio(dev->of_node, "analogix,hpd-gpio", 0);

if (gpio_is_valid(dp->hpd_gpio)) {
diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
index 941b34f..2405155 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
@@ -160,6 +160,7 @@ struct analogix_dp_device {
struct phy *phy;
int dpms_mode;
int hpd_gpio;
+ bool need_force_hpd;

struct analogix_dp_plat_data *plat_data;
};
@@ -180,6 +181,7 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
bool enable);
void analogix_dp_init_analog_func(struct analogix_dp_device *dp);
void analogix_dp_init_hpd(struct analogix_dp_device *dp);
+void analogix_dp_force_hpd(struct analogix_dp_device *dp);
enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp);
void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp);
void analogix_dp_reset_aux(struct analogix_dp_device *dp);
diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix_dp_reg.c
index a0fc1fb..bf7cee1 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.c
@@ -365,6 +365,15 @@ void analogix_dp_init_hpd(struct analogix_dp_device *dp)
writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
}

+void analogix_dp_force_hpd(struct analogix_dp_device *dp)
+{
+ u32 reg;
+
+ reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+ reg = (F_HPD | HPD_CTRL);
+ writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+}
+
enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp)
{
u32 reg;
--
1.9.1

2015-08-19 14:52:44

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 12/14] drm: bridge/analogix_dp: expand the delay time for hpd detect

Some edp screen with no hpd signal would need some delay time
to ensure that screen would be ready for work, so we can expand
the delay time in hpd detect function, it works prefectly on my
rk3288 sdk board.

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3: None
Changes in v2: None

drivers/gpu/drm/bridge/analogix_dp_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 99870f7..75dd44a 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -68,7 +68,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
return 0;

timeout_loop++;
- usleep_range(10, 11);
+ usleep_range(100, 110);
}

/*
--
1.9.1

2015-08-19 14:52:40

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 13/14] drm: bridge/analogix_dp: move hpd detect to connector detect function

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3:
- move dp hpd detect to connector detect function.

Changes in v2: None

drivers/gpu/drm/bridge/analogix_dp_core.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 75dd44a..052b9b3 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -915,12 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
DRM_ERROR("failed to disable the panel\n");
}

- ret = analogix_dp_detect_hpd(dp);
- if (ret) {
- /* Cable has been disconnected, we're done */
- return;
- }
-
ret = analogix_dp_handle_edid(dp);
if (ret) {
dev_err(dp->dev, "unable to handle edid\n");
@@ -953,6 +947,12 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
static enum drm_connector_status analogix_dp_detect(
struct drm_connector *connector, bool force)
{
+ struct analogix_dp_device *dp = connector_to_dp(connector);
+
+ if (analogix_dp_detect_hpd(dp))
+ /* Cable has been disconnected, we're done */
+ return connector_status_disconnected;
+
return connector_status_connected;
}

--
1.9.1

2015-08-19 14:53:12

by Yakir Yang

[permalink] [raw]
Subject: [PATCH v3 14/14] drm: bridge/analogix_dp: add edid modes parse in get_modes method

Display Port monitor could support kinds of mode which indicate
in monitor edid, not just one single display resolution which
defined in panel or devivetree property display timing.

Signed-off-by: Yakir Yang <[email protected]>
---
Changes in v3:
- Add edid modes parse support

Changes in v2: None

drivers/gpu/drm/bridge/analogix_dp_core.c | 17 +++++++-----
drivers/gpu/drm/bridge/analogix_dp_core.h | 45 ++++++++++++++++---------------
2 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 052b9b3..83698c6 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -111,7 +111,7 @@ static unsigned char analogix_dp_calc_edid_check_sum(unsigned char *edid_data)

static int analogix_dp_read_edid(struct analogix_dp_device *dp)
{
- unsigned char edid[EDID_BLOCK_LENGTH * 2];
+ unsigned char *edid = dp->edid;
unsigned int extend_block = 0;
unsigned char sum;
unsigned char test_vector;
@@ -915,12 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
DRM_ERROR("failed to disable the panel\n");
}

- ret = analogix_dp_handle_edid(dp);
- if (ret) {
- dev_err(dp->dev, "unable to handle edid\n");
- return;
- }
-
ret = analogix_dp_set_link_train(dp, dp->video_info->max_lane_count,
dp->video_info->max_link_rate);
if (ret) {
@@ -976,8 +970,17 @@ static int analogix_dp_get_modes(struct drm_connector *connector)
{
struct analogix_dp_device *dp = connector_to_dp(connector);
struct analogix_dp_plat_data *plat_data = dp->plat_data;
+ struct edid *edid = (struct edid *)dp->edid;
int num_modes = 0;

+ if (analogix_dp_handle_edid(dp)) {
+ dev_err(dp->dev, "unable to handle edid\n");
+ return -EINVAL;
+ }
+
+ drm_mode_connector_update_edid_property(connector, edid);
+ num_modes += drm_add_edid_modes(connector, edid);
+
if (plat_data && plat_data->panel)
num_modes += drm_panel_get_modes(plat_data->panel);

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
index 2405155..950b6ca 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
@@ -20,6 +20,28 @@
#define MAX_CR_LOOP 5
#define MAX_EQ_LOOP 5

+/* I2C EDID Chip ID, Slave Address */
+#define I2C_EDID_DEVICE_ADDR 0x50
+#define I2C_E_EDID_DEVICE_ADDR 0x30
+
+#define EDID_BLOCK_LENGTH 0x80
+#define EDID_HEADER_PATTERN 0x00
+#define EDID_EXTENSION_FLAG 0x7e
+#define EDID_CHECKSUM 0x7f
+
+/* DP_MAX_LANE_COUNT */
+#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
+#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
+
+/* DP_LANE_COUNT_SET */
+#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f)
+
+/* DP_TRAINING_LANE0_SET */
+#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3)
+#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3)
+#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0)
+#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3)
+
enum link_rate_type {
LINK_RATE_1_62GBPS = DP_LINK_BW_1_62,
LINK_RATE_2_70GBPS = DP_LINK_BW_2_7,
@@ -161,6 +183,7 @@ struct analogix_dp_device {
int dpms_mode;
int hpd_gpio;
bool need_force_hpd;
+ unsigned char edid[EDID_BLOCK_LENGTH * 2];

struct analogix_dp_plat_data *plat_data;
};
@@ -260,26 +283,4 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp);
void analogix_dp_enable_scrambling(struct analogix_dp_device *dp);
void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);

-/* I2C EDID Chip ID, Slave Address */
-#define I2C_EDID_DEVICE_ADDR 0x50
-#define I2C_E_EDID_DEVICE_ADDR 0x30
-
-#define EDID_BLOCK_LENGTH 0x80
-#define EDID_HEADER_PATTERN 0x00
-#define EDID_EXTENSION_FLAG 0x7e
-#define EDID_CHECKSUM 0x7f
-
-/* DP_MAX_LANE_COUNT */
-#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
-#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
-
-/* DP_LANE_COUNT_SET */
-#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f)
-
-/* DP_TRAINING_LANE0_SET */
-#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3)
-#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3)
-#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0)
-#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3)
-
#endif /* _ANALOGIX_DP_CORE_H */
--
1.9.1

2015-08-19 23:54:09

by Dave Airlie

[permalink] [raw]
Subject: Re: [PATCH v3 0/14] Add Analogix Core Display Port Driver

On 20 August 2015 at 00:48, Yakir Yang <[email protected]> wrote:
>
> Hi all,
> The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
> share the same IP, so a lot of parts can be re-used. I split the common
> code into bridge directory, then rk3288 and exynos only need to keep
> some platform code. Cause I can't find the exact IP name of exynos dp
> controller, so I decide to name dp core driver with "analogix" which I
> find in rk3288 eDP TRM ;)
>
> Beyond that, there are three light registers setting differents bewteen
> exynos and rk3288.
> 1. RK3288 have five special pll resigters which not indicata in exynos
> dp controller.
> 2. The address of DP_PHY_PD(dp phy power manager register) are different
> between rk3288 and exynos.
> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
> register).
>
> I have verified this series on two kinds of rockchip platform board, one
> is rk3288 sdk board which connect with a 2K display port monitor, the other
> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
> both of them works rightlly.
>
> I haven't verified the dp function on samsung platform, cause I haven't got
> exynos boards. I can only ensure that there are no build error on samsung
> platform, wish some samsung guys help to test. ;)

I'd like to pull this in, but it probably needs an ack from Samsung,

Inki can you guys find some time to test this?

Dave.

2015-08-20 01:03:15

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 0/14] Add Analogix Core Display Port Driver

Hi Dave,

On 08/19/2015 06:54 PM, Dave Airlie wrote:
> On 20 August 2015 at 00:48, Yakir Yang <[email protected]> wrote:
>> Hi all,
>> The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
>> share the same IP, so a lot of parts can be re-used. I split the common
>> code into bridge directory, then rk3288 and exynos only need to keep
>> some platform code. Cause I can't find the exact IP name of exynos dp
>> controller, so I decide to name dp core driver with "analogix" which I
>> find in rk3288 eDP TRM ;)
>>
>> Beyond that, there are three light registers setting differents bewteen
>> exynos and rk3288.
>> 1. RK3288 have five special pll resigters which not indicata in exynos
>> dp controller.
>> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>> between rk3288 and exynos.
>> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>> register).
>>
>> I have verified this series on two kinds of rockchip platform board, one
>> is rk3288 sdk board which connect with a 2K display port monitor, the other
>> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
>> both of them works rightlly.
>>
>> I haven't verified the dp function on samsung platform, cause I haven't got
>> exynos boards. I can only ensure that there are no build error on samsung
>> platform, wish some samsung guys help to test. ;)
> I'd like to pull this in, but it probably needs an ack from Samsung,
>
> Inki can you guys find some time to test this?
>
> Dave.

Wow, thanks a lots :-)

Still waiting for some reviews and acks.

Best regards,
- Yakir
>
>

2015-08-20 04:30:05

by Archit Taneja

[permalink] [raw]
Subject: Re: [PATCH v3 0/14] Add Analogix Core Display Port Driver

Hi,

On 08/19/2015 08:18 PM, Yakir Yang wrote:
>
> Hi all,
> The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
> share the same IP, so a lot of parts can be re-used. I split the common
> code into bridge directory, then rk3288 and exynos only need to keep
> some platform code. Cause I can't find the exact IP name of exynos dp
> controller, so I decide to name dp core driver with "analogix" which I
> find in rk3288 eDP TRM ;)
>
> Beyond that, there are three light registers setting differents bewteen
> exynos and rk3288.
> 1. RK3288 have five special pll resigters which not indicata in exynos
> dp controller.
> 2. The address of DP_PHY_PD(dp phy power manager register) are different
> between rk3288 and exynos.
> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
> register).
>
> I have verified this series on two kinds of rockchip platform board, one
> is rk3288 sdk board which connect with a 2K display port monitor, the other
> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
> both of them works rightlly.
>
> I haven't verified the dp function on samsung platform, cause I haven't got
> exynos boards. I can only ensure that there are no build error on samsung
> platform, wish some samsung guys help to test. ;)
>
> Thanks,
> - Yakir
>
> Changes in v3:
> - Take Thierry Reding suggest, move exynos's video_timing code
> to analogix_dp-exynos platform driver, add get_modes method
> to struct analogix_dp_plat_data.
> - Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
> - Take Thierry Reding suggest, dynamic parse video timing info from
> struct drm_display_mode and struct drm_display_info.
> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
> the DT property value directly, but we can take those as hardware limite.
> For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
> so DT property would like "link-rate = 0x0a" "lane-count = 4".
> - Take Heiko suggest, add devicetree binding documents.
> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
> from the new analogix dp driver devicetree binding.
> - Update the exist exynos dtsi file with the latest DP DT properies.
> - Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
> dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
> core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
> driver which name to "pclk".
> - Take Heiko suggest, add devicetree binding document.
> - Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
> point to get panel node.
> - Add the new function point analogix_dp_platdata.get_modes init.
> - Take Heiko suggest, add rockchip dp phy driver,
> collect the phy clocks and power control.
> - Add "analogix,need-force-hpd" to indicate whether driver need foce
> hpd when hpd detect failed.
> - move dp hpd detect to connector detect function.
> - Add edid modes parse support
>
> Changes in v2:
> - Take Joe Preches advise, improved commit message more readable, and
> avoid using some uncommon style like bellow:
> - retval = exynos_dp_read_bytes_from_i2c(...
> ...)
> + retval =
> + exynos_dp_read_bytes_from_i2c(......);
> - Take Jingoo Han suggest, just remove my name from author list.
> - Take Jingoo Han suggest, remove new copyright
> - Fix compiled failed dut to analogix_dp_device misspell
> - Take Heiko suggest, get panel node with remote-endpoint method,
> and create devicetree binding for driver.
> - Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
> leave those clock to rockchip dp phy driver.
> - Add GNU license v2 declared and samsung copyright
> - Fix compile failed dut to phy_pd_addr variable misspell error
>
> Yakir Yang (14):
> drm: exynos/dp: fix code style
> drm: exynos/dp: convert to drm bridge mode
> drm: bridge: analogix_dp: split exynos dp driver to bridge dir
> drm: bridge/analogix_dp: dynamic parse sync_pol & interlace &
> colorimetry
> drm: bridge/analogix_dp: fix link_rate & lane_count bug
> Documentation: drm/bridge: add document for analogix_dp
> drm: rockchip/dp: add rockchip platform dp driver
> phy: Add driver for rockchip Display Port PHY
> drm: bridge/analogix_dp: add platform device type support
> drm: bridge: analogix_dp: add some rk3288 special registers setting
> drm: bridge: analogix_dp: try force hpd after plug in lookup failed
> drm: bridge/analogix_dp: expand the delay time for hpd detect
> drm: bridge/analogix_dp: move hpd detect to connector detect function
> drm: bridge/analogix_dp: add edid modes parse in get_modes method
>
> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 73 +
> .../devicetree/bindings/phy/rockchip-dp-phy.txt | 26 +
> .../bindings/video/analogix_dp-rockchip.txt | 83 ++
> .../devicetree/bindings/video/exynos_dp.txt | 51 +-
> arch/arm/boot/dts/exynos5250-arndale.dts | 10 +-
> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 +-
> arch/arm/boot/dts/exynos5250-snow.dts | 12 +-
> arch/arm/boot/dts/exynos5250-spring.dts | 12 +-
> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 +-
> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 +-
> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 +-
> drivers/gpu/drm/bridge/Kconfig | 5 +
> drivers/gpu/drm/bridge/Makefile | 1 +
> drivers/gpu/drm/bridge/analogix_dp_core.c | 1382 +++++++++++++++++++
> drivers/gpu/drm/bridge/analogix_dp_core.h | 286 ++++
> drivers/gpu/drm/bridge/analogix_dp_reg.c | 1294 ++++++++++++++++++
> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h} | 270 ++--
> drivers/gpu/drm/exynos/Kconfig | 5 +-
> drivers/gpu/drm/exynos/Makefile | 2 +-
> drivers/gpu/drm/exynos/analogix_dp-exynos.c | 347 +++++
> drivers/gpu/drm/exynos/exynos_dp_core.c | 1416 --------------------
> drivers/gpu/drm/exynos/exynos_dp_core.h | 282 ----
> drivers/gpu/drm/exynos/exynos_dp_reg.c | 1263 -----------------
> drivers/gpu/drm/rockchip/Kconfig | 9 +
> drivers/gpu/drm/rockchip/Makefile | 1 +
> drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 390 ++++++
> drivers/phy/Kconfig | 7 +
> drivers/phy/Makefile | 1 +
> drivers/phy/phy-rockchip-dp.c | 185 +++
> include/drm/bridge/analogix_dp.h | 40 +
> 30 files changed, 4325 insertions(+), 3172 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
> create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
> create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c

Minor comment: Since there are a few files required for the driver,
could you create a separate folder within drivers/gpu/drm/bridge?

Thanks,
Archit

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

2015-08-20 04:42:08

by Kishon Vijay Abraham I

[permalink] [raw]
Subject: Re: [PATCH v3 08/14] phy: Add driver for rockchip Display Port PHY

Hi,

On Wednesday 19 August 2015 08:21 PM, Yakir Yang wrote:
> Signed-off-by: Yakir Yang <[email protected]>

where's the commit message?
> ---
> Changes in v3:
> - Take Heiko suggest, add rockchip dp phy driver,
> collect the phy clocks and power control.
>
> Changes in v2: None
>
> .../devicetree/bindings/phy/rockchip-dp-phy.txt | 26 +++
> drivers/phy/Kconfig | 7 +
> drivers/phy/Makefile | 1 +
> drivers/phy/phy-rockchip-dp.c | 185 +++++++++++++++++++++
> 4 files changed, 219 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
> create mode 100644 drivers/phy/phy-rockchip-dp.c
>
> diff --git a/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
> new file mode 100644
> index 0000000..5de1088
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
> @@ -0,0 +1,26 @@
> +Rockchip Soc Seroes Display Port PHY
> +------------------------------------
> +
> +Required properties:
> +- compatible : should be one of the following supported values:
> + - "rockchip.rk3288-dp-phy"
> +
> +- reg : a list of registers used by phy driver
> +- clocks: from common clock binding: handle to dp clock.
> + of memory mapped region.
> +- clock-names: from common clock binding:
> + Required elements: "sclk_dp" "sclk_dp_24m"
> +
> +- rockchip,grf: this soc should set GRF regs, so need get grf here.
> +- #phy-cells : from the generic PHY bindings, must be 0;
> +
> +Example:
> +
> +edp_phy: phy@ff770274 {
> + compatilble = "rockchip,rk3288-dp-phy";
> + reg = <0xff770274 4>;
> + rockchip,grf = <&grf>;
> + clocks = <&cru SCLK_EDP_24M>;
> + clock-names = "24m";
> + #phy-cells = <0>;
> +}
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 6b8dd16..da00440 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -297,6 +297,13 @@ config PHY_ROCKCHIP_USB
> help
> Enable this to support the Rockchip USB 2.0 PHY.
>
> +config PHY_ROCKCHIP_DP
> + tristate "Rockchip Display Port PHY Driver"
> + depends on ARCH_ROCKCHIP && OF
> + select GENERIC_PHY
> + help
> + Enable this to support the Rockchip Display Port PHY.
> +
> config PHY_ST_SPEAR1310_MIPHY
> tristate "ST SPEAR1310-MIPHY driver"
> select GENERIC_PHY
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index f344e1b..35e3ce6 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -33,6 +33,7 @@ phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
> obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
> obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
> obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
> +obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
> obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
> obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
> obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
> diff --git a/drivers/phy/phy-rockchip-dp.c b/drivers/phy/phy-rockchip-dp.c
> new file mode 100644
> index 0000000..4759111
> --- /dev/null
> +++ b/drivers/phy/phy-rockchip-dp.c
> @@ -0,0 +1,185 @@
> +/*
> + * Rockchip DP PHY driver
> + *
> + * Copyright (C) 2015 FuZhou Rockchip Co., Ltd.
> + * Author: Yakir Yang <ykk@@rock-chips.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/clk.h>
> +#include <linux/phy/phy.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/platform_device.h>
> +
> +#define GRF_SOC_CON12 0x0274
> +#define GRF_EDP_REF_CLK_SEL_INTER BIT(4)
> +
> +#define DP_PHY_SIDDQ_WRITE_EN BIT(21)
> +#define DP_PHY_SIDDQ_ON 0
> +#define DP_PHY_SIDDQ_OFF BIT(5)
> +
> +struct rockchip_dp_phy {
> + struct device *dev;
> + struct regmap *grf;
> + void __iomem *regs;
> + struct clk *phy_24m;
> +};
> +
> +static int rockchip_dp_phy_clk_enable(struct rockchip_dp_phy *dp)
> +{
> + int ret = 0;
> +
> + ret = clk_set_rate(dp->phy_24m, 24000000);
> + if (ret < 0) {
> + dev_err(dp->dev, "cannot set clock phy_24m %d\n", ret);
> + return ret;
> + }
> +
> + ret = clk_prepare_enable(dp->phy_24m);
> + if (ret < 0) {
> + dev_err(dp->dev, "cannot enable clock phy_24m %d\n", ret);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int rockchip_dp_phy_clk_disable(struct rockchip_dp_phy *dp)
> +{
> + clk_disable_unprepare(dp->phy_24m);
> +
> + return 0;
> +}
> +
> +static int rockchip_set_phy_state(struct phy *phy, bool enable)
> +{
> + struct rockchip_dp_phy *dp = phy_get_drvdata(phy);
> +
> + if (enable) {
> + rockchip_dp_phy_clk_enable(dp);
> + writel(DP_PHY_SIDDQ_WRITE_EN | DP_PHY_SIDDQ_ON, dp->regs);
> + } else {
> + rockchip_dp_phy_clk_disable(dp);
> + writel(DP_PHY_SIDDQ_WRITE_EN | DP_PHY_SIDDQ_OFF, dp->regs);
> + }
> +
> + return 0;
> +}
> +
> +static int rockchip_dp_phy_power_on(struct phy *phy)
> +{
> + return rockchip_set_phy_state(phy, true);
> +}
> +
> +static int rockchip_dp_phy_power_off(struct phy *phy)
> +{
> + return rockchip_set_phy_state(phy, false);
> +}
> +
> +static struct phy_ops rockchip_dp_phy_ops = {
> + .power_on = rockchip_dp_phy_power_on,
> + .power_off = rockchip_dp_phy_power_off,
> + .owner = THIS_MODULE,
> +};
> +
> +static int rockchip_dp_phy_init(struct rockchip_dp_phy *dp)
> +{
> + struct device *dev = dp->dev;
> + struct device_node *np = dev->of_node;
> + int ret;
> +
> + dp->phy_24m = devm_clk_get(dev, "24m");
> + if (IS_ERR(dp->phy_24m)) {
> + dev_err(dev, "cannot get clock 24m\n");
> + return PTR_ERR(dp->phy_24m);
> + }
> +
> + ret = rockchip_dp_phy_clk_enable(dp);
> + if (ret < 0) {
> + dev_err(dp->dev, "cannot enable dp phy clk %d\n", ret);
> + return ret;
> + }
> +
> + dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
> + if (IS_ERR(dp->grf)) {
> + dev_err(dev, "rk3288-dp needs rockchip,grf property\n");
> + return PTR_ERR(dp->grf);
> + }
> +
> + ret = regmap_write(dp->grf, GRF_SOC_CON12,
> + GRF_EDP_REF_CLK_SEL_INTER |
> + (GRF_EDP_REF_CLK_SEL_INTER << 16));
> + if (ret != 0) {
> + dev_err(dp->dev, "Could not config GRF edp ref clk: %d\n", ret);
> + return ret;
> + }

This function can be split to do only clk_get and syscon_regmap_lookup in
probe, clk_enable and regmap_write in phy_init?
> +
> + return 0;
> +}
> +
> +static int rockchip_dp_phy_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct phy_provider *phy_provider;
> + struct rockchip_dp_phy *dp;
> + struct resource *res;
> + struct phy *phy;
> + int ret;
> +
> + dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
> + if (IS_ERR(dp))
> + return -ENOMEM;
> +
> + dp->dev = dev;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + dp->regs = devm_ioremap_resource(dev, res);
> + if (IS_ERR(dp->regs))
> + return PTR_ERR(dp->regs);
> +
> + ret = rockchip_dp_phy_init(dp);
> + if (ret)
> + return ret;
> +
> + phy = devm_phy_create(dev, NULL, &rockchip_dp_phy_ops, NULL);
> + if (IS_ERR(phy)) {
> + dev_err(dev, "failed to create phy\n");
> + return PTR_ERR(phy);
> + }
> + phy_set_drvdata(phy, dp);
> +
> + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +
> + return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id rockchip_dp_phy_dt_ids[] = {
> + { .compatible = "rockchip,rk3288-dp-phy" },
> + {}
> +};
> +
> +MODULE_DEVICE_TABLE(of, rockchip_dp_phy_dt_ids);
> +
> +static struct platform_driver rockchip_dp_phy_driver = {
> + .probe = rockchip_dp_phy_probe,
> + .driver = {
> + .name = "rockchip-dp-phy",
> + .owner = THIS_MODULE,

owner is not required here.

Thanks
Kishon

2015-08-20 05:54:40

by Jingoo Han

[permalink] [raw]
Subject: Re: [PATCH v3 0/14] Add Analogix Core Display Port Driver

On 2015. 8. 20., at PM 1:29, Archit Taneja <[email protected]> wrote:
>
> Hi,
>
>> On 08/19/2015 08:18 PM, Yakir Yang wrote:
>>
>> Hi all,
>> The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
>> share the same IP, so a lot of parts can be re-used. I split the common
>> code into bridge directory, then rk3288 and exynos only need to keep
>> some platform code. Cause I can't find the exact IP name of exynos dp
>> controller, so I decide to name dp core driver with "analogix" which I
>> find in rk3288 eDP TRM ;)
>>
>> Beyond that, there are three light registers setting differents bewteen
>> exynos and rk3288.
>> 1. RK3288 have five special pll resigters which not indicata in exynos
>> dp controller.
>> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>> between rk3288 and exynos.
>> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>> register).
>>
>> I have verified this series on two kinds of rockchip platform board, one
>> is rk3288 sdk board which connect with a 2K display port monitor, the other
>> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
>> both of them works rightlly.
>>
>> I haven't verified the dp function on samsung platform, cause I haven't got
>> exynos boards. I can only ensure that there are no build error on samsung
>> platform, wish some samsung guys help to test. ;)
>>
>> Thanks,
>> - Yakir
>>
>> Changes in v3:
>> - Take Thierry Reding suggest, move exynos's video_timing code
>> to analogix_dp-exynos platform driver, add get_modes method
>> to struct analogix_dp_plat_data.
>> - Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
>> - Take Thierry Reding suggest, dynamic parse video timing info from
>> struct drm_display_mode and struct drm_display_info.
>> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
>> the DT property value directly, but we can take those as hardware limite.
>> For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
>> so DT property would like "link-rate = 0x0a" "lane-count = 4".
>> - Take Heiko suggest, add devicetree binding documents.
>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>> from the new analogix dp driver devicetree binding.
>> - Update the exist exynos dtsi file with the latest DP DT properies.
>> - Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
>> dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
>> core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
>> driver which name to "pclk".
>> - Take Heiko suggest, add devicetree binding document.
>> - Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
>> point to get panel node.
>> - Add the new function point analogix_dp_platdata.get_modes init.
>> - Take Heiko suggest, add rockchip dp phy driver,
>> collect the phy clocks and power control.
>> - Add "analogix,need-force-hpd" to indicate whether driver need foce
>> hpd when hpd detect failed.
>> - move dp hpd detect to connector detect function.
>> - Add edid modes parse support
>>
>> Changes in v2:
>> - Take Joe Preches advise, improved commit message more readable, and
>> avoid using some uncommon style like bellow:
>> - retval = exynos_dp_read_bytes_from_i2c(...
>> ...)
>> + retval =
>> + exynos_dp_read_bytes_from_i2c(......);
>> - Take Jingoo Han suggest, just remove my name from author list.
>> - Take Jingoo Han suggest, remove new copyright
>> - Fix compiled failed dut to analogix_dp_device misspell
>> - Take Heiko suggest, get panel node with remote-endpoint method,
>> and create devicetree binding for driver.
>> - Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
>> leave those clock to rockchip dp phy driver.
>> - Add GNU license v2 declared and samsung copyright
>> - Fix compile failed dut to phy_pd_addr variable misspell error
>>
>> Yakir Yang (14):
>> drm: exynos/dp: fix code style
>> drm: exynos/dp: convert to drm bridge mode
>> drm: bridge: analogix_dp: split exynos dp driver to bridge dir
>> drm: bridge/analogix_dp: dynamic parse sync_pol & interlace &
>> colorimetry
>> drm: bridge/analogix_dp: fix link_rate & lane_count bug
>> Documentation: drm/bridge: add document for analogix_dp
>> drm: rockchip/dp: add rockchip platform dp driver
>> phy: Add driver for rockchip Display Port PHY
>> drm: bridge/analogix_dp: add platform device type support
>> drm: bridge: analogix_dp: add some rk3288 special registers setting
>> drm: bridge: analogix_dp: try force hpd after plug in lookup failed
>> drm: bridge/analogix_dp: expand the delay time for hpd detect
>> drm: bridge/analogix_dp: move hpd detect to connector detect function
>> drm: bridge/analogix_dp: add edid modes parse in get_modes method
>>
>> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 73 +
>> .../devicetree/bindings/phy/rockchip-dp-phy.txt | 26 +
>> .../bindings/video/analogix_dp-rockchip.txt | 83 ++
>> .../devicetree/bindings/video/exynos_dp.txt | 51 +-
>> arch/arm/boot/dts/exynos5250-arndale.dts | 10 +-
>> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 +-
>> arch/arm/boot/dts/exynos5250-snow.dts | 12 +-
>> arch/arm/boot/dts/exynos5250-spring.dts | 12 +-
>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 +-
>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 +-
>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 +-
>> drivers/gpu/drm/bridge/Kconfig | 5 +
>> drivers/gpu/drm/bridge/Makefile | 1 +
>> drivers/gpu/drm/bridge/analogix_dp_core.c | 1382 +++++++++++++++++++
>> drivers/gpu/drm/bridge/analogix_dp_core.h | 286 ++++
>> drivers/gpu/drm/bridge/analogix_dp_reg.c | 1294 ++++++++++++++++++
>> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h} | 270 ++--
>> drivers/gpu/drm/exynos/Kconfig | 5 +-
>> drivers/gpu/drm/exynos/Makefile | 2 +-
>> drivers/gpu/drm/exynos/analogix_dp-exynos.c | 347 +++++
>> drivers/gpu/drm/exynos/exynos_dp_core.c | 1416 --------------------
>> drivers/gpu/drm/exynos/exynos_dp_core.h | 282 ----
>> drivers/gpu/drm/exynos/exynos_dp_reg.c | 1263 -----------------
>> drivers/gpu/drm/rockchip/Kconfig | 9 +
>> drivers/gpu/drm/rockchip/Makefile | 1 +
>> drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 390 ++++++
>> drivers/phy/Kconfig | 7 +
>> drivers/phy/Makefile | 1 +
>> drivers/phy/phy-rockchip-dp.c | 185 +++
>> include/drm/bridge/analogix_dp.h | 40 +
>> 30 files changed, 4325 insertions(+), 3172 deletions(-)
>> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>> create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
>> create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
>> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
>> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
>
> Minor comment: Since there are a few files required for the driver,
> could you create a separate folder within drivers/gpu/drm/bridge?

I agree on this opinion.
Thank you.

Best regards,
Jingoo Han

> Thanks,
> Archit
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project

2015-08-20 06:11:46

by Jingoo Han

[permalink] [raw]
Subject: Re: [PATCH v3 12/14] drm: bridge/analogix_dp: expand the delay time for hpd detect

On 2015. 8. 19., at PM 11:52, Yakir Yang <[email protected]> wrote:
>
> Some edp screen with no hpd signal would need some delay time
> to ensure that screen would be ready for work, so we can expand
> the delay time in hpd detect function, it works prefectly on my
> rk3288 sdk board.

Then, this delay has a dependency on the "rk3288 sdk" board.
Also, if the delay time is expanded, the booting time of some Exybos boards will be increased unnecessarily. :-(

So, please add new DT property such as 'hpd-delay' that can be added to board DT files.

If there is not that DT property in DT files, the default value '10' will written to a variable such as 'unsigned int hpd_delay'.
If there is the DT property in DT files, the delay value will written to the variable when parsing DT values
and will be used in analogix_dp_detect_hpd().

What I want to say is that there should not be harmful effect on the existing Exynos boards, due to unrelated reasons.

Best regards,
Jingoo Han

> Signed-off-by: Yakir Yang <[email protected]>
> ---
> Changes in v3: None
> Changes in v2: None
>
> drivers/gpu/drm/bridge/analogix_dp_core.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
> index 99870f7..75dd44a 100644
> --- a/drivers/gpu/drm/bridge/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
> @@ -68,7 +68,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
> return 0;
>
> timeout_loop++;
> - usleep_range(10, 11);
> + usleep_range(100, 110);
> }
>
> /*
> --
> 1.9.1
>
>

2015-08-20 06:24:23

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 0/14] Add Analogix Core Display Port Driver

Hi Jingoo & Archit,


On 08/20/2015 12:54 AM, Jingoo Han wrote:
> On 2015. 8. 20., at PM 1:29, Archit Taneja <[email protected]> wrote:
>> Hi,
>>
>>> On 08/19/2015 08:18 PM, Yakir Yang wrote:
>>>
>>> Hi all,
>>> The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
>>> share the same IP, so a lot of parts can be re-used. I split the common
>>> code into bridge directory, then rk3288 and exynos only need to keep
>>> some platform code. Cause I can't find the exact IP name of exynos dp
>>> controller, so I decide to name dp core driver with "analogix" which I
>>> find in rk3288 eDP TRM ;)
>>>
>>> Beyond that, there are three light registers setting differents bewteen
>>> exynos and rk3288.
>>> 1. RK3288 have five special pll resigters which not indicata in exynos
>>> dp controller.
>>> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>>> between rk3288 and exynos.
>>> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>>> register).
>>>
>>> I have verified this series on two kinds of rockchip platform board, one
>>> is rk3288 sdk board which connect with a 2K display port monitor, the other
>>> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
>>> both of them works rightlly.
>>>
>>> I haven't verified the dp function on samsung platform, cause I haven't got
>>> exynos boards. I can only ensure that there are no build error on samsung
>>> platform, wish some samsung guys help to test. ;)
>>>
>>> Thanks,
>>> - Yakir
>>>
>>> Changes in v3:
>>> - Take Thierry Reding suggest, move exynos's video_timing code
>>> to analogix_dp-exynos platform driver, add get_modes method
>>> to struct analogix_dp_plat_data.
>>> - Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
>>> - Take Thierry Reding suggest, dynamic parse video timing info from
>>> struct drm_display_mode and struct drm_display_info.
>>> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
>>> the DT property value directly, but we can take those as hardware limite.
>>> For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
>>> so DT property would like "link-rate = 0x0a" "lane-count = 4".
>>> - Take Heiko suggest, add devicetree binding documents.
>>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>> from the new analogix dp driver devicetree binding.
>>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>> - Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
>>> dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
>>> core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
>>> driver which name to "pclk".
>>> - Take Heiko suggest, add devicetree binding document.
>>> - Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
>>> point to get panel node.
>>> - Add the new function point analogix_dp_platdata.get_modes init.
>>> - Take Heiko suggest, add rockchip dp phy driver,
>>> collect the phy clocks and power control.
>>> - Add "analogix,need-force-hpd" to indicate whether driver need foce
>>> hpd when hpd detect failed.
>>> - move dp hpd detect to connector detect function.
>>> - Add edid modes parse support
>>>
>>> Changes in v2:
>>> - Take Joe Preches advise, improved commit message more readable, and
>>> avoid using some uncommon style like bellow:
>>> - retval = exynos_dp_read_bytes_from_i2c(...
>>> ...)
>>> + retval =
>>> + exynos_dp_read_bytes_from_i2c(......);
>>> - Take Jingoo Han suggest, just remove my name from author list.
>>> - Take Jingoo Han suggest, remove new copyright
>>> - Fix compiled failed dut to analogix_dp_device misspell
>>> - Take Heiko suggest, get panel node with remote-endpoint method,
>>> and create devicetree binding for driver.
>>> - Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
>>> leave those clock to rockchip dp phy driver.
>>> - Add GNU license v2 declared and samsung copyright
>>> - Fix compile failed dut to phy_pd_addr variable misspell error
>>>
>>> Yakir Yang (14):
>>> drm: exynos/dp: fix code style
>>> drm: exynos/dp: convert to drm bridge mode
>>> drm: bridge: analogix_dp: split exynos dp driver to bridge dir
>>> drm: bridge/analogix_dp: dynamic parse sync_pol & interlace &
>>> colorimetry
>>> drm: bridge/analogix_dp: fix link_rate & lane_count bug
>>> Documentation: drm/bridge: add document for analogix_dp
>>> drm: rockchip/dp: add rockchip platform dp driver
>>> phy: Add driver for rockchip Display Port PHY
>>> drm: bridge/analogix_dp: add platform device type support
>>> drm: bridge: analogix_dp: add some rk3288 special registers setting
>>> drm: bridge: analogix_dp: try force hpd after plug in lookup failed
>>> drm: bridge/analogix_dp: expand the delay time for hpd detect
>>> drm: bridge/analogix_dp: move hpd detect to connector detect function
>>> drm: bridge/analogix_dp: add edid modes parse in get_modes method
>>>
>>> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 73 +
>>> .../devicetree/bindings/phy/rockchip-dp-phy.txt | 26 +
>>> .../bindings/video/analogix_dp-rockchip.txt | 83 ++
>>> .../devicetree/bindings/video/exynos_dp.txt | 51 +-
>>> arch/arm/boot/dts/exynos5250-arndale.dts | 10 +-
>>> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 +-
>>> arch/arm/boot/dts/exynos5250-snow.dts | 12 +-
>>> arch/arm/boot/dts/exynos5250-spring.dts | 12 +-
>>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 +-
>>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 +-
>>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 +-
>>> drivers/gpu/drm/bridge/Kconfig | 5 +
>>> drivers/gpu/drm/bridge/Makefile | 1 +
>>> drivers/gpu/drm/bridge/analogix_dp_core.c | 1382 +++++++++++++++++++
>>> drivers/gpu/drm/bridge/analogix_dp_core.h | 286 ++++
>>> drivers/gpu/drm/bridge/analogix_dp_reg.c | 1294 ++++++++++++++++++
>>> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h} | 270 ++--
>>> drivers/gpu/drm/exynos/Kconfig | 5 +-
>>> drivers/gpu/drm/exynos/Makefile | 2 +-
>>> drivers/gpu/drm/exynos/analogix_dp-exynos.c | 347 +++++
>>> drivers/gpu/drm/exynos/exynos_dp_core.c | 1416 --------------------
>>> drivers/gpu/drm/exynos/exynos_dp_core.h | 282 ----
>>> drivers/gpu/drm/exynos/exynos_dp_reg.c | 1263 -----------------
>>> drivers/gpu/drm/rockchip/Kconfig | 9 +
>>> drivers/gpu/drm/rockchip/Makefile | 1 +
>>> drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 390 ++++++
>>> drivers/phy/Kconfig | 7 +
>>> drivers/phy/Makefile | 1 +
>>> drivers/phy/phy-rockchip-dp.c | 185 +++
>>> include/drm/bridge/analogix_dp.h | 40 +
>>> 30 files changed, 4325 insertions(+), 3172 deletions(-)
>>> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>> create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
>>> create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>>> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
>>> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
>>> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
>> Minor comment: Since there are a few files required for the driver,
>> could you create a separate folder within drivers/gpu/drm/bridge?
> I agree on this opinion.
> Thank you.

Thanks for your comment ;)

Yeah, bridge/ have been add four new files for this driver, it would be
better to
collect into a separate folder.

I'm wondering should I just name the folder with "analogix_dp/", or we
can make
it more common (like "analogix/")? (personally I do like the last one)

Thanks,
- Yakir
> Best regards,
> Jingoo Han
>
>> Thanks,
>> Archit
>>
>> --
>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>> a Linux Foundation Collaborative Project
>
>

2015-08-20 06:55:27

by Jingoo Han

[permalink] [raw]
Subject: Re: [PATCH v3 0/14] Add Analogix Core Display Port Driver

On 2015. 8. 20., at PM 3:23, Yakir Yang <[email protected]> wrote:
>
> Hi Jingoo & Archit,
>
>
>> On 08/20/2015 12:54 AM, Jingoo Han wrote:
>>> On 2015. 8. 20., at PM 1:29, Archit Taneja <[email protected]> wrote:
>>> Hi,
>>>
>>>> On 08/19/2015 08:18 PM, Yakir Yang wrote:
>>>>
>>>> Hi all,
>>>> The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
>>>> share the same IP, so a lot of parts can be re-used. I split the common
>>>> code into bridge directory, then rk3288 and exynos only need to keep
>>>> some platform code. Cause I can't find the exact IP name of exynos dp
>>>> controller, so I decide to name dp core driver with "analogix" which I
>>>> find in rk3288 eDP TRM ;)
>>>>
>>>> Beyond that, there are three light registers setting differents bewteen
>>>> exynos and rk3288.
>>>> 1. RK3288 have five special pll resigters which not indicata in exynos
>>>> dp controller.
>>>> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>>>> between rk3288 and exynos.
>>>> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>>>> register).
>>>>
>>>> I have verified this series on two kinds of rockchip platform board, one
>>>> is rk3288 sdk board which connect with a 2K display port monitor, the other
>>>> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
>>>> both of them works rightlly.
>>>>
>>>> I haven't verified the dp function on samsung platform, cause I haven't got
>>>> exynos boards. I can only ensure that there are no build error on samsung
>>>> platform, wish some samsung guys help to test. ;)
>>>>
>>>> Thanks,
>>>> - Yakir
>>>>
>>>> Changes in v3:
>>>> - Take Thierry Reding suggest, move exynos's video_timing code
>>>> to analogix_dp-exynos platform driver, add get_modes method
>>>> to struct analogix_dp_plat_data.
>>>> - Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
>>>> - Take Thierry Reding suggest, dynamic parse video timing info from
>>>> struct drm_display_mode and struct drm_display_info.
>>>> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
>>>> the DT property value directly, but we can take those as hardware limite.
>>>> For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
>>>> so DT property would like "link-rate = 0x0a" "lane-count = 4".
>>>> - Take Heiko suggest, add devicetree binding documents.
>>>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>>> from the new analogix dp driver devicetree binding.
>>>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>>> - Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
>>>> dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
>>>> core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
>>>> driver which name to "pclk".
>>>> - Take Heiko suggest, add devicetree binding document.
>>>> - Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
>>>> point to get panel node.
>>>> - Add the new function point analogix_dp_platdata.get_modes init.
>>>> - Take Heiko suggest, add rockchip dp phy driver,
>>>> collect the phy clocks and power control.
>>>> - Add "analogix,need-force-hpd" to indicate whether driver need foce
>>>> hpd when hpd detect failed.
>>>> - move dp hpd detect to connector detect function.
>>>> - Add edid modes parse support
>>>>
>>>> Changes in v2:
>>>> - Take Joe Preches advise, improved commit message more readable, and
>>>> avoid using some uncommon style like bellow:
>>>> - retval = exynos_dp_read_bytes_from_i2c(...
>>>> ...)
>>>> + retval =
>>>> + exynos_dp_read_bytes_from_i2c(......);
>>>> - Take Jingoo Han suggest, just remove my name from author list.
>>>> - Take Jingoo Han suggest, remove new copyright
>>>> - Fix compiled failed dut to analogix_dp_device misspell
>>>> - Take Heiko suggest, get panel node with remote-endpoint method,
>>>> and create devicetree binding for driver.
>>>> - Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
>>>> leave those clock to rockchip dp phy driver.
>>>> - Add GNU license v2 declared and samsung copyright
>>>> - Fix compile failed dut to phy_pd_addr variable misspell error
>>>>
>>>> Yakir Yang (14):
>>>> drm: exynos/dp: fix code style
>>>> drm: exynos/dp: convert to drm bridge mode
>>>> drm: bridge: analogix_dp: split exynos dp driver to bridge dir
>>>> drm: bridge/analogix_dp: dynamic parse sync_pol & interlace &
>>>> colorimetry
>>>> drm: bridge/analogix_dp: fix link_rate & lane_count bug
>>>> Documentation: drm/bridge: add document for analogix_dp
>>>> drm: rockchip/dp: add rockchip platform dp driver
>>>> phy: Add driver for rockchip Display Port PHY
>>>> drm: bridge/analogix_dp: add platform device type support
>>>> drm: bridge: analogix_dp: add some rk3288 special registers setting
>>>> drm: bridge: analogix_dp: try force hpd after plug in lookup failed
>>>> drm: bridge/analogix_dp: expand the delay time for hpd detect
>>>> drm: bridge/analogix_dp: move hpd detect to connector detect function
>>>> drm: bridge/analogix_dp: add edid modes parse in get_modes method
>>>>
>>>> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 73 +
>>>> .../devicetree/bindings/phy/rockchip-dp-phy.txt | 26 +
>>>> .../bindings/video/analogix_dp-rockchip.txt | 83 ++
>>>> .../devicetree/bindings/video/exynos_dp.txt | 51 +-
>>>> arch/arm/boot/dts/exynos5250-arndale.dts | 10 +-
>>>> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 +-
>>>> arch/arm/boot/dts/exynos5250-snow.dts | 12 +-
>>>> arch/arm/boot/dts/exynos5250-spring.dts | 12 +-
>>>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 +-
>>>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 +-
>>>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 +-
>>>> drivers/gpu/drm/bridge/Kconfig | 5 +
>>>> drivers/gpu/drm/bridge/Makefile | 1 +
>>>> drivers/gpu/drm/bridge/analogix_dp_core.c | 1382 +++++++++++++++++++
>>>> drivers/gpu/drm/bridge/analogix_dp_core.h | 286 ++++
>>>> drivers/gpu/drm/bridge/analogix_dp_reg.c | 1294 ++++++++++++++++++
>>>> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h} | 270 ++--
>>>> drivers/gpu/drm/exynos/Kconfig | 5 +-
>>>> drivers/gpu/drm/exynos/Makefile | 2 +-
>>>> drivers/gpu/drm/exynos/analogix_dp-exynos.c | 347 +++++
>>>> drivers/gpu/drm/exynos/exynos_dp_core.c | 1416 --------------------
>>>> drivers/gpu/drm/exynos/exynos_dp_core.h | 282 ----
>>>> drivers/gpu/drm/exynos/exynos_dp_reg.c | 1263 -----------------
>>>> drivers/gpu/drm/rockchip/Kconfig | 9 +
>>>> drivers/gpu/drm/rockchip/Makefile | 1 +
>>>> drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 390 ++++++
>>>> drivers/phy/Kconfig | 7 +
>>>> drivers/phy/Makefile | 1 +
>>>> drivers/phy/phy-rockchip-dp.c | 185 +++
>>>> include/drm/bridge/analogix_dp.h | 40 +
>>>> 30 files changed, 4325 insertions(+), 3172 deletions(-)
>>>> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>> create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
>>>> create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>>>> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
>>>> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
>>>> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
>>> Minor comment: Since there are a few files required for the driver,
>>> could you create a separate folder within drivers/gpu/drm/bridge?
>> I agree on this opinion.
>> Thank you.
>
> Thanks for your comment ;)
>
> Yeah, bridge/ have been add four new files for this driver, it would be better to
> collect into a separate folder.
>
> I'm wondering should I just name the folder with "analogix_dp/", or we can make
> it more common (like "analogix/")? (personally I do like the last one)

I prefer "analogix".

Best regards,
Jingoo Han

> Thanks,
> - Yakir
>> Best regards,
>> Jingoo Han
>>
>>> Thanks,
>>> Archit
>>>
>>> --
>>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>>> a Linux Foundation Collaborative Project
>
>

2015-08-20 07:22:54

by Jingoo Han

[permalink] [raw]
Subject: Re: [PATCH v3 05/14] drm: bridge/analogix_dp: fix link_rate & lane_count bug

On 2015. 8. 19., at PM 11:50, Yakir Yang <[email protected]> wrote:
>
> link_rate and lane_count already configed in analogix_dp_set_link_train(),

s/configed/configured

Also, the commit name such as "fix ... bug" is not good.
How about following?

drm: bridge/analogix_dp: remove duplicate configuration of link rate and link count

Best regards,
Jingoo Han

> so we don't need to config those repeatly after training finished, just
> remove them out.
>
> Beside Display Port 1.2 already support 5.4Gbps link rate, the maximum sets
> would change from {1.62Gbps, 2.7Gbps} to {1.62Gbps, 2.7Gbps, 5.4Gbps}.
>
> Signed-off-by: Yakir Yang <[email protected]>
> ---
> Changes in v3:
> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
> the DT property value directly, but we can take those as hardware limite.
> For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
> so DT property would like "link-rate = 0x0a" "lane-count = 4".
>
> Changes in v2: None
>
> drivers/gpu/drm/bridge/analogix_dp_core.c | 16 ++++++++--------
> drivers/gpu/drm/bridge/analogix_dp_core.h | 9 +++++----
> 2 files changed, 13 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
> index 480cc13..1778e0a 100644
> --- a/drivers/gpu/drm/bridge/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
> @@ -635,6 +635,8 @@ static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
> /*
> * For DP rev.1.1, Maximum link rate of Main Link lanes
> * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
> + * For DP rev.1.2, Maximum link rate of Main Link lanes
> + * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps, 0x14 = 5.4Gbps
> */
> analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
> *bandwidth = data;
> @@ -668,7 +670,8 @@ static void analogix_dp_init_training(struct analogix_dp_device *dp,
> analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
>
> if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
> - (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
> + (dp->link_train.link_rate != LINK_RATE_2_70GBPS) &&
> + (dp->link_train.link_rate != LINK_RATE_5_40GBPS)) {
> dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
> dp->link_train.link_rate);
> dp->link_train.link_rate = LINK_RATE_1_62GBPS;
> @@ -901,8 +904,8 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
> return;
> }
>
> - ret = analogix_dp_set_link_train(dp, dp->video_info->lane_count,
> - dp->video_info->link_rate);
> + ret = analogix_dp_set_link_train(dp, dp->video_info->max_lane_count,
> + dp->video_info->max_link_rate);
> if (ret) {
> dev_err(dp->dev, "unable to do link train\n");
> return;
> @@ -912,9 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
> analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
> analogix_dp_enable_enhanced_mode(dp, 1);
>
> - analogix_dp_set_lane_count(dp, dp->video_info->lane_count);
> - analogix_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
> -
> analogix_dp_init_video(dp);
> ret = analogix_dp_config_video(dp);
> if (ret)
> @@ -1198,13 +1198,13 @@ static struct video_info *analogix_dp_dt_parse_pdata(struct device *dev)
> }
>
> if (of_property_read_u32(dp_node, "analogix,link-rate",
> - &dp_video_config->link_rate)) {
> + &dp_video_config->max_link_rate)) {
> dev_err(dev, "failed to get link-rate\n");
> return ERR_PTR(-EINVAL);
> }
>
> if (of_property_read_u32(dp_node, "analogix,lane-count",
> - &dp_video_config->lane_count)) {
> + &dp_video_config->max_lane_count)) {
> dev_err(dev, "failed to get lane-count\n");
> return ERR_PTR(-EINVAL);
> }
> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
> index 2cefde9..941b34f 100644
> --- a/drivers/gpu/drm/bridge/analogix_dp_core.h
> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
> @@ -21,8 +21,9 @@
> #define MAX_EQ_LOOP 5
>
> enum link_rate_type {
> - LINK_RATE_1_62GBPS = 0x06,
> - LINK_RATE_2_70GBPS = 0x0a
> + LINK_RATE_1_62GBPS = DP_LINK_BW_1_62,
> + LINK_RATE_2_70GBPS = DP_LINK_BW_2_7,
> + LINK_RATE_5_40GBPS = DP_LINK_BW_5_4,
> };
>
> enum link_lane_count_type {
> @@ -128,8 +129,8 @@ struct video_info {
> enum color_coefficient ycbcr_coeff;
> enum color_depth color_depth;
>
> - enum link_rate_type link_rate;
> - enum link_lane_count_type lane_count;
> + enum link_rate_type max_link_rate;
> + enum link_lane_count_type max_lane_count;
> };
>
> struct link_train {
> --
> 1.9.1
>
>

2015-08-20 07:49:11

by Jingoo Han

[permalink] [raw]
Subject: Re: [PATCH v3 13/14] drm: bridge/analogix_dp: move hpd detect to connector detect function

On 2015. 8. 19., at PM 11:52, Yakir Yang <[email protected]> wrote:
>


What is the reason to make this patch?

Please make commit message including the reason.

Best regards,
Jingoo Han

> Signed-off-by: Yakir Yang <[email protected]>
> ---
> Changes in v3:
> - move dp hpd detect to connector detect function.
>
> Changes in v2: None
>
> drivers/gpu/drm/bridge/analogix_dp_core.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
> index 75dd44a..052b9b3 100644
> --- a/drivers/gpu/drm/bridge/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
> @@ -915,12 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
> DRM_ERROR("failed to disable the panel\n");
> }
>
> - ret = analogix_dp_detect_hpd(dp);
> - if (ret) {
> - /* Cable has been disconnected, we're done */
> - return;
> - }
> -
> ret = analogix_dp_handle_edid(dp);
> if (ret) {
> dev_err(dp->dev, "unable to handle edid\n");
> @@ -953,6 +947,12 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
> static enum drm_connector_status analogix_dp_detect(
> struct drm_connector *connector, bool force)
> {
> + struct analogix_dp_device *dp = connector_to_dp(connector);
> +
> + if (analogix_dp_detect_hpd(dp))
> + /* Cable has been disconnected, we're done */
> + return connector_status_disconnected;
> +
> return connector_status_connected;
> }
>
> --
> 1.9.1
>
>

2015-08-20 08:02:55

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 12/14] drm: bridge/analogix_dp: expand the delay time for hpd detect

Hi Jingoo,

On 08/20/2015 01:11 AM, Jingoo Han wrote:
> On 2015. 8. 19., at PM 11:52, Yakir Yang <[email protected]> wrote:
>> Some edp screen with no hpd signal would need some delay time
>> to ensure that screen would be ready for work, so we can expand
>> the delay time in hpd detect function, it works prefectly on my
>> rk3288 sdk board.
> Then, this delay has a dependency on the "rk3288 sdk" board.
> Also, if the delay time is expanded, the booting time of some Exybos boards will be increased unnecessarily. :-(
>
> So, please add new DT property such as 'hpd-delay' that can be added to board DT files.
>
> If there is not that DT property in DT files, the default value '10' will written to a variable such as 'unsigned int hpd_delay'.
> If there is the DT property in DT files, the delay value will written to the variable when parsing DT values
> and will be used in analogix_dp_detect_hpd().
>
> What I want to say is that there should not be harmful effect on the existing Exynos boards, due to unrelated reasons.

Yeah, you are right, I made an mistake here.

And I want to put this delay to "need-force-hpd" code, cause
this property is for the no-hpd-signal eDP screen.

But strangely, with my this series, I don't need the expand delay
any more, I am not sure which change improved this, I guess
those delay time should come from drm core ?

Whatever seems we don't need this delay for now, and if I can
find the exact reason and realize I still need this delay, I prefer
to add those delay in "need-force-hpd" code.

Thanks,
- Yakir
> Best regards,
> Jingoo Han
>
>> Signed-off-by: Yakir Yang <[email protected]>
>> ---
>> Changes in v3: None
>> Changes in v2: None
>>
>> drivers/gpu/drm/bridge/analogix_dp_core.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> index 99870f7..75dd44a 100644
>> --- a/drivers/gpu/drm/bridge/analogix_dp_core.c
>> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> @@ -68,7 +68,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
>> return 0;
>>
>> timeout_loop++;
>> - usleep_range(10, 11);
>> + usleep_range(100, 110);
>> }
>>
>> /*
>> --
>> 1.9.1
>>
>>
>
>

2015-08-20 08:04:03

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 0/14] Add Analogix Core Display Port Driver

Hi Jingoo,

On 08/20/2015 01:55 AM, Jingoo Han wrote:
> On 2015. 8. 20., at PM 3:23, Yakir Yang <[email protected]> wrote:
>> Hi Jingoo & Archit,
>>
>>
>>> On 08/20/2015 12:54 AM, Jingoo Han wrote:
>>>> On 2015. 8. 20., at PM 1:29, Archit Taneja <[email protected]> wrote:
>>>> Hi,
>>>>
>>>>> On 08/19/2015 08:18 PM, Yakir Yang wrote:
>>>>>
>>>>> Hi all,
>>>>> The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
>>>>> share the same IP, so a lot of parts can be re-used. I split the common
>>>>> code into bridge directory, then rk3288 and exynos only need to keep
>>>>> some platform code. Cause I can't find the exact IP name of exynos dp
>>>>> controller, so I decide to name dp core driver with "analogix" which I
>>>>> find in rk3288 eDP TRM ;)
>>>>>
>>>>> Beyond that, there are three light registers setting differents bewteen
>>>>> exynos and rk3288.
>>>>> 1. RK3288 have five special pll resigters which not indicata in exynos
>>>>> dp controller.
>>>>> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>>>>> between rk3288 and exynos.
>>>>> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>>>>> register).
>>>>>
>>>>> I have verified this series on two kinds of rockchip platform board, one
>>>>> is rk3288 sdk board which connect with a 2K display port monitor, the other
>>>>> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
>>>>> both of them works rightlly.
>>>>>
>>>>> I haven't verified the dp function on samsung platform, cause I haven't got
>>>>> exynos boards. I can only ensure that there are no build error on samsung
>>>>> platform, wish some samsung guys help to test. ;)
>>>>>
>>>>> Thanks,
>>>>> - Yakir
>>>>>
>>>>> Changes in v3:
>>>>> - Take Thierry Reding suggest, move exynos's video_timing code
>>>>> to analogix_dp-exynos platform driver, add get_modes method
>>>>> to struct analogix_dp_plat_data.
>>>>> - Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
>>>>> - Take Thierry Reding suggest, dynamic parse video timing info from
>>>>> struct drm_display_mode and struct drm_display_info.
>>>>> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
>>>>> the DT property value directly, but we can take those as hardware limite.
>>>>> For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
>>>>> so DT property would like "link-rate = 0x0a" "lane-count = 4".
>>>>> - Take Heiko suggest, add devicetree binding documents.
>>>>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>>>> from the new analogix dp driver devicetree binding.
>>>>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>>>> - Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
>>>>> dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
>>>>> core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
>>>>> driver which name to "pclk".
>>>>> - Take Heiko suggest, add devicetree binding document.
>>>>> - Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
>>>>> point to get panel node.
>>>>> - Add the new function point analogix_dp_platdata.get_modes init.
>>>>> - Take Heiko suggest, add rockchip dp phy driver,
>>>>> collect the phy clocks and power control.
>>>>> - Add "analogix,need-force-hpd" to indicate whether driver need foce
>>>>> hpd when hpd detect failed.
>>>>> - move dp hpd detect to connector detect function.
>>>>> - Add edid modes parse support
>>>>>
>>>>> Changes in v2:
>>>>> - Take Joe Preches advise, improved commit message more readable, and
>>>>> avoid using some uncommon style like bellow:
>>>>> - retval = exynos_dp_read_bytes_from_i2c(...
>>>>> ...)
>>>>> + retval =
>>>>> + exynos_dp_read_bytes_from_i2c(......);
>>>>> - Take Jingoo Han suggest, just remove my name from author list.
>>>>> - Take Jingoo Han suggest, remove new copyright
>>>>> - Fix compiled failed dut to analogix_dp_device misspell
>>>>> - Take Heiko suggest, get panel node with remote-endpoint method,
>>>>> and create devicetree binding for driver.
>>>>> - Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
>>>>> leave those clock to rockchip dp phy driver.
>>>>> - Add GNU license v2 declared and samsung copyright
>>>>> - Fix compile failed dut to phy_pd_addr variable misspell error
>>>>>
>>>>> Yakir Yang (14):
>>>>> drm: exynos/dp: fix code style
>>>>> drm: exynos/dp: convert to drm bridge mode
>>>>> drm: bridge: analogix_dp: split exynos dp driver to bridge dir
>>>>> drm: bridge/analogix_dp: dynamic parse sync_pol & interlace &
>>>>> colorimetry
>>>>> drm: bridge/analogix_dp: fix link_rate & lane_count bug
>>>>> Documentation: drm/bridge: add document for analogix_dp
>>>>> drm: rockchip/dp: add rockchip platform dp driver
>>>>> phy: Add driver for rockchip Display Port PHY
>>>>> drm: bridge/analogix_dp: add platform device type support
>>>>> drm: bridge: analogix_dp: add some rk3288 special registers setting
>>>>> drm: bridge: analogix_dp: try force hpd after plug in lookup failed
>>>>> drm: bridge/analogix_dp: expand the delay time for hpd detect
>>>>> drm: bridge/analogix_dp: move hpd detect to connector detect function
>>>>> drm: bridge/analogix_dp: add edid modes parse in get_modes method
>>>>>
>>>>> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 73 +
>>>>> .../devicetree/bindings/phy/rockchip-dp-phy.txt | 26 +
>>>>> .../bindings/video/analogix_dp-rockchip.txt | 83 ++
>>>>> .../devicetree/bindings/video/exynos_dp.txt | 51 +-
>>>>> arch/arm/boot/dts/exynos5250-arndale.dts | 10 +-
>>>>> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 +-
>>>>> arch/arm/boot/dts/exynos5250-snow.dts | 12 +-
>>>>> arch/arm/boot/dts/exynos5250-spring.dts | 12 +-
>>>>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 +-
>>>>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 +-
>>>>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 +-
>>>>> drivers/gpu/drm/bridge/Kconfig | 5 +
>>>>> drivers/gpu/drm/bridge/Makefile | 1 +
>>>>> drivers/gpu/drm/bridge/analogix_dp_core.c | 1382 +++++++++++++++++++
>>>>> drivers/gpu/drm/bridge/analogix_dp_core.h | 286 ++++
>>>>> drivers/gpu/drm/bridge/analogix_dp_reg.c | 1294 ++++++++++++++++++
>>>>> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h} | 270 ++--
>>>>> drivers/gpu/drm/exynos/Kconfig | 5 +-
>>>>> drivers/gpu/drm/exynos/Makefile | 2 +-
>>>>> drivers/gpu/drm/exynos/analogix_dp-exynos.c | 347 +++++
>>>>> drivers/gpu/drm/exynos/exynos_dp_core.c | 1416 --------------------
>>>>> drivers/gpu/drm/exynos/exynos_dp_core.h | 282 ----
>>>>> drivers/gpu/drm/exynos/exynos_dp_reg.c | 1263 -----------------
>>>>> drivers/gpu/drm/rockchip/Kconfig | 9 +
>>>>> drivers/gpu/drm/rockchip/Makefile | 1 +
>>>>> drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 390 ++++++
>>>>> drivers/phy/Kconfig | 7 +
>>>>> drivers/phy/Makefile | 1 +
>>>>> drivers/phy/phy-rockchip-dp.c | 185 +++
>>>>> include/drm/bridge/analogix_dp.h | 40 +
>>>>> 30 files changed, 4325 insertions(+), 3172 deletions(-)
>>>>> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>>> create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
>>>>> create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>>>>> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
>>>>> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
>>>>> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
>>>> Minor comment: Since there are a few files required for the driver,
>>>> could you create a separate folder within drivers/gpu/drm/bridge?
>>> I agree on this opinion.
>>> Thank you.
>> Thanks for your comment ;)
>>
>> Yeah, bridge/ have been add four new files for this driver, it would be better to
>> collect into a separate folder.
>>
>> I'm wondering should I just name the folder with "analogix_dp/", or we can make
>> it more common (like "analogix/")? (personally I do like the last one)
> I prefer "analogix".

Okay :)

- Yakir

> Best regards,
> Jingoo Han
>
>> Thanks,
>> - Yakir
>>> Best regards,
>>> Jingoo Han
>>>
>>>> Thanks,
>>>> Archit
>>>>
>>>> --
>>>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>>>> a Linux Foundation Collaborative Project
>>
>
>

2015-08-20 08:04:56

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 05/14] drm: bridge/analogix_dp: fix link_rate & lane_count bug

Hi Jingoo,

On 08/20/2015 02:22 AM, Jingoo Han wrote:
> On 2015. 8. 19., at PM 11:50, Yakir Yang <[email protected]> wrote:
>> link_rate and lane_count already configed in analogix_dp_set_link_train(),
> s/configed/configured
>
> Also, the commit name such as "fix ... bug" is not good.
> How about following?
>
> drm: bridge/analogix_dp: remove duplicate configuration of link rate and link count

Thanks, done, it's more readable.

- Yakir
> Best regards,
> Jingoo Han
>
>> so we don't need to config those repeatly after training finished, just
>> remove them out.
>>
>> Beside Display Port 1.2 already support 5.4Gbps link rate, the maximum sets
>> would change from {1.62Gbps, 2.7Gbps} to {1.62Gbps, 2.7Gbps, 5.4Gbps}.
>>
>> Signed-off-by: Yakir Yang <[email protected]>
>> ---
>> Changes in v3:
>> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
>> the DT property value directly, but we can take those as hardware limite.
>> For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
>> so DT property would like "link-rate = 0x0a" "lane-count = 4".
>>
>> Changes in v2: None
>>
>> drivers/gpu/drm/bridge/analogix_dp_core.c | 16 ++++++++--------
>> drivers/gpu/drm/bridge/analogix_dp_core.h | 9 +++++----
>> 2 files changed, 13 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> index 480cc13..1778e0a 100644
>> --- a/drivers/gpu/drm/bridge/analogix_dp_core.c
>> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> @@ -635,6 +635,8 @@ static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
>> /*
>> * For DP rev.1.1, Maximum link rate of Main Link lanes
>> * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
>> + * For DP rev.1.2, Maximum link rate of Main Link lanes
>> + * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps, 0x14 = 5.4Gbps
>> */
>> analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
>> *bandwidth = data;
>> @@ -668,7 +670,8 @@ static void analogix_dp_init_training(struct analogix_dp_device *dp,
>> analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
>>
>> if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
>> - (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
>> + (dp->link_train.link_rate != LINK_RATE_2_70GBPS) &&
>> + (dp->link_train.link_rate != LINK_RATE_5_40GBPS)) {
>> dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
>> dp->link_train.link_rate);
>> dp->link_train.link_rate = LINK_RATE_1_62GBPS;
>> @@ -901,8 +904,8 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
>> return;
>> }
>>
>> - ret = analogix_dp_set_link_train(dp, dp->video_info->lane_count,
>> - dp->video_info->link_rate);
>> + ret = analogix_dp_set_link_train(dp, dp->video_info->max_lane_count,
>> + dp->video_info->max_link_rate);
>> if (ret) {
>> dev_err(dp->dev, "unable to do link train\n");
>> return;
>> @@ -912,9 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
>> analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
>> analogix_dp_enable_enhanced_mode(dp, 1);
>>
>> - analogix_dp_set_lane_count(dp, dp->video_info->lane_count);
>> - analogix_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
>> -
>> analogix_dp_init_video(dp);
>> ret = analogix_dp_config_video(dp);
>> if (ret)
>> @@ -1198,13 +1198,13 @@ static struct video_info *analogix_dp_dt_parse_pdata(struct device *dev)
>> }
>>
>> if (of_property_read_u32(dp_node, "analogix,link-rate",
>> - &dp_video_config->link_rate)) {
>> + &dp_video_config->max_link_rate)) {
>> dev_err(dev, "failed to get link-rate\n");
>> return ERR_PTR(-EINVAL);
>> }
>>
>> if (of_property_read_u32(dp_node, "analogix,lane-count",
>> - &dp_video_config->lane_count)) {
>> + &dp_video_config->max_lane_count)) {
>> dev_err(dev, "failed to get lane-count\n");
>> return ERR_PTR(-EINVAL);
>> }
>> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
>> index 2cefde9..941b34f 100644
>> --- a/drivers/gpu/drm/bridge/analogix_dp_core.h
>> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
>> @@ -21,8 +21,9 @@
>> #define MAX_EQ_LOOP 5
>>
>> enum link_rate_type {
>> - LINK_RATE_1_62GBPS = 0x06,
>> - LINK_RATE_2_70GBPS = 0x0a
>> + LINK_RATE_1_62GBPS = DP_LINK_BW_1_62,
>> + LINK_RATE_2_70GBPS = DP_LINK_BW_2_7,
>> + LINK_RATE_5_40GBPS = DP_LINK_BW_5_4,
>> };
>>
>> enum link_lane_count_type {
>> @@ -128,8 +129,8 @@ struct video_info {
>> enum color_coefficient ycbcr_coeff;
>> enum color_depth color_depth;
>>
>> - enum link_rate_type link_rate;
>> - enum link_lane_count_type lane_count;
>> + enum link_rate_type max_link_rate;
>> + enum link_lane_count_type max_lane_count;
>> };
>>
>> struct link_train {
>> --
>> 1.9.1
>>
>>
>
>

2015-08-20 08:18:55

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 13/14] drm: bridge/analogix_dp: move hpd detect to connector detect function

Hi Jingoo,

On 08/20/2015 02:49 AM, Jingoo Han wrote:
> On 2015. 8. 19., at PM 11:52, Yakir Yang <[email protected]> wrote:
>
> What is the reason to make this patch?
>
> Please make commit message including the reason.

Okay, I think the below words would be okay :)

"This change just make a little clean to make code more like
drm core expect, move hdp detect code from bridge->enable(),
and place them into connector->detect()."

Thanks,
- Yakir

> Best regards,
> Jingoo Han
>
>> Signed-off-by: Yakir Yang <[email protected]>
>> ---
>> Changes in v3:
>> - move dp hpd detect to connector detect function.
>>
>> Changes in v2: None
>>
>> drivers/gpu/drm/bridge/analogix_dp_core.c | 12 ++++++------
>> 1 file changed, 6 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> index 75dd44a..052b9b3 100644
>> --- a/drivers/gpu/drm/bridge/analogix_dp_core.c
>> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> @@ -915,12 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
>> DRM_ERROR("failed to disable the panel\n");
>> }
>>
>> - ret = analogix_dp_detect_hpd(dp);
>> - if (ret) {
>> - /* Cable has been disconnected, we're done */
>> - return;
>> - }
>> -
>> ret = analogix_dp_handle_edid(dp);
>> if (ret) {
>> dev_err(dp->dev, "unable to handle edid\n");
>> @@ -953,6 +947,12 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
>> static enum drm_connector_status analogix_dp_detect(
>> struct drm_connector *connector, bool force)
>> {
>> + struct analogix_dp_device *dp = connector_to_dp(connector);
>> +
>> + if (analogix_dp_detect_hpd(dp))
>> + /* Cable has been disconnected, we're done */
>> + return connector_status_disconnected;
>> +
>> return connector_status_connected;
>> }
>>
>> --
>> 1.9.1
>>
>>
>
>

2015-08-21 08:21:12

by Jingoo Han

[permalink] [raw]
Subject: Re: [PATCH v3 0/14] Add Analogix Core Display Port Driver

On 2015. 8. 19., at PM 11:48, Yakir Yang <[email protected]> wrote:
>
>

.....

> .../bindings/video/analogix_dp-rockchip.txt | 83 ++
> .../devicetree/bindings/video/exynos_dp.txt | 51 +-
> arch/arm/boot/dts/exynos5250-arndale.dts | 10 +-
> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 +-
> arch/arm/boot/dts/exynos5250-snow.dts | 12 +-
> arch/arm/boot/dts/exynos5250-spring.dts | 12 +-
> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 +-
> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 +-
> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 +-
> drivers/gpu/drm/bridge/Kconfig | 5 +
> drivers/gpu/drm/bridge/Makefile | 1 +
> drivers/gpu/drm/bridge/analogix_dp_core.c | 1382 +++++++++++++++++++
> drivers/gpu/drm/bridge/analogix_dp_core.h | 286 ++++
> drivers/gpu/drm/bridge/analogix_dp_reg.c | 1294 ++++++++++++++++++
> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h} | 270 ++--
> drivers/gpu/drm/exynos/Kconfig | 5 +-
> drivers/gpu/drm/exynos/Makefile | 2 +-
> drivers/gpu/drm/exynos/analogix_dp-exynos.c | 347 +++++

Would you change this file name to "exynos_dp.c"?

Best regards,
Jingoo Han

> drivers/gpu/drm/exynos/exynos_dp_core.c | 1416 --------------------
> drivers/gpu/drm/exynos/exynos_dp_core.h | 282 ----
> drivers/gpu/drm/exynos/exynos_dp_reg.c | 1263 -----------------
> drivers/gpu/drm/rockchip/Kconfig | 9 +
> drivers/gpu/drm/rockchip/Makefile | 1 +
> drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 390 ++++++
> drivers/phy/Kconfig | 7 +
> drivers/phy/Makefile | 1 +
> drivers/phy/phy-rockchip-dp.c | 185 +++
> include/drm/bridge/analogix_dp.h | 40 +
> 30 files changed, 4325 insertions(+), 3172 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
> create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
> create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
> rename drivers/gpu/drm/{exynos/exynos_dp_reg.h => bridge/analogix_dp_reg.h} (62%)
> create mode 100644 drivers/gpu/drm/exynos/analogix_dp-exynos.c
> delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.c
> delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.h
> delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_reg.c
> create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> create mode 100644 drivers/phy/phy-rockchip-dp.c
> create mode 100644 include/drm/bridge/analogix_dp.h
>
> --
> 1.9.1
>
>

2015-08-21 13:17:54

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH v3 0/14] Add Analogix Core Display Port Driver

On Fri, Aug 21, 2015 at 08:24:16PM +0900, Jingoo Han wrote:
> On 2015. 8. 21., at PM 7:01, Yakir Yang <[email protected]> wrote:
> >
> > Hi Jingoo,
> >
> >> 在 2015/8/21 16:20, Jingoo Han 写道:
> >>> On 2015. 8. 19., at PM 11:48, Yakir Yang <[email protected]> wrote:
> >>
> >> .....
> >>
> >>> .../bindings/video/analogix_dp-rockchip.txt | 83 ++
> >>> .../devicetree/bindings/video/exynos_dp.txt | 51 +-
> >>> arch/arm/boot/dts/exynos5250-arndale.dts | 10 +-
> >>> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 +-
> >>> arch/arm/boot/dts/exynos5250-snow.dts | 12 +-
> >>> arch/arm/boot/dts/exynos5250-spring.dts | 12 +-
> >>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 +-
> >>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 +-
> >>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 +-
> >>> drivers/gpu/drm/bridge/Kconfig | 5 +
> >>> drivers/gpu/drm/bridge/Makefile | 1 +
> >>> drivers/gpu/drm/bridge/analogix_dp_core.c | 1382 +++++++++++++++++++
> >>> drivers/gpu/drm/bridge/analogix_dp_core.h | 286 ++++
> >>> drivers/gpu/drm/bridge/analogix_dp_reg.c | 1294 ++++++++++++++++++
> >>> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h} | 270 ++--
> >>> drivers/gpu/drm/exynos/Kconfig | 5 +-
> >>> drivers/gpu/drm/exynos/Makefile | 2 +-
> >>> drivers/gpu/drm/exynos/analogix_dp-exynos.c | 347 +++++
> >> Would you change this file name to "exynos_dp.c"?
> >
> > Sorry, I don't think so ;(
> >
> > I think IP_name+Soc_name would be better in this re-use case.
>
> So? Is there the naming rule such as "IP_name+SoC_name"?
>
> > Beside I see
> > there are lots of driver named with this format in kernel, such as dw_hdmi & dw_mmc
>
> Please look at other dw cases.
> For example, look at dw_pcie.
>
> drivers/pci/host/
> pcie-designware.c
> pci-spear13xx.c
> pci-exynos.c
>
> In this case, pci-spear13xx.c and pci-exynos.c do not use "IP_name+SoC_name", even though these are dw IPs.
>
> Also, naming consistency is more important.
> Now, Exynos DRM files are using "exynos_drm_" prefix.
>
> drivers/gpu/drm/exynos/
> exynos_drm_buf.c
> exynos_drm_core.c
> ....
>
> However, "analogix_dp-exynos.c" looks very inconsistent.
>
> If there is no strict naming rule, please use "exynos_dp.c"
> or "exynos_drm_dp.c".

Exynos DRM maintainers get to pick their filenames, so Yakir, please
rename as Jingoo suggested.

Even if you didn't the first thing that would go into the Exynos DRM
driver tree after this is merged is a rename patch anyway.

Thierry


Attachments:
(No filename) (2.64 kB)
signature.asc (819.00 B)
Download all attachments

2015-08-23 23:23:37

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
> Analogix dp driver is split from exynos dp driver, so we just
> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>
> Beside update some exynos dtsi file with the latest change
> according to the devicetree binding documents.

You can't just change the exynos bindings and break compatibility. Is
there some agreement with exynos folks to do this?


> Signed-off-by: Yakir Yang <[email protected]>
> ---
> Changes in v3:
> - Take Heiko suggest, add devicetree binding documents.
> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
> from the new analogix dp driver devicetree binding.
> - Update the exist exynos dtsi file with the latest DP DT properies.
>
> Changes in v2: None
>
> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 70 ++++++++++++++++++++++
> .../devicetree/bindings/video/exynos_dp.txt | 50 ++++++----------
> arch/arm/boot/dts/exynos5250-arndale.dts | 10 ++--
> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 ++--
> arch/arm/boot/dts/exynos5250-snow.dts | 12 ++--
> arch/arm/boot/dts/exynos5250-spring.dts | 12 ++--
> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 ++--
> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 ++--
> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 ++--
> 9 files changed, 119 insertions(+), 79 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>
> diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
> new file mode 100644
> index 0000000..6127018
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
> @@ -0,0 +1,70 @@
> +Analogix Display Port bridge bindings
> +
> +Required properties for dp-controller:
> + -compatible:
> + platform specific such as:
> + * "samsung,exynos5-dp"
> + * "rockchip,rk3288-dp"
> + -reg:
> + physical base address of the controller and length
> + of memory mapped region.
> + -interrupts:
> + interrupt combiner values.
> + -clocks:
> + from common clock binding: handle to dp clock.
> + -clock-names:
> + from common clock binding: Shall be "dp".
> + -interrupt-parent:
> + phandle to Interrupt combiner node.
> + -phys:
> + from general PHY binding: the phandle for the PHY device.
> + -phy-names:
> + from general PHY binding: Should be "dp".
> + -analogix,color-space:
> + input video data format.
> + COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
> + -analogix,color-depth:
> + number of bits per colour component.
> + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3

This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
drop the vendor prefix.

> + -analogix,link-rate:
> + max link rate supported by the eDP controller.
> + LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
> + LINK_RATE_5_40GBPS = 0x14

Same here. I'd rather see something like "link-rate-mbps" and use the
actual rate.

> + -analogix,lane-count:
> + max number of lanes supported by the eDP contoller.
> + LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4

And drop the vendor prefix here.

> + -port@[X]: SoC specific port nodes with endpoint definitions as defined
> + in Documentation/devicetree/bindings/media/video-interfaces.txt,
> + please refer to the SoC specific binding document:
> + * Documentation/devicetree/bindings/video/exynos_dp.txt
> + * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
> +
> +Optional properties for dp-controller:
> + -analogix,hpd-gpio:
> + Hotplug detect GPIO.
> + Indicates which GPIO should be used for hotplug
> + detection

We should align with "hpd-gpios" used by HDMI connector binding. Or do
we need a DP connector binding that this should be defined in?
Probably so.

The DRM related bindings are such a cluster f*ck with everyone picking
their own way to do things. Just grep hpd in bindings for starters.
That is just the tip.

> + -video interfaces: Device node can contain video interface port
> + nodes according to [1].

Isn't this the same as ports above? How are they optional? 0 ports
would be pretty useless.

> +
> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
> +-------------------------------------------------------------------------------
> +
> +Example:
> +
> + dp-controller {
> + compatible = "samsung,exynos5-dp";
> + reg = <0x145b0000 0x10000>;
> + interrupts = <10 3>;
> + interrupt-parent = <&combiner>;
> + clocks = <&clock 342>;
> + clock-names = "dp";
> +
> + phys = <&dp_phy>;
> + phy-names = "dp";
> +
> + analogix,color-space = <0>;
> + analogix,color-depth = <1>;
> + analogix,link-rate = <0x0a>;
> + analogix,lane-count = <4>;
> + };
> diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
> index 7a3a9cd..177506f 100644
> --- a/Documentation/devicetree/bindings/video/exynos_dp.txt
> +++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
> @@ -31,28 +31,10 @@ Required properties for dp-controller:
> from general PHY binding: the phandle for the PHY device.
> -phy-names:
> from general PHY binding: Should be "dp".
> - -samsung,color-space:
> - input video data format.
> - COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
> - -samsung,dynamic-range:
> - dynamic range for input video data.
> - VESA = 0, CEA = 1
> - -samsung,ycbcr-coeff:
> - YCbCr co-efficients for input video.
> - COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
> - -samsung,color-depth:
> - number of bits per colour component.
> - COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
> - -samsung,link-rate:
> - link rate supported by the panel.
> - LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
> - -samsung,lane-count:
> - number of lanes supported by the panel.
> - LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
> - - display-timings: timings for the connected panel as described by
> - Documentation/devicetree/bindings/video/display-timing.txt
>
> Optional properties for dp-controller:
> + - display-timings: timings for the connected panel as described by
> + Documentation/devicetree/bindings/video/display-timing.txt
> -interlaced:
> interlace scan mode.
> Progressive if defined, Interlaced if not defined
> @@ -62,14 +44,18 @@ Optional properties for dp-controller:
> -hsync-active-high:
> HSYNC polarity configuration.
> High if defined, Low if not defined
> - -samsung,hpd-gpio:
> - Hotplug detect GPIO.
> - Indicates which GPIO should be used for hotplug
> - detection
> - -video interfaces: Device node can contain video interface port
> - nodes according to [1].
>
> -[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
> +For the below properties, please refer to Analogix DP binding document:
> + * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
> + -phys (required)
> + -phy-names (required)
> + -analogix,color-space (required)
> + -analogix,color-depth (required)
> + -analogix,link-rate (required)
> + -analogix,lane-count (required)
> + -analogix,hpd-gpio (optional)
> + -video interfaces (optional)
> +-------------------------------------------------------------------------------
>
> Example:
>
> @@ -88,12 +74,10 @@ SOC specific portion:
>
> Board Specific portion:
> dp-controller {
> - samsung,color-space = <0>;
> - samsung,dynamic-range = <0>;
> - samsung,ycbcr-coeff = <0>;
> - samsung,color-depth = <1>;
> - samsung,link-rate = <0x0a>;
> - samsung,lane-count = <4>;
> + analogix,color-space = <0>;
> + analogix,color-depth = <1>;
> + analogix,link-rate = <0x0a>;
> + analogix,lane-count = <4>;
>
> display-timings {
> native-mode = <&lcd_timing>;
> diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
> index 7e728a1..e48798d 100644
> --- a/arch/arm/boot/dts/exynos5250-arndale.dts
> +++ b/arch/arm/boot/dts/exynos5250-arndale.dts
> @@ -119,12 +119,10 @@
>
> &dp {
> status = "okay";
> - samsung,color-space = <0>;
> - samsung,dynamic-range = <0>;
> - samsung,ycbcr-coeff = <0>;
> - samsung,color-depth = <1>;
> - samsung,link-rate = <0x0a>;
> - samsung,lane-count = <4>;
> + analogix,color-space = <0>;
> + analogix,color-depth = <1>;
> + analogix,link-rate = <0x0a>;
> + analogix,lane-count = <4>;
> };
>
> &fimd {
> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
> index 4fe186d..b8c6b8b 100644
> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
> @@ -75,12 +75,10 @@
> };
>
> &dp {
> - samsung,color-space = <0>;
> - samsung,dynamic-range = <0>;
> - samsung,ycbcr-coeff = <0>;
> - samsung,color-depth = <1>;
> - samsung,link-rate = <0x0a>;
> - samsung,lane-count = <4>;
> + analogix,color-space = <0>;
> + analogix,color-depth = <1>;
> + analogix,link-rate = <0x0a>;
> + analogix,lane-count = <4>;
>
> pinctrl-names = "default";
> pinctrl-0 = <&dp_hpd>;
> diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
> index b7f4122..9ce2b89 100644
> --- a/arch/arm/boot/dts/exynos5250-snow.dts
> +++ b/arch/arm/boot/dts/exynos5250-snow.dts
> @@ -239,13 +239,11 @@
> status = "okay";
> pinctrl-names = "default";
> pinctrl-0 = <&dp_hpd>;
> - samsung,color-space = <0>;
> - samsung,dynamic-range = <0>;
> - samsung,ycbcr-coeff = <0>;
> - samsung,color-depth = <1>;
> - samsung,link-rate = <0x0a>;
> - samsung,lane-count = <2>;
> - samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
> + analogix,color-space = <0>;
> + analogix,color-depth = <1>;
> + analogix,link-rate = <0x0a>;
> + analogix,lane-count = <2>;
> + analogix,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>
> ports {
> port@0 {
> diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
> index d03f9b8..9288ae6 100644
> --- a/arch/arm/boot/dts/exynos5250-spring.dts
> +++ b/arch/arm/boot/dts/exynos5250-spring.dts
> @@ -69,13 +69,11 @@
> status = "okay";
> pinctrl-names = "default";
> pinctrl-0 = <&dp_hpd_gpio>;
> - samsung,color-space = <0>;
> - samsung,dynamic-range = <0>;
> - samsung,ycbcr-coeff = <0>;
> - samsung,color-depth = <1>;
> - samsung,link-rate = <0x0a>;
> - samsung,lane-count = <1>;
> - samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
> + analogix,color-space = <0>;
> + analogix,color-depth = <1>;
> + analogix,link-rate = <0x0a>;
> + analogix,lane-count = <1>;
> + analogix,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
> };
>
> &ehci {
> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
> index 8f4d76c..695a380 100644
> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
> @@ -147,13 +147,11 @@
> status = "okay";
> pinctrl-names = "default";
> pinctrl-0 = <&dp_hpd_gpio>;
> - samsung,color-space = <0>;
> - samsung,dynamic-range = <0>;
> - samsung,ycbcr-coeff = <0>;
> - samsung,color-depth = <1>;
> - samsung,link-rate = <0x06>;
> - samsung,lane-count = <2>;
> - samsung,hpd-gpio = <&gpx2 6 0>;
> + analogix,color-space = <0>;
> + analogix,color-depth = <1>;
> + analogix,link-rate = <0x06>;
> + analogix,lane-count = <2>;
> + analogix,hpd-gpio = <&gpx2 6 0>;
>
> ports {
> port@0 {
> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
> index 98871f9..fd46714 100644
> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
> @@ -91,12 +91,10 @@
> &dp {
> pinctrl-names = "default";
> pinctrl-0 = <&dp_hpd>;
> - samsung,color-space = <0>;
> - samsung,dynamic-range = <0>;
> - samsung,ycbcr-coeff = <0>;
> - samsung,color-depth = <1>;
> - samsung,link-rate = <0x0a>;
> - samsung,lane-count = <4>;
> + analogix,color-space = <0>;
> + analogix,color-depth = <1>;
> + analogix,link-rate = <0x0a>;
> + analogix,lane-count = <4>;
> status = "okay";
> };
>
> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
> index 7d5b386..54b4c63 100644
> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
> @@ -141,13 +141,11 @@
> status = "okay";
> pinctrl-names = "default";
> pinctrl-0 = <&dp_hpd_gpio>;
> - samsung,color-space = <0>;
> - samsung,dynamic-range = <0>;
> - samsung,ycbcr-coeff = <0>;
> - samsung,color-depth = <1>;
> - samsung,link-rate = <0x0a>;
> - samsung,lane-count = <2>;
> - samsung,hpd-gpio = <&gpx2 6 0>;
> + analogix,color-space = <0>;
> + analogix,color-depth = <1>;
> + analogix,link-rate = <0x0a>;
> + analogix,lane-count = <2>;
> + analogix,hpd-gpio = <&gpx2 6 0>;
> panel = <&panel>;
> };
>
> --
> 1.9.1
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

2015-08-24 00:43:36

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

2015-08-24 8:23 GMT+09:00 Rob Herring <[email protected]>:
> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>> Analogix dp driver is split from exynos dp driver, so we just
>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>
>> Beside update some exynos dtsi file with the latest change
>> according to the devicetree binding documents.
>
> You can't just change the exynos bindings and break compatibility. Is
> there some agreement with exynos folks to do this?

No, there is no agreement. This wasn't even sent to Exynos maintainers.
Additionally the patchset did not look interesting to me because of
misleading subject - Documentation instead of "ARM: dts:".

Yakir, please:
1. Provide backward compatibility. Mark old properties as deprecated
but still support them.
2. Separate all DTS changes to a separate patch, unless bisectability
would be hurt. Anyway you should prepare it in a such way that
separation would be possible without breaking bisectability.
3. Use proper subject for the patch changing DTS. This is not
documentation change!
4. Please use script get_maintainers to obtain list of valid
maintainers and CC-them with at least cover letter and patches
requiring their attention.

Best regards,
Krzysztof


>
>
>> Signed-off-by: Yakir Yang <[email protected]>
>> ---
>> Changes in v3:
>> - Take Heiko suggest, add devicetree binding documents.
>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>> from the new analogix dp driver devicetree binding.
>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>
>> Changes in v2: None
>>
>> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 70 ++++++++++++++++++++++
>> .../devicetree/bindings/video/exynos_dp.txt | 50 ++++++----------
>> arch/arm/boot/dts/exynos5250-arndale.dts | 10 ++--
>> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 ++--
>> arch/arm/boot/dts/exynos5250-snow.dts | 12 ++--
>> arch/arm/boot/dts/exynos5250-spring.dts | 12 ++--
>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 ++--
>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 ++--
>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 ++--
>> 9 files changed, 119 insertions(+), 79 deletions(-)
>> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>
>> diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>> new file mode 100644
>> index 0000000..6127018
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>> @@ -0,0 +1,70 @@
>> +Analogix Display Port bridge bindings
>> +
>> +Required properties for dp-controller:
>> + -compatible:
>> + platform specific such as:
>> + * "samsung,exynos5-dp"
>> + * "rockchip,rk3288-dp"
>> + -reg:
>> + physical base address of the controller and length
>> + of memory mapped region.
>> + -interrupts:
>> + interrupt combiner values.
>> + -clocks:
>> + from common clock binding: handle to dp clock.
>> + -clock-names:
>> + from common clock binding: Shall be "dp".
>> + -interrupt-parent:
>> + phandle to Interrupt combiner node.
>> + -phys:
>> + from general PHY binding: the phandle for the PHY device.
>> + -phy-names:
>> + from general PHY binding: Should be "dp".
>> + -analogix,color-space:
>> + input video data format.
>> + COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>> + -analogix,color-depth:
>> + number of bits per colour component.
>> + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>
> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
> drop the vendor prefix.
>
>> + -analogix,link-rate:
>> + max link rate supported by the eDP controller.
>> + LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
>> + LINK_RATE_5_40GBPS = 0x14
>
> Same here. I'd rather see something like "link-rate-mbps" and use the
> actual rate.
>
>> + -analogix,lane-count:
>> + max number of lanes supported by the eDP contoller.
>> + LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>
> And drop the vendor prefix here.
>
>> + -port@[X]: SoC specific port nodes with endpoint definitions as defined
>> + in Documentation/devicetree/bindings/media/video-interfaces.txt,
>> + please refer to the SoC specific binding document:
>> + * Documentation/devicetree/bindings/video/exynos_dp.txt
>> + * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>> +
>> +Optional properties for dp-controller:
>> + -analogix,hpd-gpio:
>> + Hotplug detect GPIO.
>> + Indicates which GPIO should be used for hotplug
>> + detection
>
> We should align with "hpd-gpios" used by HDMI connector binding. Or do
> we need a DP connector binding that this should be defined in?
> Probably so.
>
> The DRM related bindings are such a cluster f*ck with everyone picking
> their own way to do things. Just grep hpd in bindings for starters.
> That is just the tip.
>
>> + -video interfaces: Device node can contain video interface port
>> + nodes according to [1].
>
> Isn't this the same as ports above? How are they optional? 0 ports
> would be pretty useless.
>
>> +
>> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>> +-------------------------------------------------------------------------------
>> +
>> +Example:
>> +
>> + dp-controller {
>> + compatible = "samsung,exynos5-dp";
>> + reg = <0x145b0000 0x10000>;
>> + interrupts = <10 3>;
>> + interrupt-parent = <&combiner>;
>> + clocks = <&clock 342>;
>> + clock-names = "dp";
>> +
>> + phys = <&dp_phy>;
>> + phy-names = "dp";
>> +
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <4>;
>> + };
>> diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
>> index 7a3a9cd..177506f 100644
>> --- a/Documentation/devicetree/bindings/video/exynos_dp.txt
>> +++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
>> @@ -31,28 +31,10 @@ Required properties for dp-controller:
>> from general PHY binding: the phandle for the PHY device.
>> -phy-names:
>> from general PHY binding: Should be "dp".
>> - -samsung,color-space:
>> - input video data format.
>> - COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>> - -samsung,dynamic-range:
>> - dynamic range for input video data.
>> - VESA = 0, CEA = 1
>> - -samsung,ycbcr-coeff:
>> - YCbCr co-efficients for input video.
>> - COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>> - -samsung,color-depth:
>> - number of bits per colour component.
>> - COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>> - -samsung,link-rate:
>> - link rate supported by the panel.
>> - LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
>> - -samsung,lane-count:
>> - number of lanes supported by the panel.
>> - LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>> - - display-timings: timings for the connected panel as described by
>> - Documentation/devicetree/bindings/video/display-timing.txt
>>
>> Optional properties for dp-controller:
>> + - display-timings: timings for the connected panel as described by
>> + Documentation/devicetree/bindings/video/display-timing.txt
>> -interlaced:
>> interlace scan mode.
>> Progressive if defined, Interlaced if not defined
>> @@ -62,14 +44,18 @@ Optional properties for dp-controller:
>> -hsync-active-high:
>> HSYNC polarity configuration.
>> High if defined, Low if not defined
>> - -samsung,hpd-gpio:
>> - Hotplug detect GPIO.
>> - Indicates which GPIO should be used for hotplug
>> - detection
>> - -video interfaces: Device node can contain video interface port
>> - nodes according to [1].
>>
>> -[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>> +For the below properties, please refer to Analogix DP binding document:
>> + * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>> + -phys (required)
>> + -phy-names (required)
>> + -analogix,color-space (required)
>> + -analogix,color-depth (required)
>> + -analogix,link-rate (required)
>> + -analogix,lane-count (required)
>> + -analogix,hpd-gpio (optional)
>> + -video interfaces (optional)
>> +-------------------------------------------------------------------------------
>>
>> Example:
>>
>> @@ -88,12 +74,10 @@ SOC specific portion:
>>
>> Board Specific portion:
>> dp-controller {
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <4>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <4>;
>>
>> display-timings {
>> native-mode = <&lcd_timing>;
>> diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
>> index 7e728a1..e48798d 100644
>> --- a/arch/arm/boot/dts/exynos5250-arndale.dts
>> +++ b/arch/arm/boot/dts/exynos5250-arndale.dts
>> @@ -119,12 +119,10 @@
>>
>> &dp {
>> status = "okay";
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <4>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <4>;
>> };
>>
>> &fimd {
>> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>> index 4fe186d..b8c6b8b 100644
>> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>> @@ -75,12 +75,10 @@
>> };
>>
>> &dp {
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <4>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <4>;
>>
>> pinctrl-names = "default";
>> pinctrl-0 = <&dp_hpd>;
>> diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
>> index b7f4122..9ce2b89 100644
>> --- a/arch/arm/boot/dts/exynos5250-snow.dts
>> +++ b/arch/arm/boot/dts/exynos5250-snow.dts
>> @@ -239,13 +239,11 @@
>> status = "okay";
>> pinctrl-names = "default";
>> pinctrl-0 = <&dp_hpd>;
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <2>;
>> - samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <2>;
>> + analogix,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>
>> ports {
>> port@0 {
>> diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
>> index d03f9b8..9288ae6 100644
>> --- a/arch/arm/boot/dts/exynos5250-spring.dts
>> +++ b/arch/arm/boot/dts/exynos5250-spring.dts
>> @@ -69,13 +69,11 @@
>> status = "okay";
>> pinctrl-names = "default";
>> pinctrl-0 = <&dp_hpd_gpio>;
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <1>;
>> - samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <1>;
>> + analogix,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>> };
>>
>> &ehci {
>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> index 8f4d76c..695a380 100644
>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> @@ -147,13 +147,11 @@
>> status = "okay";
>> pinctrl-names = "default";
>> pinctrl-0 = <&dp_hpd_gpio>;
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x06>;
>> - samsung,lane-count = <2>;
>> - samsung,hpd-gpio = <&gpx2 6 0>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x06>;
>> + analogix,lane-count = <2>;
>> + analogix,hpd-gpio = <&gpx2 6 0>;
>>
>> ports {
>> port@0 {
>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> index 98871f9..fd46714 100644
>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> @@ -91,12 +91,10 @@
>> &dp {
>> pinctrl-names = "default";
>> pinctrl-0 = <&dp_hpd>;
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <4>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <4>;
>> status = "okay";
>> };
>>
>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> index 7d5b386..54b4c63 100644
>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> @@ -141,13 +141,11 @@
>> status = "okay";
>> pinctrl-names = "default";
>> pinctrl-0 = <&dp_hpd_gpio>;
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <2>;
>> - samsung,hpd-gpio = <&gpx2 6 0>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <2>;
>> + analogix,hpd-gpio = <&gpx2 6 0>;
>> panel = <&panel>;
>> };
>>
>> --
>> 1.9.1
>>
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> [email protected]
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

2015-08-24 02:21:49

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Hi Rob,

在 08/23/2015 06:23 PM, Rob Herring 写道:
> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>> Analogix dp driver is split from exynos dp driver, so we just
>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>
>> Beside update some exynos dtsi file with the latest change
>> according to the devicetree binding documents.
> You can't just change the exynos bindings and break compatibility. Is
> there some agreement with exynos folks to do this?
>

Yeah, this change only start to introduce in version 3 series, so there is
no agreement or discuss before.

>
>> Signed-off-by: Yakir Yang <[email protected]>
>> ---
>> Changes in v3:
>> - Take Heiko suggest, add devicetree binding documents.
>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>> from the new analogix dp driver devicetree binding.
>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>
>> Changes in v2: None
>>
>> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 70 ++++++++++++++++++++++
>> .../devicetree/bindings/video/exynos_dp.txt | 50 ++++++----------
>> arch/arm/boot/dts/exynos5250-arndale.dts | 10 ++--
>> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 ++--
>> arch/arm/boot/dts/exynos5250-snow.dts | 12 ++--
>> arch/arm/boot/dts/exynos5250-spring.dts | 12 ++--
>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 ++--
>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 ++--
>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 ++--
>> 9 files changed, 119 insertions(+), 79 deletions(-)
>> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>
>> diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>> new file mode 100644
>> index 0000000..6127018
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>> @@ -0,0 +1,70 @@
>> +Analogix Display Port bridge bindings
>> +
>> +Required properties for dp-controller:
>> + -compatible:
>> + platform specific such as:
>> + * "samsung,exynos5-dp"
>> + * "rockchip,rk3288-dp"
>> + -reg:
>> + physical base address of the controller and length
>> + of memory mapped region.
>> + -interrupts:
>> + interrupt combiner values.
>> + -clocks:
>> + from common clock binding: handle to dp clock.
>> + -clock-names:
>> + from common clock binding: Shall be "dp".
>> + -interrupt-parent:
>> + phandle to Interrupt combiner node.
>> + -phys:
>> + from general PHY binding: the phandle for the PHY device.
>> + -phy-names:
>> + from general PHY binding: Should be "dp".
>> + -analogix,color-space:
>> + input video data format.
>> + COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>> + -analogix,color-depth:
>> + number of bits per colour component.
>> + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
> drop the vendor prefix.

Okay, thanks


>> + -analogix,link-rate:
>> + max link rate supported by the eDP controller.
>> + LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
>> + LINK_RATE_5_40GBPS = 0x14
> Same here. I'd rather see something like "link-rate-mbps" and use the
> actual rate.

Like "link-rate-mbps = 162000", so I need of_property_read_u32() for
this prop.

Okay, done.

>> + -analogix,lane-count:
>> + max number of lanes supported by the eDP contoller.
>> + LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
> And drop the vendor prefix here.

Done

>> + -port@[X]: SoC specific port nodes with endpoint definitions as defined
>> + in Documentation/devicetree/bindings/media/video-interfaces.txt,
>> + please refer to the SoC specific binding document:
>> + * Documentation/devicetree/bindings/video/exynos_dp.txt
>> + * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>> +
>> +Optional properties for dp-controller:
>> + -analogix,hpd-gpio:
>> + Hotplug detect GPIO.
>> + Indicates which GPIO should be used for hotplug
>> + detection
> We should align with "hpd-gpios" used by HDMI connector binding. Or do
> we need a DP connector binding that this should be defined in?
> Probably so.
>
> The DRM related bindings are such a cluster f*ck with everyone picking
> their own way to do things. Just grep hpd in bindings for starters.
> That is just the tip.
>

Hmm... I don't understand how the HDMI connector binding works, there are no
driver that name with "hdmi-connector" compatible, does it just an
sample case
for all HDMI dts node?

But I'm okay with your suggest here, change "analogix,hpd-gpio" to
"hpd-gpios" ;)

>> + -video interfaces: Device node can contain video interface port
>> + nodes according to [1].
> Isn't this the same as ports above? How are they optional? 0 ports
> would be pretty useless.

I though I make an mistaken here, "-video interfaces" is the same as
previous "ports".

And "ports" is an required property in rockchip case, cause we use it to
bind "dp" driver
to crtc "vop" driver. But I thinks "ports" in not an required property
in exynos case, they
only use when there are a dp/lvds application scenarios.

Here are example (./arch/arm/boot/dts/exynos5420-peach-pit.dts):
&dp {
[...]
ports {
port@0 {
dp_out: endpoint {
remote-endpoint = <&bridge_in>;
};
};
};
};

ps8625: lvds-bridge@48 {
[...]
ports {
port@0 {
bridge_out: endpoint {
remote-endpoint = <&panel_in>;
};
};

port@1 {
bridge_in: endpoint {
remote-endpoint = <&dp_out>;
};
};
};

};

So I would rather to remove "ports" to analogix_dp-rockchip.txt with
"required" flag,
and keep "video-port" in analogox-dp.txt with "optional" flag.

>> +
>> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>> +-------------------------------------------------------------------------------
>> +
>> +Example:
>> +
>> + dp-controller {
>> + compatible = "samsung,exynos5-dp";
>> + reg = <0x145b0000 0x10000>;
>> + interrupts = <10 3>;
>> + interrupt-parent = <&combiner>;
>> + clocks = <&clock 342>;
>> + clock-names = "dp";
>> +
>> + phys = <&dp_phy>;
>> + phy-names = "dp";
>> +
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <4>;
>> + };
>> diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
>> index 7a3a9cd..177506f 100644
>> --- a/Documentation/devicetree/bindings/video/exynos_dp.txt
>> +++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
>> @@ -31,28 +31,10 @@ Required properties for dp-controller:
>> from general PHY binding: the phandle for the PHY device.
>> -phy-names:
>> from general PHY binding: Should be "dp".
>> - -samsung,color-space:
>> - input video data format.
>> - COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>> - -samsung,dynamic-range:
>> - dynamic range for input video data.
>> - VESA = 0, CEA = 1
>> - -samsung,ycbcr-coeff:
>> - YCbCr co-efficients for input video.
>> - COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>> - -samsung,color-depth:
>> - number of bits per colour component.
>> - COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>> - -samsung,link-rate:
>> - link rate supported by the panel.
>> - LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
>> - -samsung,lane-count:
>> - number of lanes supported by the panel.
>> - LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>> - - display-timings: timings for the connected panel as described by
>> - Documentation/devicetree/bindings/video/display-timing.txt
>>
>> Optional properties for dp-controller:
>> + - display-timings: timings for the connected panel as described by
>> + Documentation/devicetree/bindings/video/display-timing.txt
>> -interlaced:
>> interlace scan mode.
>> Progressive if defined, Interlaced if not defined
>> @@ -62,14 +44,18 @@ Optional properties for dp-controller:
>> -hsync-active-high:
>> HSYNC polarity configuration.
>> High if defined, Low if not defined
>> - -samsung,hpd-gpio:
>> - Hotplug detect GPIO.
>> - Indicates which GPIO should be used for hotplug
>> - detection
>> - -video interfaces: Device node can contain video interface port
>> - nodes according to [1].
>>
>> -[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>> +For the below properties, please refer to Analogix DP binding document:
>> + * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>> + -phys (required)
>> + -phy-names (required)
>> + -analogix,color-space (required)
>> + -analogix,color-depth (required)
>> + -analogix,link-rate (required)
>> + -analogix,lane-count (required)
>> + -analogix,hpd-gpio (optional)
>> + -video interfaces (optional)
>> +-------------------------------------------------------------------------------
>>
>> Example:
>>
>> @@ -88,12 +74,10 @@ SOC specific portion:
>>
>> Board Specific portion:
>> dp-controller {
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <4>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <4>;
>>
>> display-timings {
>> native-mode = <&lcd_timing>;
>> diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
>> index 7e728a1..e48798d 100644
>> --- a/arch/arm/boot/dts/exynos5250-arndale.dts
>> +++ b/arch/arm/boot/dts/exynos5250-arndale.dts
>> @@ -119,12 +119,10 @@
>>
>> &dp {
>> status = "okay";
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <4>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <4>;
>> };
>>
>> &fimd {
>> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>> index 4fe186d..b8c6b8b 100644
>> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>> @@ -75,12 +75,10 @@
>> };
>>
>> &dp {
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <4>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <4>;
>>
>> pinctrl-names = "default";
>> pinctrl-0 = <&dp_hpd>;
>> diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
>> index b7f4122..9ce2b89 100644
>> --- a/arch/arm/boot/dts/exynos5250-snow.dts
>> +++ b/arch/arm/boot/dts/exynos5250-snow.dts
>> @@ -239,13 +239,11 @@
>> status = "okay";
>> pinctrl-names = "default";
>> pinctrl-0 = <&dp_hpd>;
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <2>;
>> - samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <2>;
>> + analogix,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>
>> ports {
>> port@0 {
>> diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
>> index d03f9b8..9288ae6 100644
>> --- a/arch/arm/boot/dts/exynos5250-spring.dts
>> +++ b/arch/arm/boot/dts/exynos5250-spring.dts
>> @@ -69,13 +69,11 @@
>> status = "okay";
>> pinctrl-names = "default";
>> pinctrl-0 = <&dp_hpd_gpio>;
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <1>;
>> - samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <1>;
>> + analogix,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>> };
>>
>> &ehci {
>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> index 8f4d76c..695a380 100644
>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> @@ -147,13 +147,11 @@
>> status = "okay";
>> pinctrl-names = "default";
>> pinctrl-0 = <&dp_hpd_gpio>;
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x06>;
>> - samsung,lane-count = <2>;
>> - samsung,hpd-gpio = <&gpx2 6 0>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x06>;
>> + analogix,lane-count = <2>;
>> + analogix,hpd-gpio = <&gpx2 6 0>;
>>
>> ports {
>> port@0 {
>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> index 98871f9..fd46714 100644
>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> @@ -91,12 +91,10 @@
>> &dp {
>> pinctrl-names = "default";
>> pinctrl-0 = <&dp_hpd>;
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <4>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <4>;
>> status = "okay";
>> };
>>
>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> index 7d5b386..54b4c63 100644
>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> @@ -141,13 +141,11 @@
>> status = "okay";
>> pinctrl-names = "default";
>> pinctrl-0 = <&dp_hpd_gpio>;
>> - samsung,color-space = <0>;
>> - samsung,dynamic-range = <0>;
>> - samsung,ycbcr-coeff = <0>;
>> - samsung,color-depth = <1>;
>> - samsung,link-rate = <0x0a>;
>> - samsung,lane-count = <2>;
>> - samsung,hpd-gpio = <&gpx2 6 0>;
>> + analogix,color-space = <0>;
>> + analogix,color-depth = <1>;
>> + analogix,link-rate = <0x0a>;
>> + analogix,lane-count = <2>;
>> + analogix,hpd-gpio = <&gpx2 6 0>;
>> panel = <&panel>;
>> };
>>
>> --
>> 1.9.1
>>
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> [email protected]
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
>

2015-08-24 02:42:50

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Hi Krzysztof,

在 08/23/2015 07:43 PM, Krzysztof Kozlowski 写道:
> 2015-08-24 8:23 GMT+09:00 Rob Herring <[email protected]>:
>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>>> Analogix dp driver is split from exynos dp driver, so we just
>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>
>>> Beside update some exynos dtsi file with the latest change
>>> according to the devicetree binding documents.
>> You can't just change the exynos bindings and break compatibility. Is
>> there some agreement with exynos folks to do this?
> No, there is no agreement. This wasn't even sent to Exynos maintainers.

Sorry about this one, actually I have add Exynos maintainers in version
1 & version 2,
but lose some maintainers in version 3, I would fix it in bellow versions.

> Additionally the patchset did not look interesting to me because of
> misleading subject - Documentation instead of "ARM: dts:".
>
> Yakir, please:
> 1. Provide backward compatibility. Mark old properties as deprecated
> but still support them.

Do you mean that I should keep the old properties declare in exynos-dp.txt,
but just mark them as deprecated flag. Let me show same examples, make
me understand your suggest rightly.

1. "samsung,ycbcr-coeff" is abandoned in latest analogix-dp driver,
absolutely
I should not carry this to analogix-dp.txt document. But I should
keep this in
exynos-dp.txt document, and mark them with an little "deprecated" flag.

[Documentation/devicetree/bindings/video/exynos_dp.txt]
Required properties for dp-controller:
[...]
-samsung,ycbcr-coeff (DEPRECATED):
YCbCr co-efficients for input video.
COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1

Is it right ?

> 2. Separate all DTS changes to a separate patch, unless bisectability
> would be hurt. Anyway you should prepare it in a such way that
> separation would be possible without breaking bisectability.

So I should separate this patch into two parts, one is name "Document:",
the other is "ARM: dts: ".

Honestly, I don't understand what the "bisectability" means in this case.

> 3. Use proper subject for the patch changing DTS. This is not
> documentation change!

Hmm... when I separate this patch into two parts, I though I can keep
"Documentation" proper subject in this patch, and the other is the "ARM:
dts"
proper subject. Am I right ?

> 4. Please use script get_maintainers to obtain list of valid
> maintainers and CC-them with at least cover letter and patches
> requiring their attention.

Yeah, thanks.


Thanks a lot,
- Yakir

> Best regards,
> Krzysztof
>
>
>>
>>> Signed-off-by: Yakir Yang <[email protected]>
>>> ---
>>> Changes in v3:
>>> - Take Heiko suggest, add devicetree binding documents.
>>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>> from the new analogix dp driver devicetree binding.
>>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>>
>>> Changes in v2: None
>>>
>>> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 70 ++++++++++++++++++++++
>>> .../devicetree/bindings/video/exynos_dp.txt | 50 ++++++----------
>>> arch/arm/boot/dts/exynos5250-arndale.dts | 10 ++--
>>> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 ++--
>>> arch/arm/boot/dts/exynos5250-snow.dts | 12 ++--
>>> arch/arm/boot/dts/exynos5250-spring.dts | 12 ++--
>>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 ++--
>>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 ++--
>>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 ++--
>>> 9 files changed, 119 insertions(+), 79 deletions(-)
>>> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>> new file mode 100644
>>> index 0000000..6127018
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>> @@ -0,0 +1,70 @@
>>> +Analogix Display Port bridge bindings
>>> +
>>> +Required properties for dp-controller:
>>> + -compatible:
>>> + platform specific such as:
>>> + * "samsung,exynos5-dp"
>>> + * "rockchip,rk3288-dp"
>>> + -reg:
>>> + physical base address of the controller and length
>>> + of memory mapped region.
>>> + -interrupts:
>>> + interrupt combiner values.
>>> + -clocks:
>>> + from common clock binding: handle to dp clock.
>>> + -clock-names:
>>> + from common clock binding: Shall be "dp".
>>> + -interrupt-parent:
>>> + phandle to Interrupt combiner node.
>>> + -phys:
>>> + from general PHY binding: the phandle for the PHY device.
>>> + -phy-names:
>>> + from general PHY binding: Should be "dp".
>>> + -analogix,color-space:
>>> + input video data format.
>>> + COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>>> + -analogix,color-depth:
>>> + number of bits per colour component.
>>> + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
>> drop the vendor prefix.
>>
>>> + -analogix,link-rate:
>>> + max link rate supported by the eDP controller.
>>> + LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
>>> + LINK_RATE_5_40GBPS = 0x14
>> Same here. I'd rather see something like "link-rate-mbps" and use the
>> actual rate.
>>
>>> + -analogix,lane-count:
>>> + max number of lanes supported by the eDP contoller.
>>> + LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>> And drop the vendor prefix here.
>>
>>> + -port@[X]: SoC specific port nodes with endpoint definitions as defined
>>> + in Documentation/devicetree/bindings/media/video-interfaces.txt,
>>> + please refer to the SoC specific binding document:
>>> + * Documentation/devicetree/bindings/video/exynos_dp.txt
>>> + * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>>> +
>>> +Optional properties for dp-controller:
>>> + -analogix,hpd-gpio:
>>> + Hotplug detect GPIO.
>>> + Indicates which GPIO should be used for hotplug
>>> + detection
>> We should align with "hpd-gpios" used by HDMI connector binding. Or do
>> we need a DP connector binding that this should be defined in?
>> Probably so.
>>
>> The DRM related bindings are such a cluster f*ck with everyone picking
>> their own way to do things. Just grep hpd in bindings for starters.
>> That is just the tip.
>>
>>> + -video interfaces: Device node can contain video interface port
>>> + nodes according to [1].
>> Isn't this the same as ports above? How are they optional? 0 ports
>> would be pretty useless.
>>
>>> +
>>> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>>> +-------------------------------------------------------------------------------
>>> +
>>> +Example:
>>> +
>>> + dp-controller {
>>> + compatible = "samsung,exynos5-dp";
>>> + reg = <0x145b0000 0x10000>;
>>> + interrupts = <10 3>;
>>> + interrupt-parent = <&combiner>;
>>> + clocks = <&clock 342>;
>>> + clock-names = "dp";
>>> +
>>> + phys = <&dp_phy>;
>>> + phy-names = "dp";
>>> +
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <4>;
>>> + };
>>> diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
>>> index 7a3a9cd..177506f 100644
>>> --- a/Documentation/devicetree/bindings/video/exynos_dp.txt
>>> +++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
>>> @@ -31,28 +31,10 @@ Required properties for dp-controller:
>>> from general PHY binding: the phandle for the PHY device.
>>> -phy-names:
>>> from general PHY binding: Should be "dp".
>>> - -samsung,color-space:
>>> - input video data format.
>>> - COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>>> - -samsung,dynamic-range:
>>> - dynamic range for input video data.
>>> - VESA = 0, CEA = 1
>>> - -samsung,ycbcr-coeff:
>>> - YCbCr co-efficients for input video.
>>> - COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>>> - -samsung,color-depth:
>>> - number of bits per colour component.
>>> - COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>> - -samsung,link-rate:
>>> - link rate supported by the panel.
>>> - LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
>>> - -samsung,lane-count:
>>> - number of lanes supported by the panel.
>>> - LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>>> - - display-timings: timings for the connected panel as described by
>>> - Documentation/devicetree/bindings/video/display-timing.txt
>>>
>>> Optional properties for dp-controller:
>>> + - display-timings: timings for the connected panel as described by
>>> + Documentation/devicetree/bindings/video/display-timing.txt
>>> -interlaced:
>>> interlace scan mode.
>>> Progressive if defined, Interlaced if not defined
>>> @@ -62,14 +44,18 @@ Optional properties for dp-controller:
>>> -hsync-active-high:
>>> HSYNC polarity configuration.
>>> High if defined, Low if not defined
>>> - -samsung,hpd-gpio:
>>> - Hotplug detect GPIO.
>>> - Indicates which GPIO should be used for hotplug
>>> - detection
>>> - -video interfaces: Device node can contain video interface port
>>> - nodes according to [1].
>>>
>>> -[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>>> +For the below properties, please refer to Analogix DP binding document:
>>> + * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>> + -phys (required)
>>> + -phy-names (required)
>>> + -analogix,color-space (required)
>>> + -analogix,color-depth (required)
>>> + -analogix,link-rate (required)
>>> + -analogix,lane-count (required)
>>> + -analogix,hpd-gpio (optional)
>>> + -video interfaces (optional)
>>> +-------------------------------------------------------------------------------
>>>
>>> Example:
>>>
>>> @@ -88,12 +74,10 @@ SOC specific portion:
>>>
>>> Board Specific portion:
>>> dp-controller {
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <4>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <4>;
>>>
>>> display-timings {
>>> native-mode = <&lcd_timing>;
>>> diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
>>> index 7e728a1..e48798d 100644
>>> --- a/arch/arm/boot/dts/exynos5250-arndale.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-arndale.dts
>>> @@ -119,12 +119,10 @@
>>>
>>> &dp {
>>> status = "okay";
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <4>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <4>;
>>> };
>>>
>>> &fimd {
>>> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> index 4fe186d..b8c6b8b 100644
>>> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> @@ -75,12 +75,10 @@
>>> };
>>>
>>> &dp {
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <4>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <4>;
>>>
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&dp_hpd>;
>>> diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
>>> index b7f4122..9ce2b89 100644
>>> --- a/arch/arm/boot/dts/exynos5250-snow.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-snow.dts
>>> @@ -239,13 +239,11 @@
>>> status = "okay";
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&dp_hpd>;
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <2>;
>>> - samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <2>;
>>> + analogix,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>>
>>> ports {
>>> port@0 {
>>> diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
>>> index d03f9b8..9288ae6 100644
>>> --- a/arch/arm/boot/dts/exynos5250-spring.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-spring.dts
>>> @@ -69,13 +69,11 @@
>>> status = "okay";
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&dp_hpd_gpio>;
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <1>;
>>> - samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <1>;
>>> + analogix,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>>> };
>>>
>>> &ehci {
>>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> index 8f4d76c..695a380 100644
>>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> @@ -147,13 +147,11 @@
>>> status = "okay";
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&dp_hpd_gpio>;
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x06>;
>>> - samsung,lane-count = <2>;
>>> - samsung,hpd-gpio = <&gpx2 6 0>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x06>;
>>> + analogix,lane-count = <2>;
>>> + analogix,hpd-gpio = <&gpx2 6 0>;
>>>
>>> ports {
>>> port@0 {
>>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> index 98871f9..fd46714 100644
>>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> @@ -91,12 +91,10 @@
>>> &dp {
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&dp_hpd>;
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <4>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <4>;
>>> status = "okay";
>>> };
>>>
>>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> index 7d5b386..54b4c63 100644
>>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> @@ -141,13 +141,11 @@
>>> status = "okay";
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&dp_hpd_gpio>;
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <2>;
>>> - samsung,hpd-gpio = <&gpx2 6 0>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <2>;
>>> + analogix,hpd-gpio = <&gpx2 6 0>;
>>> panel = <&panel>;
>>> };
>>>
>>> --
>>> 1.9.1
>>>
>>>
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> [email protected]
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>> _______________________________________________
>> linux-arm-kernel mailing list
>> [email protected]
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
>

2015-08-24 04:20:22

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On 24.08.2015 11:42, Yakir Yang wrote:
> Hi Krzysztof,
>
> 在 08/23/2015 07:43 PM, Krzysztof Kozlowski 写道:
>> 2015-08-24 8:23 GMT+09:00 Rob Herring <[email protected]>:
>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>
>>>> Beside update some exynos dtsi file with the latest change
>>>> according to the devicetree binding documents.
>>> You can't just change the exynos bindings and break compatibility. Is
>>> there some agreement with exynos folks to do this?
>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
>
> Sorry about this one, actually I have add Exynos maintainers in version
> 1 & version 2,
> but lose some maintainers in version 3, I would fix it in bellow versions.
>
>> Additionally the patchset did not look interesting to me because of
>> misleading subject - Documentation instead of "ARM: dts:".
>>
>> Yakir, please:
>> 1. Provide backward compatibility. Mark old properties as deprecated
>> but still support them.
>
> Do you mean that I should keep the old properties declare in exynos-dp.txt,
> but just mark them as deprecated flag.

That is one of ways how to do this. However more important is that
driver should still support old bindings so such code:

- if (of_property_read_u32(dp_node, "samsung,color-space",
+ if (of_property_read_u32(dp_node, "analogix,color-space",

is probably wrong. Will the driver support old DTB in the same way as it
was supporting before the change?

> Let me show same examples, make
> me understand your suggest rightly.

exynos-dp already contains deprecated properties. Other ways of doing
this would be:
Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
Documentation/devicetree/bindings/rtc/s3c-rtc.txt

It depends up to you. The "touchscreen" looks good because it organizes
old properties in a common section. In case of exynos-dp.txt you can add
at beginning of file information about new bindings and mark everything
deprecated.

>
> 1. "samsung,ycbcr-coeff" is abandoned in latest analogix-dp driver,
> absolutely
> I should not carry this to analogix-dp.txt document. But I should
> keep this in
> exynos-dp.txt document, and mark them with an little "deprecated" flag.
>
> [Documentation/devicetree/bindings/video/exynos_dp.txt]
> Required properties for dp-controller:
> [...]
> -samsung,ycbcr-coeff (DEPRECATED):
> YCbCr co-efficients for input video.
> COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>
> Is it right ?

Yes, this is right.

>
>> 2. Separate all DTS changes to a separate patch, unless bisectability
>> would be hurt. Anyway you should prepare it in a such way that
>> separation would be possible without breaking bisectability.
>
> So I should separate this patch into two parts, one is name "Document:",
> the other is "ARM: dts: ".

Yes.

>
> Honestly, I don't understand what the "bisectability" means in this case.

I was referring to bisectability in general. The patchset should be
fully bisectable which means that it does not introduce any issues
during "git bisect". This effectively means that at each intermediate
step (after applying each patch, one by one) every existing stuff works
the same as previously without any regression. Including booting with
old DTB.

>
>> 3. Use proper subject for the patch changing DTS. This is not
>> documentation change!
>
> Hmm... when I separate this patch into two parts, I though I can keep
> "Documentation" proper subject in this patch, and the other is the "ARM:
> dts"
> proper subject. Am I right ?

Yes, you're right.

>
>> 4. Please use script get_maintainers to obtain list of valid
>> maintainers and CC-them with at least cover letter and patches
>> requiring their attention.
>
> Yeah, thanks.

Sure. Now I found older versions of the patchset but previously there
were no changes to the bindings. Again the prefix in subject is
important to easily filter out and find necessary emails.

BTW, I like the patchset because I like in general works which merge
code and reduce duplicate stuff.

Best regards,
Krzysztof

2015-08-24 07:40:56

by Jingoo Han

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On 2015. 8. 24., at AM 9:43, Krzysztof Kozlowski <[email protected]> wrote:
>
> 2015-08-24 8:23 GMT+09:00 Rob Herring <[email protected]>:
>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>>> Analogix dp driver is split from exynos dp driver, so we just
>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>
>>> Beside update some exynos dtsi file with the latest change
>>> according to the devicetree binding documents.
>>
>> You can't just change the exynos bindings and break compatibility. Is
>> there some agreement with exynos folks to do this?
>
> No, there is no agreement. This wasn't even sent to Exynos maintainers.
> Additionally the patchset did not look interesting to me because of
> misleading subject - Documentation instead of "ARM: dts:".
>
> Yakir, please:
> 1. Provide backward compatibility. Mark old properties as deprecated
> but still support them.
> 2. Separate all DTS changes to a separate patch, unless bisectability
> would be hurt. Anyway you should prepare it in a such way that
> separation would be possible without breaking bisectability.
> 3. Use proper subject for the patch changing DTS. This is not
> documentation change!
> 4. Please use script get_maintainers to obtain list of valid
> maintainers and CC-them with at least cover letter and patches
> requiring their attention.

To Yakir Yang,

Please be careful when you CC people.

I don't find the reason why you CC'ed the following people. Of course, they
look to be one of the talented developers. However, they look to be
unrelated to your patchset.

Takashi Iwai
Vincent Palatin
Fabio Estevam
Philipp Zabel


Also, please add Exynos Architecture maintainers to CC list. I don't understand
why you removed them from CC list.
Kukjin Kim
Krzysztof Kozlowski

Without their Ack, you will not change the codes of ARM Exynos Architecture.

Best regards,
Jingoo Han

>
> Best regards,
> Krzysztof
>
>
>>
>>
>>> Signed-off-by: Yakir Yang <[email protected]>
>>> ---
>>> Changes in v3:
>>> - Take Heiko suggest, add devicetree binding documents.
>>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>> from the new analogix dp driver devicetree binding.
>>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>>
>>> Changes in v2: None
>>>
>>> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 70 ++++++++++++++++++++++
>>> .../devicetree/bindings/video/exynos_dp.txt | 50 ++++++----------
>>> arch/arm/boot/dts/exynos5250-arndale.dts | 10 ++--
>>> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 ++--
>>> arch/arm/boot/dts/exynos5250-snow.dts | 12 ++--
>>> arch/arm/boot/dts/exynos5250-spring.dts | 12 ++--
>>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 ++--
>>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 ++--
>>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 ++--
>>> 9 files changed, 119 insertions(+), 79 deletions(-)
>>> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>> new file mode 100644
>>> index 0000000..6127018
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>> @@ -0,0 +1,70 @@
>>> +Analogix Display Port bridge bindings
>>> +
>>> +Required properties for dp-controller:
>>> + -compatible:
>>> + platform specific such as:
>>> + * "samsung,exynos5-dp"
>>> + * "rockchip,rk3288-dp"
>>> + -reg:
>>> + physical base address of the controller and length
>>> + of memory mapped region.
>>> + -interrupts:
>>> + interrupt combiner values.
>>> + -clocks:
>>> + from common clock binding: handle to dp clock.
>>> + -clock-names:
>>> + from common clock binding: Shall be "dp".
>>> + -interrupt-parent:
>>> + phandle to Interrupt combiner node.
>>> + -phys:
>>> + from general PHY binding: the phandle for the PHY device.
>>> + -phy-names:
>>> + from general PHY binding: Should be "dp".
>>> + -analogix,color-space:
>>> + input video data format.
>>> + COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>>> + -analogix,color-depth:
>>> + number of bits per colour component.
>>> + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>
>> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
>> drop the vendor prefix.
>>
>>> + -analogix,link-rate:
>>> + max link rate supported by the eDP controller.
>>> + LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
>>> + LINK_RATE_5_40GBPS = 0x14
>>
>> Same here. I'd rather see something like "link-rate-mbps" and use the
>> actual rate.
>>
>>> + -analogix,lane-count:
>>> + max number of lanes supported by the eDP contoller.
>>> + LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>>
>> And drop the vendor prefix here.
>>
>>> + -port@[X]: SoC specific port nodes with endpoint definitions as defined
>>> + in Documentation/devicetree/bindings/media/video-interfaces.txt,
>>> + please refer to the SoC specific binding document:
>>> + * Documentation/devicetree/bindings/video/exynos_dp.txt
>>> + * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>>> +
>>> +Optional properties for dp-controller:
>>> + -analogix,hpd-gpio:
>>> + Hotplug detect GPIO.
>>> + Indicates which GPIO should be used for hotplug
>>> + detection
>>
>> We should align with "hpd-gpios" used by HDMI connector binding. Or do
>> we need a DP connector binding that this should be defined in?
>> Probably so.
>>
>> The DRM related bindings are such a cluster f*ck with everyone picking
>> their own way to do things. Just grep hpd in bindings for starters.
>> That is just the tip.
>>
>>> + -video interfaces: Device node can contain video interface port
>>> + nodes according to [1].
>>
>> Isn't this the same as ports above? How are they optional? 0 ports
>> would be pretty useless.
>>
>>> +
>>> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>>> +-------------------------------------------------------------------------------
>>> +
>>> +Example:
>>> +
>>> + dp-controller {
>>> + compatible = "samsung,exynos5-dp";
>>> + reg = <0x145b0000 0x10000>;
>>> + interrupts = <10 3>;
>>> + interrupt-parent = <&combiner>;
>>> + clocks = <&clock 342>;
>>> + clock-names = "dp";
>>> +
>>> + phys = <&dp_phy>;
>>> + phy-names = "dp";
>>> +
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <4>;
>>> + };
>>> diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
>>> index 7a3a9cd..177506f 100644
>>> --- a/Documentation/devicetree/bindings/video/exynos_dp.txt
>>> +++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
>>> @@ -31,28 +31,10 @@ Required properties for dp-controller:
>>> from general PHY binding: the phandle for the PHY device.
>>> -phy-names:
>>> from general PHY binding: Should be "dp".
>>> - -samsung,color-space:
>>> - input video data format.
>>> - COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>>> - -samsung,dynamic-range:
>>> - dynamic range for input video data.
>>> - VESA = 0, CEA = 1
>>> - -samsung,ycbcr-coeff:
>>> - YCbCr co-efficients for input video.
>>> - COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>>> - -samsung,color-depth:
>>> - number of bits per colour component.
>>> - COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>> - -samsung,link-rate:
>>> - link rate supported by the panel.
>>> - LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
>>> - -samsung,lane-count:
>>> - number of lanes supported by the panel.
>>> - LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>>> - - display-timings: timings for the connected panel as described by
>>> - Documentation/devicetree/bindings/video/display-timing.txt
>>>
>>> Optional properties for dp-controller:
>>> + - display-timings: timings for the connected panel as described by
>>> + Documentation/devicetree/bindings/video/display-timing.txt
>>> -interlaced:
>>> interlace scan mode.
>>> Progressive if defined, Interlaced if not defined
>>> @@ -62,14 +44,18 @@ Optional properties for dp-controller:
>>> -hsync-active-high:
>>> HSYNC polarity configuration.
>>> High if defined, Low if not defined
>>> - -samsung,hpd-gpio:
>>> - Hotplug detect GPIO.
>>> - Indicates which GPIO should be used for hotplug
>>> - detection
>>> - -video interfaces: Device node can contain video interface port
>>> - nodes according to [1].
>>>
>>> -[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>>> +For the below properties, please refer to Analogix DP binding document:
>>> + * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>> + -phys (required)
>>> + -phy-names (required)
>>> + -analogix,color-space (required)
>>> + -analogix,color-depth (required)
>>> + -analogix,link-rate (required)
>>> + -analogix,lane-count (required)
>>> + -analogix,hpd-gpio (optional)
>>> + -video interfaces (optional)
>>> +-------------------------------------------------------------------------------
>>>
>>> Example:
>>>
>>> @@ -88,12 +74,10 @@ SOC specific portion:
>>>
>>> Board Specific portion:
>>> dp-controller {
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <4>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <4>;
>>>
>>> display-timings {
>>> native-mode = <&lcd_timing>;
>>> diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
>>> index 7e728a1..e48798d 100644
>>> --- a/arch/arm/boot/dts/exynos5250-arndale.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-arndale.dts
>>> @@ -119,12 +119,10 @@
>>>
>>> &dp {
>>> status = "okay";
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <4>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <4>;
>>> };
>>>
>>> &fimd {
>>> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> index 4fe186d..b8c6b8b 100644
>>> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> @@ -75,12 +75,10 @@
>>> };
>>>
>>> &dp {
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <4>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <4>;
>>>
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&dp_hpd>;
>>> diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
>>> index b7f4122..9ce2b89 100644
>>> --- a/arch/arm/boot/dts/exynos5250-snow.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-snow.dts
>>> @@ -239,13 +239,11 @@
>>> status = "okay";
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&dp_hpd>;
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <2>;
>>> - samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <2>;
>>> + analogix,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>>
>>> ports {
>>> port@0 {
>>> diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
>>> index d03f9b8..9288ae6 100644
>>> --- a/arch/arm/boot/dts/exynos5250-spring.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-spring.dts
>>> @@ -69,13 +69,11 @@
>>> status = "okay";
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&dp_hpd_gpio>;
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <1>;
>>> - samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <1>;
>>> + analogix,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>>> };
>>>
>>> &ehci {
>>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> index 8f4d76c..695a380 100644
>>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> @@ -147,13 +147,11 @@
>>> status = "okay";
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&dp_hpd_gpio>;
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x06>;
>>> - samsung,lane-count = <2>;
>>> - samsung,hpd-gpio = <&gpx2 6 0>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x06>;
>>> + analogix,lane-count = <2>;
>>> + analogix,hpd-gpio = <&gpx2 6 0>;
>>>
>>> ports {
>>> port@0 {
>>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> index 98871f9..fd46714 100644
>>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> @@ -91,12 +91,10 @@
>>> &dp {
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&dp_hpd>;
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <4>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <4>;
>>> status = "okay";
>>> };
>>>
>>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> index 7d5b386..54b4c63 100644
>>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> @@ -141,13 +141,11 @@
>>> status = "okay";
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&dp_hpd_gpio>;
>>> - samsung,color-space = <0>;
>>> - samsung,dynamic-range = <0>;
>>> - samsung,ycbcr-coeff = <0>;
>>> - samsung,color-depth = <1>;
>>> - samsung,link-rate = <0x0a>;
>>> - samsung,lane-count = <2>;
>>> - samsung,hpd-gpio = <&gpx2 6 0>;
>>> + analogix,color-space = <0>;
>>> + analogix,color-depth = <1>;
>>> + analogix,link-rate = <0x0a>;
>>> + analogix,lane-count = <2>;
>>> + analogix,hpd-gpio = <&gpx2 6 0>;
>>> panel = <&panel>;
>>> };
>>>
>>> --
>>> 1.9.1
>>>
>>>
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> [email protected]
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> [email protected]
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

2015-08-24 12:48:20

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Hi Krzysztof,

在 08/24/2015 12:20 PM, Krzysztof Kozlowski 写道:
> On 24.08.2015 11:42, Yakir Yang wrote:
>> Hi Krzysztof,
>>
>> 在 08/23/2015 07:43 PM, Krzysztof Kozlowski 写道:
>>> 2015-08-24 8:23 GMT+09:00 Rob Herring <[email protected]>:
>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>>
>>>>> Beside update some exynos dtsi file with the latest change
>>>>> according to the devicetree binding documents.
>>>> You can't just change the exynos bindings and break compatibility. Is
>>>> there some agreement with exynos folks to do this?
>>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
>> Sorry about this one, actually I have add Exynos maintainers in version
>> 1 & version 2,
>> but lose some maintainers in version 3, I would fix it in bellow versions.
>>
>>> Additionally the patchset did not look interesting to me because of
>>> misleading subject - Documentation instead of "ARM: dts:".
>>>
>>> Yakir, please:
>>> 1. Provide backward compatibility. Mark old properties as deprecated
>>> but still support them.
>> Do you mean that I should keep the old properties declare in exynos-dp.txt,
>> but just mark them as deprecated flag.
> That is one of ways how to do this. However more important is that
> driver should still support old bindings so such code:
> - if (of_property_read_u32(dp_node, "samsung,color-space",
> + if (of_property_read_u32(dp_node, "analogix,color-space",
>
> is probably wrong. Will the driver support old DTB in the same way as it
> was supporting before the change?

Okay, I got your means. So document is not the focus, the most important
is that
driver should support the old dts prop. If so the new analogix dp driver
should keep
the "samsung,color-space", rather then just mark it with [DEPRECATED] flag.

But from your follow suggest, I think you agree to update driver code,
and just mark
old prop with deprecated flag. If so I think such code would not be wrong

- if (of_property_read_u32(dp_node, "samsung,color-space",
+ if (of_property_read_u32(dp_node, "analogix,color-space",

And actually @Rob have suggest me to remove the prefix, just use
"color-space" here.

>
>> Let me show same examples, make
>> me understand your suggest rightly.
> exynos-dp already contains deprecated properties. Other ways of doing
> this would be:
> Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
> Documentation/devicetree/bindings/rtc/s3c-rtc.txt
>
> It depends up to you. The "touchscreen" looks good because it organizes
> old properties in a common section. In case of exynos-dp.txt you can add
> at beginning of file information about new bindings and mark everything
> deprecated.

Whoops, thanks for your remind, I prefer the "touchscreen" style.

>> 1. "samsung,ycbcr-coeff" is abandoned in latest analogix-dp driver,
>> absolutely
>> I should not carry this to analogix-dp.txt document. But I should
>> keep this in
>> exynos-dp.txt document, and mark them with an little "deprecated" flag.
>>
>> [Documentation/devicetree/bindings/video/exynos_dp.txt]
>> Required properties for dp-controller:
>> [...]
>> -samsung,ycbcr-coeff (DEPRECATED):
>> YCbCr co-efficients for input video.
>> COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>>
>> Is it right ?
> Yes, this is right.
>
>>> 2. Separate all DTS changes to a separate patch, unless bisectability
>>> would be hurt. Anyway you should prepare it in a such way that
>>> separation would be possible without breaking bisectability.
>> So I should separate this patch into two parts, one is name "Document:",
>> the other is "ARM: dts: ".
> Yes.
>
>> Honestly, I don't understand what the "bisectability" means in this case.
> I was referring to bisectability in general. The patchset should be
> fully bisectable which means that it does not introduce any issues
> during "git bisect". This effectively means that at each intermediate
> step (after applying each patch, one by one) every existing stuff works
> the same as previously without any regression. Including booting with
> old DTB.

Oh, thanks for your careful explain, so I guess your first comment is
talking about
the "bisectability" that if I only apply the 01 - 05 patches, kernel
could not bootup
normally, cause driver need "analogix,color-space" but DTB only have
"samsung,color-space".

>
>>> 3. Use proper subject for the patch changing DTS. This is not
>>> documentation change!
>> Hmm... when I separate this patch into two parts, I though I can keep
>> "Documentation" proper subject in this patch, and the other is the "ARM:
>> dts"
>> proper subject. Am I right ?
> Yes, you're right.
>
>>> 4. Please use script get_maintainers to obtain list of valid
>>> maintainers and CC-them with at least cover letter and patches
>>> requiring their attention.
>> Yeah, thanks.
> Sure. Now I found older versions of the patchset but previously there
> were no changes to the bindings. Again the prefix in subject is
> important to easily filter out and find necessary emails.
>
> BTW, I like the patchset because I like in general works which merge
> code and reduce duplicate stuff.

Aha, thanks :-D

Best regards,
- Yakir

> Best regards,
> Krzysztof
>
>
>
>
>

2015-08-24 12:55:28

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Hi Jingoo,

在 08/24/2015 03:40 PM, Jingoo Han 写道:
> On 2015. 8. 24., at AM 9:43, Krzysztof Kozlowski <[email protected]> wrote:
>> 2015-08-24 8:23 GMT+09:00 Rob Herring <[email protected]>:
>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>
>>>> Beside update some exynos dtsi file with the latest change
>>>> according to the devicetree binding documents.
>>> You can't just change the exynos bindings and break compatibility. Is
>>> there some agreement with exynos folks to do this?
>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
>> Additionally the patchset did not look interesting to me because of
>> misleading subject - Documentation instead of "ARM: dts:".
>>
>> Yakir, please:
>> 1. Provide backward compatibility. Mark old properties as deprecated
>> but still support them.
>> 2. Separate all DTS changes to a separate patch, unless bisectability
>> would be hurt. Anyway you should prepare it in a such way that
>> separation would be possible without breaking bisectability.
>> 3. Use proper subject for the patch changing DTS. This is not
>> documentation change!
>> 4. Please use script get_maintainers to obtain list of valid
>> maintainers and CC-them with at least cover letter and patches
>> requiring their attention.
> To Yakir Yang,
>
> Please be careful when you CC people.
>
> I don't find the reason why you CC'ed the following people. Of course, they
> look to be one of the talented developers. However, they look to be
> unrelated to your patchset.
>
> Takashi Iwai
> Vincent Palatin
> Fabio Estevam
> Philipp Zabel

Yeah, actually I just got those people from patman tools. Thanks for your
remind, I would pay more attention in next version :-)

>
> Also, please add Exynos Architecture maintainers to CC list. I don't understand
> why you removed them from CC list.
> Kukjin Kim
> Krzysztof Kozlowski
>
> Without their Ack, you will not change the codes of ARM Exynos Architecture.

Wow, thanks a lot, it's a serious mistaken ;)

Thanks,
- Yakir

> Best regards,
> Jingoo Han
>
>> Best regards,
>> Krzysztof
>>
>>
>>>
>>>> Signed-off-by: Yakir Yang <[email protected]>
>>>> ---
>>>> Changes in v3:
>>>> - Take Heiko suggest, add devicetree binding documents.
>>>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>>> from the new analogix dp driver devicetree binding.
>>>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>>>
>>>> Changes in v2: None
>>>>
>>>> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 70 ++++++++++++++++++++++
>>>> .../devicetree/bindings/video/exynos_dp.txt | 50 ++++++----------
>>>> arch/arm/boot/dts/exynos5250-arndale.dts | 10 ++--
>>>> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 ++--
>>>> arch/arm/boot/dts/exynos5250-snow.dts | 12 ++--
>>>> arch/arm/boot/dts/exynos5250-spring.dts | 12 ++--
>>>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 ++--
>>>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 ++--
>>>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 ++--
>>>> 9 files changed, 119 insertions(+), 79 deletions(-)
>>>> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>> new file mode 100644
>>>> index 0000000..6127018
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>> @@ -0,0 +1,70 @@
>>>> +Analogix Display Port bridge bindings
>>>> +
>>>> +Required properties for dp-controller:
>>>> + -compatible:
>>>> + platform specific such as:
>>>> + * "samsung,exynos5-dp"
>>>> + * "rockchip,rk3288-dp"
>>>> + -reg:
>>>> + physical base address of the controller and length
>>>> + of memory mapped region.
>>>> + -interrupts:
>>>> + interrupt combiner values.
>>>> + -clocks:
>>>> + from common clock binding: handle to dp clock.
>>>> + -clock-names:
>>>> + from common clock binding: Shall be "dp".
>>>> + -interrupt-parent:
>>>> + phandle to Interrupt combiner node.
>>>> + -phys:
>>>> + from general PHY binding: the phandle for the PHY device.
>>>> + -phy-names:
>>>> + from general PHY binding: Should be "dp".
>>>> + -analogix,color-space:
>>>> + input video data format.
>>>> + COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>>>> + -analogix,color-depth:
>>>> + number of bits per colour component.
>>>> + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
>>> drop the vendor prefix.
>>>
>>>> + -analogix,link-rate:
>>>> + max link rate supported by the eDP controller.
>>>> + LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
>>>> + LINK_RATE_5_40GBPS = 0x14
>>> Same here. I'd rather see something like "link-rate-mbps" and use the
>>> actual rate.
>>>
>>>> + -analogix,lane-count:
>>>> + max number of lanes supported by the eDP contoller.
>>>> + LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>>> And drop the vendor prefix here.
>>>
>>>> + -port@[X]: SoC specific port nodes with endpoint definitions as defined
>>>> + in Documentation/devicetree/bindings/media/video-interfaces.txt,
>>>> + please refer to the SoC specific binding document:
>>>> + * Documentation/devicetree/bindings/video/exynos_dp.txt
>>>> + * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>>>> +
>>>> +Optional properties for dp-controller:
>>>> + -analogix,hpd-gpio:
>>>> + Hotplug detect GPIO.
>>>> + Indicates which GPIO should be used for hotplug
>>>> + detection
>>> We should align with "hpd-gpios" used by HDMI connector binding. Or do
>>> we need a DP connector binding that this should be defined in?
>>> Probably so.
>>>
>>> The DRM related bindings are such a cluster f*ck with everyone picking
>>> their own way to do things. Just grep hpd in bindings for starters.
>>> That is just the tip.
>>>
>>>> + -video interfaces: Device node can contain video interface port
>>>> + nodes according to [1].
>>> Isn't this the same as ports above? How are they optional? 0 ports
>>> would be pretty useless.
>>>
>>>> +
>>>> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>>>> +-------------------------------------------------------------------------------
>>>> +
>>>> +Example:
>>>> +
>>>> + dp-controller {
>>>> + compatible = "samsung,exynos5-dp";
>>>> + reg = <0x145b0000 0x10000>;
>>>> + interrupts = <10 3>;
>>>> + interrupt-parent = <&combiner>;
>>>> + clocks = <&clock 342>;
>>>> + clock-names = "dp";
>>>> +
>>>> + phys = <&dp_phy>;
>>>> + phy-names = "dp";
>>>> +
>>>> + analogix,color-space = <0>;
>>>> + analogix,color-depth = <1>;
>>>> + analogix,link-rate = <0x0a>;
>>>> + analogix,lane-count = <4>;
>>>> + };
>>>> diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
>>>> index 7a3a9cd..177506f 100644
>>>> --- a/Documentation/devicetree/bindings/video/exynos_dp.txt
>>>> +++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
>>>> @@ -31,28 +31,10 @@ Required properties for dp-controller:
>>>> from general PHY binding: the phandle for the PHY device.
>>>> -phy-names:
>>>> from general PHY binding: Should be "dp".
>>>> - -samsung,color-space:
>>>> - input video data format.
>>>> - COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>>>> - -samsung,dynamic-range:
>>>> - dynamic range for input video data.
>>>> - VESA = 0, CEA = 1
>>>> - -samsung,ycbcr-coeff:
>>>> - YCbCr co-efficients for input video.
>>>> - COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>>>> - -samsung,color-depth:
>>>> - number of bits per colour component.
>>>> - COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>>> - -samsung,link-rate:
>>>> - link rate supported by the panel.
>>>> - LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
>>>> - -samsung,lane-count:
>>>> - number of lanes supported by the panel.
>>>> - LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>>>> - - display-timings: timings for the connected panel as described by
>>>> - Documentation/devicetree/bindings/video/display-timing.txt
>>>>
>>>> Optional properties for dp-controller:
>>>> + - display-timings: timings for the connected panel as described by
>>>> + Documentation/devicetree/bindings/video/display-timing.txt
>>>> -interlaced:
>>>> interlace scan mode.
>>>> Progressive if defined, Interlaced if not defined
>>>> @@ -62,14 +44,18 @@ Optional properties for dp-controller:
>>>> -hsync-active-high:
>>>> HSYNC polarity configuration.
>>>> High if defined, Low if not defined
>>>> - -samsung,hpd-gpio:
>>>> - Hotplug detect GPIO.
>>>> - Indicates which GPIO should be used for hotplug
>>>> - detection
>>>> - -video interfaces: Device node can contain video interface port
>>>> - nodes according to [1].
>>>>
>>>> -[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>>>> +For the below properties, please refer to Analogix DP binding document:
>>>> + * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>> + -phys (required)
>>>> + -phy-names (required)
>>>> + -analogix,color-space (required)
>>>> + -analogix,color-depth (required)
>>>> + -analogix,link-rate (required)
>>>> + -analogix,lane-count (required)
>>>> + -analogix,hpd-gpio (optional)
>>>> + -video interfaces (optional)
>>>> +-------------------------------------------------------------------------------
>>>>
>>>> Example:
>>>>
>>>> @@ -88,12 +74,10 @@ SOC specific portion:
>>>>
>>>> Board Specific portion:
>>>> dp-controller {
>>>> - samsung,color-space = <0>;
>>>> - samsung,dynamic-range = <0>;
>>>> - samsung,ycbcr-coeff = <0>;
>>>> - samsung,color-depth = <1>;
>>>> - samsung,link-rate = <0x0a>;
>>>> - samsung,lane-count = <4>;
>>>> + analogix,color-space = <0>;
>>>> + analogix,color-depth = <1>;
>>>> + analogix,link-rate = <0x0a>;
>>>> + analogix,lane-count = <4>;
>>>>
>>>> display-timings {
>>>> native-mode = <&lcd_timing>;
>>>> diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
>>>> index 7e728a1..e48798d 100644
>>>> --- a/arch/arm/boot/dts/exynos5250-arndale.dts
>>>> +++ b/arch/arm/boot/dts/exynos5250-arndale.dts
>>>> @@ -119,12 +119,10 @@
>>>>
>>>> &dp {
>>>> status = "okay";
>>>> - samsung,color-space = <0>;
>>>> - samsung,dynamic-range = <0>;
>>>> - samsung,ycbcr-coeff = <0>;
>>>> - samsung,color-depth = <1>;
>>>> - samsung,link-rate = <0x0a>;
>>>> - samsung,lane-count = <4>;
>>>> + analogix,color-space = <0>;
>>>> + analogix,color-depth = <1>;
>>>> + analogix,link-rate = <0x0a>;
>>>> + analogix,lane-count = <4>;
>>>> };
>>>>
>>>> &fimd {
>>>> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> index 4fe186d..b8c6b8b 100644
>>>> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> @@ -75,12 +75,10 @@
>>>> };
>>>>
>>>> &dp {
>>>> - samsung,color-space = <0>;
>>>> - samsung,dynamic-range = <0>;
>>>> - samsung,ycbcr-coeff = <0>;
>>>> - samsung,color-depth = <1>;
>>>> - samsung,link-rate = <0x0a>;
>>>> - samsung,lane-count = <4>;
>>>> + analogix,color-space = <0>;
>>>> + analogix,color-depth = <1>;
>>>> + analogix,link-rate = <0x0a>;
>>>> + analogix,lane-count = <4>;
>>>>
>>>> pinctrl-names = "default";
>>>> pinctrl-0 = <&dp_hpd>;
>>>> diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
>>>> index b7f4122..9ce2b89 100644
>>>> --- a/arch/arm/boot/dts/exynos5250-snow.dts
>>>> +++ b/arch/arm/boot/dts/exynos5250-snow.dts
>>>> @@ -239,13 +239,11 @@
>>>> status = "okay";
>>>> pinctrl-names = "default";
>>>> pinctrl-0 = <&dp_hpd>;
>>>> - samsung,color-space = <0>;
>>>> - samsung,dynamic-range = <0>;
>>>> - samsung,ycbcr-coeff = <0>;
>>>> - samsung,color-depth = <1>;
>>>> - samsung,link-rate = <0x0a>;
>>>> - samsung,lane-count = <2>;
>>>> - samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>>> + analogix,color-space = <0>;
>>>> + analogix,color-depth = <1>;
>>>> + analogix,link-rate = <0x0a>;
>>>> + analogix,lane-count = <2>;
>>>> + analogix,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>>>
>>>> ports {
>>>> port@0 {
>>>> diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
>>>> index d03f9b8..9288ae6 100644
>>>> --- a/arch/arm/boot/dts/exynos5250-spring.dts
>>>> +++ b/arch/arm/boot/dts/exynos5250-spring.dts
>>>> @@ -69,13 +69,11 @@
>>>> status = "okay";
>>>> pinctrl-names = "default";
>>>> pinctrl-0 = <&dp_hpd_gpio>;
>>>> - samsung,color-space = <0>;
>>>> - samsung,dynamic-range = <0>;
>>>> - samsung,ycbcr-coeff = <0>;
>>>> - samsung,color-depth = <1>;
>>>> - samsung,link-rate = <0x0a>;
>>>> - samsung,lane-count = <1>;
>>>> - samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>>>> + analogix,color-space = <0>;
>>>> + analogix,color-depth = <1>;
>>>> + analogix,link-rate = <0x0a>;
>>>> + analogix,lane-count = <1>;
>>>> + analogix,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>>>> };
>>>>
>>>> &ehci {
>>>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>>> index 8f4d76c..695a380 100644
>>>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>>> @@ -147,13 +147,11 @@
>>>> status = "okay";
>>>> pinctrl-names = "default";
>>>> pinctrl-0 = <&dp_hpd_gpio>;
>>>> - samsung,color-space = <0>;
>>>> - samsung,dynamic-range = <0>;
>>>> - samsung,ycbcr-coeff = <0>;
>>>> - samsung,color-depth = <1>;
>>>> - samsung,link-rate = <0x06>;
>>>> - samsung,lane-count = <2>;
>>>> - samsung,hpd-gpio = <&gpx2 6 0>;
>>>> + analogix,color-space = <0>;
>>>> + analogix,color-depth = <1>;
>>>> + analogix,link-rate = <0x06>;
>>>> + analogix,lane-count = <2>;
>>>> + analogix,hpd-gpio = <&gpx2 6 0>;
>>>>
>>>> ports {
>>>> port@0 {
>>>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>>> index 98871f9..fd46714 100644
>>>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>>> @@ -91,12 +91,10 @@
>>>> &dp {
>>>> pinctrl-names = "default";
>>>> pinctrl-0 = <&dp_hpd>;
>>>> - samsung,color-space = <0>;
>>>> - samsung,dynamic-range = <0>;
>>>> - samsung,ycbcr-coeff = <0>;
>>>> - samsung,color-depth = <1>;
>>>> - samsung,link-rate = <0x0a>;
>>>> - samsung,lane-count = <4>;
>>>> + analogix,color-space = <0>;
>>>> + analogix,color-depth = <1>;
>>>> + analogix,link-rate = <0x0a>;
>>>> + analogix,lane-count = <4>;
>>>> status = "okay";
>>>> };
>>>>
>>>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>>> index 7d5b386..54b4c63 100644
>>>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>>> @@ -141,13 +141,11 @@
>>>> status = "okay";
>>>> pinctrl-names = "default";
>>>> pinctrl-0 = <&dp_hpd_gpio>;
>>>> - samsung,color-space = <0>;
>>>> - samsung,dynamic-range = <0>;
>>>> - samsung,ycbcr-coeff = <0>;
>>>> - samsung,color-depth = <1>;
>>>> - samsung,link-rate = <0x0a>;
>>>> - samsung,lane-count = <2>;
>>>> - samsung,hpd-gpio = <&gpx2 6 0>;
>>>> + analogix,color-space = <0>;
>>>> + analogix,color-depth = <1>;
>>>> + analogix,link-rate = <0x0a>;
>>>> + analogix,lane-count = <2>;
>>>> + analogix,hpd-gpio = <&gpx2 6 0>;
>>>> panel = <&panel>;
>>>> };
>>>>
>>>> --
>>>> 1.9.1
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> linux-arm-kernel mailing list
>>>> [email protected]
>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> [email protected]
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
>

2015-08-24 12:58:26

by Russell King - ARM Linux

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
> > + -analogix,color-depth:
> > + number of bits per colour component.
> > + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>
> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
> drop the vendor prefix.

Please think about this some more. What does "color-depth" mean? Does it
mean the number of bits per colour _component_, or does it mean the total
number of bits to represent a particular colour. It's confusing as it
stands.

> > +Optional properties for dp-controller:
> > + -analogix,hpd-gpio:
> > + Hotplug detect GPIO.
> > + Indicates which GPIO should be used for hotplug
> > + detection
>
> We should align with "hpd-gpios" used by HDMI connector binding. Or do
> we need a DP connector binding that this should be defined in?
> Probably so.
>
> The DRM related bindings are such a cluster f*ck with everyone picking
> their own way to do things. Just grep hpd in bindings for starters.
> That is just the tip.

I'm not surprised one iota that DRM bindings are a mess. There's no one
overlooking the adoption of DRM bindings, so surprise surprise, everyone
does their own thing. This is exactly what happens every time in that
scenario. It's not a new problem.

When we adopted the graph bindings for iMX DRM, I thought exactly at that
time "it would be nice if this could become the standard for binding DRM
components together" but I don't have the authority from either the DT
perspective or the DRM perspective to mandate that. Neither does anyone
else. That's the _real_ problem here.

I've seen several DRM bindings go by which don't use the of-graph stuff,
which means that they'll never be compatible with generic components
which do use the of-graph stuff.

Like you say, it's a mess, but it's a mess of our own making, because no
one has the authority to regulate this.

--
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

2015-08-24 13:03:43

by Heiko Stuebner

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Hi Yakir,

Am Montag, 24. August 2015, 20:48:01 schrieb Yakir Yang:
> 在 08/24/2015 12:20 PM, Krzysztof Kozlowski 写道:
> > On 24.08.2015 11:42, Yakir Yang wrote:
> >> Hi Krzysztof,
> >>
> >> 在 08/23/2015 07:43 PM, Krzysztof Kozlowski 写道:
> >>> 2015-08-24 8:23 GMT+09:00 Rob Herring <[email protected]>:
> >>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
> >>>>> Analogix dp driver is split from exynos dp driver, so we just
> >>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
> >>>>>
> >>>>> Beside update some exynos dtsi file with the latest change
> >>>>> according to the devicetree binding documents.
> >>>>
> >>>> You can't just change the exynos bindings and break compatibility. Is
> >>>> there some agreement with exynos folks to do this?
> >>>
> >>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
> >>
> >> Sorry about this one, actually I have add Exynos maintainers in version
> >> 1 & version 2,
> >> but lose some maintainers in version 3, I would fix it in bellow
> >> versions.
> >>
> >>> Additionally the patchset did not look interesting to me because of
> >>> misleading subject - Documentation instead of "ARM: dts:".
> >>>
> >>> Yakir, please:
> >>> 1. Provide backward compatibility. Mark old properties as deprecated
> >>> but still support them.
> >>
> >> Do you mean that I should keep the old properties declare in
> >> exynos-dp.txt,
> >> but just mark them as deprecated flag.
> >
> > That is one of ways how to do this. However more important is that
> > driver should still support old bindings so such code:
> > - if (of_property_read_u32(dp_node, "samsung,color-space",
> > + if (of_property_read_u32(dp_node, "analogix,color-space",
> >
> > is probably wrong. Will the driver support old DTB in the same way as it
> > was supporting before the change?
>
> Okay, I got your means. So document is not the focus, the most important
> is that
> driver should support the old dts prop. If so the new analogix dp driver
> should keep
> the "samsung,color-space", rather then just mark it with [DEPRECATED] flag.
>
> But from your follow suggest, I think you agree to update driver code,
> and just mark
> old prop with deprecated flag. If so I think such code would not be wrong
>
> - if (of_property_read_u32(dp_node, "samsung,color-space",
> + if (of_property_read_u32(dp_node, "analogix,color-space",

In a generic driver, the property should have either none, or the analogix
prefix. But DT-properties need to be backwards compatible, meaning an older
Exynos devicetree should run unmodified with a newer kernel.

So the common course of action is to mark the old one as deprecated but still
test for both, so something like:

if (of_property_read_u32(dp_node, "analogix,color-space",
&dp_video_config->color_space))
if (of_property_read_u32(dp_node, "samsung,color-space",
&dp_video_config->color_space)) {

dev_err(dev, "failed to get color-space\n");
return ERR_PTR(-EINVAL);
}



2015-08-24 14:48:52

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Mon, Aug 24, 2015 at 7:57 AM, Russell King - ARM Linux
<[email protected]> wrote:
> On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>> > + -analogix,color-depth:
>> > + number of bits per colour component.
>> > + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>
>> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
>> drop the vendor prefix.
>
> Please think about this some more. What does "color-depth" mean? Does it
> mean the number of bits per colour _component_, or does it mean the total
> number of bits to represent a particular colour. It's confusing as it
> stands.

Then "component-color-bpp" perhaps?

>
>> > +Optional properties for dp-controller:
>> > + -analogix,hpd-gpio:
>> > + Hotplug detect GPIO.
>> > + Indicates which GPIO should be used for hotplug
>> > + detection
>>
>> We should align with "hpd-gpios" used by HDMI connector binding. Or do
>> we need a DP connector binding that this should be defined in?
>> Probably so.
>>
>> The DRM related bindings are such a cluster f*ck with everyone picking
>> their own way to do things. Just grep hpd in bindings for starters.
>> That is just the tip.
>
> I'm not surprised one iota that DRM bindings are a mess. There's no one
> overlooking the adoption of DRM bindings, so surprise surprise, everyone
> does their own thing. This is exactly what happens every time in that
> scenario. It's not a new problem.

True.

> When we adopted the graph bindings for iMX DRM, I thought exactly at that
> time "it would be nice if this could become the standard for binding DRM
> components together" but I don't have the authority from either the DT
> perspective or the DRM perspective to mandate that. Neither does anyone
> else. That's the _real_ problem here.
>
> I've seen several DRM bindings go by which don't use the of-graph stuff,
> which means that they'll never be compatible with generic components
> which do use the of-graph stuff.

It goes beyond bindings IMO. The use of the component framework or not
has been at the whim of driver writers as well. It is either used or
private APIs are created. I'm using components and my need for it
boils down to passing the struct drm_device pointer to the encoder.
Other components like panels and bridges have different ways to attach
to the DRM driver.

> Like you say, it's a mess, but it's a mess of our own making, because no
> one has the authority to regulate this.

Certainly, and I will take some blame here. We deferred a lot of
binding review to subsystem maintainers with the directive to ask for
help when needed. The latter has not happened. We need to improve the
situation here before we end up with a bigger mess. The momentum to
use DRM on Android is growing, so the problem is only going to get
worse if we do nothing.

Rob

2015-08-24 16:17:12

by Heiko Stuebner

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Am Montag, 24. August 2015, 09:48:27 schrieb Rob Herring:
> On Mon, Aug 24, 2015 at 7:57 AM, Russell King - ARM Linux
> > When we adopted the graph bindings for iMX DRM, I thought exactly at that
> > time "it would be nice if this could become the standard for binding DRM
> > components together" but I don't have the authority from either the DT
> > perspective or the DRM perspective to mandate that. Neither does anyone
> > else. That's the _real_ problem here.
> >
> > I've seen several DRM bindings go by which don't use the of-graph stuff,
> > which means that they'll never be compatible with generic components
> > which do use the of-graph stuff.
>
> It goes beyond bindings IMO. The use of the component framework or not
> has been at the whim of driver writers as well. It is either used or
> private APIs are created. I'm using components and my need for it
> boils down to passing the struct drm_device pointer to the encoder.
> Other components like panels and bridges have different ways to attach
> to the DRM driver.

but that is then simply implementation specific. Panels and bridges can very
well be part of and created from an of_graph description without needing to be
a (linux-)component - see patch 7.

2015-08-24 23:49:56

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On 24.08.2015 21:48, Yakir Yang wrote:
> Hi Krzysztof,
>
> 在 08/24/2015 12:20 PM, Krzysztof Kozlowski 写道:
>> On 24.08.2015 11:42, Yakir Yang wrote:
>>> Hi Krzysztof,
>>>
>>> 在 08/23/2015 07:43 PM, Krzysztof Kozlowski 写道:
>>>> 2015-08-24 8:23 GMT+09:00 Rob Herring <[email protected]>:
>>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]>
>>>>> wrote:
>>>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>>>
>>>>>> Beside update some exynos dtsi file with the latest change
>>>>>> according to the devicetree binding documents.
>>>>> You can't just change the exynos bindings and break compatibility. Is
>>>>> there some agreement with exynos folks to do this?
>>>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
>>> Sorry about this one, actually I have add Exynos maintainers in version
>>> 1 & version 2,
>>> but lose some maintainers in version 3, I would fix it in bellow
>>> versions.
>>>
>>>> Additionally the patchset did not look interesting to me because of
>>>> misleading subject - Documentation instead of "ARM: dts:".
>>>>
>>>> Yakir, please:
>>>> 1. Provide backward compatibility. Mark old properties as deprecated
>>>> but still support them.
>>> Do you mean that I should keep the old properties declare in
>>> exynos-dp.txt,
>>> but just mark them as deprecated flag.
>> That is one of ways how to do this. However more important is that
>> driver should still support old bindings so such code:
>> - if (of_property_read_u32(dp_node, "samsung,color-space",
>> + if (of_property_read_u32(dp_node, "analogix,color-space",
>>
>> is probably wrong. Will the driver support old DTB in the same way as it
>> was supporting before the change?
>
> Okay, I got your means. So document is not the focus, the most important
> is that
> driver should support the old dts prop.

Right, the focus is on the driver.

> If so the new analogix dp driver
> should keep
> the "samsung,color-space", rather then just mark it with [DEPRECATED] flag.

If you are replacing a binding/property then it should be marked
deprecated. This means that the old property is still working but new
users of it should not be added.

>
> But from your follow suggest, I think you agree to update driver code,
> and just mark
> old prop with deprecated flag. If so I think such code would not be wrong
>
> - if (of_property_read_u32(dp_node, "samsung,color-space",
> + if (of_property_read_u32(dp_node, "analogix,color-space",

It looks wrong because it breaks backward compatibility with existing
DTB. As I said before:
>>> 1. Provide backward compatibility. Mark old properties
>>> as deprecated but still support them.


> And actually @Rob have suggest me to remove the prefix, just use
> "color-space" here.

For new bindings I don't mind. But please remember about existing users,
existing DTB and bisectability.

>
>>
>>> Let me show same examples, make
>>> me understand your suggest rightly.
>> exynos-dp already contains deprecated properties. Other ways of doing
>> this would be:
>> Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
>> Documentation/devicetree/bindings/rtc/s3c-rtc.txt
>>
>> It depends up to you. The "touchscreen" looks good because it organizes
>> old properties in a common section. In case of exynos-dp.txt you can add
>> at beginning of file information about new bindings and mark everything
>> deprecated.
>
> Whoops, thanks for your remind, I prefer the "touchscreen" style.
>
>>> 1. "samsung,ycbcr-coeff" is abandoned in latest analogix-dp driver,
>>> absolutely
>>> I should not carry this to analogix-dp.txt document. But I should
>>> keep this in
>>> exynos-dp.txt document, and mark them with an little
>>> "deprecated" flag.
>>>
>>> [Documentation/devicetree/bindings/video/exynos_dp.txt]
>>> Required properties for dp-controller:
>>> [...]
>>> -samsung,ycbcr-coeff (DEPRECATED):
>>> YCbCr co-efficients for input video.
>>> COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>>>
>>> Is it right ?
>> Yes, this is right.
>>
>>>> 2. Separate all DTS changes to a separate patch, unless bisectability
>>>> would be hurt. Anyway you should prepare it in a such way that
>>>> separation would be possible without breaking bisectability.
>>> So I should separate this patch into two parts, one is name "Document:",
>>> the other is "ARM: dts: ".
>> Yes.
>>
>>> Honestly, I don't understand what the "bisectability" means in this
>>> case.
>> I was referring to bisectability in general. The patchset should be
>> fully bisectable which means that it does not introduce any issues
>> during "git bisect". This effectively means that at each intermediate
>> step (after applying each patch, one by one) every existing stuff works
>> the same as previously without any regression. Including booting with
>> old DTB.
>
> Oh, thanks for your careful explain, so I guess your first comment is
> talking about
> the "bisectability" that if I only apply the 01 - 05 patches, kernel
> could not bootup
> normally, cause driver need "analogix,color-space" but DTB only have
> "samsung,color-space".

Right. In the same time please remember that kernel may be booted with
old DTB.

Best regards,
Krzysztof

2015-08-25 01:22:13

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp



在 2015/8/24 22:48, Rob Herring 写道:
> On Mon, Aug 24, 2015 at 7:57 AM, Russell King - ARM Linux
> <[email protected]> wrote:
>> On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>>>> + -analogix,color-depth:
>>>> + number of bits per colour component.
>>>> + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
>>> drop the vendor prefix.
>> Please think about this some more. What does "color-depth" mean? Does it
>> mean the number of bits per colour _component_, or does it mean the total
>> number of bits to represent a particular colour. It's confusing as it
>> stands.
> Then "component-color-bpp" perhaps?

Actually this "color-bpp" should come from crtc driver, maybe should
come from
"struct drm_crtc {".

Like rockchip stuffs, analogix_dp-rockchip call an mode_config from
rockchip_drm_vop
driver and set output mode to RGB[10:10:10], then vop driver just store
the output mode
type to the private struct "vop->connecot_out_mode". do think that this
outmode should
store into crtc, not just come from DT prop.

- Yakir

2015-08-25 01:34:18

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Hi Krzysztof,

在 2015/8/25 7:49, Krzysztof Kozlowski 写道:
> On 24.08.2015 21:48, Yakir Yang wrote:
>> Hi Krzysztof,
>>
>> 在 08/24/2015 12:20 PM, Krzysztof Kozlowski 写道:
>>> On 24.08.2015 11:42, Yakir Yang wrote:
>>>> Hi Krzysztof,
>>>>
>>>> 在 08/23/2015 07:43 PM, Krzysztof Kozlowski 写道:
>>>>> 2015-08-24 8:23 GMT+09:00 Rob Herring <[email protected]>:
>>>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]>
>>>>>> wrote:
>>>>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>>>>
>>>>>>> Beside update some exynos dtsi file with the latest change
>>>>>>> according to the devicetree binding documents.
>>>>>> You can't just change the exynos bindings and break compatibility. Is
>>>>>> there some agreement with exynos folks to do this?
>>>>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
>>>> Sorry about this one, actually I have add Exynos maintainers in version
>>>> 1 & version 2,
>>>> but lose some maintainers in version 3, I would fix it in bellow
>>>> versions.
>>>>
>>>>> Additionally the patchset did not look interesting to me because of
>>>>> misleading subject - Documentation instead of "ARM: dts:".
>>>>>
>>>>> Yakir, please:
>>>>> 1. Provide backward compatibility. Mark old properties as deprecated
>>>>> but still support them.
>>>> Do you mean that I should keep the old properties declare in
>>>> exynos-dp.txt,
>>>> but just mark them as deprecated flag.
>>> That is one of ways how to do this. However more important is that
>>> driver should still support old bindings so such code:
>>> - if (of_property_read_u32(dp_node, "samsung,color-space",
>>> + if (of_property_read_u32(dp_node, "analogix,color-space",
>>>
>>> is probably wrong. Will the driver support old DTB in the same way as it
>>> was supporting before the change?
>> Okay, I got your means. So document is not the focus, the most important
>> is that
>> driver should support the old dts prop.
> Right, the focus is on the driver.
>
>> If so the new analogix dp driver
>> should keep
>> the "samsung,color-space", rather then just mark it with [DEPRECATED] flag.
> If you are replacing a binding/property then it should be marked
> deprecated. This means that the old property is still working but new
> users of it should not be added.

Okay, so just quote Heiko's reply, such code would be need in analogix
dp driver.

if (of_property_read_u32(dp_node, "analogix,color-space",
&dp_video_config->color_space))
if (of_property_read_u32(dp_node, "samsung,color-space",
&dp_video_config->color_space)) {

dev_err(dev, "failed to get color-space\n");
return ERR_PTR(-EINVAL);
}


>> But from your follow suggest, I think you agree to update driver code,
>> and just mark
>> old prop with deprecated flag. If so I think such code would not be wrong
>>
>> - if (of_property_read_u32(dp_node, "samsung,color-space",
>> + if (of_property_read_u32(dp_node, "analogix,color-space",
> It looks wrong because it breaks backward compatibility with existing
> DTB. As I said before:
>>>> 1. Provide backward compatibility. Mark old properties
>>>> as deprecated but still support them.
>
>> And actually @Rob have suggest me to remove the prefix, just use
>> "color-space" here.
> For new bindings I don't mind. But please remember about existing users,
> existing DTB and bisectability.
>
>>>> Let me show same examples, make
>>>> me understand your suggest rightly.
>>> exynos-dp already contains deprecated properties. Other ways of doing
>>> this would be:
>>> Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
>>> Documentation/devicetree/bindings/rtc/s3c-rtc.txt
>>>
>>> It depends up to you. The "touchscreen" looks good because it organizes
>>> old properties in a common section. In case of exynos-dp.txt you can add
>>> at beginning of file information about new bindings and mark everything
>>> deprecated.
>> Whoops, thanks for your remind, I prefer the "touchscreen" style.
>>
>>>> 1. "samsung,ycbcr-coeff" is abandoned in latest analogix-dp driver,
>>>> absolutely
>>>> I should not carry this to analogix-dp.txt document. But I should
>>>> keep this in
>>>> exynos-dp.txt document, and mark them with an little
>>>> "deprecated" flag.
>>>>
>>>> [Documentation/devicetree/bindings/video/exynos_dp.txt]
>>>> Required properties for dp-controller:
>>>> [...]
>>>> -samsung,ycbcr-coeff (DEPRECATED):
>>>> YCbCr co-efficients for input video.
>>>> COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>>>>
>>>> Is it right ?
>>> Yes, this is right.
>>>
>>>>> 2. Separate all DTS changes to a separate patch, unless bisectability
>>>>> would be hurt. Anyway you should prepare it in a such way that
>>>>> separation would be possible without breaking bisectability.
>>>> So I should separate this patch into two parts, one is name "Document:",
>>>> the other is "ARM: dts: ".
>>> Yes.
>>>
>>>> Honestly, I don't understand what the "bisectability" means in this
>>>> case.
>>> I was referring to bisectability in general. The patchset should be
>>> fully bisectable which means that it does not introduce any issues
>>> during "git bisect". This effectively means that at each intermediate
>>> step (after applying each patch, one by one) every existing stuff works
>>> the same as previously without any regression. Including booting with
>>> old DTB.
>> Oh, thanks for your careful explain, so I guess your first comment is
>> talking about
>> the "bisectability" that if I only apply the 01 - 05 patches, kernel
>> could not bootup
>> normally, cause driver need "analogix,color-space" but DTB only have
>> "samsung,color-space".
> Right. In the same time please remember that kernel may be booted with
> old DTB.

Okay, thanks a lot ;)

- Yakir

> Best regards,
> Krzysztof
>
>
>

2015-08-25 01:35:46

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On 25.08.2015 10:33, Yakir Yang wrote:
> Hi Krzysztof,
>
> 在 2015/8/25 7:49, Krzysztof Kozlowski 写道:
>> On 24.08.2015 21:48, Yakir Yang wrote:
>>> Hi Krzysztof,
>>>
>>> 在 08/24/2015 12:20 PM, Krzysztof Kozlowski 写道:
>>>> On 24.08.2015 11:42, Yakir Yang wrote:
>>>>> Hi Krzysztof,
>>>>>
>>>>> 在 08/23/2015 07:43 PM, Krzysztof Kozlowski 写道:
>>>>>> 2015-08-24 8:23 GMT+09:00 Rob Herring <[email protected]>:
>>>>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]>
>>>>>>> wrote:
>>>>>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>>>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>>>>>
>>>>>>>> Beside update some exynos dtsi file with the latest change
>>>>>>>> according to the devicetree binding documents.
>>>>>>> You can't just change the exynos bindings and break
>>>>>>> compatibility. Is
>>>>>>> there some agreement with exynos folks to do this?
>>>>>> No, there is no agreement. This wasn't even sent to Exynos
>>>>>> maintainers.
>>>>> Sorry about this one, actually I have add Exynos maintainers in
>>>>> version
>>>>> 1 & version 2,
>>>>> but lose some maintainers in version 3, I would fix it in bellow
>>>>> versions.
>>>>>
>>>>>> Additionally the patchset did not look interesting to me because of
>>>>>> misleading subject - Documentation instead of "ARM: dts:".
>>>>>>
>>>>>> Yakir, please:
>>>>>> 1. Provide backward compatibility. Mark old properties as deprecated
>>>>>> but still support them.
>>>>> Do you mean that I should keep the old properties declare in
>>>>> exynos-dp.txt,
>>>>> but just mark them as deprecated flag.
>>>> That is one of ways how to do this. However more important is that
>>>> driver should still support old bindings so such code:
>>>> - if (of_property_read_u32(dp_node, "samsung,color-space",
>>>> + if (of_property_read_u32(dp_node, "analogix,color-space",
>>>>
>>>> is probably wrong. Will the driver support old DTB in the same way
>>>> as it
>>>> was supporting before the change?
>>> Okay, I got your means. So document is not the focus, the most important
>>> is that
>>> driver should support the old dts prop.
>> Right, the focus is on the driver.
>>
>>> If so the new analogix dp driver
>>> should keep
>>> the "samsung,color-space", rather then just mark it with [DEPRECATED]
>>> flag.
>> If you are replacing a binding/property then it should be marked
>> deprecated. This means that the old property is still working but new
>> users of it should not be added.
>
> Okay, so just quote Heiko's reply, such code would be need in analogix
> dp driver.
>
> if (of_property_read_u32(dp_node, "analogix,color-space",
> &dp_video_config->color_space))
> if (of_property_read_u32(dp_node, "samsung,color-space",
> &dp_video_config->color_space)) {
>
> dev_err(dev, "failed to get color-space\n");
> return ERR_PTR(-EINVAL);
> }

Yes. It does not look pretty but something like this is needed.

Best regards,
Krzysztof

2015-08-25 01:38:01

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Hi Heiko,

在 2015/8/24 21:03, Heiko Stuebner 写道:
> Hi Yakir,
>
> Am Montag, 24. August 2015, 20:48:01 schrieb Yakir Yang:
>> 在 08/24/2015 12:20 PM, Krzysztof Kozlowski 写道:
>>> On 24.08.2015 11:42, Yakir Yang wrote:
>>>> Hi Krzysztof,
>>>>
>>>> 在 08/23/2015 07:43 PM, Krzysztof Kozlowski 写道:
>>>>> 2015-08-24 8:23 GMT+09:00 Rob Herring <[email protected]>:
>>>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>>>>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>>>>
>>>>>>> Beside update some exynos dtsi file with the latest change
>>>>>>> according to the devicetree binding documents.
>>>>>> You can't just change the exynos bindings and break compatibility. Is
>>>>>> there some agreement with exynos folks to do this?
>>>>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
>>>> Sorry about this one, actually I have add Exynos maintainers in version
>>>> 1 & version 2,
>>>> but lose some maintainers in version 3, I would fix it in bellow
>>>> versions.
>>>>
>>>>> Additionally the patchset did not look interesting to me because of
>>>>> misleading subject - Documentation instead of "ARM: dts:".
>>>>>
>>>>> Yakir, please:
>>>>> 1. Provide backward compatibility. Mark old properties as deprecated
>>>>> but still support them.
>>>> Do you mean that I should keep the old properties declare in
>>>> exynos-dp.txt,
>>>> but just mark them as deprecated flag.
>>> That is one of ways how to do this. However more important is that
>>> driver should still support old bindings so such code:
>>> - if (of_property_read_u32(dp_node, "samsung,color-space",
>>> + if (of_property_read_u32(dp_node, "analogix,color-space",
>>>
>>> is probably wrong. Will the driver support old DTB in the same way as it
>>> was supporting before the change?
>> Okay, I got your means. So document is not the focus, the most important
>> is that
>> driver should support the old dts prop. If so the new analogix dp driver
>> should keep
>> the "samsung,color-space", rather then just mark it with [DEPRECATED] flag.
>>
>> But from your follow suggest, I think you agree to update driver code,
>> and just mark
>> old prop with deprecated flag. If so I think such code would not be wrong
>>
>> - if (of_property_read_u32(dp_node, "samsung,color-space",
>> + if (of_property_read_u32(dp_node, "analogix,color-space",
> In a generic driver, the property should have either none, or the analogix
> prefix. But DT-properties need to be backwards compatible, meaning an older
> Exynos devicetree should run unmodified with a newer kernel.
>
> So the common course of action is to mark the old one as deprecated but still
> test for both, so something like:
>
> if (of_property_read_u32(dp_node, "analogix,color-space",
> &dp_video_config->color_space))
> if (of_property_read_u32(dp_node, "samsung,color-space",
> &dp_video_config->color_space)) {
>
> dev_err(dev, "failed to get color-space\n");
> return ERR_PTR(-EINVAL);
> }
>

Wow, thanks a lot for your explain and code, it do help me to understand
this suggest rightly :-)

Thanks,
- Yakir

>
>
>
>
>

2015-08-25 09:14:22

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Mon, Aug 24, 2015 at 09:48:27AM -0500, Rob Herring wrote:
> On Mon, Aug 24, 2015 at 7:57 AM, Russell King - ARM Linux
> <[email protected]> wrote:
> > On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
> >> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
> >> > + -analogix,color-depth:
> >> > + number of bits per colour component.
> >> > + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
> >>
> >> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
> >> drop the vendor prefix.
> >
> > Please think about this some more. What does "color-depth" mean? Does it
> > mean the number of bits per colour _component_, or does it mean the total
> > number of bits to represent a particular colour. It's confusing as it
> > stands.
>
> Then "component-color-bpp" perhaps?

There should be no need to have this in DT at all. The BPC is a property
of the attached panel and it should come from the panel (either the
panel driver or parsed from EDID if available).

> > When we adopted the graph bindings for iMX DRM, I thought exactly at that
> > time "it would be nice if this could become the standard for binding DRM
> > components together" but I don't have the authority from either the DT
> > perspective or the DRM perspective to mandate that. Neither does anyone
> > else. That's the _real_ problem here.
> >
> > I've seen several DRM bindings go by which don't use the of-graph stuff,
> > which means that they'll never be compatible with generic components
> > which do use the of-graph stuff.
>
> It goes beyond bindings IMO. The use of the component framework or not
> has been at the whim of driver writers as well. It is either used or
> private APIs are created. I'm using components and my need for it
> boils down to passing the struct drm_device pointer to the encoder.
> Other components like panels and bridges have different ways to attach
> to the DRM driver.

I certainly support unification, but it needs to be reasonable. There
are cases where a different structure for the binding work better than
another and I think this always needs to be evaluated on a case by case
basis.

Because of that I think it makes sense to make all these framework bits
opt-in, otherwise we could easily end up in a situation where drivers
have to be rearchitected (or even DT bindings altered!) in order to be
able to reuse code.

Thierry


Attachments:
(No filename) (2.39 kB)
signature.asc (819.00 B)
Download all attachments

2015-08-25 09:17:11

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
[...]
> > + -analogix,link-rate:
> > + max link rate supported by the eDP controller.
> > + LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
> > + LINK_RATE_5_40GBPS = 0x14
>
> Same here. I'd rather see something like "link-rate-mbps" and use the
> actual rate.

There is no need whatsoever to hard-code this in DT. (e)DP provides the
means to detect what rate the link supports and the specification
provides guidance on how to select an appropriate one.

>
> > + -analogix,lane-count:
> > + max number of lanes supported by the eDP contoller.
> > + LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>
> And drop the vendor prefix here.

Same as for the link rate.

Thierry


Attachments:
(No filename) (923.00 B)
signature.asc (819.00 B)
Download all attachments

2015-08-25 09:30:11

by Russell King - ARM Linux

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Tue, Aug 25, 2015 at 11:12:48AM +0200, Thierry Reding wrote:
> On Mon, Aug 24, 2015 at 09:48:27AM -0500, Rob Herring wrote:
> > It goes beyond bindings IMO. The use of the component framework or not
> > has been at the whim of driver writers as well. It is either used or
> > private APIs are created. I'm using components and my need for it
> > boils down to passing the struct drm_device pointer to the encoder.
> > Other components like panels and bridges have different ways to attach
> > to the DRM driver.
>
> I certainly support unification, but it needs to be reasonable. There
> are cases where a different structure for the binding work better than
> another and I think this always needs to be evaluated on a case by case
> basis.

It can't be a case-by-case basis.

The TDA998x encoder/connector is going to be component only. This is
a generic chip, which can be attached to the output of any parallel
RGB+sync+clock bus. In other words, it could appear anywhere.

Are you really saying that we need to support multiple schemes of
attaching the driver to DRM? That's totally insane IMHO.

The problem with the drm_encoder_slave stuff is that you can't sanely
attach of-nodes to the drm-created i2c device. Yes, you can parse
them from the DT file as a sub-node of the upper device, but that
then goes against the principle of the I2C bindings, which is to
list the I2C devices as a child below the I2C adapter node. If you
try and put the DT node there, then the OF code will create the I2C
device for you, and the drm_encoder_slave stuff won't have the
control it needs to communicate through the wrapped i2c_driver
stuff.

So, tda998x is going component-only, as that's the _only_ sane solution
for it.

Now, what happens when some other DRM driver wants to use the tda998x
driver, and its bindings are not compatible with the component helpers?
They're pretty much stuck up the creek without a paddle.

Case by case doesn't work unless you're talking about truely isolated
hardware where no one shares anything.

--
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

2015-08-25 09:37:24

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Hi Thierry,

在 2015/8/25 17:15, Thierry Reding 写道:
> On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
> [...]
>>> + -analogix,link-rate:
>>> + max link rate supported by the eDP controller.
>>> + LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
>>> + LINK_RATE_5_40GBPS = 0x14
>> Same here. I'd rather see something like "link-rate-mbps" and use the
>> actual rate.
> There is no need whatsoever to hard-code this in DT. (e)DP provides the
> means to detect what rate the link supports and the specification
> provides guidance on how to select an appropriate one.

Hmm... could you share more about this :-)

I only find that drm_dp_link_probe() could get the panel link-rate and
num-lanes by reading the DP_DPCD_REV messag.

I don't found there are some guidance to help select the approriate one.
Beside this DT prop just indicate the max eDP controller link-rate & lanes
support, how could eDP detect them automatically?

- Yakir

>>> + -analogix,lane-count:
>>> + max number of lanes supported by the eDP contoller.
>>> + LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>> And drop the vendor prefix here.
> Same as for the link rate.
>
> Thierry

2015-08-25 09:41:33

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Hi Thierry,

在 2015/8/25 17:12, Thierry Reding 写道:
> On Mon, Aug 24, 2015 at 09:48:27AM -0500, Rob Herring wrote:
>> On Mon, Aug 24, 2015 at 7:57 AM, Russell King - ARM Linux
>> <[email protected]> wrote:
>>> On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>>>>> + -analogix,color-depth:
>>>>> + number of bits per colour component.
>>>>> + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>>> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
>>>> drop the vendor prefix.
>>> Please think about this some more. What does "color-depth" mean? Does it
>>> mean the number of bits per colour _component_, or does it mean the total
>>> number of bits to represent a particular colour. It's confusing as it
>>> stands.
>> Then "component-color-bpp" perhaps?
> There should be no need to have this in DT at all. The BPC is a property
> of the attached panel and it should come from the panel (either the
> panel driver or parsed from EDID if available).

Actually I have send an email about this one to you in version 2, just
past from that email:

"samsung,color_space" and "samsung,color-depth"

The drm_display_info's color_formats and bpc indicate the monitor
display ability, but
the edp driver could not take it as input video format directly.

For example, with my DP TV I would found "RGB444 & YCRCB422 & & YCRCB444"
support in drm_display_info.color_formats and 16bit bpc support, but
RK3288 crtc
driver could only output RGB & ITU formats, so finally
analogix_dp-rockchip driver
config crtc to RGBaaa 10bpc mode.

In this sutiation, the analogix_dp core driver would pazzled by the
drm_display_info,
can't chose the right color_space and bpc.

And this is the place that confused me, wish you could give some ideas
about this one :-)

- Yakir
>>> When we adopted the graph bindings for iMX DRM, I thought exactly at that
>>> time "it would be nice if this could become the standard for binding DRM
>>> components together" but I don't have the authority from either the DT
>>> perspective or the DRM perspective to mandate that. Neither does anyone
>>> else. That's the _real_ problem here.
>>>
>>> I've seen several DRM bindings go by which don't use the of-graph stuff,
>>> which means that they'll never be compatible with generic components
>>> which do use the of-graph stuff.
>> It goes beyond bindings IMO. The use of the component framework or not
>> has been at the whim of driver writers as well. It is either used or
>> private APIs are created. I'm using components and my need for it
>> boils down to passing the struct drm_device pointer to the encoder.
>> Other components like panels and bridges have different ways to attach
>> to the DRM driver.
> I certainly support unification, but it needs to be reasonable. There
> are cases where a different structure for the binding work better than
> another and I think this always needs to be evaluated on a case by case
> basis.
>
> Because of that I think it makes sense to make all these framework bits
> opt-in, otherwise we could easily end up in a situation where drivers
> have to be rearchitected (or even DT bindings altered!) in order to be
> able to reuse code.
>
> Thierry

2015-08-25 09:59:48

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Wed, Aug 19, 2015 at 09:50:34AM -0500, Yakir Yang wrote:
[...]
> + -analogix,color-space:
> + input video data format.
> + COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2

I don't think DT is an appropriate place to set this. To my knowledge
this depends on the display and/or mode, so I don't think hard-coding
it here is the right thing to do.

Thierry


Attachments:
(No filename) (367.00 B)
signature.asc (819.00 B)
Download all attachments

2015-08-25 10:07:59

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Tue, Aug 25, 2015 at 05:41:19PM +0800, Yakir Yang wrote:
> Hi Thierry,
>
> 在 2015/8/25 17:12, Thierry Reding 写道:
> >On Mon, Aug 24, 2015 at 09:48:27AM -0500, Rob Herring wrote:
> >>On Mon, Aug 24, 2015 at 7:57 AM, Russell King - ARM Linux
> >><[email protected]> wrote:
> >>>On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
> >>>>On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
> >>>>>+ -analogix,color-depth:
> >>>>>+ number of bits per colour component.
> >>>>>+ COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
> >>>>This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
> >>>>drop the vendor prefix.
> >>>Please think about this some more. What does "color-depth" mean? Does it
> >>>mean the number of bits per colour _component_, or does it mean the total
> >>>number of bits to represent a particular colour. It's confusing as it
> >>>stands.
> >>Then "component-color-bpp" perhaps?
> >There should be no need to have this in DT at all. The BPC is a property
> >of the attached panel and it should come from the panel (either the
> >panel driver or parsed from EDID if available).
>
> Actually I have send an email about this one to you in version 2, just past
> from that email:
>
> "samsung,color_space" and "samsung,color-depth"
>
> The drm_display_info's color_formats and bpc indicate the monitor display
> ability, but
> the edp driver could not take it as input video format directly.
>
> For example, with my DP TV I would found "RGB444 & YCRCB422 & & YCRCB444"
> support in drm_display_info.color_formats and 16bit bpc support, but RK3288
> crtc
> driver could only output RGB & ITU formats, so finally analogix_dp-rockchip
> driver
> config crtc to RGBaaa 10bpc mode.
>
> In this sutiation, the analogix_dp core driver would pazzled by the
> drm_display_info,
> can't chose the right color_space and bpc.
>
> And this is the place that confused me, wish you could give some ideas about
> this one :-)

Your display driver should choose whatever it is capable of outputting.
If the display reports that it can do 16 bits-per-color, but your
display driver can't do it, then it should choose a configuration that
it supports. Similarily for the color encodings. If you can't generate
YCrCb444 with your hardware, then it's the driver's job to know about
that and select the next appropriate configuration.

But hard-coding this is not the right solution because the value in DT
may end up conflicting with what the display reports.

Thierry


Attachments:
(No filename) (2.51 kB)
signature.asc (819.00 B)
Download all attachments

2015-08-25 10:41:27

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Tue, Aug 25, 2015 at 10:29:39AM +0100, Russell King - ARM Linux wrote:
> On Tue, Aug 25, 2015 at 11:12:48AM +0200, Thierry Reding wrote:
> > On Mon, Aug 24, 2015 at 09:48:27AM -0500, Rob Herring wrote:
> > > It goes beyond bindings IMO. The use of the component framework or not
> > > has been at the whim of driver writers as well. It is either used or
> > > private APIs are created. I'm using components and my need for it
> > > boils down to passing the struct drm_device pointer to the encoder.
> > > Other components like panels and bridges have different ways to attach
> > > to the DRM driver.
> >
> > I certainly support unification, but it needs to be reasonable. There
> > are cases where a different structure for the binding work better than
> > another and I think this always needs to be evaluated on a case by case
> > basis.
>
> It can't be a case-by-case basis.
>
> The TDA998x encoder/connector is going to be component only. This is
> a generic chip, which can be attached to the output of any parallel
> RGB+sync+clock bus. In other words, it could appear anywhere.
>
> Are you really saying that we need to support multiple schemes of
> attaching the driver to DRM? That's totally insane IMHO.

No, what I'm saying is that we should have a single scheme, but one
that doesn't put any restrictions on what kind of DT binding you use or
how your driver is architected.

> The problem with the drm_encoder_slave stuff is that you can't sanely
> attach of-nodes to the drm-created i2c device. Yes, you can parse
> them from the DT file as a sub-node of the upper device, but that
> then goes against the principle of the I2C bindings, which is to
> list the I2C devices as a child below the I2C adapter node. If you
> try and put the DT node there, then the OF code will create the I2C
> device for you, and the drm_encoder_slave stuff won't have the
> control it needs to communicate through the wrapped i2c_driver
> stuff.
>
> So, tda998x is going component-only, as that's the _only_ sane solution
> for it.

Has anyone ever considered turning it into a DRM bridge driver? I had
always envisioned component/master to be primarily useful to glue
together various SoC components to form one componentized device. Now
if tda998x is an I2C slave it is external to the SoC (auxiliary), so
in my opinion much better off as a bridge driver.

Bridge drivers don't come with any of the disadvantages that the
drm_encoder_slave stuff has. They are regular drivers that are probed
via their parent busses (I2C, platform, SPI, ...) and hook into DRM via
an abstract interface. The DT aspect is taken care of automatically
because they get instantiated by their parent bus like any other device.

> Now, what happens when some other DRM driver wants to use the tda998x
> driver, and its bindings are not compatible with the component helpers?
> They're pretty much stuck up the creek without a paddle.

I'm sure that will be very helpful response for whoever's going to end
up having to deal with that situation.

> Case by case doesn't work unless you're talking about truely isolated
> hardware where no one shares anything.

There are two different things here. The inter-driver interface, which,
in my opinion, it makes a lot of sense to standardize. Like I mentioned
above I think it unwise to make this interface depend upon a framework
or the firmware description such as DT in order to avoid unnecessary
restrictions. The second, orthogonal, issue, is the DT bindings. Those
I think should absolutely be designed case by case and select whatever
most accurately describes the hardware.

Thierry


Attachments:
(No filename) (3.54 kB)
signature.asc (819.00 B)
Download all attachments

2015-08-25 10:53:15

by Russell King - ARM Linux

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Tue, Aug 25, 2015 at 12:40:01PM +0200, Thierry Reding wrote:
> On Tue, Aug 25, 2015 at 10:29:39AM +0100, Russell King - ARM Linux wrote:
> > Now, what happens when some other DRM driver wants to use the tda998x
> > driver, and its bindings are not compatible with the component helpers?
> > They're pretty much stuck up the creek without a paddle.
>
> I'm sure that will be very helpful response for whoever's going to end
> up having to deal with that situation.

Thank you for that comment, it's very constructive and much appreciated.
I can see it's well worth me continuing to spend time on this thread.

--
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

2015-08-25 13:27:33

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Tue, Aug 25, 2015 at 4:15 AM, Thierry Reding <[email protected]> wrote:
> On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
> [...]
>> > + -analogix,link-rate:
>> > + max link rate supported by the eDP controller.
>> > + LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
>> > + LINK_RATE_5_40GBPS = 0x14
>>
>> Same here. I'd rather see something like "link-rate-mbps" and use the
>> actual rate.
>
> There is no need whatsoever to hard-code this in DT. (e)DP provides the
> means to detect what rate the link supports and the specification
> provides guidance on how to select an appropriate one.

Good, even better.

Rob

2015-08-25 14:02:42

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Hi Thierry,

在 2015/8/25 18:06, Thierry Reding 写道:
> On Tue, Aug 25, 2015 at 05:41:19PM +0800, Yakir Yang wrote:
>> Hi Thierry,
>>
>> 在 2015/8/25 17:12, Thierry Reding 写道:
>>> On Mon, Aug 24, 2015 at 09:48:27AM -0500, Rob Herring wrote:
>>>> On Mon, Aug 24, 2015 at 7:57 AM, Russell King - ARM Linux
>>>> <[email protected]> wrote:
>>>>> On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
>>>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>>>>>>> + -analogix,color-depth:
>>>>>>> + number of bits per colour component.
>>>>>>> + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>>>>> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
>>>>>> drop the vendor prefix.
>>>>> Please think about this some more. What does "color-depth" mean? Does it
>>>>> mean the number of bits per colour _component_, or does it mean the total
>>>>> number of bits to represent a particular colour. It's confusing as it
>>>>> stands.
>>>> Then "component-color-bpp" perhaps?
>>> There should be no need to have this in DT at all. The BPC is a property
>>> of the attached panel and it should come from the panel (either the
>>> panel driver or parsed from EDID if available).
>> Actually I have send an email about this one to you in version 2, just past
>> from that email:
>>
>> "samsung,color_space" and "samsung,color-depth"
>>
>> The drm_display_info's color_formats and bpc indicate the monitor display
>> ability, but
>> the edp driver could not take it as input video format directly.
>>
>> For example, with my DP TV I would found "RGB444 & YCRCB422 & & YCRCB444"
>> support in drm_display_info.color_formats and 16bit bpc support, but RK3288
>> crtc
>> driver could only output RGB & ITU formats, so finally analogix_dp-rockchip
>> driver
>> config crtc to RGBaaa 10bpc mode.
>>
>> In this sutiation, the analogix_dp core driver would pazzled by the
>> drm_display_info,
>> can't chose the right color_space and bpc.
>>
>> And this is the place that confused me, wish you could give some ideas about
>> this one :-)
> Your display driver should choose whatever it is capable of outputting.
> If the display reports that it can do 16 bits-per-color, but your
> display driver can't do it, then it should choose a configuration that
> it supports. Similarily for the color encodings. If you can't generate
> YCrCb444 with your hardware, then it's the driver's job to know about
> that and select the next appropriate configuration.
>
> But hard-coding this is not the right solution because the value in DT
> may end up conflicting with what the display reports.

Yeah, thanks for your explain, you are right. It's the best way to get
"color-depth"
and "color-space" from display driver, not to hard-code in DT prop.

But if the common analogix-dp driver want to get those values, then
those values
should come from the common drm struct data. Personally I think "struct
drm_crtc"
is the best place that should indicate the output ability of SoC vop/lcdc.

But I haven't find out there are some place to store those message for
now (I don't
think it's good to modify the original color-space and color-bpc which
parsed from
monitor edid).

So could you share sme ideas about this, and I would rather to talk with
Mark (Author
of rockchip drm driver) to find out the better way to fix this one.

Besides, I would appreciate very much if you can share some ideas about
how Exynos
handler with this problem ;)

Thanks,
- Yakir
> Thierry

2015-08-25 14:04:07

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Hi Thierry,

在 2015/8/25 17:58, Thierry Reding 写道:
> On Wed, Aug 19, 2015 at 09:50:34AM -0500, Yakir Yang wrote:
> [...]
>> + -analogix,color-space:
>> + input video data format.
>> + COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
> I don't think DT is an appropriate place to set this. To my knowledge
> this depends on the display and/or mode, so I don't think hard-coding
> it here is the right thing to do.

Yeah, same question with my previous reply ;)

Thanks,
- Yakir
>
> Thierry

2015-08-25 14:18:15

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Tue, Aug 25, 2015 at 09:48:01PM +0800, Yakir Yang wrote:
> Hi Thierry & Rob,
>
> 在 2015/8/25 21:27, Rob Herring 写道:
> >On Tue, Aug 25, 2015 at 4:15 AM, Thierry Reding <[email protected]> wrote:
> >>On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
> >>>On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
> >>[...]
> >>>>+ -analogix,link-rate:
> >>>>+ max link rate supported by the eDP controller.
> >>>>+ LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
> >>>>+ LINK_RATE_5_40GBPS = 0x14
> >>>Same here. I'd rather see something like "link-rate-mbps" and use the
> >>>actual rate.
> >>There is no need whatsoever to hard-code this in DT. (e)DP provides the
> >>means to detect what rate the link supports and the specification
> >>provides guidance on how to select an appropriate one.
> >Good, even better.
>
> I do think we still need keep this DT prop yet.
>
> I think drm_dp_help.c could get the "panel" max link-rate and lane-count,
> but it's not enough, we still need knew the "eDP controller" max link-rate
> and lane-count.
>
> Let me show the exact example that happened in my side. When I connect
> my board to my 2K DP-1.2 TV. Analogix dp driver would get the max link-rate
> from dpcd, and the max link-rate is 5.4Gbps. So if I just set eDP controller
> link-rate
> to 5.4Gbps, the DP TV just broken, do not light up normally.
>
> This reason why TV broken is the max link-rate which support by RK3288 eDP
> controller is 2.7Gbps. Here are the exact words that RK3288 eDP TRM said:
>
> *Compliant with DisplayPortTM Specification, Version 1.2.
> Compliant with eDPTM Specification, Version 1.3.
> HDCP v1.3 amendment for DisplayPortTM Revision 1.0.
> Main link containing 4 physical lanes of 2.7/1.62 Gbps/lane
> *
> **
>
>
> Beside I haven't found there are some registers would indicate the eDP
> controller
> max link-rate and lane-count, so this is why I still instance that we need
> this DT
> prop to indicata "Max rate controller support".
>
> So, I wish you could agree with me on this point.

Your driver should know what link rates it supports and restrict itself
to use those. This is implied by the compatible string and doesn't need
to be duplicated into device tree.

Thierry


Attachments:
(No filename) (2.29 kB)
signature.asc (819.00 B)
Download all attachments

2015-08-25 14:23:23

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Tue, Aug 25, 2015 at 10:03:52PM +0800, Yakir Yang wrote:
> Hi Thierry,
>
> 在 2015/8/25 17:58, Thierry Reding 写道:
> >On Wed, Aug 19, 2015 at 09:50:34AM -0500, Yakir Yang wrote:
> >[...]
> >>+ -analogix,color-space:
> >>+ input video data format.
> >>+ COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
> >I don't think DT is an appropriate place to set this. To my knowledge
> >this depends on the display and/or mode, so I don't think hard-coding
> >it here is the right thing to do.
>
> Yeah, same question with my previous reply ;)

I don't have an answer for you, unfortunately. But like I said,
hard-coding isn't going to work. What if, for example, you set this to a
fixed value and then you connect a monitor that doesn't support the
specific one you set?

You cited code from dw_hdmi.c earlier, it looks like it might be correct
even though it doesn't cite a reference for why this was done. Perhaps
someone on this thread, or someone involved with dw_hdmi can answer
where that code came from.

Thierry


Attachments:
(No filename) (1.00 kB)
signature.asc (819.00 B)
Download all attachments

2015-08-25 14:23:54

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

Hi Thierry,

在 2015/8/25 22:16, Thierry Reding 写道:
> On Tue, Aug 25, 2015 at 09:48:01PM +0800, Yakir Yang wrote:
>> Hi Thierry & Rob,
>>
>> 在 2015/8/25 21:27, Rob Herring 写道:
>>> On Tue, Aug 25, 2015 at 4:15 AM, Thierry Reding <[email protected]> wrote:
>>>> On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
>>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <[email protected]> wrote:
>>>> [...]
>>>>>> + -analogix,link-rate:
>>>>>> + max link rate supported by the eDP controller.
>>>>>> + LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
>>>>>> + LINK_RATE_5_40GBPS = 0x14
>>>>> Same here. I'd rather see something like "link-rate-mbps" and use the
>>>>> actual rate.
>>>> There is no need whatsoever to hard-code this in DT. (e)DP provides the
>>>> means to detect what rate the link supports and the specification
>>>> provides guidance on how to select an appropriate one.
>>> Good, even better.
>> I do think we still need keep this DT prop yet.
>>
>> I think drm_dp_help.c could get the "panel" max link-rate and lane-count,
>> but it's not enough, we still need knew the "eDP controller" max link-rate
>> and lane-count.
>>
>> Let me show the exact example that happened in my side. When I connect
>> my board to my 2K DP-1.2 TV. Analogix dp driver would get the max link-rate
>> from dpcd, and the max link-rate is 5.4Gbps. So if I just set eDP controller
>> link-rate
>> to 5.4Gbps, the DP TV just broken, do not light up normally.
>>
>> This reason why TV broken is the max link-rate which support by RK3288 eDP
>> controller is 2.7Gbps. Here are the exact words that RK3288 eDP TRM said:
>>
>> *Compliant with DisplayPortTM Specification, Version 1.2.
>> Compliant with eDPTM Specification, Version 1.3.
>> HDCP v1.3 amendment for DisplayPortTM Revision 1.0.
>> Main link containing 4 physical lanes of 2.7/1.62 Gbps/lane
>> *
>> **
>>
>>
>> Beside I haven't found there are some registers would indicate the eDP
>> controller
>> max link-rate and lane-count, so this is why I still instance that we need
>> this DT
>> prop to indicata "Max rate controller support".
>>
>> So, I wish you could agree with me on this point.
> Your driver should know what link rates it supports and restrict itself
> to use those. This is implied by the compatible string and doesn't need
> to be duplicated into device tree.

Oh, yeah, good idea :-D
Thanks for your point out.

- Yakir

> Thierry

2015-08-25 15:58:29

by Russell King - ARM Linux

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] Documentation: drm/bridge: add document for analogix_dp

On Tue, Aug 25, 2015 at 04:21:51PM +0200, Thierry Reding wrote:
> You cited code from dw_hdmi.c earlier, it looks like it might be correct
> even though it doesn't cite a reference for why this was done. Perhaps
> someone on this thread, or someone involved with dw_hdmi can answer
> where that code came from.

dw_hdmi doesn't do any format conversion - it's hard coded to RGB, 8
bits per colour component. That's a requirement for all HDMI sinks.

The reason it's hard-coded in dw_hdmi is that (a) no one has yet decided
its worth the effort to get the dw_hdmi hardware to do the colourspace
conversion to the YUV spaces and verify that it works, and (b) I really
don't see the point when we're talking about computer like devices which
work primerily with RGB and RGB is always supported by the sink.

As far as greater colour depths go, the driver came from the Freescale
iMX6 code base, and the hardware which feeds dw_hdmi can't do more than
8 bits per component - so going to 10, 12 or 16 bits per component is
beyond what iMX6 can cope with. Hence, no one on the iMX6 side has a
need for the deep colour stuff.

In any case, I view this as a very low priority issue - it would be nice
to have audio support on HDMI for iMX6 at some point in the next 20 years,
preferably before the hardware becomes obsolete. I've been maintaining
patches for this for 1.5 years now... how much longer is it going to take?
My pull request to David from 15th July was ignored. My re-send of that
after he returned was ignored. My reminder of it has been ignored. What's
going on in DRM land? It would be nice to get _some_ kind of feedback so
I know why they're not being taken, so I can fix whatever the issue is.

--
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

2015-08-30 12:16:21

by Romain Perier

[permalink] [raw]
Subject: Re: [PATCH v3 0/14] Add Analogix Core Display Port Driver

Hi,

Could you rebase your serie onto linux-next or 4.2-rc8 ? it does not
apply here...

Regards,
Romain

2015-08-21 15:16 GMT+02:00 Thierry Reding <[email protected]>:
> On Fri, Aug 21, 2015 at 08:24:16PM +0900, Jingoo Han wrote:
>> On 2015. 8. 21., at PM 7:01, Yakir Yang <[email protected]> wrote:
>> >
>> > Hi Jingoo,
>> >
>> >> 在 2015/8/21 16:20, Jingoo Han 写道:
>> >>> On 2015. 8. 19., at PM 11:48, Yakir Yang <[email protected]> wrote:
>> >>
>> >> .....
>> >>
>> >>> .../bindings/video/analogix_dp-rockchip.txt | 83 ++
>> >>> .../devicetree/bindings/video/exynos_dp.txt | 51 +-
>> >>> arch/arm/boot/dts/exynos5250-arndale.dts | 10 +-
>> >>> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 +-
>> >>> arch/arm/boot/dts/exynos5250-snow.dts | 12 +-
>> >>> arch/arm/boot/dts/exynos5250-spring.dts | 12 +-
>> >>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 +-
>> >>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 +-
>> >>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 +-
>> >>> drivers/gpu/drm/bridge/Kconfig | 5 +
>> >>> drivers/gpu/drm/bridge/Makefile | 1 +
>> >>> drivers/gpu/drm/bridge/analogix_dp_core.c | 1382 +++++++++++++++++++
>> >>> drivers/gpu/drm/bridge/analogix_dp_core.h | 286 ++++
>> >>> drivers/gpu/drm/bridge/analogix_dp_reg.c | 1294 ++++++++++++++++++
>> >>> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h} | 270 ++--
>> >>> drivers/gpu/drm/exynos/Kconfig | 5 +-
>> >>> drivers/gpu/drm/exynos/Makefile | 2 +-
>> >>> drivers/gpu/drm/exynos/analogix_dp-exynos.c | 347 +++++
>> >> Would you change this file name to "exynos_dp.c"?
>> >
>> > Sorry, I don't think so ;(
>> >
>> > I think IP_name+Soc_name would be better in this re-use case.
>>
>> So? Is there the naming rule such as "IP_name+SoC_name"?
>>
>> > Beside I see
>> > there are lots of driver named with this format in kernel, such as dw_hdmi & dw_mmc
>>
>> Please look at other dw cases.
>> For example, look at dw_pcie.
>>
>> drivers/pci/host/
>> pcie-designware.c
>> pci-spear13xx.c
>> pci-exynos.c
>>
>> In this case, pci-spear13xx.c and pci-exynos.c do not use "IP_name+SoC_name", even though these are dw IPs.
>>
>> Also, naming consistency is more important.
>> Now, Exynos DRM files are using "exynos_drm_" prefix.
>>
>> drivers/gpu/drm/exynos/
>> exynos_drm_buf.c
>> exynos_drm_core.c
>> ....
>>
>> However, "analogix_dp-exynos.c" looks very inconsistent.
>>
>> If there is no strict naming rule, please use "exynos_dp.c"
>> or "exynos_drm_dp.c".
>
> Exynos DRM maintainers get to pick their filenames, so Yakir, please
> rename as Jingoo suggested.
>
> Even if you didn't the first thing that would go into the Exynos DRM
> driver tree after this is merged is a rename patch anyway.
>
> Thierry

2015-08-31 02:40:56

by Yakir Yang

[permalink] [raw]
Subject: Re: [PATCH v3 0/14] Add Analogix Core Display Port Driver

Hi Romain,

在 08/30/2015 08:16 PM, Romain Perier 写道:
> Hi,
>
> Could you rebase your serie onto linux-next or 4.2-rc8 ? it does not
> apply here...

Thanks for try to applied, and feel sorry for that failed.

This v3 series was rebased on github.com/torvalds/linux.git, so I should
rebase on kernel/next/linux-next.git when I'm preparing v4 series.

Thanks,
- Yakir

> Regards,
> Romain
>
> 2015-08-21 15:16 GMT+02:00 Thierry Reding <[email protected]>:
>> On Fri, Aug 21, 2015 at 08:24:16PM +0900, Jingoo Han wrote:
>>> On 2015. 8. 21., at PM 7:01, Yakir Yang <[email protected]> wrote:
>>>> Hi Jingoo,
>>>>
>>>>> 在 2015/8/21 16:20, Jingoo Han 写道:
>>>>>> On 2015. 8. 19., at PM 11:48, Yakir Yang <[email protected]> wrote:
>>>>> .....
>>>>>
>>>>>> .../bindings/video/analogix_dp-rockchip.txt | 83 ++
>>>>>> .../devicetree/bindings/video/exynos_dp.txt | 51 +-
>>>>>> arch/arm/boot/dts/exynos5250-arndale.dts | 10 +-
>>>>>> arch/arm/boot/dts/exynos5250-smdk5250.dts | 10 +-
>>>>>> arch/arm/boot/dts/exynos5250-snow.dts | 12 +-
>>>>>> arch/arm/boot/dts/exynos5250-spring.dts | 12 +-
>>>>>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 +-
>>>>>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 +-
>>>>>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 +-
>>>>>> drivers/gpu/drm/bridge/Kconfig | 5 +
>>>>>> drivers/gpu/drm/bridge/Makefile | 1 +
>>>>>> drivers/gpu/drm/bridge/analogix_dp_core.c | 1382 +++++++++++++++++++
>>>>>> drivers/gpu/drm/bridge/analogix_dp_core.h | 286 ++++
>>>>>> drivers/gpu/drm/bridge/analogix_dp_reg.c | 1294 ++++++++++++++++++
>>>>>> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h} | 270 ++--
>>>>>> drivers/gpu/drm/exynos/Kconfig | 5 +-
>>>>>> drivers/gpu/drm/exynos/Makefile | 2 +-
>>>>>> drivers/gpu/drm/exynos/analogix_dp-exynos.c | 347 +++++
>>>>> Would you change this file name to "exynos_dp.c"?
>>>> Sorry, I don't think so ;(
>>>>
>>>> I think IP_name+Soc_name would be better in this re-use case.
>>> So? Is there the naming rule such as "IP_name+SoC_name"?
>>>
>>>> Beside I see
>>>> there are lots of driver named with this format in kernel, such as dw_hdmi & dw_mmc
>>> Please look at other dw cases.
>>> For example, look at dw_pcie.
>>>
>>> drivers/pci/host/
>>> pcie-designware.c
>>> pci-spear13xx.c
>>> pci-exynos.c
>>>
>>> In this case, pci-spear13xx.c and pci-exynos.c do not use "IP_name+SoC_name", even though these are dw IPs.
>>>
>>> Also, naming consistency is more important.
>>> Now, Exynos DRM files are using "exynos_drm_" prefix.
>>>
>>> drivers/gpu/drm/exynos/
>>> exynos_drm_buf.c
>>> exynos_drm_core.c
>>> ....
>>>
>>> However, "analogix_dp-exynos.c" looks very inconsistent.
>>>
>>> If there is no strict naming rule, please use "exynos_dp.c"
>>> or "exynos_drm_dp.c".
>> Exynos DRM maintainers get to pick their filenames, so Yakir, please
>> rename as Jingoo suggested.
>>
>> Even if you didn't the first thing that would go into the Exynos DRM
>> driver tree after this is merged is a rename patch anyway.
>>
>> Thierry
>
>