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

Commit 5e03abc5 authored by Benjamin Gaignard's avatar Benjamin Gaignard
Browse files

drm: sti: enable auxiliary CRTC



For stih407 SoC enable the second mixer to get two CRTC.
Allow GPD planes and encoders to be connected to this new CRTC.
Cursor plane can only be set on first CRTC.
GPD clocks needed change the parent clock depending on which
CRTC GPD are used.

Signed-off-by: default avatarBenjamin Gaignard <benjamin.gaignard@linaro.org>
parent 7f2d479c
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -24,14 +24,15 @@
 * stiH407 compositor properties
 */
struct sti_compositor_data stih407_compositor_data = {
	.nb_subdev = 6,
	.nb_subdev = 7,
	.subdev_desc = {
			{STI_GPD_SUBDEV, (int)STI_GDP_0, 0x100},
			{STI_GPD_SUBDEV, (int)STI_GDP_1, 0x200},
			{STI_GPD_SUBDEV, (int)STI_GDP_2, 0x300},
			{STI_GPD_SUBDEV, (int)STI_GDP_3, 0x400},
			{STI_VID_SUBDEV, (int)STI_VID_0, 0x700},
			{STI_MIXER_MAIN_SUBDEV, STI_MIXER_MAIN, 0xC00}
			{STI_MIXER_MAIN_SUBDEV, STI_MIXER_MAIN, 0xC00},
			{STI_MIXER_AUX_SUBDEV, STI_MIXER_AUX, 0xD00},
	},
};

@@ -102,21 +103,21 @@ static int sti_compositor_bind(struct device *dev, struct device *master,
			enum sti_layer_type type = desc & STI_LAYER_TYPE_MASK;
			enum drm_plane_type plane_type = DRM_PLANE_TYPE_OVERLAY;

			if (compo->mixer[crtc])
			if (crtc < compo->nb_mixers)
				plane_type = DRM_PLANE_TYPE_PRIMARY;

			switch (type) {
			case STI_CUR:
				cursor = sti_drm_plane_init(drm_dev,
						compo->layer[i],
						(1 << crtc) - 1,
						DRM_PLANE_TYPE_CURSOR);
						1, DRM_PLANE_TYPE_CURSOR);
				break;
			case STI_GDP:
			case STI_VID:
				primary = sti_drm_plane_init(drm_dev,
						compo->layer[i],
						(1 << crtc) - 1, plane_type);
						(1 << compo->nb_mixers) - 1,
						plane_type);
				plane++;
				break;
			case STI_BCK:
