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; dp->link_train.lt_state = START; /* Process here */ while (!training_finished) { switch (dp->link_train.lt_state) { case START: exynos_dp_link_start(dp); break; case CLOCK_RECOVERY: exynos_dp_process_clock_recovery(dp); break; case EQUALIZER_TRAINING: exynos_dp_process_equalizer_training(dp); break; case FINISHED: training_finished = 1; break; case FAILED: return -EREMOTEIO; } } return retval; }
int exynos_dp_init_analog_func(void) { int ret = EXYNOS_DP_SUCCESS; unsigned int retry_cnt = 10; u32 reg; /*Power On All Analog block */ exynos_dp_set_analog_power_down(POWER_ALL, DP_DISABLE); reg = PLL_LOCK_CHG; lwrite32(reg, &dp_regs->common_int_sta1); reg = lread32(&dp_regs->debug_ctl); reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL); lwrite32(reg, &dp_regs->debug_ctl); /*Assert DP PLL Reset*/ reg = lread32(&dp_regs->pll_ctl); reg |= DP_PLL_RESET; lwrite32(reg, &dp_regs->pll_ctl); mdelay(1); /*Deassert DP PLL Reset*/ reg = lread32(&dp_regs->pll_ctl); reg &= ~(DP_PLL_RESET); lwrite32(reg, &dp_regs->pll_ctl); exynos_dp_set_pll_power(DP_ENABLE); while (exynos_dp_get_pll_lock_status() == PLL_UNLOCKED) { mdelay(1); retry_cnt--; if (retry_cnt == 0) { printk(BIOS_ERR, "DP dp's pll lock failed : retry : %d\n", retry_cnt); return -1; } } printk(BIOS_DEBUG, "dp's pll lock success(%d)\n", retry_cnt); /* Enable Serdes FIFO function and Link symbol clock domain module */ reg = lread32(&dp_regs->func_en2); reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N | AUX_FUNC_EN_N); lwrite32(reg, &dp_regs->func_en2); return ret; }
static void exynos_dp_init_training(struct exynos_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); /* 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); 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 */ exynos_dp_set_analog_power_down(dp, POWER_ALL, 0); }