Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0b9892b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: move pm_qos vote to command mode only"

parents 3f16c992 7fdd4c2b
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -577,23 +577,26 @@ int sde_connector_pre_kickoff(struct drm_connector *connector)
	return rc;
}

void sde_connector_clk_ctrl(struct drm_connector *connector, bool enable)
int sde_connector_clk_ctrl(struct drm_connector *connector, bool enable)
{
	struct sde_connector *c_conn;
	struct dsi_display *display;
	u32 state = enable ? DSI_CLK_ON : DSI_CLK_OFF;
	int rc = 0;

	if (!connector) {
		SDE_ERROR("invalid connector\n");
		return;
		return -EINVAL;
	}

	c_conn = to_sde_connector(connector);
	display = (struct dsi_display *) c_conn->display;

	if (display && c_conn->ops.clk_ctrl)
		c_conn->ops.clk_ctrl(display->mdp_clk_handle,
		rc = c_conn->ops.clk_ctrl(display->mdp_clk_handle,
				DSI_ALL_CLKS, state);

	return rc;
}

static void sde_connector_destroy(struct drm_connector *connector)
+2 −1
Original line number Diff line number Diff line
@@ -547,8 +547,9 @@ int sde_connector_get_info(struct drm_connector *connector,
 * sde_connector_clk_ctrl - enables/disables the connector clks
 * @connector: Pointer to drm connector object
 * @enable: true/false to enable/disable
 * Returns: Zero on success
 */
void sde_connector_clk_ctrl(struct drm_connector *connector, bool enable);
int sde_connector_clk_ctrl(struct drm_connector *connector, bool enable);

/**
 * sde_connector_get_dpms - query dpms setting
+18 −2
Original line number Diff line number Diff line
@@ -460,6 +460,7 @@ void sde_core_irq_preinstall(struct sde_kms *sde_kms)
{
	struct msm_drm_private *priv;
	int i;
	int rc;

	if (!sde_kms) {
		SDE_ERROR("invalid sde_kms\n");
@@ -473,7 +474,14 @@ void sde_core_irq_preinstall(struct sde_kms *sde_kms)
	}
	priv = sde_kms->dev->dev_private;

	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true);
	rc = sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
			true);
	if (rc) {
		SDE_ERROR("failed to enable power resource %d\n", rc);
		SDE_EVT32(rc, SDE_EVTLOG_ERROR);
		return;
	}

	sde_clear_all_irqs(sde_kms);
	sde_disable_all_irqs(sde_kms);
	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
@@ -504,6 +512,7 @@ void sde_core_irq_uninstall(struct sde_kms *sde_kms)
{
	struct msm_drm_private *priv;
	int i;
	int rc;

	if (!sde_kms) {
		SDE_ERROR("invalid sde_kms\n");
@@ -517,7 +526,14 @@ void sde_core_irq_uninstall(struct sde_kms *sde_kms)
	}
	priv = sde_kms->dev->dev_private;

	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true);
	rc = sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
			true);
	if (rc) {
		SDE_ERROR("failed to enable power resource %d\n", rc);
		SDE_EVT32(rc, SDE_EVTLOG_ERROR);
		return;
	}

	for (i = 0; i < sde_kms->irq_obj.total_irqs; i++)
		if (atomic_read(&sde_kms->irq_obj.enable_counts[i]) ||
				!list_empty(&sde_kms->irq_obj.irq_cb_tbl[i]))
+39 −3
Original line number Diff line number Diff line
@@ -3048,6 +3048,11 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc,
		return;
	}

	if (!sde_kms_power_resource_is_enabled(crtc->dev)) {
		SDE_ERROR("power resource is not enabled\n");
		return;
	}

	SDE_DEBUG("crtc%d\n", crtc->base.id);

	sde_crtc = to_sde_crtc(crtc);
@@ -3137,6 +3142,11 @@ static void sde_crtc_atomic_flush(struct drm_crtc *crtc,
		return;
	}

	if (!sde_kms_power_resource_is_enabled(crtc->dev)) {
		SDE_ERROR("power resource is not enabled\n");
		return;
	}

	SDE_DEBUG("crtc%d\n", crtc->base.id);

	sde_crtc = to_sde_crtc(crtc);
@@ -4032,6 +4042,12 @@ static void sde_crtc_disable(struct drm_crtc *crtc)
		SDE_ERROR("invalid crtc\n");
		return;
	}

	if (!sde_kms_power_resource_is_enabled(crtc->dev)) {
		SDE_ERROR("power resource is not enabled\n");
		return;
	}

	sde_crtc = to_sde_crtc(crtc);
	cstate = to_sde_crtc_state(crtc->state);
	priv = crtc->dev->dev_private;
@@ -4146,6 +4162,11 @@ static void sde_crtc_enable(struct drm_crtc *crtc)
	}
	priv = crtc->dev->dev_private;

	if (!sde_kms_power_resource_is_enabled(crtc->dev)) {
		SDE_ERROR("power resource is not enabled\n");
		return;
	}

	SDE_DEBUG("crtc%d\n", crtc->base.id);
	SDE_EVT32_VERBOSE(DRMID(crtc));
	sde_crtc = to_sde_crtc(crtc);
@@ -5817,8 +5838,15 @@ static int _sde_crtc_event_enable(struct sde_kms *kms,
	priv = kms->dev->dev_private;
	ret = 0;
	if (crtc_drm->enabled) {
		sde_power_resource_enable(&priv->phandle, kms->core_client,
				true);
		ret = sde_power_resource_enable(&priv->phandle,
				kms->core_client, true);
		if (ret) {
			SDE_ERROR("failed to enable power resource %d\n", ret);
			SDE_EVT32(ret, SDE_EVTLOG_ERROR);
			kfree(node);
			return ret;
		}

		INIT_LIST_HEAD(&node->irq.list);
		ret = node->func(crtc_drm, true, &node->irq);
		sde_power_resource_enable(&priv->phandle, kms->core_client,
@@ -5872,7 +5900,15 @@ static int _sde_crtc_event_disable(struct sde_kms *kms,
		return 0;
	}
	priv = kms->dev->dev_private;
	sde_power_resource_enable(&priv->phandle, kms->core_client, true);
	ret = sde_power_resource_enable(&priv->phandle, kms->core_client, true);
	if (ret) {
		SDE_ERROR("failed to enable power resource %d\n", ret);
		SDE_EVT32(ret, SDE_EVTLOG_ERROR);
		list_del(&node->list);
		kfree(node);
		return ret;
	}

	ret = node->func(crtc_drm, false, &node->irq);
	list_del(&node->list);
	kfree(node);
+138 −7
Original line number Diff line number Diff line
@@ -247,6 +247,70 @@ struct sde_encoder_virt {

#define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base)

static void _sde_encoder_pm_qos_add_request(struct drm_encoder *drm_enc)
{
	struct msm_drm_private *priv;
	struct sde_kms *sde_kms;
	struct pm_qos_request *req;
	u32 cpu_mask;
	u32 cpu_dma_latency;
	int cpu;

	if (!drm_enc->dev || !drm_enc->dev->dev_private) {
		SDE_ERROR("drm device invalid\n");
		return;
	}

	priv = drm_enc->dev->dev_private;
	if (!priv->kms) {
		SDE_ERROR("invalid kms\n");
		return;
	}

	sde_kms = to_sde_kms(priv->kms);
	if (!sde_kms || !sde_kms->catalog)
		return;

	cpu_mask = sde_kms->catalog->perf.cpu_mask;
	cpu_dma_latency = sde_kms->catalog->perf.cpu_dma_latency;
	if (!cpu_mask)
		return;

	req = &sde_kms->pm_qos_cpu_req;
	req->type = PM_QOS_REQ_AFFINE_CORES;
	cpumask_empty(&req->cpus_affine);
	for_each_possible_cpu(cpu) {
		if ((1 << cpu) & cpu_mask)
			cpumask_set_cpu(cpu, &req->cpus_affine);
	}
	pm_qos_add_request(req, PM_QOS_CPU_DMA_LATENCY, cpu_dma_latency);

	SDE_EVT32_VERBOSE(DRMID(drm_enc), cpu_mask, cpu_dma_latency);
}

static void _sde_encoder_pm_qos_remove_request(struct drm_encoder *drm_enc)
{
	struct msm_drm_private *priv;
	struct sde_kms *sde_kms;

	if (!drm_enc->dev || !drm_enc->dev->dev_private) {
		SDE_ERROR("drm device invalid\n");
		return;
	}

	priv = drm_enc->dev->dev_private;
	if (!priv->kms) {
		SDE_ERROR("invalid kms\n");
		return;
	}

	sde_kms = to_sde_kms(priv->kms);
	if (!sde_kms || !sde_kms->catalog || !sde_kms->catalog->perf.cpu_mask)
		return;

	pm_qos_remove_request(&sde_kms->pm_qos_cpu_req);
}

static struct drm_connector_state *_sde_encoder_get_conn_state(
		struct drm_encoder *drm_enc)
{
@@ -1671,37 +1735,61 @@ static void _sde_encoder_resource_control_rsc_update(
	}
}

static void _sde_encoder_resource_control_helper(struct drm_encoder *drm_enc,
static int _sde_encoder_resource_control_helper(struct drm_encoder *drm_enc,
		bool enable)
{
	struct msm_drm_private *priv;
	struct sde_kms *sde_kms;
	struct sde_encoder_virt *sde_enc;
	int rc;
	bool is_cmd_mode, is_primary;

	sde_enc = to_sde_encoder_virt(drm_enc);
	priv = drm_enc->dev->dev_private;
	sde_kms = to_sde_kms(priv->kms);

	is_cmd_mode = sde_enc->disp_info.capabilities &
			MSM_DISPLAY_CAP_CMD_MODE;
	is_primary = sde_enc->disp_info.is_primary;

	SDE_DEBUG_ENC(sde_enc, "enable:%d\n", enable);
	SDE_EVT32(DRMID(drm_enc), enable);

	if (!sde_enc->cur_master) {
		SDE_ERROR("encoder master not set\n");
		return;
		return -EINVAL;
	}

	if (enable) {
		/* enable SDE core clks */
		sde_power_resource_enable(&priv->phandle,
		rc = sde_power_resource_enable(&priv->phandle,
				sde_kms->core_client, true);
		if (rc) {
			SDE_ERROR("failed to enable power resource %d\n", rc);
			SDE_EVT32(rc, SDE_EVTLOG_ERROR);
			return rc;
		}

		/* enable DSI clks */
		sde_connector_clk_ctrl(sde_enc->cur_master->connector, true);
		rc = sde_connector_clk_ctrl(sde_enc->cur_master->connector,
				true);
		if (rc) {
			SDE_ERROR("failed to enable clk control %d\n", rc);
			sde_power_resource_enable(&priv->phandle,
					sde_kms->core_client, false);
			return rc;
		}

		/* enable all the irq */
		_sde_encoder_irq_control(drm_enc, true);

		if (is_cmd_mode && is_primary)
			_sde_encoder_pm_qos_add_request(drm_enc);

	} else {
		if (is_cmd_mode && is_primary)
			_sde_encoder_pm_qos_remove_request(drm_enc);

		/* disable all the irq */
		_sde_encoder_irq_control(drm_enc, false);

@@ -1713,6 +1801,7 @@ static void _sde_encoder_resource_control_helper(struct drm_encoder *drm_enc,
				sde_kms->core_client, false);
	}

	return 0;
}

static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
@@ -1791,7 +1880,19 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
			_sde_encoder_irq_control(drm_enc, true);
		} else {
			/* enable all the clks and resources */
			_sde_encoder_resource_control_helper(drm_enc, true);
			ret = _sde_encoder_resource_control_helper(drm_enc,
					true);
			if (ret) {
				SDE_ERROR_ENC(sde_enc,
						"sw_event:%d, rc in state %d\n",
						sw_event, sde_enc->rc_state);
				SDE_EVT32(DRMID(drm_enc), sw_event,
						sde_enc->rc_state,
						SDE_EVTLOG_ERROR);
				mutex_unlock(&sde_enc->rc_lock);
				return ret;
			}

			_sde_encoder_resource_control_rsc_update(drm_enc, true);
		}