@@ -124,7 +125,7 @@ static int sti_compositor_bind(struct device *dev, struct device *master,
			}

			/* The first planes are reserved for primary planes*/
			if (compo->mixer[crtc]) {
			if (crtc < compo->nb_mixers) {
				sti_drm_crtc_init(drm_dev, compo->mixer[crtc],
						primary, cursor);
				crtc++;
+0 −2
Original line number Diff line number Diff line
@@ -64,7 +64,6 @@ struct sti_compositor_data {
 * @layer: array of layers
 * @nb_mixers: number of mixers for this compositor
 * @nb_layers: number of layers (GDP,VID,...) for this compositor
 * @enable: true if compositor is enable else false
 * @vtg_vblank_nb: callback for VTG VSYNC notification
 */
struct sti_compositor {
@@ -83,7 +82,6 @@ struct sti_compositor {
	struct sti_layer *layer[STI_MAX_LAYER];
	int nb_mixers;
	int nb_layers;
	bool enable;
	struct notifier_block vtg_vblank_nb;
};

+4 −3
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ static void sti_drm_crtc_prepare(struct drm_crtc *crtc)
	struct device *dev = mixer->dev;
	struct sti_compositor *compo = dev_get_drvdata(dev);

	compo->enable = true;
	mixer->enabled = true;

	/* Prepare and enable the compo IP clock */
	if (mixer->id == STI_MIXER_MAIN) {
@@ -200,7 +200,7 @@ static void sti_drm_crtc_disable(struct drm_crtc *crtc)
	struct sti_compositor *compo = dev_get_drvdata(dev);
	struct sti_layer *layer;

	if (!compo->enable)
	if (!mixer->enabled)
		return;

	DRM_DEBUG_KMS("CRTC:%d (%s)\n", crtc->base.id, sti_mixer_to_str(mixer));
@@ -237,7 +237,7 @@ static void sti_drm_crtc_disable(struct drm_crtc *crtc)
		clk_disable_unprepare(compo->clk_compo_aux);
	}

	compo->enable = false;
	mixer->enabled = false;
}

static struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
@@ -399,6 +399,7 @@ bool sti_drm_crtc_is_main(struct drm_crtc *crtc)

	return false;
}
EXPORT_SYMBOL(sti_drm_crtc_is_main);

int sti_drm_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer,
		struct drm_plane *primary, struct drm_plane *cursor)
+23 −0
Original line number Diff line number Diff line
@@ -83,6 +83,8 @@ struct sti_gdp_node_list {
 *
 * @layer:		layer structure
 * @clk_pix:            pixel clock for the current gdp
 * @clk_main_parent:    gdp parent clock if main path used
 * @clk_aux_parent:     gdp parent clock if aux path used
 * @vtg_field_nb:       callback for VTG FIELD (top or bottom) notification
 * @is_curr_top:        true if the current node processed is the top field
 * @node_list:		array of node list
@@ -90,6 +92,8 @@ struct sti_gdp_node_list {
struct sti_gdp {
	struct sti_layer layer;
	struct clk *clk_pix;
	struct clk *clk_main_parent;
	struct clk *clk_aux_parent;
	struct notifier_block vtg_field_nb;
	bool is_curr_top;
	struct sti_gdp_node_list node_list[GDP_NODE_NB_BANK];
@@ -307,6 +311,17 @@ static int sti_gdp_prepare_layer(struct sti_layer *layer, bool first_prepare)

		/* Set and enable gdp clock */
		if (gdp->clk_pix) {
			struct clk *clkp;
			/* According to the mixer used, the gdp pixel clock
			 * should have a different parent clock. */
			if (layer->mixer_id == STI_MIXER_MAIN)
				clkp = gdp->clk_main_parent;
			else
				clkp = gdp->clk_aux_parent;

			if (clkp)
				clk_set_parent(gdp->clk_pix, clkp);

			res = clk_set_rate(gdp->clk_pix, rate);
			if (res < 0) {
				DRM_ERROR("Cannot set rate (%dHz) for gdp\n",
@@ -521,6 +536,14 @@ static void sti_gdp_init(struct sti_layer *layer)
		gdp->clk_pix = devm_clk_get(layer->dev, clk_name);
		if (IS_ERR(gdp->clk_pix))
			DRM_ERROR("Cannot get %s clock\n", clk_name);

		gdp->clk_main_parent = devm_clk_get(layer->dev, "main_parent");
		if (IS_ERR(gdp->clk_main_parent))
			DRM_ERROR("Cannot get main_parent clock\n");

		gdp->clk_aux_parent = devm_clk_get(layer->dev, "aux_parent");
		if (IS_ERR(gdp->clk_aux_parent))
			DRM_ERROR("Cannot get aux_parent clock\n");
	}
}

+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
 * @id: id of the mixer
 * @drm_crtc: crtc object link to the mixer
 * @pending_event: set if a flip event is pending on crtc
 * @enabled: to know if the mixer is active or not
 */
struct sti_mixer {
	struct device *dev;
@@ -30,6 +31,7 @@ struct sti_mixer {
	int id;
	struct drm_crtc	drm_crtc;
	struct drm_pending_vblank_event *pending_event;
	bool enabled;
};

const char *sti_mixer_to_str(struct sti_mixer *mixer);
Loading