]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'common/fbdev-mipi' of master.kernel.org:/pub/scm/linux/kernel/git/letha...
authorPaul Mundt <lethal@linux-sh.org>
Wed, 5 Jan 2011 08:30:20 +0000 (17:30 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Wed, 5 Jan 2011 08:30:20 +0000 (17:30 +0900)
1  2 
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/clock-sh7372.c

index a054f0d450d8c468a9f583dc3296ed7eafffa47f,acbb4f0579abf75190999e6e5b1248de29ae48b5..b1222dc43380f9dd6e99081a2080c8dd56d7ef8b
@@@ -514,6 -514,7 +514,7 @@@ static struct resource mipidsi0_resourc
  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 = {
        },
  };
  
- /* 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,
  
  /* FSI */
  #define IRQ_FSI               evt2irq(0x1840)
 +static int __fsi_set_rate(struct clk *clk, long rate, int enable)
 +{
 +      int ret = 0;
 +
 +      if (rate <= 0)
 +              return ret;
 +
 +      if (enable) {
 +              ret = clk_set_rate(clk, rate);
 +              if (0 == ret)
 +                      ret = clk_enable(clk);
 +      } else {
 +              clk_disable(clk);
 +      }
 +
 +      return ret;
 +}
 +
 +static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
 +{
 +      return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable);
 +}
 +
 +static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable)
 +{
 +      struct clk *fsia_ick;
 +      struct clk *fsiack;
 +      int ret = -EIO;
 +
 +      fsia_ick = clk_get(dev, "icka");
 +      if (IS_ERR(fsia_ick))
 +              return PTR_ERR(fsia_ick);
 +
 +      /*
 +       * FSIACK is connected to AK4642,
 +       * and use external clock pin from it.
 +       * it is parent of fsia_ick now.
 +       */
 +      fsiack = clk_get_parent(fsia_ick);
 +      if (!fsiack)
 +              goto fsia_ick_out;
 +
 +      /*
 +       * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick
 +       *
 +       ** FIXME **
 +       * Because the freq_table of external clk (fsiack) are all 0,
 +       * the return value of clk_round_rate became 0.
 +       * So, it use __fsi_set_rate here.
 +       */
 +      ret = __fsi_set_rate(fsiack, rate, enable);
 +      if (ret < 0)
 +              goto fsiack_out;
 +
 +      ret = __fsi_set_round_rate(fsia_ick, rate, enable);
 +      if ((ret < 0) && enable)
 +              __fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */
 +
 +fsiack_out:
 +      clk_put(fsiack);
 +
 +fsia_ick_out:
 +      clk_put(fsia_ick);
  
 -static int fsi_set_rate(int is_porta, int rate)
 +      return 0;
 +}
 +
 +static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
  {
        struct clk *fsib_clk;
        struct clk *fdiv_clk = &sh7372_fsidivb_clk;
 +      long fsib_rate = 0;
 +      long fdiv_rate = 0;
 +      int ackmd_bpfmd;
        int ret;
  
 -      /* set_rate is not needed if port A */
 -      if (is_porta)
 -              return 0;
 -
 -      fsib_clk = clk_get(NULL, "fsib_clk");
 -      if (IS_ERR(fsib_clk))
 -              return -EINVAL;
 -
        switch (rate) {
        case 44100:
 -              clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 11283000));
 -              ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
 +              fsib_rate       = rate * 256;
 +              ackmd_bpfmd     = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
                break;
        case 48000:
 -              clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000));
 -              clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000));
 -              ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
 +              fsib_rate       = 85428000; /* around 48kHz x 256 x 7 */
 +              fdiv_rate       = rate * 256;
 +              ackmd_bpfmd     = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
                break;
        default:
                pr_err("unsupported rate in FSI2 port B\n");
 -              ret = -EINVAL;
 -              break;
 +              return -EINVAL;
        }
  
 +      /* FSI B setting */
 +      fsib_clk = clk_get(dev, "ickb");
 +      if (IS_ERR(fsib_clk))
 +              return -EIO;
 +
 +      ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
        clk_put(fsib_clk);
 +      if (ret < 0)
 +              return ret;
 +
 +      /* FSI DIV setting */
 +      ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
 +      if (ret < 0) {
 +              /* disable FSI B */
 +              if (enable)
 +                      __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
 +              return ret;
 +      }
 +
 +      return ackmd_bpfmd;
 +}
 +
 +static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
 +{
 +      int ret;
 +
 +      if (is_porta)
 +              ret = fsi_ak4642_set_rate(dev, rate, enable);
 +      else
 +              ret = fsi_hdmi_set_rate(dev, rate, enable);
  
        return ret;
  }
@@@ -769,15 -643,10 +732,15 @@@ static struct platform_device lcdc1_dev
        },
  };
  
 +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,25 -673,6 +767,25 @@@ static struct platform_device hdmi_devi
        },
  };
  
 +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",
