Exemplo n.º 1
0
static void edp_ctrl_off_worker(struct work_struct *work)
{
	struct edp_ctrl *ctrl = container_of(
				work, struct edp_ctrl, off_work);
	int ret;

	mutex_lock(&ctrl->dev_mutex);

	if (!ctrl->power_on) {
		DBG("already off");
		goto unlock_ret;
	}

	reinit_completion(&ctrl->idle_comp);
	edp_state_ctrl(ctrl, EDP_STATE_CTRL_PUSH_IDLE);

	ret = wait_for_completion_timeout(&ctrl->idle_comp,
						msecs_to_jiffies(500));
	if (ret <= 0)
		DBG("%s: idle pattern timedout, %d\n",
				__func__, ret);

	edp_state_ctrl(ctrl, 0);

	drm_dp_link_power_down(ctrl->drm_aux, &ctrl->dp_link);

	edp_ctrl_irq_enable(ctrl, 0);

	edp_ctrl_link_enable(ctrl, 0);

	edp_ctrl_phy_aux_enable(ctrl, 0);

	ctrl->power_on = false;

unlock_ret:
	mutex_unlock(&ctrl->dev_mutex);
}
Exemplo n.º 2
0
static void edp_host_train_set(struct edp_ctrl *ctrl, u32 train)
{
	int cnt = 10;
	u32 data;
	u32 shift = train - 1;

	DBG("train=%d", train);

	edp_state_ctrl(ctrl, EDP_STATE_CTRL_TRAIN_PATTERN_1 << shift);
	while (--cnt) {
		data = edp_read(ctrl->base + REG_EDP_MAINLINK_READY);
		if (data & (EDP_MAINLINK_READY_TRAIN_PATTERN_1_READY << shift))
			break;
	}

	if (cnt == 0)
		pr_err("%s: set link_train=%d failed\n", __func__, train);
}
Exemplo n.º 3
0
static int edp_do_link_train(struct edp_ctrl *ctrl)
{
	int ret;
	struct drm_dp_link dp_link;

	DBG("");
	/*
	 * Set the current link rate and lane cnt to panel. They may have been
	 * adjusted and the values are different from them in DPCD CAP
	 */
	dp_link.num_lanes = ctrl->lane_cnt;
	dp_link.rate = drm_dp_bw_code_to_link_rate(ctrl->link_rate);
	dp_link.capabilities = ctrl->dp_link.capabilities;
	if (drm_dp_link_configure(ctrl->drm_aux, &dp_link) < 0)
		return EDP_TRAIN_FAIL;

	ctrl->v_level = 0; /* start from default level */
	ctrl->p_level = 0;

	edp_state_ctrl(ctrl, 0);
	if (edp_clear_training_pattern(ctrl))
		return EDP_TRAIN_FAIL;

	ret = edp_start_link_train_1(ctrl);
	if (ret < 0) {
		if (edp_link_rate_down_shift(ctrl) == 0) {
			DBG("link reconfig");
			ret = EDP_TRAIN_RECONFIG;
			goto clear;
		} else {
			pr_err("%s: Training 1 failed", __func__);
			ret = EDP_TRAIN_FAIL;
			goto clear;
		}
	}
	DBG("Training 1 completed successfully");

	edp_state_ctrl(ctrl, 0);
	if (edp_clear_training_pattern(ctrl))
		return EDP_TRAIN_FAIL;

	ret = edp_start_link_train_2(ctrl);
	if (ret < 0) {
		if (edp_link_rate_down_shift(ctrl) == 0) {
			DBG("link reconfig");
			ret = EDP_TRAIN_RECONFIG;
			goto clear;
		} else {
			pr_err("%s: Training 2 failed", __func__);
			ret = EDP_TRAIN_FAIL;
			goto clear;
		}
	}
	DBG("Training 2 completed successfully");

	edp_state_ctrl(ctrl, EDP_STATE_CTRL_SEND_VIDEO);
clear:
	edp_clear_training_pattern(ctrl);

	return ret;
}