aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen-Yu Tsai <wens@csie.org>2017-04-21 04:38:50 -0400
committerMaxime Ripard <maxime.ripard@free-electrons.com>2017-05-14 02:27:41 -0400
commit80a58240efef576ef909f7d99180ae2a70ca68a5 (patch)
tree579be060ea896da911715c4e583b5a465181f3c4
parentde120d092eeb69b5285586a9fd33b1778ce9ee27 (diff)
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: Chen-Yu Tsai <wens@csie.org> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.c6
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.h4
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_drv.c2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_drv.h5
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.c14
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.h4
6 files changed, 30 insertions, 5 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index d660741ba475..95a77c6a9161 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -19,6 +19,7 @@
19#include <drm/drm_plane_helper.h> 19#include <drm/drm_plane_helper.h>
20 20
21#include <linux/component.h> 21#include <linux/component.h>
22#include <linux/list.h>
22#include <linux/reset.h> 23#include <linux/reset.h>
23 24
24#include "sun4i_backend.h" 25#include "sun4i_backend.h"
@@ -310,7 +311,6 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
310 if (!backend) 311 if (!backend)
311 return -ENOMEM; 312 return -ENOMEM;
312 dev_set_drvdata(dev, backend); 313 dev_set_drvdata(dev, backend);
313 drv->backend = backend;
314 314
315 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 315 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
316 regs = devm_ioremap_resource(dev, res); 316 regs = devm_ioremap_resource(dev, res);
@@ -369,6 +369,8 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
369 } 369 }
370 } 370 }
371 371
372 list_add_tail(&backend->list, &drv->backend_list);
373
372 /* Reset the registers */ 374 /* Reset the registers */
373 for (i = 0x800; i < 0x1000; i += 4) 375 for (i = 0x800; i < 0x1000; i += 4)
374 regmap_write(backend->regs, i, 0); 376 regmap_write(backend->regs, i, 0);
@@ -400,6 +402,8 @@ static void sun4i_backend_unbind(struct device *dev, struct device *master,
400{ 402{
401 struct sun4i_backend *backend = dev_get_drvdata(dev); 403 struct sun4i_backend *backend = dev_get_drvdata(dev);
402 404
405 list_del(&backend->list);
406
403 if (of_device_is_compatible(dev->of_node, 407 if (of_device_is_compatible(dev->of_node,
404 "allwinner,sun8i-a33-display-backend")) 408 "allwinner,sun8i-a33-display-backend"))
405 sun4i_backend_free_sat(dev); 409 sun4i_backend_free_sat(dev);
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h
index 83e63cc702b4..9c8287309c65 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.h
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.h
@@ -14,6 +14,7 @@
14#define _SUN4I_BACKEND_H_ 14#define _SUN4I_BACKEND_H_
15 15
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/list.h>
17#include <linux/regmap.h> 18#include <linux/regmap.h>
18#include <linux/reset.h> 19#include <linux/reset.h>
19 20
@@ -149,6 +150,9 @@ struct sun4i_backend {
149 150
150 struct clk *sat_clk; 151 struct clk *sat_clk;
151 struct reset_control *sat_reset; 152 struct reset_control *sat_reset;
153
154 /* Backend list management */
155 struct list_head list;
152}; 156};
153 157
154void sun4i_backend_apply_color_correction(struct sun4i_backend *backend); 158void sun4i_backend_apply_color_correction(struct sun4i_backend *backend);
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 8ddd72cd5873..c52f7a9eb045 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -91,6 +91,8 @@ static int sun4i_drv_bind(struct device *dev)
91 goto free_drm; 91 goto free_drm;
92 } 92 }
93 drm->dev_private = drv; 93 drm->dev_private = drv;
94 INIT_LIST_HEAD(&drv->backend_list);
95 INIT_LIST_HEAD(&drv->tcon_list);
94 96
95 ret = of_reserved_mem_device_init(dev); 97 ret = of_reserved_mem_device_init(dev);
96 if (ret && ret != -ENODEV) { 98 if (ret && ret != -ENODEV) {
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.h b/drivers/gpu/drm/sun4i/sun4i_drv.h
index 5df50126ff52..250c29017ef5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.h
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.h
@@ -14,11 +14,12 @@
14#define _SUN4I_DRV_H_ 14#define _SUN4I_DRV_H_
15 15
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/list.h>
17#include <linux/regmap.h> 18#include <linux/regmap.h>
18 19
19struct sun4i_drv { 20struct sun4i_drv {
20 struct sun4i_backend *backend; 21 struct list_head backend_list;
21 struct sun4i_tcon *tcon; 22 struct list_head tcon_list;
22 23
23 struct drm_fbdev_cma *fbdev; 24 struct drm_fbdev_cma *fbdev;
24}; 25};
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 9a83a85529ac..5adb643ed41d 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -25,6 +25,7 @@
25#include <linux/regmap.h> 25#include <linux/regmap.h>
26#include <linux/reset.h> 26#include <linux/reset.h>
27 27
28#include "sun4i_backend.h"
28#include "sun4i_crtc.h" 29#include "sun4i_crtc.h"
29#include "sun4i_dotclock.h" 30#include "sun4i_dotclock.h"
30#include "sun4i_drv.h" 31#include "sun4i_drv.h"
@@ -407,14 +408,18 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
407{ 408{
408 struct drm_device *drm = data; 409 struct drm_device *drm = data;
409 struct sun4i_drv *drv = drm->dev_private; 410 struct sun4i_drv *drv = drm->dev_private;
411 struct sun4i_backend *backend;
410 struct sun4i_tcon *tcon; 412 struct sun4i_tcon *tcon;
411 int ret; 413 int ret;
412 414
415 /* Wait for a backend to be registered */
416 if (list_empty(&drv->backend_list))
417 return -EPROBE_DEFER;
418
413 tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL); 419 tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL);
414 if (!tcon) 420 if (!tcon)
415 return -ENOMEM; 421 return -ENOMEM;
416 dev_set_drvdata(dev, tcon); 422 dev_set_drvdata(dev, tcon);
417 drv->tcon = tcon;
418 tcon->drm = drm; 423 tcon->drm = drm;
419 tcon->dev = dev; 424 tcon->dev = dev;
420 tcon->quirks = of_device_get_match_data(dev); 425 tcon->quirks = of_device_get_match_data(dev);
@@ -459,7 +464,9 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
459 goto err_free_dotclock; 464 goto err_free_dotclock;
460 } 465 }
461 466
462 tcon->crtc = sun4i_crtc_init(drm, drv->backend, tcon); 467 backend = list_first_entry(&drv->backend_list,
468 struct sun4i_backend, list);
469 tcon->crtc = sun4i_crtc_init(drm, backend, tcon);
463 if (IS_ERR(tcon->crtc)) { 470 if (IS_ERR(tcon->crtc)) {
464 dev_err(dev, "Couldn't create our CRTC\n"); 471 dev_err(dev, "Couldn't create our CRTC\n");
465 ret = PTR_ERR(tcon->crtc); 472 ret = PTR_ERR(tcon->crtc);
@@ -470,6 +477,8 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
470 if (ret < 0) 477 if (ret < 0)
471 goto err_free_clocks; 478 goto err_free_clocks;
472 479
480 list_add_tail(&tcon->list, &drv->tcon_list);
481
473 return 0; 482 return 0;
474 483
475err_free_dotclock: 484err_free_dotclock:
@@ -486,6 +495,7 @@ static void sun4i_tcon_unbind(struct device *dev, struct device *master,
486{ 495{
487 struct sun4i_tcon *tcon = dev_get_drvdata(dev); 496 struct sun4i_tcon *tcon = dev_get_drvdata(dev);
488 497
498 list_del(&tcon->list);
489 sun4i_dclk_free(tcon); 499 sun4i_dclk_free(tcon);
490 sun4i_tcon_free_clocks(tcon); 500 sun4i_tcon_free_clocks(tcon);
491} 501}
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index f636343a935d..1bda4d183eec 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -17,6 +17,7 @@
17#include <drm/drm_crtc.h> 17#include <drm/drm_crtc.h>
18 18
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/list.h>
20#include <linux/reset.h> 21#include <linux/reset.h>
21 22
22#define SUN4I_TCON_GCTL_REG 0x0 23#define SUN4I_TCON_GCTL_REG 0x0
@@ -172,6 +173,9 @@ struct sun4i_tcon {
172 173
173 /* Associated crtc */ 174 /* Associated crtc */
174 struct sun4i_crtc *crtc; 175 struct sun4i_crtc *crtc;
176
177 /* TCON list management */
178 struct list_head list;
175}; 179};
176 180
177struct drm_bridge *sun4i_tcon_find_bridge(struct device_node *node); 181struct drm_bridge *sun4i_tcon_find_bridge(struct device_node *node);