@@@ -998,11 -848,6 +961,11 @@@ static int __init hdmi_init_pm_clock(vo
                goto out;
        }
  
 +      ret = clk_enable(&sh7372_pllc2_clk);
 +      if (ret < 0) {
 +              pr_err("Cannot enable pllc2 clock\n");
 +              goto out;
 +      }
        pr_debug("PLLC2 set frequency %lu\n", rate);
  
        ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
@@@ -1019,11 -864,23 +982,11 @@@ out
  
  device_initcall(hdmi_init_pm_clock);
  
 -#define FSIACK_DUMMY_RATE 48000
  static int __init fsi_init_pm_clock(void)
  {
        struct clk *fsia_ick;
        int ret;
  
 -      /*
 -       * FSIACK is connected to AK4642,
 -       * and the rate is depend on playing sound rate.
 -       * So, set dummy rate (= 48k) here
 -       */
 -      ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
 -      if (ret < 0) {
 -              pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
 -              return ret;
 -      }
 -
        fsia_ick = clk_get(&fsi_device.dev, "icka");
        if (IS_ERR(fsia_ick)) {
                ret = PTR_ERR(fsia_ick);
        }
  
        ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
 -      if (ret < 0) {
 -              pr_err("Cannot set FSI-A parent: %d\n", ret);
 -              goto out;
 -      }
 -
 -      ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
        if (ret < 0)
 -              pr_err("Cannot set FSI-A rate: %d\n", ret);
 +              pr_err("Cannot set FSI-A parent: %d\n", ret);
  
 -out:
        clk_put(fsia_ick);
  
        return ret;
index 3aa026069435a7b99ae1cbff5ccac101af016731,f4b9ae211566e1d59205f324b54d6fcf68a75e57..66663adb21f83ea51bcc9f282d32b8d20c6dae1b
@@@ -220,7 -220,8 +220,7 @@@ static void pllc2_disable(struct clk *c
        __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
  }
  
 -static int pllc2_set_rate(struct clk *clk,
 -                        unsigned long rate, int algo_id)
 +static int pllc2_set_rate(struct clk *clk, unsigned long rate)
  {
        unsigned long value;
        int idx;
        if (idx < 0)
                return idx;
  
 -      if (rate == clk->parent->rate) {
 -              pllc2_disable(clk);
 -              return 0;
 -      }
 +      if (rate == clk->parent->rate)
 +              return -EINVAL;
  
        value = __raw_readl(PLLC2CR) & ~(0x3f << 24);
  
 -      if (value & 0x80000000)
 -              pllc2_disable(clk);
 -
        __raw_writel((value & ~0x80000000) | ((idx + 19) << 24), PLLC2CR);
  
 -      if (value & 0x80000000)
 -              return pllc2_enable(clk);
 -
        return 0;
  }
  
@@@ -444,24 -453,32 +444,24 @@@ static int fsidiv_enable(struct clk *cl
        unsigned long value;
  
        value  = __raw_readl(clk->mapping->base) >> 16;
 -      if (value < 2) {
 -              fsidiv_disable(clk);
 -              return -ENOENT;
 -      }
 +      if (value < 2)
 +              return -EIO;
  
        __raw_writel((value << 16) | 0x3, clk->mapping->base);
  
        return 0;
  }
  
 -static int fsidiv_set_rate(struct clk *clk,
 -                         unsigned long rate, int algo_id)
 +static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
  {
        int idx;
  
 -      if (clk->parent->rate == rate) {
 -              fsidiv_disable(clk);
 -              return 0;
 -      }
 -
        idx = (clk->parent->rate / rate) & 0xffff;
        if (idx < 2)
 -              return -ENOENT;
 +              return -EINVAL;
  
        __raw_writel(idx << 16, clk->mapping->base);
 -      return fsidiv_enable(clk);
 +      return 0;
  }
  
  static struct clk_ops fsidiv_clk_ops = {
@@@ -507,7 -524,7 +507,7 @@@ enum { MSTP001
         MSTP223,
         MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
         MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
-        MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
+        MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
         MSTP_NR };
  
  #define MSTP(_parent, _reg, _bit, _flags) \
@@@ -543,6 -560,7 +543,7 @@@ static struct clk mstp_clks[MSTP_NR] = 
        [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
        [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
        [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
+       [MSTP423] = MSTP(&div4_clks[DIV4_B], SMSTPCR4, 23, 0), /* DSITX1 */
        [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
        [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
        [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
@@@ -592,13 -610,16 +593,14 @@@ static struct clk_lookup lookups[] = 
        CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
        CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
        CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
 -      CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FSIA]),
 -      CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FSIB]),
        CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
        CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
        CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
        CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
-       CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]),
-       CLKDEV_CON_ID("dsi0p_clk", &div6_clks[DIV6_DSI0P]),
-       CLKDEV_CON_ID("dsi1p_clk", &div6_clks[DIV6_DSI1P]),
+       CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
+       CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
+       CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
+       CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
  
        /* MSTP32 clocks */
        CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
        CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
        CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
        CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
-       CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
+       CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
        CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
        CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
        CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
        CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
        CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
        CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
 -      CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */
 -      CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP323]), /* USB0 */
 +      CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
 +      CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
        CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
+       CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
        CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
        CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */