drm/sun4i: backend: Handle the SAT
authorMaxime Ripard <maxime.ripard@free-electrons.com>
Tue, 6 Sep 2016 13:23:03 +0000 (15:23 +0200)
committerMaxime Ripard <maxime.ripard@free-electrons.com>
Thu, 8 Sep 2016 07:29:42 +0000 (09:29 +0200)
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: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Chen-Yu Tsai <wens@csie.org>
Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
drivers/gpu/drm/sun4i/sun4i_backend.c
drivers/gpu/drm/sun4i/sun4i_backend.h

index 46d8c570aa11efb055b5bb514e544c96eca53819..abe9e9d8b7852ae324c3a2b5dad15382be966754 100644 (file)
@@ -76,6 +76,14 @@ Required properties:
   Documentation/devicetree/bindings/media/video-interfaces.txt. The
   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
 -----------------------
 
index 9bfd2e45fceb055f6e7940042b2afea3bfb69ce5..91a702225ded49550131520b5aef376cfbe0c779 100644 (file)
@@ -217,6 +217,51 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
 }
 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 = {
        .reg_bits       = 32,
        .val_bits       = 32,
@@ -291,6 +336,15 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
        }
        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 */
        for (i = 0x800; i < 0x1000; i += 4)
                regmap_write(backend->regs, i, 0);
@@ -306,6 +360,8 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
 
        return 0;
 
+err_disable_ram_clk:
+       clk_disable_unprepare(backend->ram_clk);
 err_disable_mod_clk:
        clk_disable_unprepare(backend->mod_clk);
 err_disable_bus_clk:
@@ -320,6 +376,10 @@ static void sun4i_backend_unbind(struct device *dev, struct device *master,
 {
        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->mod_clk);
        clk_disable_unprepare(backend->bus_clk);
index 7070bb3434e5de73dca8e4d8f805670895e49cdc..e00718627748491eae0bd0de2b055c7f761089ca 100644 (file)
@@ -146,6 +146,9 @@ struct sun4i_backend {
        struct clk              *bus_clk;
        struct clk              *mod_clk;
        struct clk              *ram_clk;
+
+       struct clk              *sat_clk;
+       struct reset_control    *sat_reset;
 };
 
 void sun4i_backend_apply_color_correction(struct sun4i_backend *backend);