diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-12 10:21:02 +0900 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-12 10:21:02 +0900 |
commit | 5f76945a9c978b8b8bf8eb7fe3b17b9981240a97 (patch) | |
tree | df61aca168df657bc71ce8b578bcb0c81b0622ee /drivers/video/exynos | |
parent | 940e3a8dd6683a3787faf769b3df7a06f1c2fa31 (diff) | |
parent | cd9d6f10d07f26dd8a70e519c22b6b4f8a9e3e7a (diff) | |
download | blackbird-op-linux-5f76945a9c978b8b8bf8eb7fe3b17b9981240a97.tar.gz blackbird-op-linux-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.c | 322 | ||||
-rw-r--r-- | drivers/video/exynos/exynos_dp_core.h | 6 | ||||
-rw-r--r-- | drivers/video/exynos/exynos_dp_reg.c | 58 | ||||
-rw-r--r-- | drivers/video/exynos/exynos_dp_reg.h | 3 | ||||
-rw-r--r-- | drivers/video/exynos/exynos_mipi_dsi.c | 9 | ||||
-rw-r--r-- | drivers/video/exynos/exynos_mipi_dsi_common.c | 8 |
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, |