Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux...
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-shmobile / board-ap4evb.c
index f59e93919e26c422d7a0f66734c0e2c99397dd49..86edc772f82a7b3549f0b7ebcad7900826c0d192 100644 (file)
@@ -61,6 +61,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
+#include <asm/setup.h>
 
 /*
  * Address     Interface               BusWidth        note
@@ -511,7 +512,12 @@ static struct platform_device keysc_device = {
 static struct resource mipidsi0_resources[] = {
        [0] = {
                .start  = 0xffc60000,
-               .end    = 0xffc68fff,
+               .end    = 0xffc63073,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 0xffc68000,
+               .end    = 0xffc680ef,
                .flags  = IORESOURCE_MEM,
        },
 };
@@ -519,6 +525,7 @@ static struct resource mipidsi0_resources[] = {
 static struct sh_mipi_dsi_info mipidsi0_info = {
        .data_format    = MIPI_RGB888,
        .lcd_chan       = &lcdc_info.ch[0],
+       .vsynw_offset   = 17,
 };
 
 static struct platform_device mipidsi0_device = {
@@ -531,44 +538,6 @@ static struct platform_device mipidsi0_device = {
        },
 };
 
-/* This function will disappear when we switch to (runtime) PM */
-static int __init ap4evb_init_display_clk(void)
-{
-       struct clk *lcdc_clk;
-       struct clk *dsitx_clk;
-       int ret;
-
-       lcdc_clk = clk_get(&lcdc_device.dev, "sh_mobile_lcdc_fb.0");
-       if (IS_ERR(lcdc_clk))
-               return PTR_ERR(lcdc_clk);
-
-       dsitx_clk = clk_get(&mipidsi0_device.dev, "sh-mipi-dsi.0");
-       if (IS_ERR(dsitx_clk)) {
-               ret = PTR_ERR(dsitx_clk);
-               goto eclkdsitxget;
-       }
-
-       ret = clk_enable(lcdc_clk);
-       if (ret < 0)
-               goto eclklcdcon;
-
-       ret = clk_enable(dsitx_clk);
-       if (ret < 0)
-               goto eclkdsitxon;
-
-       return 0;
-
-eclkdsitxon:
-       clk_disable(lcdc_clk);
-eclklcdcon:
-       clk_put(dsitx_clk);
-eclkdsitxget:
-       clk_put(lcdc_clk);
-
-       return ret;
-}
-device_initcall(ap4evb_init_display_clk);
-
 static struct platform_device *qhd_devices[] __initdata = {
        &mipidsi0_device,
        &keysc_device,
@@ -674,9 +643,8 @@ static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
                return -EIO;
 
        ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
-       clk_put(fsib_clk);
        if (ret < 0)
-               return ret;
+               goto fsi_set_rate_end;
 
        /* FSI DIV setting */
        ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
@@ -684,10 +652,14 @@ static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
                /* disable FSI B */
                if (enable)
                        __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
-               return ret;
+               goto fsi_set_rate_end;
        }
 
-       return ackmd_bpfmd;
+       ret = ackmd_bpfmd;
+
+fsi_set_rate_end:
+       clk_put(fsib_clk);
+       return ret;
 }
 
 static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
@@ -774,10 +746,15 @@ static struct platform_device lcdc1_device = {
        },
 };
 
+static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
+                               unsigned long *parent_freq);
+
+
 static struct sh_mobile_hdmi_info hdmi_info = {
        .lcd_chan = &sh_mobile_lcdc1_info.ch[0],
        .lcd_dev = &lcdc1_device.dev,
        .flags = HDMI_SND_SRC_SPDIF,
+       .clk_optimize_parent = ap4evb_clk_optimize,
 };
 
 static struct resource hdmi_resources[] = {
@@ -804,6 +781,25 @@ static struct platform_device hdmi_device = {
        },
 };
 
+static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
+                               unsigned long *parent_freq)
+{
+       struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick");
+       long error;
+
+       if (IS_ERR(hdmi_ick)) {
+               int ret = PTR_ERR(hdmi_ick);
+               pr_err("Cannot get HDMI ICK: %d\n", ret);
+               return ret;
+       }
+
+       error = clk_round_parent(hdmi_ick, target, best_freq, parent_freq, 1, 64);
+
+       clk_put(hdmi_ick);
+
+       return error;
+}
+
 static struct gpio_led ap4evb_leds[] = {
        {
                .name                   = "led4",