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

Commit 80a58240 authored by Chen-Yu Tsai's avatar Chen-Yu Tsai Committed by Maxime Ripard
Browse files

drm/sun4i: Use lists to track registered display backends and TCONs



To support multiple display pipelines, we need to keep track of the
multiple display backends and TCONs registered with the driver.

Switch to lists to track registered components. Components are only
appended to their respective lists if the bind process was successful.
The TCON bind function now defers if a backend was not registered.

Signed-off-by: default avatarChen-Yu Tsai <wens@csie.org>
Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
parent de120d09
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <drm/drm_plane_helper.h>

#include <linux/component.h>
#include <linux/list.h>
#include <linux/reset.h>

#include "sun4i_backend.h"
@@ -310,7 +311,6 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
	if (!backend)
		return -ENOMEM;
	dev_set_drvdata(dev, backend);
	drv->backend = backend;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	regs = devm_ioremap_resource(dev, res);
@@ -369,6 +369,8 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
		}
	}

	list_add_tail(&backend->list, &drv->backend_list);

	/* Reset the registers */
	for (i = 0x800; i < 0x1000; i += 4)
		regmap_write(backend->regs, i, 0);
@@ -400,6 +402,8 @@ static void sun4i_backend_unbind(struct device *dev, struct device *master,
{
	struct sun4i_backend *backend = dev_get_drvdata(dev);

	list_del(&backend->list);

	if (of_device_is_compatible(dev->of_node,
				    "allwinner,sun8i-a33-display-backend"))
		sun4i_backend_free_sat(dev);
+4 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#define _SUN4I_BACKEND_H_

#include <linux/clk.h>
#include <linux/list.h>
#include <linux/regmap.h>
#include <linux/reset.h>

@@ -149,6 +150,9 @@ struct sun4i_backend {

	struct clk		*sat_clk;
	struct reset_control	*sat_reset;

	/* Backend list management */
	struct list_head	list;
};

void sun4i_backend_apply_color_correction(struct sun4i_backend *backend);
+2 −0
Original line number Diff line number Diff line
@@ -91,6 +91,8 @@ static int sun4i_drv_bind(struct device *dev)
		goto free_drm;
	}
	drm->dev_private = drv;
	INIT_LIST_HEAD(&drv->backend_list);
	INIT_LIST_HEAD(&drv->tcon_list);

	ret = of_reserved_mem_device_init(dev);
	if (ret && ret != -ENODEV) {
+3 −2
Original line number Diff line number Diff line
@@ -14,11 +14,12 @@
#define _SUN4I_DRV_H_

#include <linux/clk.h>
#include <linux/list.h>
#include <linux/regmap.h>

struct sun4i_drv {
	struct sun4i_backend	*backend;
	struct sun4i_tcon	*tcon;
	struct list_head	backend_list;
	struct list_head	tcon_list;

	struct drm_fbdev_cma	*fbdev;
};
+12 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/regmap.h>
#include <linux/reset.h>

#include "sun4i_backend.h"
#include "sun4i_crtc.h"
#include "sun4i_dotclock.h"
#include "sun4i_drv.h"
@@ -407,14 +408,18 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
{
	struct drm_device *drm = data;
	struct sun4i_drv *drv = drm->dev_private;
	struct sun4i_backend *backend;
	struct sun4i_tcon *tcon;
	int ret;

	/* Wait for a backend to be registered */
	if (list_empty(&drv->backend_list))
		return -EPROBE_DEFER;

	tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL);
	if (!tcon)
		return -ENOMEM;
	dev_set_drvdata(dev, tcon);
	drv->tcon = tcon;
	tcon->drm = drm;
	tcon->dev = dev;
	tcon->quirks = of_device_get_match_data(dev);
@@ -459,7 +464,9 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
		goto err_free_dotclock;
	}

	tcon->crtc = sun4i_crtc_init(drm, drv->backend, tcon);
	backend = list_first_entry(&drv->backend_list,
				   struct sun4i_backend, list);
	tcon->crtc = sun4i_crtc_init(drm, backend, tcon);
	if (IS_ERR(tcon->crtc)) {
		dev_err(dev, "Couldn't create our CRTC\n");
		ret = PTR_ERR(tcon->crtc);
@@ -470,6 +477,8 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
	if (ret < 0)
		goto err_free_clocks;

	list_add_tail(&tcon->list, &drv->tcon_list);

	return 0;

err_free_dotclock:
@@ -486,6 +495,7 @@ static void sun4i_tcon_unbind(struct device *dev, struct device *master,
{
	struct sun4i_tcon *tcon = dev_get_drvdata(dev);

	list_del(&tcon->list);
	sun4i_dclk_free(tcon);
	sun4i_tcon_free_clocks(tcon);
}
Loading