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

Commit e6e01da7 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: add uevent handler to release pipes"

parents 8517b967 b5f1a490
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -1625,8 +1625,18 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
	sde_kms_info_add_keyint(info, "hw_version", catalog->hwversion);
	sde_kms_info_add_keyint(info, "max_linewidth",
			catalog->max_mixer_width);

	/* till now, we can't know which display early RVC will run on.
	 * Not to impact early RVC's layer, we decrease all lm's blend stage.
	 * This should be restored after handoff is done.
	 */
	if (sde_kms->splash_info.handoff)
		sde_kms_info_add_keyint(info, "max_blendstages",
				catalog->max_mixer_blendstages - 1);
	else
		sde_kms_info_add_keyint(info, "max_blendstages",
				catalog->max_mixer_blendstages);

	if (catalog->qseed_type == SDE_SSPP_SCALER_QSEED2)
		sde_kms_info_add_keystr(info, "qseed_type", "qseed2");
	if (catalog->qseed_type == SDE_SSPP_SCALER_QSEED3)
+19 −4
Original line number Diff line number Diff line
@@ -830,6 +830,7 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms)

	struct msm_drm_private *priv;
	struct sde_mdss_cfg *catalog;
	struct sde_splash_info *sinfo;

	int primary_planes_idx, i, ret;
	int max_crtc_count, max_plane_count;
@@ -842,6 +843,7 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms)
	dev = sde_kms->dev;
	priv = dev->dev_private;
	catalog = sde_kms->catalog;
	sinfo = &sde_kms->splash_info;

	ret = sde_core_irq_domain_add(sde_kms);
	if (ret)
