
The patch enables/disables the LCD domain clock when the device is probed/removed.
To get the LCD domain clock, the device tree had to be changed. In the Beaglebone device tree of the most recent Linux kernels, the LCD controller node is the child of a node that the documentation explains to be an interconnect module with one or more devices connected to it, which manages, among other things, even the clocks.
target-module@e000 { /* 0x4830e000, ap 72 4a.0 */ compatible = "ti,sysc-omap4", "ti,sysc"; reg = <0xe000 0x4>, <0xe054 0x4>; reg-names = "rev", "sysc"; ti,sysc-midle = <SYSC_IDLE_FORCE>, <SYSC_IDLE_NO>, <SYSC_IDLE_SMART>; ti,sysc-sidle = <SYSC_IDLE_FORCE>, <SYSC_IDLE_NO>, <SYSC_IDLE_SMART>; /* Domains (P, C): per_pwrdm, lcdc_clkdm */ clocks = <&lcdc_clkctrl AM3_LCDC_LCDC_CLKCTRL 0>; clock-names = "fck"; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0xe000 0x1000>;
lcdc: lcdc@0 { compatible = "ti,am33xx-tilcdc"; reg = <0x0 0x1000>; interrupts = <36>; status = "disabled"; }; };
This shows that the domain clock reference is missing in the U-Boot device tree and that replicating the most recent kernels structure in U-Boot is now to be avoided. Since the LCD controller node is not the child of any interconnection node in the current device tree, I added the domain clock reference inside the LCD controller node. I think getting the domain clock from the device tree and using the driver model API is still an improvement. In the future, when possible, we can move the domain clock in the interconnection module created for the LCD controller node.
Signed-off-by: Dario Binacchi dariobin@libero.it ---
arch/arm/dts/am33xx.dtsi | 3 +++ arch/arm/mach-omap2/am33xx/clock_am33xx.c | 2 +- drivers/video/am335x-fb.c | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/am33xx.dtsi b/arch/arm/dts/am33xx.dtsi index fa7492a9b6..2e123aab87 100644 --- a/arch/arm/dts/am33xx.dtsi +++ b/arch/arm/dts/am33xx.dtsi @@ -946,6 +946,9 @@ reg = <0x4830e000 0x1000>; interrupts = <36>; ti,hwmods = "lcdc"; + clocks = <&l4_per_clkctrl AM3_LCDC_CLKCTRL 0>; + clock-names = "fck"; + status = "disabled"; };
diff --git a/arch/arm/mach-omap2/am33xx/clock_am33xx.c b/arch/arm/mach-omap2/am33xx/clock_am33xx.c index 2427933c8b..cf71192360 100644 --- a/arch/arm/mach-omap2/am33xx/clock_am33xx.c +++ b/arch/arm/mach-omap2/am33xx/clock_am33xx.c @@ -226,7 +226,7 @@ void enable_basic_clocks(void) &cmper->usb0clkctrl, &cmper->emiffwclkctrl, &cmper->emifclkctrl, -#if CONFIG_IS_ENABLED(AM335X_LCD) +#if CONFIG_IS_ENABLED(AM335X_LCD) && !CONFIG_IS_ENABLED(DM_VIDEO) &cmper->lcdclkctrl, &cmper->lcdcclkstctrl, #endif diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c index dc959baa27..104f7891cc 100644 --- a/drivers/video/am335x-fb.c +++ b/drivers/video/am335x-fb.c @@ -12,6 +12,7 @@ * - starts output DMA from gd->fb_base buffer */ #include <common.h> +#include <clk.h> #include <dm.h> #include <lcd.h> #include <log.h> @@ -335,14 +336,17 @@ enum {
struct am335x_fb_priv { struct am335x_lcdhw *regs; + struct clk clkdm; };
static int am335x_fb_remove(struct udevice *dev) { struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); + struct am335x_fb_priv *priv = dev_get_priv(dev);
uc_plat->base -= 0x20; uc_plat->size += 0x20; + clk_release_all(&priv->clkdm, 1); return 0; }
@@ -416,6 +420,18 @@ static int am335x_fb_probe(struct udevice *dev) return -EINVAL; }
+ err = clk_get_by_name(dev, "fck", &priv->clkdm); + if (err) { + dev_err(dev, "%s: failed to get clock domain\n", __func__); + return err; + } + + err = clk_enable(&priv->clkdm); + if (err) { + dev_err(dev, "%s: failed to enable clock domain\n", __func__); + return err; + } + am335x_fb_set_pixel_clk_rate(regs, timing.pixelclock.typ);
/* clock source for LCDC from dispPLL M2 */