Commit 440d2c7b authored by Maxime Ripard's avatar Maxime Ripard

drm/sun4i: backend: Handle the SAT

The A33 has an block called SAT that is part of the backend that needs to
be clocked and out of reset to be able for the backend to operate properly.

Extend the binding to have the SAT resources listed, and claim them when
the backend probes.
Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: default avatarChen-Yu Tsai <wens@csie.org>
parent 4a408f1f
...@@ -76,6 +76,14 @@ Required properties: ...@@ -76,6 +76,14 @@ Required properties:
Documentation/devicetree/bindings/media/video-interfaces.txt. The Documentation/devicetree/bindings/media/video-interfaces.txt. The
first port should be the input endpoints, the second one the output first port should be the input endpoints, the second one the output
On the A33, some additional properties are required:
- reg needs to have an additional region corresponding to the SAT
- reg-names need to be set, with "be" and "sat"
- clocks and clock-names need to have a phandle to the SAT bus
clocks, whose name will be "sat"
- resets and reset-names need to have a phandle to the SAT bus
resets, whose name will be "sat"
Display Engine Frontend Display Engine Frontend
----------------------- -----------------------
......
...@@ -217,6 +217,51 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, ...@@ -217,6 +217,51 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
} }
EXPORT_SYMBOL(sun4i_backend_update_layer_buffer); EXPORT_SYMBOL(sun4i_backend_update_layer_buffer);
static int sun4i_backend_init_sat(struct device *dev) {
struct sun4i_backend *backend = dev_get_drvdata(dev);
int ret;
backend->sat_reset = devm_reset_control_get(dev, "sat");
if (IS_ERR(backend->sat_reset)) {
dev_err(dev, "Couldn't get the SAT reset line\n");
return PTR_ERR(backend->sat_reset);
}
ret = reset_control_deassert(backend->sat_reset);
if (ret) {
dev_err(dev, "Couldn't deassert the SAT reset line\n");
return ret;
}
backend->sat_clk = devm_clk_get(dev, "sat");
if (IS_ERR(backend->sat_clk)) {
dev_err(dev, "Couldn't get our SAT clock\n");
ret = PTR_ERR(backend->sat_clk);
goto err_assert_reset;
}
ret = clk_prepare_enable(backend->sat_clk);
if (ret) {
dev_err(dev, "Couldn't enable the SAT clock\n");
return ret;
}
return 0;
err_assert_reset:
reset_control_assert(backend->sat_reset);
return ret;
}
static int sun4i_backend_free_sat(struct device *dev) {
struct sun4i_backend *backend = dev_get_drvdata(dev);
clk_disable_unprepare(backend->sat_clk);
reset_control_assert(backend->sat_reset);
return 0;
}
static struct regmap_config sun4i_backend_regmap_config = { static struct regmap_config sun4i_backend_regmap_config = {
.reg_bits = 32, .reg_bits = 32,
.val_bits = 32, .val_bits = 32,
...@@ -291,6 +336,15 @@ static int sun4i_backend_bind(struct device *dev, struct device *master, ...@@ -291,6 +336,15 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
} }
clk_prepare_enable(backend->ram_clk); clk_prepare_enable(backend->ram_clk);
if (of_device_is_compatible(dev->of_node,
"allwinner,sun8i-a33-display-backend")) {
ret = sun4i_backend_init_sat(dev);
if (ret) {
dev_err(dev, "Couldn't init SAT resources\n");
goto err_disable_ram_clk;
}
}
/* Reset the registers */ /* Reset the registers */
for (i = 0x800; i < 0x1000; i += 4) for (i = 0x800; i < 0x1000; i += 4)
regmap_write(backend->regs, i, 0); regmap_write(backend->regs, i, 0);
...@@ -306,6 +360,8 @@ static int sun4i_backend_bind(struct device *dev, struct device *master, ...@@ -306,6 +360,8 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
return 0; return 0;
err_disable_ram_clk:
clk_disable_unprepare(backend->ram_clk);
err_disable_mod_clk: err_disable_mod_clk:
clk_disable_unprepare(backend->mod_clk); clk_disable_unprepare(backend->mod_clk);
err_disable_bus_clk: err_disable_bus_clk:
...@@ -320,6 +376,10 @@ static void sun4i_backend_unbind(struct device *dev, struct device *master, ...@@ -320,6 +376,10 @@ static void sun4i_backend_unbind(struct device *dev, struct device *master,
{ {
struct sun4i_backend *backend = dev_get_drvdata(dev); struct sun4i_backend *backend = dev_get_drvdata(dev);
if (of_device_is_compatible(dev->of_node,
"allwinner,sun8i-a33-display-backend"))
sun4i_backend_free_sat(dev);
clk_disable_unprepare(backend->ram_clk); clk_disable_unprepare(backend->ram_clk);
clk_disable_unprepare(backend->mod_clk); clk_disable_unprepare(backend->mod_clk);
clk_disable_unprepare(backend->bus_clk); clk_disable_unprepare(backend->bus_clk);
......
...@@ -146,6 +146,9 @@ struct sun4i_backend { ...@@ -146,6 +146,9 @@ struct sun4i_backend {
struct clk *bus_clk; struct clk *bus_clk;
struct clk *mod_clk; struct clk *mod_clk;
struct clk *ram_clk; struct clk *ram_clk;
struct clk *sat_clk;
struct reset_control *sat_reset;
}; };
void sun4i_backend_apply_color_correction(struct sun4i_backend *backend); void sun4i_backend_apply_color_correction(struct sun4i_backend *backend);
......
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