@@ -869,7 +871,7 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms)
				primary = false;

			plane = sde_plane_init(dev, catalog->vp[i].id,
					primary, 1UL << crtc_id, true);
					primary, 1UL << crtc_id, true, false);
			if (IS_ERR(plane)) {
				SDE_ERROR("sde_plane_init failed\n");
				ret = PTR_ERR(plane);
@@ -887,14 +889,22 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms)

		for (i = 0; i < max_plane_count; i++) {
			bool primary = true;
			bool resv_plane = false;

			if (catalog->sspp[i].features & BIT(SDE_SSPP_CURSOR)
				|| primary_planes_idx >= max_crtc_count)
				primary = false;

			if (sde_splash_query_plane_is_reserved(sinfo,
							catalog->sspp[i].id)) {
				resv_plane = true;
				DRM_INFO("pipe%d is reserved\n",
					catalog->sspp[i].id);
			}

			plane = sde_plane_init(dev, catalog->sspp[i].id,
					primary, (1UL << max_crtc_count) - 1,
					false);
					false, resv_plane);
			if (IS_ERR(plane)) {
				SDE_ERROR("sde_plane_init failed\n");
				ret = PTR_ERR(plane);
@@ -1355,12 +1365,17 @@ static int sde_kms_hw_init(struct msm_kms *kms)
	 */
	sinfo = &sde_kms->splash_info;
	if (sinfo->handoff) {
		rc = sde_splash_parse_dt(dev);
		rc = sde_splash_parse_memory_dt(dev);
		if (rc) {
			SDE_ERROR("parse dt for splash info failed: %d\n", rc);
			SDE_ERROR("parse memory dt failed: %d\n", rc);
			goto power_error;
		}

		rc = sde_splash_parse_reserved_plane_dt(sinfo,
							sde_kms->catalog);
		if (rc)
			SDE_ERROR("parse reserved plane dt failed: %d\n", rc);

		sde_splash_init(&priv->phandle, kms);
	}

+14 −3
Original line number Diff line number Diff line
@@ -1798,7 +1798,7 @@ static void sde_plane_atomic_update(struct drm_plane *plane,

/* helper to install properties which are common to planes and crtcs */
static void _sde_plane_install_properties(struct drm_plane *plane,
	struct sde_mdss_cfg *catalog)
	struct sde_mdss_cfg *catalog, bool plane_reserved)
{
	static const struct drm_prop_enum_list e_blend_op[] = {
		{SDE_DRM_BLEND_OP_NOT_DEFINED,    "not_defined"},
@@ -1994,6 +1994,16 @@ static void _sde_plane_install_properties(struct drm_plane *plane,
	sde_kms_info_add_keyint(info, "max_downscale", maxdwnscale);
	sde_kms_info_add_keyint(info, "max_horizontal_deci", maxhdeciexp);
	sde_kms_info_add_keyint(info, "max_vertical_deci", maxvdeciexp);

	/* When early RVC is enabled in bootloader and doesn't exit,
	 * user app should not touch the pipe which RVC is on.
	 * So mark the plane_unavailibility to the special pipe's property,
	 * user can parse this property of this pipe and stop this pipe's
	 * allocation after parsing.
	 * plane_reserved is 1, means the pipe is occupied in bootloader.
	 * plane_reserved is 0, means it's not used in bootloader.
	 */
	sde_kms_info_add_keyint(info, "plane_unavailability", plane_reserved);
	msm_property_set_blob(&psde->property_info, &psde->blob_info,
			info->data, info->len, PLANE_PROP_INFO);

@@ -2731,7 +2741,8 @@ end:
/* initialize plane */
struct drm_plane *sde_plane_init(struct drm_device *dev,
		uint32_t pipe, bool primary_plane,
		unsigned long possible_crtcs, bool vp_enabled)
		unsigned long possible_crtcs,
		bool vp_enabled, bool plane_reserved)
{
	struct drm_plane *plane = NULL;
	struct sde_plane *psde;
@@ -2856,7 +2867,7 @@ struct drm_plane *sde_plane_init(struct drm_device *dev,
			PLANE_PROP_COUNT, PLANE_PROP_BLOBCOUNT,
			sizeof(struct sde_plane_state));

	_sde_plane_install_properties(plane, kms->catalog);
	_sde_plane_install_properties(plane, kms->catalog, plane_reserved);

	/* save user friendly pipe name for later */
	snprintf(psde->pipe_name, SDE_NAME_SIZE, "plane%u", plane->base.id);
+4 −2
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
@@ -77,10 +77,12 @@ void sde_plane_flush(struct drm_plane *plane);
 * @primary_plane: true if this pipe is primary plane for crtc
 * @possible_crtcs: bitmask of crtc that can be attached to the given pipe
 * @vp_enabled:  Flag indicating if virtual planes enabled
 * @plane_reserved: Flag indicating the plane is occupied in bootloader
 */
struct drm_plane *sde_plane_init(struct drm_device *dev,
		uint32_t pipe, bool primary_plane,
		unsigned long possible_crtcs, bool vp_enabled);
		unsigned long possible_crtcs,
		bool vp_enabled, bool plane_reserved);

/**
 * sde_plane_wait_input_fence - wait for input fence object
+116 −3
Original line number Diff line number Diff line
@@ -288,6 +288,44 @@ static void _sde_splash_destroy_splash_node(struct sde_splash_info *sinfo)
	sinfo->splash_mem_size = NULL;
}

static void _sde_splash_sent_pipe_update_uevent(struct sde_kms *sde_kms)
{
	char *event_string;
	char *envp[2];
	struct drm_device *dev;
	struct device *kdev;
	int i =  0;

	if (!sde_kms || !sde_kms->dev) {
		DRM_ERROR("invalid input\n");
		return;
	}

	dev = sde_kms->dev;
	kdev = dev->primary->kdev;

	event_string = kzalloc(SZ_4K, GFP_KERNEL);
	if (!event_string) {
		SDE_ERROR("failed to allocate event string\n");
		return;
	}

	for (i = 0; i < MAX_BLOCKS; i++) {
		if (sde_kms->splash_info.reserved_pipe_info[i] != 0xFFFFFFFF)
			snprintf(event_string, SZ_4K, "pipe%d avialable",
				sde_kms->splash_info.reserved_pipe_info[i]);
	}

	DRM_INFO("generating pipe update event[%s]", event_string);

	envp[0] = event_string;
	envp[1] = NULL;

	kobject_uevent_env(&kdev->kobj, KOBJ_CHANGE, envp);

	kfree(event_string);
}

static void _sde_splash_get_connector_ref_cnt(struct sde_splash_info *sinfo,
					u32 *hdmi_cnt, u32 *dsi_cnt)
{
@@ -377,12 +415,12 @@ void sde_splash_destroy(struct sde_splash_info *sinfo,
}

/*
 * sde_splash_parse_dt.
 * sde_splash_parse_memory_dt.
 * In the function, it will parse and reserve two kinds of memory node.
 * First is to get the reserved memory for display buffers.
 * Second is to get the memory node LK's code stack is running on.
 * Second is to get the memory node which LK's heap memory is running on.
 */
int sde_splash_parse_dt(struct drm_device *dev)
int sde_splash_parse_memory_dt(struct drm_device *dev)
{
	struct msm_drm_private *priv = dev->dev_private;
	struct sde_kms *sde_kms;
@@ -409,6 +447,79 @@ int sde_splash_parse_dt(struct drm_device *dev)
	return 0;
}

static inline u32 _sde_splash_parse_sspp_id(struct sde_mdss_cfg *cfg,
					const char *name)
{
	int i;

	for (i = 0; i < cfg->sspp_count; i++) {
		if (!strcmp(cfg->sspp[i].name, name))
			return cfg->sspp[i].id;
	}

	return 0;
}

int sde_splash_parse_reserved_plane_dt(struct sde_splash_info *splash_info,
				struct sde_mdss_cfg *cfg)
{
	struct device_node *parent, *node;
	struct property *prop;
	const char *cname;
	int ret = 0, i = 0;

	if (!splash_info || !cfg)
		return -EINVAL;

	parent = of_find_node_by_path("/qcom,sde-reserved-plane");
	if (!parent)
		return -EINVAL;

	for (i = 0; i < MAX_BLOCKS; i++)
		splash_info->reserved_pipe_info[i] = 0xFFFFFFFF;

	i = 0;
	for_each_child_of_node(parent, node) {
		if (i >= MAX_BLOCKS) {
			SDE_ERROR("num of nodes(%d) is bigger than max(%d)\n",
				i, MAX_BLOCKS);
			ret = -EINVAL;
			goto parent_node_err;
		}

		of_property_for_each_string(node, "qcom,plane-name",
					prop, cname)
		splash_info->reserved_pipe_info[i] =
					_sde_splash_parse_sspp_id(cfg, cname);
		i++;
	}

parent_node_err:
	of_node_put(parent);

	return ret;
}

bool sde_splash_query_plane_is_reserved(struct sde_splash_info *sinfo,
					uint32_t pipe)
{
	int i = 0;

	if (!sinfo)
		return false;

	/* early return if no splash is enabled */
	if (!sinfo->handoff)
		return false;

	for (i = 0; i < MAX_BLOCKS; i++) {
		if (sinfo->reserved_pipe_info[i] == pipe)
			return true;
	}

	return false;
}

int sde_splash_get_handoff_status(struct msm_kms *kms)
{
	uint32_t intf_sel = 0;
@@ -651,6 +762,8 @@ int sde_splash_clean_up_free_resource(struct msm_kms *kms,
		sde_power_data_bus_bandwidth_ctrl(phandle,
				sde_kms->core_client, false);

		_sde_splash_sent_pipe_update_uevent(sde_kms);

		mutex_unlock(&sde_splash_lock);
		return 0;
	}
Loading