Пример #1
0
static void s5p_dp_disable(struct s5p_dp_device *dp)
{
	struct s5p_dp_platdata *pdata = dp->dev->platform_data;

	mutex_lock(&dp->lock);

	if (!dp->enabled)
		goto out;

	dp->enabled = 0;

	s5p_dp_reset(dp);
	s5p_dp_set_pll_power_down(dp, 1);
	s5p_dp_set_analog_power_down(dp, POWER_ALL, 1);

#ifdef CONFIG_S5P_DP_PSR
	if (dp->psr_enter_state != PSR_ENTER_DONE)
		clk_disable(dp->clock);
#else
	clk_disable(dp->clock);
#endif
	pm_runtime_put_sync(dp->dev);

out:
	mutex_unlock(&dp->lock);
}
Пример #2
0
static void s5p_dp_disable(struct s5p_dp_device *dp)
{
	struct s5p_dp_platdata *pdata = dp->dev->platform_data;
#if defined(CONFIG_SOC_EXYNOS5260)
	if ((pdata->clock_reinit == true) && (dp->clock_status == true))
		dp->clock_status = false;
#endif
	mutex_lock(&dp->lock);

	if (!dp->enabled)
		goto out;

	dp->enabled = 0;

	s5p_dp_reset(dp);
	s5p_dp_set_pll_power_down(dp, 1);
	s5p_dp_set_analog_power_down(dp, POWER_ALL, 1);

	if (pdata && pdata->phy_exit)
		pdata->phy_exit();

	clk_disable(dp->clock);
	pm_runtime_put_sync(dp->dev);

out:
	mutex_unlock(&dp->lock);
}
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;
}
static void s5p_dp_disable(struct s5p_dp_device *dp)
{
	struct s5p_dp_platdata *pdata = dp->dev->platform_data;

	mutex_lock(&dp->lock);

	if (!dp->enabled)
		goto out;

	dp->enabled = 0;

	s5p_dp_reset(dp);
	s5p_dp_set_pll_power_down(dp, 1);
	s5p_dp_set_analog_power_down(dp, POWER_ALL, 1);

	if (pdata && pdata->phy_exit)
		pdata->phy_exit();

	clk_disable(dp->clock);
	pm_runtime_put_sync(dp->dev);

out:
	mutex_unlock(&dp->lock);
}
Пример #5
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;
}
Пример #6
0
int s5p_dp_psr_exit(struct s5p_dp_device *dp)
{
	struct platform_device *pdev;
	struct s5p_dp_platdata *pdata;
	int timeout_loop = 0;
	u8 data;
	u32 reg;
	int ret = 0;

	pdev = to_platform_device(dp->dev);
	pdata = pdev->dev.platform_data;

	mutex_lock(&dp->lock);
	dev_dbg(dp->dev, "%s +\n", __func__);

	if (dp->psr_enter_state == PSR_NONE) {
		dev_info(dp->dev, "%s: Already edP PSR_EXIT state\n", __func__);
		dp->psr_exit_state = PSR_NONE;
		mutex_unlock(&dp->lock);
		return 0;
	}

	clk_enable(dp->clock);

	s5p_dp_exit_psr(dp);

	s5p_dp_set_fifo_reset(dp);
	s5p_dp_reset_macro_onoff(dp, 1);
	s5p_dp_set_analog_power_down(dp, ANALOG_TOTAL, 0);

	if (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
		while (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
			timeout_loop++;
			if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
				dev_err(dp->dev, "failed to get pll lock status\n");
				ret = -ETIMEDOUT;
				goto err_exit;
			}
			udelay(10);
		}
	}

	ndelay(600);
	s5p_dp_clear_fifo_reset(dp);
	s5p_dp_reset_macro_onoff(dp, 0);
	s5p_dp_reset_serdes_fifo(dp);

	/* Set sink to D0 (Normal operation) mode. */
	s5p_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
		DPCD_SET_POWER_STATE_D0);

	s5p_dp_set_link_train_for_psr(dp, dp->video_info->lane_count,
		dp->video_info->link_rate);

	s5p_dp_set_idle_en(dp);
	timeout_loop = 0;

	for (;;) {
		timeout_loop++;
		if (s5p_dp_get_psr_status(dp) == PSR_STATUS_INACTIVE)
			break;
		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
			dev_err(dp->dev, "DP: Timeout of PSR inactive\n");
			ret = -ETIMEDOUT;
			goto err_exit;
		}
		usleep_range(100, 110);
	}

	s5p_dp_set_force_stream_valid(dp);

	timeout_loop = 0;

	for (;;) {
		timeout_loop++;
		if (s5p_dp_is_video_stream_on(dp) == 0)
			break;
		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
			dev_err(dp->dev, "Timeout of video streamclk ok\n");
			ret = -ETIMEDOUT;
			goto err_exit;
		}
		usleep_range(1000, 1100);
	}

	timeout_loop = 0;
	for (;;) {
		timeout_loop++;
		s5p_dp_read_byte_from_dpcd(dp,
			DPCD_ADDR_SINK_PSR_STATUS,
			&data);
		if (data == SINK_PSR_INACTIVE_STATE || data == 4) {
			break;
		}
		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
			dev_err(dp->dev, "LCD: Timeout of Sink PSR inactive\n");
			ret = -ETIMEDOUT;
			goto err_exit;
		}
		usleep_range(100, 110);
	}

	dp->psr_enter_state = PSR_NONE;
	dp->psr_exit_state = PSR_EXIT_DONE;

	dev_dbg(dp->dev, "%s -\n", __func__);
	mutex_unlock(&dp->lock);
	return ret;

