static int s5p_dp_init_training(struct s5p_dp_device *dp, enum link_lane_count_type max_lane, enum link_rate_type max_rate) { int retval; /* * MACRO_RST must be applied after the PLL_LOCK to avoid * the DP inter pair skew issue for at least 10 us */ s5p_dp_reset_macro(dp); /* Initialize by reading RX's DPCD */ retval = s5p_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate); if (retval < 0) return retval; retval = s5p_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count); if (retval < 0) return retval; if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) && (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; } if (dp->link_train.lane_count == 0) { dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n", dp->link_train.lane_count); dp->link_train.lane_count = (u8)LANE_COUNT1; } /* Setup TX lane count & rate */ if (dp->link_train.lane_count > max_lane) dp->link_train.lane_count = max_lane; if (dp->link_train.link_rate > max_rate) dp->link_train.link_rate = max_rate; /* All DP analog module power up */ s5p_dp_set_analog_power_down(dp, POWER_ALL, 0); return 0; }
/* * DP H/w Link Training. Set DPCD link rate and bandwidth. * param dp pointer to main s5p-dp structure * param max_lane No of lanes * param max_rate bandwidth * return status */ static int s5p_dp_hw_link_training(struct s5p_dp_device *dp, unsigned int max_lane, unsigned int max_rate) { int pll_is_locked = 0; u32 data; int lane; struct mono_time current, end; struct exynos5_dp *base = dp->base; /* Stop Video */ clrbits_le32(&base->video_ctl_1, VIDEO_EN); timer_monotonic_get(¤t); end = current; mono_time_add_msecs(&end, PLL_LOCK_TIMEOUT); while ((pll_is_locked = s5p_dp_get_pll_lock_status(dp)) == PLL_UNLOCKED) { if (mono_time_after(¤t, &end)) { /* Ignore this error, and try to continue */ printk(BIOS_ERR, "PLL is not locked yet.\n"); break; } timer_monotonic_get(¤t); } printk(BIOS_SPEW, "PLL is %slocked\n", pll_is_locked == PLL_LOCKED ? "": "not "); /* Reset Macro */ setbits_le32(&base->dp_phy_test, MACRO_RST); /* 10 us is the minimum reset time. */ udelay(10); clrbits_le32(&base->dp_phy_test, MACRO_RST); /* Set TX pre-emphasis to minimum */ for (lane = 0; lane < max_lane; lane++) if (s5p_dp_set_lane_lane_pre_emphasis(dp, PRE_EMPHASIS_LEVEL_0, lane)) { printk(BIOS_DEBUG, "Unable to set pre emphasis level\n"); return -ERR_PRE_EMPHASIS_LEVELS; } /* All DP analog module power up */ writel(0x00, &base->dp_phy_pd); /* Initialize by reading RX's DPCD */ s5p_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate); s5p_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count); printk(BIOS_SPEW, "%s: rate 0x%x, lane_count %d\n", __func__, dp->link_train.link_rate, dp->link_train.lane_count); if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) && (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) { printk(BIOS_DEBUG, "Rx Max Link Rate is abnormal :%x !\n", dp->link_train.link_rate); /* Not Retrying */ return -ERR_LINK_RATE_ABNORMAL; } if (dp->link_train.lane_count == 0) { printk(BIOS_DEBUG, "Rx Max Lane count is abnormal :%x !\n", dp->link_train.lane_count); /* Not retrying */ return -ERR_MAX_LANE_COUNT_ABNORMAL; } /* Setup TX lane count & rate */ if (dp->link_train.lane_count > max_lane) dp->link_train.lane_count = max_lane; if (dp->link_train.link_rate > max_rate) dp->link_train.link_rate = max_rate; /* Set link rate and count as you want to establish*/ writel(dp->link_train.lane_count, &base->lane_count_set); writel(dp->link_train.link_rate, &base->link_bw_set); /* Set sink to D0 (Sink Not Ready) mode. */ s5p_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE, DPCD_SET_POWER_STATE_D0); /* Start HW link training */ writel(HW_TRAINING_EN, &base->dp_hw_link_training); /* Wait until HW link training done */ s5p_dp_wait_hw_link_training_done(dp); /* Get hardware link training status */ data = readl(&base->dp_hw_link_training); printk(BIOS_SPEW, "hardware link training status: 0x%08x\n", data); if (data != 0) { printk(BIOS_ERR, " H/W link training failure: 0x%x\n", data); return -ERR_LINK_TRAINING_FAILURE; } /* Get Link Bandwidth */ data = readl(&base->link_bw_set); dp->link_train.link_rate = data; data = readl(&base->lane_count_set); dp->link_train.lane_count = data; printk(BIOS_SPEW, "Done training: Link bandwidth: 0x%x, lane_count: %d\n", dp->link_train.link_rate, data); return 0; }
static int s5p_dp_init_training(struct s5p_dp_device *dp, enum link_lane_count_type max_lane, enum link_rate_type max_rate) { int retval; #ifdef CONFIG_S5P_DP_PSR u8 data; #endif /* * MACRO_RST must be applied after the PLL_LOCK to avoid * the DP inter pair skew issue for at least 10 us */ s5p_dp_reset_macro(dp); #ifdef CONFIG_S5P_DP_PSR s5p_dp_enable_rx_to_enhanced_mode(dp, 0); s5p_dp_read_byte_from_dpcd(dp, DPCD_ADDR_EDP_CONFIGURATION_SET, &data); s5p_dp_write_byte_to_dpcd(dp, DPCD_ADDR_EDP_CONFIGURATION_SET, data | (1<<1)); s5p_dp_enable_enhanced_mode(dp, 1); #endif /* Initialize by reading RX's DPCD */ retval = s5p_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate); if (retval < 0) return retval; retval = s5p_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count); if (retval < 0) return retval; if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) && (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; } if (dp->link_train.lane_count == 0) { dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n", dp->link_train.lane_count); dp->link_train.lane_count = (u8)LANE_COUNT1; } /* Setup TX lane count & rate */ if (dp->link_train.lane_count > max_lane) dp->link_train.lane_count = max_lane; if (dp->link_train.link_rate > max_rate) dp->link_train.link_rate = max_rate; #ifdef CONFIG_S5P_DP_PSR s5p_dp_enable_ssc(dp, 0); #endif /* All DP analog module power up */ s5p_dp_set_analog_power_down(dp, POWER_ALL, 0); return 0; }