aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/exynos
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-12 10:21:02 +0900
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-12 10:21:02 +0900
commit5f76945a9c978b8b8bf8eb7fe3b17b9981240a97 (patch)
treedf61aca168df657bc71ce8b578bcb0c81b0622ee /drivers/video/exynos
parentMerge tag 'for-linus-merge-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs (diff)
parentgbefb: fix compile error (diff)
downloadlinux-dev-5f76945a9c978b8b8bf8eb7fe3b17b9981240a97.tar.xz
linux-dev-5f76945a9c978b8b8bf8eb7fe3b17b9981240a97.zip
Merge tag 'fbdev-updates-for-3.7' of git://github.com/schandinat/linux-2.6
Pull fbdev updates from Florian Tobias Schandinat: "This includes: - large updates for OMAP - basic OMAP5 DSS support for DPI and DSI outputs - large cleanups and restructuring - some update to Exynos and da8xx-fb - removal of the pnx4008 driver (arch removed) - various other small patches" Fix up some trivial conflicts (mostly just include line changes, but also some due to the renaming of the deferred work functions by Tejun). * tag 'fbdev-updates-for-3.7' of git://github.com/schandinat/linux-2.6: (193 commits) gbefb: fix compile error video: mark nuc900fb_map_video_memory as __devinit video/mx3fb: set .owner to prevent module unloading while being used video: exynos_dp: use clk_prepare_enable and clk_disable_unprepare drivers/video/exynos/exynos_mipi_dsi.c: fix error return code drivers/video/savage/savagefb_driver.c: fix error return code video: s3c-fb: use clk_prepare_enable and clk_disable_unprepare da8xx-fb: save and restore LCDC context across suspend/resume cycle da8xx-fb: add pm_runtime support video/udlfb: fix line counting in fb_write OMAPDSS: add missing include for string.h OMAPDSS: DISPC: Configure color conversion coefficients for writeback OMAPDSS: DISPC: Add manager like functions for writeback OMAPDSS: DISPC: Configure writeback FIFOs OMAPDSS: DISPC: Configure writeback specific parameters in dispc_wb_setup() OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup OMAPDSS: DISPC: Add function to set channel in for writeback OMAPDSS: DISPC: Don't set chroma resampling bit for writeback OMAPDSS: DISPC: Downscale chroma if plane is writeback OMAPDSS: DISPC: Configure input and output sizes for writeback ...
Diffstat (limited to 'drivers/video/exynos')
-rw-r--r--drivers/video/exynos/exynos_dp_core.c322
-rw-r--r--drivers/video/exynos/exynos_dp_core.h6
-rw-r--r--drivers/video/exynos/exynos_dp_reg.c58
-rw-r--r--drivers/video/exynos/exynos_dp_reg.h3
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi.c9
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi_common.c8
6 files changed, 208 insertions, 198 deletions
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index c6c016a506ce..d55470e75412 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -29,6 +29,9 @@ static int exynos_dp_init_dp(struct exynos_dp_device *dp)
exynos_dp_swreset(dp);
+ exynos_dp_init_analog_param(dp);
+ exynos_dp_init_interrupt(dp);
+
/* SW defined function Normal operation */
exynos_dp_enable_sw_function(dp);
@@ -260,7 +263,7 @@ static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
static void exynos_dp_link_start(struct exynos_dp_device *dp)
{
- u8 buf[5];
+ u8 buf[4];
int lane;
int lane_count;
@@ -295,10 +298,10 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
/* Set RX training pattern */
- buf[0] = DPCD_SCRAMBLING_DISABLED |
- DPCD_TRAINING_PATTERN_1;
exynos_dp_write_byte_to_dpcd(dp,
- DPCD_ADDR_TRAINING_PATTERN_SET, buf[0]);
+ DPCD_ADDR_TRAINING_PATTERN_SET,
+ DPCD_SCRAMBLING_DISABLED |
+ DPCD_TRAINING_PATTERN_1);
for (lane = 0; lane < lane_count; lane++)
buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
@@ -308,7 +311,7 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
lane_count, buf);
}
-static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane)
+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];
@@ -316,7 +319,7 @@ static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane)
return (link_value >> shift) & 0xf;
}
-static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count)
+static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
{
int lane;
u8 lane_status;
@@ -329,22 +332,23 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count)
return 0;
}
-static int exynos_dp_channel_eq_ok(u8 link_status[6], int lane_count)
+static int exynos_dp_channel_eq_ok(u8 link_align[3], int lane_count)
{
int lane;
u8 lane_align;
u8 lane_status;
- lane_align = link_status[2];
+ lane_align = link_align[2];
if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
return -EINVAL;
for (lane = 0; lane < lane_count; lane++) {
- lane_status = exynos_dp_get_lane_status(link_status, lane);
+ lane_status = exynos_dp_get_lane_status(link_align, lane);
lane_status &= DPCD_CHANNEL_EQ_BITS;
if (lane_status != DPCD_CHANNEL_EQ_BITS)
return -EINVAL;
}
+
return 0;
}
@@ -417,69 +421,17 @@ static unsigned int exynos_dp_get_lane_link_training(
static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
{
- if (dp->link_train.link_rate == LINK_RATE_2_70GBPS) {
- /* set to reduced bit rate */
- dp->link_train.link_rate = LINK_RATE_1_62GBPS;
- dev_err(dp->dev, "set to bandwidth %.2x\n",
- dp->link_train.link_rate);
- dp->link_train.lt_state = START;
- } else {
- exynos_dp_training_pattern_dis(dp);
- /* set enhanced mode if available */
- exynos_dp_set_enhanced_mode(dp);
- dp->link_train.lt_state = FAILED;
- }
-}
+ exynos_dp_training_pattern_dis(dp);
+ exynos_dp_set_enhanced_mode(dp);
-static void exynos_dp_get_adjust_train(struct exynos_dp_device *dp,
- u8 adjust_request[2])
-{
- int lane;
- int lane_count;
- u8 voltage_swing;
- u8 pre_emphasis;
- u8 training_lane;
-
- lane_count = dp->link_train.lane_count;
- for (lane = 0; lane < lane_count; lane++) {
- voltage_swing = exynos_dp_get_adjust_request_voltage(
- adjust_request, lane);
- pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
- adjust_request, lane);
- training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
- DPCD_PRE_EMPHASIS_SET(pre_emphasis);
-
- if (voltage_swing == VOLTAGE_LEVEL_3 ||
- pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
- training_lane |= DPCD_MAX_SWING_REACHED;
- training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
- }
- dp->link_train.training_lane[lane] = training_lane;
- }
-}
-
-static int exynos_dp_check_max_cr_loop(struct exynos_dp_device *dp,
- u8 voltage_swing)
-{
- int lane;
- int lane_count;
-
- lane_count = dp->link_train.lane_count;
- for (lane = 0; lane < lane_count; lane++) {
- if (voltage_swing == VOLTAGE_LEVEL_3 ||
- dp->link_train.cr_loop[lane] == MAX_CR_LOOP)
- return -EINVAL;
- }
- return 0;
+ dp->link_train.lt_state = FAILED;
}
static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
{
- u8 data;
- u8 link_status[6];
+ u8 link_status[2];
int lane;
int lane_count;
- u8 buf[5];
u8 adjust_request[2];
u8 voltage_swing;
@@ -488,100 +440,154 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
usleep_range(100, 101);
- exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
- 6, link_status);
lane_count = dp->link_train.lane_count;
+ exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+ 2, link_status);
+
if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
/* set training pattern 2 for EQ */
exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
- adjust_request[0] = link_status[4];
- adjust_request[1] = link_status[5];
+ for (lane = 0; lane < lane_count; lane++) {
+ exynos_dp_read_bytes_from_dpcd(dp,
+ DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+ 2, adjust_request);
+ voltage_swing = exynos_dp_get_adjust_request_voltage(
+ adjust_request, lane);
+ pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+ adjust_request, lane);
+ training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+ DPCD_PRE_EMPHASIS_SET(pre_emphasis);
- exynos_dp_get_adjust_train(dp, adjust_request);
+ if (voltage_swing == VOLTAGE_LEVEL_3)
+ training_lane |= DPCD_MAX_SWING_REACHED;
+ if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
+ training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
- buf[0] = DPCD_SCRAMBLING_DISABLED |
- DPCD_TRAINING_PATTERN_2;
- exynos_dp_write_byte_to_dpcd(dp,
- DPCD_ADDR_TRAINING_PATTERN_SET,
- buf[0]);
+ dp->link_train.training_lane[lane] = training_lane;
- for (lane = 0; lane < lane_count; lane++) {
exynos_dp_set_lane_link_training(dp,
dp->link_train.training_lane[lane],
lane);
- buf[lane] = dp->link_train.training_lane[lane];
- exynos_dp_write_byte_to_dpcd(dp,
- DPCD_ADDR_TRAINING_LANE0_SET + lane,
- buf[lane]);
}
- dp->link_train.lt_state = EQUALIZER_TRAINING;
- } else {
- exynos_dp_read_byte_from_dpcd(dp,
- DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
- &data);
- adjust_request[0] = data;
- exynos_dp_read_byte_from_dpcd(dp,
- DPCD_ADDR_ADJUST_REQUEST_LANE2_3,
- &data);
- adjust_request[1] = data;
+ exynos_dp_write_byte_to_dpcd(dp,
+ DPCD_ADDR_TRAINING_PATTERN_SET,
+ DPCD_SCRAMBLING_DISABLED |
+ DPCD_TRAINING_PATTERN_2);
+
+ exynos_dp_write_bytes_to_dpcd(dp,
+ DPCD_ADDR_TRAINING_LANE0_SET,
+ lane_count,
+ dp->link_train.training_lane);
+ dev_info(dp->dev, "Link Training Clock Recovery success\n");
+ dp->link_train.lt_state = EQUALIZER_TRAINING;
+ } else {
for (lane = 0; lane < lane_count; lane++) {
training_lane = exynos_dp_get_lane_link_training(
dp, lane);
+ exynos_dp_read_bytes_from_dpcd(dp,
+ DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+ 2, adjust_request);
voltage_swing = exynos_dp_get_adjust_request_voltage(
adjust_request, lane);
pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
adjust_request, lane);
- if ((DPCD_VOLTAGE_SWING_GET(training_lane) == voltage_swing) &&
- (DPCD_PRE_EMPHASIS_GET(training_lane) == pre_emphasis))
- dp->link_train.cr_loop[lane]++;
- dp->link_train.training_lane[lane] = training_lane;
- }
- if (exynos_dp_check_max_cr_loop(dp, voltage_swing) != 0) {
- exynos_dp_reduce_link_rate(dp);
- } else {
- exynos_dp_get_adjust_train(dp, adjust_request);
+ if (voltage_swing == VOLTAGE_LEVEL_3 ||
+ pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
+ dev_err(dp->dev, "voltage or pre emphasis reached max level\n");
+ goto reduce_link_rate;
+ }
- for (lane = 0; lane < lane_count; lane++) {
- exynos_dp_set_lane_link_training(dp,
- dp->link_train.training_lane[lane],
- lane);
- buf[lane] = dp->link_train.training_lane[lane];
- exynos_dp_write_byte_to_dpcd(dp,
- DPCD_ADDR_TRAINING_LANE0_SET + lane,
- buf[lane]);
+ if ((DPCD_VOLTAGE_SWING_GET(training_lane) ==
+ voltage_swing) &&
+ (DPCD_PRE_EMPHASIS_GET(training_lane) ==
+ pre_emphasis)) {
+ dp->link_train.cr_loop[lane]++;
+ if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP) {
+ dev_err(dp->dev, "CR Max loop\n");
+ goto reduce_link_rate;
+ }
}
+
+ training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+ DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+
+ if (voltage_swing == VOLTAGE_LEVEL_3)
+ training_lane |= DPCD_MAX_SWING_REACHED;
+ if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
+ training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+
+ dp->link_train.training_lane[lane] = training_lane;
+
+ exynos_dp_set_lane_link_training(dp,
+ dp->link_train.training_lane[lane], lane);
}
+
+ exynos_dp_write_bytes_to_dpcd(dp,
+ DPCD_ADDR_TRAINING_LANE0_SET,
+ lane_count,
+ dp->link_train.training_lane);
}
return 0;
+
+reduce_link_rate:
+ exynos_dp_reduce_link_rate(dp);
+ return -EIO;
}
static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
{
- u8 link_status[6];
+ u8 link_status[2];
+ u8 link_align[3];
int lane;
int lane_count;
- u8 buf[5];
u32 reg;
u8 adjust_request[2];
+ u8 voltage_swing;
+ u8 pre_emphasis;
+ u8 training_lane;
usleep_range(400, 401);
- exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
- 6, link_status);
lane_count = dp->link_train.lane_count;
+ exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+ 2, link_status);
+
if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
- adjust_request[0] = link_status[4];
- adjust_request[1] = link_status[5];
+ link_align[0] = link_status[0];
+ link_align[1] = link_status[1];
- if (exynos_dp_channel_eq_ok(link_status, lane_count) == 0) {
+ exynos_dp_read_byte_from_dpcd(dp,
+ DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED,
+ &link_align[2]);
+
+ for (lane = 0; lane < lane_count; lane++) {
+ exynos_dp_read_bytes_from_dpcd(dp,
+ DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+ 2, adjust_request);
+ voltage_swing = exynos_dp_get_adjust_request_voltage(
+ adjust_request, lane);
+ pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+ adjust_request, lane);
+ training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+ DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+
+ if (voltage_swing == VOLTAGE_LEVEL_3)
+ training_lane |= DPCD_MAX_SWING_REACHED;
+ if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
+ training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+
+ dp->link_train.training_lane[lane] = training_lane;
+ }
+
+ if (exynos_dp_channel_eq_ok(link_align, lane_count) == 0) {
/* traing pattern Set to Normal */
exynos_dp_training_pattern_dis(dp);
@@ -596,39 +602,42 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
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);
-
dp->link_train.lt_state = FINISHED;
} else {
/* not all locked */
dp->link_train.eq_loop++;
if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
- exynos_dp_reduce_link_rate(dp);
- } else {
- exynos_dp_get_adjust_train(dp, adjust_request);
-
- for (lane = 0; lane < lane_count; lane++) {
- exynos_dp_set_lane_link_training(dp,
- dp->link_train.training_lane[lane],
- lane);
- buf[lane] = dp->link_train.training_lane[lane];
- exynos_dp_write_byte_to_dpcd(dp,
- DPCD_ADDR_TRAINING_LANE0_SET + lane,
- buf[lane]);
- }
+ dev_err(dp->dev, "EQ Max loop\n");
+ goto reduce_link_rate;
}
+
+ for (lane = 0; lane < lane_count; lane++)
+ exynos_dp_set_lane_link_training(dp,
+ dp->link_train.training_lane[lane],
+ lane);
+
+ exynos_dp_write_bytes_to_dpcd(dp,
+ DPCD_ADDR_TRAINING_LANE0_SET,
+ lane_count,
+ dp->link_train.training_lane);
}
} else {
- exynos_dp_reduce_link_rate(dp);
+ goto reduce_link_rate;
}
return 0;
+
+reduce_link_rate:
+ exynos_dp_reduce_link_rate(dp);
+ return -EIO;
}
static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
- u8 *bandwidth)
+ u8 *bandwidth)
{
u8 data;
@@ -641,7 +650,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;
@@ -693,13 +702,7 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
{
int retval = 0;
- int training_finished;
-
- /* Turn off unnecessary lane */
- if (dp->link_train.lane_count == 1)
- exynos_dp_set_analog_power_down(dp, CH1_BLOCK, 1);
-
- training_finished = 0;
+ int training_finished = 0;
dp->link_train.lt_state = START;
@@ -710,10 +713,14 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
exynos_dp_link_start(dp);
break;
case CLOCK_RECOVERY:
- exynos_dp_process_clock_recovery(dp);
+ retval = exynos_dp_process_clock_recovery(dp);
+ if (retval)
+ dev_err(dp->dev, "LT CR failed!\n");
break;
case EQUALIZER_TRAINING:
- exynos_dp_process_equalizer_training(dp);
+ retval = exynos_dp_process_equalizer_training(dp);
+ if (retval)
+ dev_err(dp->dev, "LT EQ failed!\n");
break;
case FINISHED:
training_finished = 1;
@@ -872,40 +879,33 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
dp->dev = &pdev->dev;
- dp->clock = clk_get(&pdev->dev, "dp");
+ dp->clock = devm_clk_get(&pdev->dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(&pdev->dev, "failed to get clock\n");
return PTR_ERR(dp->clock);
}
- clk_enable(dp->clock);
+ clk_prepare_enable(dp->clock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "failed to get registers\n");
- ret = -EINVAL;
- goto err_clock;
- }
dp->reg_base = devm_request_and_ioremap(&pdev->dev, res);
if (!dp->reg_base) {
dev_err(&pdev->dev, "failed to ioremap\n");
- ret = -ENOMEM;
- goto err_clock;
+ return -ENOMEM;
}
dp->irq = platform_get_irq(pdev, 0);
if (!dp->irq) {
dev_err(&pdev->dev, "failed to get irq\n");
- ret = -ENODEV;
- goto err_clock;
+ return -ENODEV;
}
ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
"exynos-dp", dp);
if (ret) {
dev_err(&pdev->dev, "failed to request irq\n");
- goto err_clock;
+ return ret;
}
dp->video_info = pdata->video_info;
@@ -917,7 +917,7 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
ret = exynos_dp_detect_hpd(dp);
if (ret) {
dev_err(&pdev->dev, "unable to detect hpd\n");
- goto err_clock;
+ return ret;
}
exynos_dp_handle_edid(dp);
@@ -926,7 +926,7 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
dp->video_info->link_rate);
if (ret) {
dev_err(&pdev->dev, "unable to do link train\n");
- goto err_clock;
+ return ret;
}
exynos_dp_enable_scramble(dp, 1);
@@ -940,17 +940,12 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
ret = exynos_dp_config_video(dp, dp->video_info);
if (ret) {
dev_err(&pdev->dev, "unable to config video\n");
- goto err_clock;
+ return ret;
}
platform_set_drvdata(pdev, dp);
return 0;
-
-err_clock:
- clk_put(dp->clock);
-
- return ret;
}
static int __devexit exynos_dp_remove(struct platform_device *pdev)
@@ -961,8 +956,7 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
if (pdata && pdata->phy_exit)
pdata->phy_exit();
- clk_disable(dp->clock);
- clk_put(dp->clock);
+ clk_disable_unprepare(dp->clock);
return 0;
}
@@ -977,7 +971,7 @@ static int exynos_dp_suspend(struct device *dev)
if (pdata && pdata->phy_exit)
pdata->phy_exit();
- clk_disable(dp->clock);
+ clk_disable_unprepare(dp->clock);
return 0;
}
@@ -991,7 +985,7 @@ static int exynos_dp_resume(struct device *dev)
if (pdata && pdata->phy_init)
pdata->phy_init();
- clk_enable(dp->clock);
+ clk_prepare_enable(dp->clock);
exynos_dp_init_dp(dp);
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 8526e548c385..57b8a6531c0e 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -43,7 +43,7 @@ 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);
-u32 exynos_dp_get_pll_lock_status(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,
@@ -105,7 +105,7 @@ 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);
-int exynos_dp_init_video(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,
u32 color_depth,
@@ -144,7 +144,7 @@ void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
#define DPCD_ADDR_TRAINING_PATTERN_SET 0x0102
#define DPCD_ADDR_TRAINING_LANE0_SET 0x0103
#define DPCD_ADDR_LANE0_1_STATUS 0x0202
-#define DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED 0x0204
+#define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED 0x0204
#define DPCD_ADDR_ADJUST_REQUEST_LANE0_1 0x0206
#define DPCD_ADDR_ADJUST_REQUEST_LANE2_3 0x0207
#define DPCD_ADDR_TEST_REQUEST 0x0218
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 2db5b9aa250a..3f5ca8a0d5ea 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -77,7 +77,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3);
reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
- TX_CUR1_2X | TX_CUR_8_MA;
+ 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 |
@@ -148,9 +148,6 @@ void exynos_dp_reset(struct exynos_dp_device *dp)
writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH);
writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
-
- exynos_dp_init_analog_param(dp);
- exynos_dp_init_interrupt(dp);
}
void exynos_dp_swreset(struct exynos_dp_device *dp)
@@ -179,7 +176,7 @@ void exynos_dp_config_interrupt(struct exynos_dp_device *dp)
writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
}
-u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
+enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
{
u32 reg;
@@ -401,6 +398,7 @@ 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);
@@ -409,8 +407,15 @@ int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
/* Is AUX CH command reply received? */
reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
- while (!(reg & RPLY_RECEIV))
+ 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);
@@ -471,7 +476,8 @@ int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
if (retval == 0)
break;
else
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}
return retval;
@@ -511,7 +517,8 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
if (retval == 0)
break;
else
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}
/* Read data buffer */
@@ -575,7 +582,8 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
if (retval == 0)
break;
else
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}
start_offset += cur_data_count;
@@ -632,7 +640,8 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
if (retval == 0)
break;
else
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}
for (cur_data_idx = 0; cur_data_idx < cur_data_count;
@@ -677,7 +686,7 @@ int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
/* Start AUX transaction */
retval = exynos_dp_start_aux_transaction(dp);
if (retval != 0)
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
return retval;
}
@@ -717,7 +726,8 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
if (retval == 0)
break;
else
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}
/* Read data */
@@ -777,7 +787,9 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
if (retval == 0)
break;
else
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ 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);
@@ -883,7 +895,9 @@ void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level)
{
u32 reg;
- reg = level << PRE_EMPHASIS_SET_SHIFT;
+ 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);
}
@@ -891,7 +905,9 @@ void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level)
{
u32 reg;
- reg = level << PRE_EMPHASIS_SET_SHIFT;
+ 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);
}
@@ -899,7 +915,9 @@ void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level)
{
u32 reg;
- reg = level << PRE_EMPHASIS_SET_SHIFT;
+ 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);
}
@@ -907,7 +925,9 @@ void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
{
u32 reg;
- reg = level << PRE_EMPHASIS_SET_SHIFT;
+ 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);
}
@@ -994,7 +1014,7 @@ void exynos_dp_reset_macro(struct exynos_dp_device *dp)
writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
}
-int exynos_dp_init_video(struct exynos_dp_device *dp)
+void exynos_dp_init_video(struct exynos_dp_device *dp)
{
u32 reg;
@@ -1012,8 +1032,6 @@ int exynos_dp_init_video(struct exynos_dp_device *dp)
reg = VID_HRES_TH(2) | VID_VRES_TH(0);
writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
-
- return 0;
}
void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
index 125b27cd57ae..1f2f014cfe88 100644
--- a/drivers/video/exynos/exynos_dp_reg.h
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -187,7 +187,7 @@
#define PD_RING_OSC (0x1 << 6)
#define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4)
#define TX_CUR1_2X (0x1 << 2)
-#define TX_CUR_8_MA (0x2 << 0)
+#define TX_CUR_16_MA (0x3 << 0)
/* EXYNOS_DP_TX_AMP_TUNING_CTL */
#define CH3_AMP_400_MV (0x0 << 24)
@@ -285,6 +285,7 @@
#define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0)
/* EXYNOS_DP_LN0_LINK_TRAINING_CTL */
+#define PRE_EMPHASIS_SET_MASK (0x3 << 3)
#define PRE_EMPHASIS_SET_SHIFT (3)
/* EXYNOS_DP_DEBUG_CTL */
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
index 663c308d0e73..07d70a3a628b 100644
--- a/drivers/video/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -205,7 +205,8 @@ int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev)
return 0;
}
-struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv)
+static struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(
+ struct mipi_dsim_lcd_driver *lcd_drv)
{
struct mipi_dsim_ddi *dsim_ddi, *next;
struct mipi_dsim_lcd_device *lcd_dev;
@@ -265,7 +266,8 @@ int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
}
-struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim,
+static struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(
+ struct mipi_dsim_device *dsim,
const char *name)
{
struct mipi_dsim_ddi *dsim_ddi, *next;
@@ -373,6 +375,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
dsim->clock = clk_get(&pdev->dev, "dsim0");
if (IS_ERR(dsim->clock)) {
dev_err(&pdev->dev, "failed to get dsim clock source\n");
+ ret = -ENODEV;
goto err_clock_get;
}
@@ -381,6 +384,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "failed to get io memory region\n");
+ ret = -ENODEV;
goto err_platform_get;
}
@@ -405,6 +409,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name);
if (!dsim_ddi) {
dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n");
+ ret = -EINVAL;
goto err_bind;
}
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c
index 47b533a183be..3cd29a4fc10a 100644
--- a/drivers/video/exynos/exynos_mipi_dsi_common.c
+++ b/drivers/video/exynos/exynos_mipi_dsi_common.c
@@ -79,11 +79,6 @@ irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id)
struct mipi_dsim_device *dsim = dev_id;
unsigned int intsrc, intmsk;
- if (dsim == NULL) {
- dev_err(dsim->dev, "%s: wrong parameter\n", __func__);
- return IRQ_NONE;
- }
-
intsrc = exynos_mipi_dsi_read_interrupt(dsim);
intmsk = exynos_mipi_dsi_read_interrupt_mask(dsim);
intmsk = ~intmsk & intsrc;
@@ -288,9 +283,6 @@ int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
mutex_unlock(&dsim->lock);
return -EINVAL;
}
-
- mutex_unlock(&dsim->lock);
- return 0;
}
static unsigned int exynos_mipi_dsi_long_data_rd(struct mipi_dsim_device *dsim,