Example #1
0
File: fb.c Project: 0ida/coreboot
/*
 * Configure DP in slave mode and wait for video stream.
 *
 * param dp		pointer to main s5p-dp structure
 * param video_info	pointer to main video_info structure.
 * return		status
 */
static int s5p_dp_config_video(struct s5p_dp_device *dp,
			       struct video_info *video_info)
{
	int timeout = 0;
	struct exynos5_dp *base = dp->base;
	struct mono_time start, current, end;
	s5p_dp_config_video_slave_mode(dp, video_info);

	s5p_dp_set_video_color_format(dp, video_info->color_depth,
				      video_info->color_space,
				      video_info->dynamic_range,
				      video_info->ycbcr_coeff);

	if (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
		printk(BIOS_DEBUG, "PLL is not locked yet.\n");
		return -ERR_PLL_NOT_UNLOCKED;
	}

	timer_monotonic_get(&start);
	end = current = start;
	mono_time_add_usecs(&end, STREAM_ON_TIMEOUT * USECS_PER_MSEC);
	do {
		if (s5p_dp_is_slave_video_stream_clock_on(dp) == 0) {
			timeout++;
			break;
		}
		timer_monotonic_get(&current);
	} while (mono_time_before(&current, &end));

	if (!timeout) {
		printk(BIOS_ERR, "Video Clock Not ok after %ldus.\n",
				mono_time_diff_microseconds(&start, &end));
		return -ERR_VIDEO_CLOCK_BAD;
	}

	/* Set to use the register calculated M/N video */
	s5p_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);

	clrbits_le32(&base->video_ctl_10, FORMAT_SEL);

	/* Disable video mute */
	clrbits_le32(&base->video_ctl_1, HDCP_VIDEO_MUTE);

	/* Configure video slave mode */
	s5p_dp_enable_video_master(dp);

	/* Enable video */
	setbits_le32(&base->video_ctl_1, VIDEO_EN);
	timeout = s5p_dp_is_video_stream_on(dp);

	if (timeout) {
		printk(BIOS_DEBUG, "Video Stream Not on\n");
		return -ERR_VIDEO_STREAM_BAD;
	}

	return 0;
}
Example #2
0
/*
 * Configure DP in slave mode and wait for video stream.
 *
 * param dp		pointer to main s5p-dp structure
 * param video_info	pointer to main video_info structure.
 * return		status
 */
static int s5p_dp_config_video(struct s5p_dp_device *dp,
			       struct video_info *video_info)
{
	int timeout = 0;
	struct exynos5_dp *base = dp->base;
	struct stopwatch sw;
	s5p_dp_config_video_slave_mode(dp, video_info);

	s5p_dp_set_video_color_format(dp, video_info->color_depth,
				      video_info->color_space,
				      video_info->dynamic_range,
				      video_info->ycbcr_coeff);

	if (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
		printk(BIOS_DEBUG, "PLL is not locked yet.\n");
		return -ERR_PLL_NOT_UNLOCKED;
	}

	stopwatch_init_msecs_expire(&sw, STREAM_ON_TIMEOUT);
	do {
		if (s5p_dp_is_slave_video_stream_clock_on(dp) == 0) {
			timeout++;
			break;
		}
	} while (!stopwatch_expired(&sw));

	if (!timeout) {
		printk(BIOS_ERR, "Video Clock Not ok after %ldus.\n",
				stopwatch_duration_usecs(&sw));
		return -ERR_VIDEO_CLOCK_BAD;
	}

	/* Set to use the register calculated M/N video */
	s5p_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);

	clrbits_le32(&base->video_ctl_10, FORMAT_SEL);

	/* Disable video mute */
	clrbits_le32(&base->video_ctl_1, HDCP_VIDEO_MUTE);

	/* Configure video slave mode */
	s5p_dp_enable_video_master(dp);

	/* Enable video */
	setbits_le32(&base->video_ctl_1, VIDEO_EN);
	timeout = s5p_dp_is_video_stream_on(dp);

	if (timeout) {
		printk(BIOS_DEBUG, "Video Stream Not on\n");
		return -ERR_VIDEO_STREAM_BAD;
	}

	return 0;
}
static int s5p_dp_config_video(struct s5p_dp_device *dp,
			struct video_info *video_info)
{
	int retval = 0;
	int timeout_loop = 0;
	int done_count = 0;

	s5p_dp_config_video_slave_mode(dp, video_info);

	s5p_dp_set_video_color_format(dp, video_info->color_depth,
			video_info->color_space,
			video_info->dynamic_range,
			video_info->ycbcr_coeff);

	if (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
		dev_err(dp->dev, "PLL is not locked yet.\n");
		return -EINVAL;
	}

	for (;;) {
		timeout_loop++;
		if (s5p_dp_is_slave_video_stream_clock_on(dp) == 0)
			break;
		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
			dev_err(dp->dev, "Timeout of video streamclk ok\n");
			return -ETIMEDOUT;
		}

		usleep_range(1, 1);
	}

	/* Set to use the register calculated M/N video */
	s5p_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);

	/* For video bist, Video timing must be generated by register */
	s5p_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE);

	/* Disable video mute */
	s5p_dp_enable_video_mute(dp, 0);

	/* Configure video slave mode */
	s5p_dp_enable_video_master(dp, 0);

	/* Enable video */
	s5p_dp_start_video(dp);

	timeout_loop = 0;

	for (;;) {
		timeout_loop++;
		if (s5p_dp_is_video_stream_on(dp) == 0) {
			done_count++;
			if (done_count > 10)
				break;
		} else if (done_count) {
			done_count = 0;
		}
		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
			dev_err(dp->dev, "Timeout of video streamclk ok\n");
			return -ETIMEDOUT;
		}

		usleep_range(1000, 1000);
	}

	if (retval != 0)
		dev_err(dp->dev, "Video stream is not detected!\n");

	return retval;
}
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;
}