err_exit:
	dp->psr_exit_state = PSR_NONE;
	dev_dbg(dp->dev, "%s -\n", __func__);
	mutex_unlock(&dp->lock);
	return ret;
}
Пример #7
0
static int s5p_dp_psr_enter(struct s5p_dp_device *dp)
{
	struct platform_device *pdev;
	struct s5p_dp_platdata *pdata;
	int timeout_loop = 0;
	struct fb_event event;
	int ret = 0;
	u8 data;

	pdev = to_platform_device(dp->dev);
	pdata = pdev->dev.platform_data;

	mutex_lock(&dp->lock);
	dev_dbg(dp->dev, "%s +\n", __func__);

	if (dp->psr_enter_state == PSR_ENTER_DONE) {
		dev_info(dp->dev, "%s: Already edP PSR_ENTER state\n", __func__);
		goto err_exit;
	}

	if (dp->psr_exit_state == PSR_PRE_EXIT) {
		dev_info(dp->dev, "%s: edP does not need to PSR_ENTER\n", __func__);
		goto err_exit;
	}

	dp->psr_enter_state = PSR_PRE_ENTER;
	s5p_dp_enable_psr(dp);

	for (;;) {
		timeout_loop++;
		if (s5p_dp_get_psr_status(dp) == PSR_STATUS_ACTIVE)
			break;
		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
			dev_err(dp->dev, "DP: Timeout of PSR active\n");
			ret = -ETIMEDOUT;
			dp->psr_enter_state = PSR_NONE;
			dp->psr_error_count++;
			goto err_exit;
		}
		mdelay(1);
	}

	mdelay(2);
	dev_dbg(dp->dev, "PSR ENTER DP timeout_loop: %d\n", timeout_loop);

	s5p_dp_read_byte_from_dpcd(dp, DPCD_ADDR_SINK_PSR_STATUS, &data);
	if (data == 0)
		dev_info(dp->dev, "%s: SINK_PSR_STATUS = 0x%02X\n",
			__func__, data);

	s5p_dp_set_analog_power_down(dp, ANALOG_TOTAL, 1);

	clk_disable(dp->clock);

	fb_notifier_call_chain(FB_EVENT_PSR_DONE, &event);
	dp->psr_enter_state = PSR_ENTER_DONE;

err_exit:
	dev_dbg(dp->dev, "%s -\n", __func__);
	mutex_unlock(&dp->lock);
	return ret;
}