@@ -1949,7 +2050,18 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
		/* return if the resource control is already in ON state */
		if (sde_enc->rc_state != SDE_ENC_RC_STATE_ON) {
			/* enable all the clks and resources */
			_sde_encoder_resource_control_helper(drm_enc, true);
			ret = _sde_encoder_resource_control_helper(drm_enc,
					true);
			if (ret) {
				SDE_ERROR_ENC(sde_enc,
						"sw_event:%d, rc in state %d\n",
						sw_event, sde_enc->rc_state);
				SDE_EVT32(DRMID(drm_enc), sw_event,
						sde_enc->rc_state,
						SDE_EVTLOG_ERROR);
				mutex_unlock(&sde_enc->rc_lock);
				return ret;
			}

			_sde_encoder_resource_control_rsc_update(drm_enc, true);

@@ -2078,6 +2190,11 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
		return;
	}

	if (!sde_kms_power_resource_is_enabled(drm_enc->dev)) {
		SDE_ERROR("power resource is not enabled\n");
		return;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);
	SDE_DEBUG_ENC(sde_enc, "\n");

@@ -2285,6 +2402,11 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
	}
	sde_enc = to_sde_encoder_virt(drm_enc);

	if (!sde_kms_power_resource_is_enabled(drm_enc->dev)) {
		SDE_ERROR("power resource is not enabled\n");
		return;
	}

	ret = _sde_encoder_get_mode_info(drm_enc, &mode_info);
	if (ret) {
		SDE_ERROR_ENC(sde_enc, "failed to get mode info\n");
@@ -2379,6 +2501,11 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
		return;
	}

	if (!sde_kms_power_resource_is_enabled(drm_enc->dev)) {
		SDE_ERROR("power resource is not enabled\n");
		return;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);
	SDE_DEBUG_ENC(sde_enc, "\n");

@@ -3301,7 +3428,11 @@ int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
	}
	SDE_ATRACE_END("enc_prepare_for_kickoff");

	sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_KICKOFF);
	rc = sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_KICKOFF);
	if (rc) {
		SDE_ERROR_ENC(sde_enc, "resource kickoff failed rc %d\n", rc);
		return rc;
	}

	/* if any phys needs reset, reset all phys, in-order */
	if (needs_hw_reset) {
Loading