diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-15 13:03:48 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-15 13:03:48 -0800 |
commit | 2b8318881ddbcb67c5e8d2178b42284749442222 (patch) | |
tree | b43ded0118bb7a6d9f89f6875c18d7ef447ba3be /drivers/video | |
parent | e81d372ff9f694e13fa46e8b5aaed505c7fd2a1f (diff) | |
parent | e7f5c9a16ea2648a3e85af8e34191026bf3dcb62 (diff) |
Merge tag 'fbdev-for-3.8' of git://gitorious.org/linux-omap-dss2/linux
Pull fbdev changes from Tomi Valkeinen:
"OMAPDSS changes, including:
- use dynanic debug prints
- OMAP platform dependency removals
- Creation of compat-layer, helping us to improve omapdrm
- Misc cleanups, aiming to make omadss more in line with the upcoming
common display framework
Exynos DP changes for the 3.8 merge window:
- Device Tree support for Samsung Exynos DP
- SW Link training is cleaned up.
- HPD interrupt is supported.
Samsung Framebuffer changes for the 3.8 merge window:
- The bit definitions of header file are updated.
- Some minor typos are fixed.
- Some minor bugs of s3c_fb_check_var() are fixed.
FB related changes for SH Mobile, Freescale DIU
Add support for the Solomon SSD1307 OLED Controller"
* tag 'fbdev-for-3.8' of git://gitorious.org/linux-omap-dss2/linux: (191 commits)
OMAPDSS: fix TV-out issue with DSI PLL
Revert "OMAPFB: simplify locking"
OMAPFB: remove silly loop in fb2display()
OMAPFB: fix error handling in omapfb_find_best_mode()
OMAPFB: use devm_kzalloc to allocate omapfb2_device
OMAPDSS: DISPC: remove dispc fck uses
OMAPDSS: DISPC: get dss clock rate from dss driver
drivers/video/console/softcursor.c: remove redundant NULL check before kfree()
drivers/video: add support for the Solomon SSD1307 OLED Controller
OMAPDSS: use omapdss_compat_init() in other drivers
OMAPDSS: export dispc functions
OMAPDSS: export dss_feat functions
OMAPDSS: export dss_mgr_ops functions
OMAPDSS: separate compat files in the Makefile
OMAPDSS: move display sysfs init to compat layer
OMAPDSS: DPI: use dispc's check_timings
OMAPDSS: DISPC: add dispc_ovl_check()
OMAPDSS: move irq handling to dispc-compat
OMAPDSS: move omap_dispc_wait_for_irq_interruptible_timeout to dispc-compat.c
OMAPDSS: move blocking mgr enable/disable to compat layer
...
Conflicts:
arch/arm/mach-davinci/devices-da8xx.c
arch/arm/plat-omap/common.c
drivers/media/platform/omap/omap_vout.c
Diffstat (limited to 'drivers/video')
58 files changed, 3561 insertions, 3376 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index d08d7998a4a..9c31277b3a8 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2045,7 +2045,7 @@ config FB_S3C_DEBUG_REGWRITE bool "Debug register writes" depends on FB_S3C ---help--- - Show all register writes via printk(KERN_DEBUG) + Show all register writes via pr_debug() config FB_S3C2410 tristate "S3C2410 LCD framebuffer support" @@ -2442,4 +2442,19 @@ config FB_SH_MOBILE_MERAM Up to 4 memory channels can be configured, allowing 4 RGB or 2 YCbCr framebuffers to be configured. +config FB_SSD1307 + tristate "Solomon SSD1307 framebuffer support" + depends on FB && I2C + depends on OF + depends on GENERIC_GPIO + select FB_SYS_FOPS + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_DEFERRED_IO + select PWM + help + This driver implements support for the Solomon SSD1307 + OLED controller over I2C. + endmenu diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 23e948ebfab..768a137a1ba 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -161,6 +161,7 @@ obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o obj-$(CONFIG_FB_MX3) += mx3fb.o obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o obj-$(CONFIG_FB_MXS) += mxsfb.o +obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o # the test framebuffer is last obj-$(CONFIG_FB_VIRTUAL) += vfb.o diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c index 25f835bf3d7..46dd8f5d2e9 100644 --- a/drivers/video/console/softcursor.c +++ b/drivers/video/console/softcursor.c @@ -35,8 +35,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) dsize = s_pitch * cursor->image.height; if (dsize + sizeof(struct fb_image) != ops->cursor_size) { - if (ops->cursor_src != NULL) - kfree(ops->cursor_src); + kfree(ops->cursor_src); ops->cursor_size = dsize + sizeof(struct fb_image); ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC); diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 80665f66ac1..46534e00fe0 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -213,62 +213,51 @@ static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = { .accel = FB_ACCEL_NONE }; -struct da8xx_panel { - const char name[25]; /* Full name <vendor>_<model> */ - unsigned short width; - unsigned short height; - int hfp; /* Horizontal front porch */ - int hbp; /* Horizontal back porch */ - int hsw; /* Horizontal Sync Pulse Width */ - int vfp; /* Vertical front porch */ - int vbp; /* Vertical back porch */ - int vsw; /* Vertical Sync Pulse Width */ - unsigned int pxl_clk; /* Pixel clock */ - unsigned char invert_pxl_clk; /* Invert Pixel clock */ -}; - -static struct da8xx_panel known_lcd_panels[] = { +static struct fb_videomode known_lcd_panels[] = { /* Sharp LCD035Q3DG01 */ [0] = { - .name = "Sharp_LCD035Q3DG01", - .width = 320, - .height = 240, - .hfp = 8, - .hbp = 6, - .hsw = 0, - .vfp = 2, - .vbp = 2, - .vsw = 0, - .pxl_clk = 4608000, - .invert_pxl_clk = 1, + .name = "Sharp_LCD035Q3DG01", + .xres = 320, + .yres = 240, + .pixclock = 4608000, + .left_margin = 6, + .right_margin = 8, + .upper_margin = 2, + .lower_margin = 2, + .hsync_len = 0, + .vsync_len = 0, + .sync = FB_SYNC_CLK_INVERT | + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, }, /* Sharp LK043T1DG01 */ [1] = { - .name = "Sharp_LK043T1DG01", - .width = 480, - .height = 272, - .hfp = 2, - .hbp = 2, - .hsw = 41, - .vfp = 2, - .vbp = 2, - .vsw = 10, - .pxl_clk = 7833600, - .invert_pxl_clk = 0, + .name = "Sharp_LK043T1DG01", + .xres = 480, + .yres = 272, + .pixclock = 7833600, + .left_margin = 2, + .right_margin = 2, + .upper_margin = 2, + .lower_margin = 2, + .hsync_len = 41, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .flag = 0, }, [2] = { /* Hitachi SP10Q010 */ - .name = "SP10Q010", - .width = 320, - .height = 240, - .hfp = 10, - .hbp = 10, - .hsw = 10, - .vfp = 10, - .vbp = 10, - .vsw = 10, - .pxl_clk = 7833600, - .invert_pxl_clk = 0, + .name = "SP10Q010", + .xres = 320, + .yres = 240, + .pixclock = 7833600, + .left_margin = 10, + .right_margin = 10, + .upper_margin = 10, + .lower_margin = 10, + .hsync_len = 10, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .flag = 0, }, }; @@ -399,10 +388,9 @@ static int lcd_cfg_dma(int burst_size, int fifo_th) reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8); break; case 16: + default: reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16); break; - default: - return -EINVAL; } reg |= (fifo_th << 8); @@ -447,7 +435,8 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width, lcdc_write(reg, LCD_RASTER_TIMING_1_REG); } -static int lcd_cfg_display(const struct lcd_ctrl_config *cfg) +static int lcd_cfg_display(const struct lcd_ctrl_config *cfg, + struct fb_videomode *panel) { u32 reg; u32 reg_int; @@ -456,7 +445,7 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg) LCD_MONO_8BIT_MODE | LCD_MONOCHROME_MODE); - switch (cfg->p_disp_panel->panel_shade) { + switch (cfg->panel_shade) { case MONOCHROME: reg |= LCD_MONOCHROME_MODE; if (cfg->mono_8bit_mode) @@ -469,7 +458,9 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg) break; case COLOR_PASSIVE: - if (cfg->stn_565_mode) + /* AC bias applicable only for Pasive panels */ + lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt); + if (cfg->bpp == 12 && cfg->stn_565_mode) reg |= LCD_STN_565_ENABLE; break; @@ -490,22 +481,19 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg) reg = lcdc_read(LCD_RASTER_TIMING_2_REG); - if (cfg->sync_ctrl) - reg |= LCD_SYNC_CTRL; - else - reg &= ~LCD_SYNC_CTRL; + reg |= LCD_SYNC_CTRL; if (cfg->sync_edge) reg |= LCD_SYNC_EDGE; else reg &= ~LCD_SYNC_EDGE; - if (cfg->invert_line_clock) + if (panel->sync & FB_SYNC_HOR_HIGH_ACT) reg |= LCD_INVERT_LINE_CLOCK; else reg &= ~LCD_INVERT_LINE_CLOCK; - if (cfg->invert_frm_clock) + if (panel->sync & FB_SYNC_VERT_HIGH_ACT) reg |= LCD_INVERT_FRAME_CLOCK; else reg &= ~LCD_INVERT_FRAME_CLOCK; @@ -728,7 +716,7 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par) } static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, - struct da8xx_panel *panel) + struct fb_videomode *panel) { u32 bpp; int ret = 0; @@ -738,7 +726,7 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, /* Calculate the divider */ lcd_calc_clk_divider(par); - if (panel->invert_pxl_clk) + if (panel->sync & FB_SYNC_CLK_INVERT) lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) | LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG); else @@ -750,30 +738,23 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, if (ret < 0) return ret; - /* Configure the AC bias properties. */ - lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt); - /* Configure the vertical and horizontal sync properties. */ - lcd_cfg_vertical_sync(panel->vbp, panel->vsw, panel->vfp); - lcd_cfg_horizontal_sync(panel->hbp, panel->hsw, panel->hfp); + lcd_cfg_vertical_sync(panel->lower_margin, panel->vsync_len, + panel->upper_margin); + lcd_cfg_horizontal_sync(panel->right_margin, panel->hsync_len, + panel->left_margin); /* Configure for disply */ - ret = lcd_cfg_display(cfg); + ret = lcd_cfg_display(cfg, panel); if (ret < 0) return ret; - if (QVGA != cfg->p_disp_panel->panel_type) - return -EINVAL; + bpp = cfg->bpp; - if (cfg->bpp <= cfg->p_disp_panel->max_bpp && - cfg->bpp >= cfg->p_disp_panel->min_bpp) - bpp = cfg->bpp; - else - bpp = cfg->p_disp_panel->max_bpp; if (bpp == 12) bpp = 16; - ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->width, - (unsigned int)panel->height, bpp, + ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->xres, + (unsigned int)panel->yres, bpp, cfg->raster_order); if (ret < 0) return ret; @@ -1235,7 +1216,7 @@ static int __devinit fb_probe(struct platform_device *device) struct da8xx_lcdc_platform_data *fb_pdata = device->dev.platform_data; struct lcd_ctrl_config *lcd_cfg; - struct da8xx_panel *lcdc_info; + struct fb_videomode *lcdc_info; struct fb_info *da8xx_fb_info; struct clk *fb_clk = NULL; struct da8xx_fb_par *par; @@ -1267,7 +1248,7 @@ static int __devinit fb_probe(struct platform_device *device) goto err_request_mem; } - fb_clk = clk_get(&device->dev, NULL); + fb_clk = clk_get(&device->dev, "fck"); if (IS_ERR(fb_clk)) { dev_err(&device->dev, "Can not get device clock\n"); ret = -ENODEV; @@ -1283,6 +1264,7 @@ static int __devinit fb_probe(struct platform_device *device) lcd_revision = LCD_VERSION_1; break; case 0x4F200800: + case 0x4F201000: lcd_revision = LCD_VERSION_2; break; default: @@ -1323,7 +1305,7 @@ static int __devinit fb_probe(struct platform_device *device) #ifdef CONFIG_CPU_FREQ par->lcd_fck_rate = clk_get_rate(fb_clk); #endif - par->pxl_clk = lcdc_info->pxl_clk; + par->pxl_clk = lcdc_info->pixclock; if (fb_pdata->panel_power_ctrl) { par->panel_power_ctrl = fb_pdata->panel_power_ctrl; par->panel_power_ctrl(1); @@ -1336,8 +1318,8 @@ static int __devinit fb_probe(struct platform_device *device) } /* allocate frame buffer */ - par->vram_size = lcdc_info->width * lcdc_info->height * lcd_cfg->bpp; - ulcm = lcm((lcdc_info->width * lcd_cfg->bpp)/8, PAGE_SIZE); + par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp; + ulcm = lcm((lcdc_info->xres * lcd_cfg->bpp)/8, PAGE_SIZE); par->vram_size = roundup(par->vram_size/8, ulcm); par->vram_size = par->vram_size * LCD_NUM_BUFFERS; @@ -1355,10 +1337,10 @@ static int __devinit fb_probe(struct platform_device *device) da8xx_fb_info->screen_base = (char __iomem *) par->vram_virt; da8xx_fb_fix.smem_start = par->vram_phys; da8xx_fb_fix.smem_len = par->vram_size; - da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8; + da8xx_fb_fix.line_length = (lcdc_info->xres * lcd_cfg->bpp) / 8; par->dma_start = par->vram_phys; - par->dma_end = par->dma_start + lcdc_info->height * + par->dma_end = par->dma_start + lcdc_info->yres * da8xx_fb_fix.line_length - 1; /* allocate palette buffer */ @@ -1384,22 +1366,22 @@ static int __devinit fb_probe(struct platform_device *device) /* Initialize par */ da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp; - da8xx_fb_var.xres = lcdc_info->width; - da8xx_fb_var.xres_virtual = lcdc_info->width; + da8xx_fb_var.xres = lcdc_info->xres; + da8xx_fb_var.xres_virtual = lcdc_info->xres; - da8xx_fb_var.yres = lcdc_info->height; - da8xx_fb_var.yres_virtual = lcdc_info->height * LCD_NUM_BUFFERS; + da8xx_fb_var.yres = lcdc_info->yres; + da8xx_fb_var.yres_virtual = lcdc_info->yres * LCD_NUM_BUFFERS; da8xx_fb_var.grayscale = - lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0; + lcd_cfg->panel_shade == MONOCHROME ? 1 : 0; da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp; - da8xx_fb_var.hsync_len = lcdc_info->hsw; - da8xx_fb_var.vsync_len = lcdc_info->vsw; - da8xx_fb_var.right_margin = lcdc_info->hfp; - da8xx_fb_var.left_margin = lcdc_info->hbp; - da8xx_fb_var.lower_margin = lcdc_info->vfp; - da8xx_fb_var.upper_margin = lcdc_info->vbp; + da8xx_fb_var.hsync_len = lcdc_info->hsync_len; + da8xx_fb_var.vsync_len = lcdc_info->vsync_len; + da8xx_fb_var.right_margin = lcdc_info->right_margin; + da8xx_fb_var.left_margin = lcdc_info->left_margin; + da8xx_fb_var.lower_margin = lcdc_info->lower_margin; + da8xx_fb_var.upper_margin = lcdc_info->upper_margin; da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par); /* Initialize fbinfo */ diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c index d55470e7541..28fd686c6b8 100644 --- a/drivers/video/exynos/exynos_dp_core.c +++ b/drivers/video/exynos/exynos_dp_core.c @@ -18,6 +18,7 @@ #include <linux/io.h> #include <linux/interrupt.h> #include <linux/delay.h> +#include <linux/of.h> #include <video/exynos_dp.h> @@ -48,10 +49,6 @@ static int exynos_dp_detect_hpd(struct exynos_dp_device *dp) { int timeout_loop = 0; - exynos_dp_init_hpd(dp); - - usleep_range(200, 210); - while (exynos_dp_get_plug_in_status(dp) != 0) { timeout_loop++; if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { @@ -90,9 +87,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp) */ /* Read Extension Flag, Number of 128-byte EDID extension blocks */ - exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR, + retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR, EDID_EXTENSION_FLAG, &extend_block); + if (retval) + return retval; if (extend_block > 0) { dev_dbg(dp->dev, "EDID data includes a single extension!\n"); @@ -181,14 +180,15 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp) int retval; /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */ - exynos_dp_read_bytes_from_dpcd(dp, - DPCD_ADDR_DPCD_REV, - 12, buf); + retval = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_DPCD_REV, + 12, buf); + if (retval) + return retval; /* Read EDID */ for (i = 0; i < 3; i++) { retval = exynos_dp_read_edid(dp); - if (retval == 0) + if (!retval) break; } @@ -261,11 +261,10 @@ 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) +static int exynos_dp_link_start(struct exynos_dp_device *dp) { u8 buf[4]; - int lane; - int lane_count; + int lane, lane_count, pll_tries, retval; lane_count = dp->link_train.lane_count; @@ -275,10 +274,6 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp) for (lane = 0; lane < lane_count; lane++) dp->link_train.cr_loop[lane] = 0; - /* Set sink to D0 (Sink Not Ready) mode. */ - exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE, - DPCD_SET_POWER_STATE_D0); - /* 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); @@ -286,29 +281,46 @@ static void 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; - exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET, + retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_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); + /* Wait for PLL lock */ + pll_tries = 0; + while (exynos_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; + } + + pll_tries++; + usleep_range(90, 120); + } + /* Set training pattern 1 */ exynos_dp_set_training_pattern(dp, TRAINING_PTN1); /* Set RX training pattern */ - exynos_dp_write_byte_to_dpcd(dp, - DPCD_ADDR_TRAINING_PATTERN_SET, - DPCD_SCRAMBLING_DISABLED | - DPCD_TRAINING_PATTERN_1); + retval = exynos_dp_write_byte_to_dpcd(dp, + DPCD_ADDR_TRAINING_PATTERN_SET, + DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1); + if (retval) + return retval; for (lane = 0; lane < lane_count; lane++) buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 | DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0; - exynos_dp_write_bytes_to_dpcd(dp, - DPCD_ADDR_TRAINING_LANE0_SET, - lane_count, buf); + + retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET, + lane_count, buf); + + return retval; } static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane) @@ -332,18 +344,17 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count) return 0; } -static int exynos_dp_channel_eq_ok(u8 link_align[3], int lane_count) +static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align, + int lane_count) { int lane; - u8 lane_align; u8 lane_status; - lane_align = link_align[2]; - if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) == 0) + if ((link_align & DPCD_INTERLANE_ALIGN_DONE) == 0) return -EINVAL; for (lane = 0; lane < lane_count; lane++) { - lane_status = exynos_dp_get_lane_status(link_align, lane); + lane_status = exynos_dp_get_lane_status(link_status, lane); lane_status &= DPCD_CHANNEL_EQ_BITS; if (lane_status != DPCD_CHANNEL_EQ_BITS) return -EINVAL; @@ -427,60 +438,60 @@ static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp) dp->link_train.lt_state = FAILED; } -static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp) +static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp, + u8 adjust_request[2]) { - u8 link_status[2]; - int lane; - int lane_count; + int lane, lane_count; + u8 voltage_swing, pre_emphasis, training_lane; - u8 adjust_request[2]; - 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_SWI |