Commit 46cce6da authored by Chen-Yu Tsai's avatar Chen-Yu Tsai Committed by Maxime Ripard

drm/sun4i: Initialize crtc from tcon bind function

The tcon provides part of the functionality of the crtc, and also
provides the device node for the output port of the crtc. To be able
to use drm_of_find_possible_crtcs(), all crtc must be initialized before
any downstream encoders. The other part of the crtc is the display
backend.

The Rockchip DRM driver does this by first binding all vops, which is
their crtc, and this step also creates the crtc objects. Then all
remaining hardware components are bound. With the Allwinner display
pipeline, we have multiple components comprising the crtc, and varying
depths of the display pipeline. Since components are added with a depth
first search of the of_graph, we can initialize the crtc object within
the tcon bind function. Since the backend precedes the tcon, and the
backends cannot be muxed or switched around, we can be sure that the
associated backend is already initialized.

This patch also moves the crtc pointer from the main drm_device data to
the tcon device data. Besides the crtc callbacks, the crtc structure is
only used within the tcon driver to signal vblank events from its
interrupt handler.

As the crtc and layer bits are now called from the tcon bits, we must
move them from the sun4i-drm module to the sun4i-tcon module to avoid
circular dependencies between the two modules. This is because sun4i-drm
also calls into sun4i-tcon.
Signed-off-by: default avatarChen-Yu Tsai <wens@csie.org>
Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
parent b3f266e4
sun4i-drm-y += sun4i_crtc.o
sun4i-drm-y += sun4i_drv.o sun4i-drm-y += sun4i_drv.o
sun4i-drm-y += sun4i_framebuffer.o sun4i-drm-y += sun4i_framebuffer.o
sun4i-drm-y += sun4i_layer.o
sun4i-tcon-y += sun4i_tcon.o sun4i-tcon-y += sun4i_tcon.o
sun4i-tcon-y += sun4i_rgb.o sun4i-tcon-y += sun4i_rgb.o
sun4i-tcon-y += sun4i_dotclock.o sun4i-tcon-y += sun4i_dotclock.o
sun4i-tcon-y += sun4i_crtc.o
sun4i-tcon-y += sun4i_layer.o
obj-$(CONFIG_DRM_SUN4I) += sun4i-drm.o sun4i-tcon.o obj-$(CONFIG_DRM_SUN4I) += sun4i-drm.o sun4i-tcon.o
obj-$(CONFIG_DRM_SUN4I) += sun4i_backend.o obj-$(CONFIG_DRM_SUN4I) += sun4i_backend.o
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_of.h> #include <drm/drm_of.h>
#include "sun4i_crtc.h"
#include "sun4i_drv.h" #include "sun4i_drv.h"
#include "sun4i_framebuffer.h" #include "sun4i_framebuffer.h"
#include "sun4i_tcon.h" #include "sun4i_tcon.h"
...@@ -115,13 +114,6 @@ static int sun4i_drv_bind(struct device *dev) ...@@ -115,13 +114,6 @@ static int sun4i_drv_bind(struct device *dev)
goto cleanup_mode_config; goto cleanup_mode_config;
} }
/* Create our CRTC */
drv->crtc = sun4i_crtc_init(drm);
if (IS_ERR(drv->crtc)) {
dev_err(drm->dev, "Couldn't create the CRTC\n");
ret = PTR_ERR(drv->crtc);
goto cleanup_mode_config;
}
drm->irq_enabled = true; drm->irq_enabled = true;
/* Remove early framebuffers (ie. simplefb) */ /* Remove early framebuffers (ie. simplefb) */
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
struct sun4i_drv { struct sun4i_drv {
struct sun4i_backend *backend; struct sun4i_backend *backend;
struct sun4i_crtc *crtc;
struct sun4i_tcon *tcon; struct sun4i_tcon *tcon;
struct drm_plane *primary; struct drm_plane *primary;
......
...@@ -290,8 +290,7 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private) ...@@ -290,8 +290,7 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private)
{ {
struct sun4i_tcon *tcon = private; struct sun4i_tcon *tcon = private;
struct drm_device *drm = tcon->drm; struct drm_device *drm = tcon->drm;
struct sun4i_drv *drv = drm->dev_private; struct sun4i_crtc *scrtc = tcon->crtc;
struct sun4i_crtc *scrtc = drv->crtc;
unsigned int status; unsigned int status;
regmap_read(tcon->regs, SUN4I_TCON_GINT0_REG, &status); regmap_read(tcon->regs, SUN4I_TCON_GINT0_REG, &status);
...@@ -524,6 +523,13 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, ...@@ -524,6 +523,13 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
goto err_free_clocks; goto err_free_clocks;
} }
tcon->crtc = sun4i_crtc_init(drm);
if (IS_ERR(tcon->crtc)) {
dev_err(dev, "Couldn't create our CRTC\n");
ret = PTR_ERR(tcon->crtc);
goto err_free_clocks;
}
ret = sun4i_rgb_init(drm); ret = sun4i_rgb_init(drm);
if (ret < 0) if (ret < 0)
goto err_free_clocks; goto err_free_clocks;
......
...@@ -169,6 +169,9 @@ struct sun4i_tcon { ...@@ -169,6 +169,9 @@ struct sun4i_tcon {
/* Platform adjustments */ /* Platform adjustments */
const struct sun4i_tcon_quirks *quirks; const struct sun4i_tcon_quirks *quirks;
/* Associated crtc */
struct sun4i_crtc *crtc;
}; };
struct drm_bridge *sun4i_tcon_find_bridge(struct device_node *node); struct drm_bridge *sun4i_tcon_find_bridge(struct device_node *node);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment