]> Git Repo - linux.git/commitdiff
Merge branch '4.8/omapdrm-pll' (omapdrm PLL work)
authorTomi Valkeinen <[email protected]>
Mon, 6 Jun 2016 07:16:51 +0000 (10:16 +0300)
committerTomi Valkeinen <[email protected]>
Mon, 6 Jun 2016 07:16:51 +0000 (10:16 +0300)
Merge omapdrm PLL work, which makes it possible to use the DSS PLLs in a
versatile manner, for example, HDMI PLL can be used for LCDs.

1  2 
drivers/gpu/drm/omapdrm/dss/dsi.c
drivers/gpu/drm/omapdrm/dss/dss.c
drivers/gpu/drm/omapdrm/dss/hdmi4.c
drivers/gpu/drm/omapdrm/dss/hdmi5.c
drivers/gpu/drm/omapdrm/dss/hdmi_pll.c

index 9ed8272e54ae183240c7560f35f969470acb6e5e,ee8bbfa468f3dfd00c45a89c1ff650c0e1a0dc1a..0a634438ba3b97da41e9aca2de55f7f335502c88
@@@ -1180,6 -1180,15 +1180,6 @@@ static int dsi_regulator_init(struct pl
                return PTR_ERR(vdds_dsi);
        }
  
 -      if (regulator_can_change_voltage(vdds_dsi)) {
 -              r = regulator_set_voltage(vdds_dsi, 1800000, 1800000);
 -              if (r) {
 -                      devm_regulator_put(vdds_dsi);
 -                      DSSERR("can't set the DSI regulator voltage\n");
 -                      return r;
 -              }
 -      }
 -
        dsi->vdds_dsi_reg = vdds_dsi;
  
        return 0;
@@@ -1262,7 -1271,7 +1262,7 @@@ static unsigned long dsi_fclk_rate(stru
        unsigned long r;
        struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
  
-       if (dss_get_dsi_clk_source(dsi->module_id) == OMAP_DSS_CLK_SRC_FCK) {
+       if (dss_get_dsi_clk_source(dsi->module_id) == DSS_CLK_SRC_FCK) {
                /* DSI FCLK source is DSS_CLK_FCK */
                r = clk_get_rate(dsi->dss_clk);
        } else {
@@@ -1475,7 -1484,7 +1475,7 @@@ static void dsi_dump_dsidev_clocks(stru
  {
        struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
        struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo;
-       enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
+       enum dss_clk_source dispc_clk_src, dsi_clk_src;
        int dsi_module = dsi->module_id;
        struct dss_pll *pll = &dsi->pll;
  
                        cinfo->clkdco, cinfo->m);
  
        seq_printf(s,   "DSI_PLL_HSDIV_DISPC (%s)\t%-16lum_dispc %u\t(%s)\n",
-                       dss_feat_get_clk_source_name(dsi_module == 0 ?
-                               OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
-                               OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC),
+                       dss_get_clk_source_name(dsi_module == 0 ?
+                               DSS_CLK_SRC_PLL1_1 :
+                               DSS_CLK_SRC_PLL2_1),
                        cinfo->clkout[HSDIV_DISPC],
                        cinfo->mX[HSDIV_DISPC],
-                       dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ?
+                       dispc_clk_src == DSS_CLK_SRC_FCK ?
                        "off" : "on");
  
        seq_printf(s,   "DSI_PLL_HSDIV_DSI (%s)\t%-16lum_dsi %u\t(%s)\n",
-                       dss_feat_get_clk_source_name(dsi_module == 0 ?
-                               OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
-                               OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI),
+                       dss_get_clk_source_name(dsi_module == 0 ?
+                               DSS_CLK_SRC_PLL1_2 :
+                               DSS_CLK_SRC_PLL2_2),
                        cinfo->clkout[HSDIV_DSI],
                        cinfo->mX[HSDIV_DSI],
-                       dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ?
+                       dsi_clk_src == DSS_CLK_SRC_FCK ?
                        "off" : "on");
  
        seq_printf(s,   "- DSI%d -\n", dsi_module + 1);
  
-       seq_printf(s,   "dsi fclk source = %s (%s)\n",
-                       dss_get_generic_clk_source_name(dsi_clk_src),
-                       dss_feat_get_clk_source_name(dsi_clk_src));
+       seq_printf(s,   "dsi fclk source = %s\n",
+                       dss_get_clk_source_name(dsi_clk_src));
  
        seq_printf(s,   "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev));
  
@@@ -4102,8 -4110,8 +4101,8 @@@ static int dsi_display_init_dispc(struc
        int r;
  
        dss_select_lcd_clk_source(channel, dsi->module_id == 0 ?
-                       OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
-                       OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC);
+                       DSS_CLK_SRC_PLL1_1 :
+                       DSS_CLK_SRC_PLL2_1);
  
        if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
                r = dss_mgr_register_framedone_handler(channel,
@@@ -4150,7 -4158,7 +4149,7 @@@ err1
                dss_mgr_unregister_framedone_handler(channel,
                                dsi_framedone_irq_callback, dsidev);
  err:
-       dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK);
+       dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
        return r;
  }
  
@@@ -4163,7 -4171,7 +4162,7 @@@ static void dsi_display_uninit_dispc(st
                dss_mgr_unregister_framedone_handler(channel,
                                dsi_framedone_irq_callback, dsidev);
  
-       dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK);
+       dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
  }
  
  static int dsi_configure_dsi_clocks(struct platform_device *dsidev)
@@@ -4197,8 -4205,8 +4196,8 @@@ static int dsi_display_init_dsi(struct 
                goto err1;
  
        dss_select_dsi_clk_source(dsi->module_id, dsi->module_id == 0 ?
-                       OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
-                       OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI);
+                       DSS_CLK_SRC_PLL1_2 :
+                       DSS_CLK_SRC_PLL2_2);
  
        DSSDBG("PLL OK\n");
  
  err3:
        dsi_cio_uninit(dsidev);
  err2:
-       dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
+       dss_select_dsi_clk_source(dsi->module_id, DSS_CLK_SRC_FCK);
  err1:
        dss_pll_disable(&dsi->pll);
  err0:
@@@ -4252,7 -4260,7 +4251,7 @@@ static void dsi_display_uninit_dsi(stru
        dsi_vc_enable(dsidev, 2, 0);
        dsi_vc_enable(dsidev, 3, 0);
  
-       dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
+       dss_select_dsi_clk_source(dsi->module_id, DSS_CLK_SRC_FCK);
        dsi_cio_uninit(dsidev);
        dsi_pll_uninit(dsidev, disconnect_lanes);
  }
@@@ -4453,7 -4461,7 +4452,7 @@@ static bool dsi_cm_calc_pll_cb(int n, i
        ctx->dsi_cinfo.fint = fint;
        ctx->dsi_cinfo.clkdco = clkdco;
  
-       return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min,
+       return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
                        dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
                        dsi_cm_calc_hsdiv_cb, ctx);
  }
@@@ -4492,7 -4500,7 +4491,7 @@@ static bool dsi_cm_calc(struct dsi_dat
        pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4);
        pll_max = cfg->hs_clk_max * 4;
  
-       return dss_pll_calc(ctx->pll, clkin,
+       return dss_pll_calc_a(ctx->pll, clkin,
                        pll_min, pll_max,
                        dsi_cm_calc_pll_cb, ctx);
  }
@@@ -4751,7 -4759,7 +4750,7 @@@ static bool dsi_vm_calc_pll_cb(int n, i
        ctx->dsi_cinfo.fint = fint;
        ctx->dsi_cinfo.clkdco = clkdco;
  
-       return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min,
+       return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
                        dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
                        dsi_vm_calc_hsdiv_cb, ctx);
  }
@@@ -4793,7 -4801,7 +4792,7 @@@ static bool dsi_vm_calc(struct dsi_dat
                pll_max = byteclk_max * 4 * 4;
        }
  
-       return dss_pll_calc(ctx->pll, clkin,
+       return dss_pll_calc_a(ctx->pll, clkin,
                        pll_min, pll_max,
                        dsi_vm_calc_pll_cb, ctx);
  }
@@@ -5139,6 -5147,8 +5138,8 @@@ static const struct dss_pll_ops dsi_pll
  };
  
  static const struct dss_pll_hw dss_omap3_dsi_pll_hw = {
+       .type = DSS_PLL_TYPE_A,
        .n_max = (1 << 7) - 1,
        .m_max = (1 << 11) - 1,
        .mX_max = (1 << 4) - 1,
  };
  
  static const struct dss_pll_hw dss_omap4_dsi_pll_hw = {
+       .type = DSS_PLL_TYPE_A,
        .n_max = (1 << 8) - 1,
        .m_max = (1 << 12) - 1,
        .mX_max = (1 << 5) - 1,
  };
  
  static const struct dss_pll_hw dss_omap5_dsi_pll_hw = {
+       .type = DSS_PLL_TYPE_A,
        .n_max = (1 << 8) - 1,
        .m_max = (1 << 12) - 1,
        .mX_max = (1 << 5) - 1,
index 3303cfad4838d5921b31370e263443c6c9b8bc71,2937a28126905fbab9f788da8c7ce011374e3649..6ac54c35227ed36f93520d9e8666a1146e6e05d1
@@@ -30,7 -30,6 +30,7 @@@
  #include <linux/delay.h>
  #include <linux/seq_file.h>
  #include <linux/clk.h>
 +#include <linux/pinctrl/consumer.h>
  #include <linux/platform_device.h>
  #include <linux/pm_runtime.h>
  #include <linux/gfp.h>
@@@ -76,6 -75,8 +76,8 @@@ struct dss_features 
        const enum omap_display_type *ports;
        int num_ports;
        int (*dpi_select_source)(int port, enum omap_channel channel);
+       int (*select_lcd_source)(enum omap_channel channel,
+               enum dss_clk_source clk_src);
  };
  
  static struct {
@@@ -92,9 -93,9 +94,9 @@@
        unsigned long   cache_prate;
        struct dispc_clock_info cache_dispc_cinfo;
  
-       enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI];
-       enum omap_dss_clk_source dispc_clk_source;
-       enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
+       enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
+       enum dss_clk_source dispc_clk_source;
+       enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
  
        bool            ctx_valid;
        u32             ctx[DSS_SZ_REGS / sizeof(u32)];
  } dss;
  
  static const char * const dss_generic_clk_source_names[] = {
-       [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC]  = "DSI_PLL_HSDIV_DISPC",
-       [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI]    = "DSI_PLL_HSDIV_DSI",
-       [OMAP_DSS_CLK_SRC_FCK]                  = "DSS_FCK",
-       [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DSI_PLL2_HSDIV_DISPC",
-       [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI]   = "DSI_PLL2_HSDIV_DSI",
+       [DSS_CLK_SRC_FCK]       = "FCK",
+       [DSS_CLK_SRC_PLL1_1]    = "PLL1:1",
+       [DSS_CLK_SRC_PLL1_2]    = "PLL1:2",
+       [DSS_CLK_SRC_PLL1_3]    = "PLL1:3",
+       [DSS_CLK_SRC_PLL2_1]    = "PLL2:1",
+       [DSS_CLK_SRC_PLL2_2]    = "PLL2:2",
+       [DSS_CLK_SRC_PLL2_3]    = "PLL2:3",
+       [DSS_CLK_SRC_HDMI_PLL]  = "HDMI PLL",
  };
  
  static bool dss_initialized;
@@@ -203,68 -207,70 +208,70 @@@ void dss_ctrl_pll_enable(enum dss_pll_i
                1 << shift, val << shift);
  }
  
void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id,
static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src,
        enum omap_channel channel)
  {
        unsigned shift, val;
  
        if (!dss.syscon_pll_ctrl)
-               return;
+               return -EINVAL;
  
        switch (channel) {
        case OMAP_DSS_CHANNEL_LCD:
                shift = 3;
  
-               switch (pll_id) {
-               case DSS_PLL_VIDEO1:
+               switch (clk_src) {
+               case DSS_CLK_SRC_PLL1_1:
                        val = 0; break;
-               case DSS_PLL_HDMI:
+               case DSS_CLK_SRC_HDMI_PLL:
                        val = 1; break;
                default:
                        DSSERR("error in PLL mux config for LCD\n");
-                       return;
+                       return -EINVAL;
                }
  
                break;
        case OMAP_DSS_CHANNEL_LCD2:
                shift = 5;
  
-               switch (pll_id) {
-               case DSS_PLL_VIDEO1:
+               switch (clk_src) {
+               case DSS_CLK_SRC_PLL1_3:
                        val = 0; break;
-               case DSS_PLL_VIDEO2:
+               case DSS_CLK_SRC_PLL2_3:
                        val = 1; break;
-               case DSS_PLL_HDMI:
+               case DSS_CLK_SRC_HDMI_PLL:
                        val = 2; break;
                default:
                        DSSERR("error in PLL mux config for LCD2\n");
-                       return;
+                       return -EINVAL;
                }
  
                break;
        case OMAP_DSS_CHANNEL_LCD3:
                shift = 7;
  
-               switch (pll_id) {
-               case DSS_PLL_VIDEO1:
-                       val = 1; break;
-               case DSS_PLL_VIDEO2:
+               switch (clk_src) {
+               case DSS_CLK_SRC_PLL2_1:
                        val = 0; break;
-               case DSS_PLL_HDMI:
+               case DSS_CLK_SRC_PLL1_3:
+                       val = 1; break;
+               case DSS_CLK_SRC_HDMI_PLL:
                        val = 2; break;
                default:
                        DSSERR("error in PLL mux config for LCD3\n");
-                       return;
+                       return -EINVAL;
                }
  
                break;
        default:
                DSSERR("error in PLL mux config\n");
-               return;
+               return -EINVAL;
        }
  
        regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
                0x3 << shift, val << shift);
+       return 0;
  }
  
  void dss_sdi_init(int datapairs)
@@@ -354,14 -360,14 +361,14 @@@ void dss_sdi_disable(void
        REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
  }
  
- const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
+ const char *dss_get_clk_source_name(enum dss_clk_source clk_src)
  {
        return dss_generic_clk_source_names[clk_src];
  }
  
  void dss_dump_clocks(struct seq_file *s)
  {
-       const char *fclk_name, *fclk_real_name;
+       const char *fclk_name;
        unsigned long fclk_rate;
  
        if (dss_runtime_get())
  
        seq_printf(s, "- DSS -\n");
  
-       fclk_name = dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
-       fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
+       fclk_name = dss_get_clk_source_name(DSS_CLK_SRC_FCK);
        fclk_rate = clk_get_rate(dss.dss_clk);
  
-       seq_printf(s, "%s (%s) = %lu\n",
-                       fclk_name, fclk_real_name,
+       seq_printf(s, "%s = %lu\n",
+                       fclk_name,
                        fclk_rate);
  
        dss_runtime_put();
@@@ -403,19 -408,42 +409,42 @@@ static void dss_dump_regs(struct seq_fi
  #undef DUMPREG
  }
  
- static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
+ static int dss_get_channel_index(enum omap_channel channel)
+ {
+       switch (channel) {
+       case OMAP_DSS_CHANNEL_LCD:
+               return 0;
+       case OMAP_DSS_CHANNEL_LCD2:
+               return 1;
+       case OMAP_DSS_CHANNEL_LCD3:
+               return 2;
+       default:
+               WARN_ON(1);
+               return 0;
+       }
+ }
+ static void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
  {
        int b;
        u8 start, end;
  
+       /*
+        * We always use PRCM clock as the DISPC func clock, except on DSS3,
+        * where we don't have separate DISPC and LCD clock sources.
+        */
+       if (WARN_ON(dss_has_feature(FEAT_LCD_CLK_SRC) &&
+               clk_src != DSS_CLK_SRC_FCK))
+               return;
        switch (clk_src) {
-       case OMAP_DSS_CLK_SRC_FCK:
+       case DSS_CLK_SRC_FCK:
                b = 0;
                break;
-       case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
+       case DSS_CLK_SRC_PLL1_1:
                b = 1;
                break;
-       case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
+       case DSS_CLK_SRC_PLL2_1:
                b = 2;
                break;
        default:
  }
  
  void dss_select_dsi_clk_source(int dsi_module,
-               enum omap_dss_clk_source clk_src)
+               enum dss_clk_source clk_src)
  {
        int b, pos;
  
        switch (clk_src) {
-       case OMAP_DSS_CLK_SRC_FCK:
+       case DSS_CLK_SRC_FCK:
                b = 0;
                break;
-       case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
+       case DSS_CLK_SRC_PLL1_2:
                BUG_ON(dsi_module != 0);
                b = 1;
                break;
-       case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI:
+       case DSS_CLK_SRC_PLL2_2:
                BUG_ON(dsi_module != 1);
                b = 1;
                break;
        dss.dsi_clk_source[dsi_module] = clk_src;
  }
  
+ static int dss_lcd_clk_mux_dra7(enum omap_channel channel,
+       enum dss_clk_source clk_src)
+ {
+       const u8 ctrl_bits[] = {
+               [OMAP_DSS_CHANNEL_LCD] = 0,
+               [OMAP_DSS_CHANNEL_LCD2] = 12,
+               [OMAP_DSS_CHANNEL_LCD3] = 19,
+       };
+       u8 ctrl_bit = ctrl_bits[channel];
+       int r;
+       if (clk_src == DSS_CLK_SRC_FCK) {
+               /* LCDx_CLK_SWITCH */
+               REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
+               return -EINVAL;
+       }
+       r = dss_ctrl_pll_set_control_mux(clk_src, channel);
+       if (r)
+               return r;
+       REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
+       return 0;
+ }
+ static int dss_lcd_clk_mux_omap5(enum omap_channel channel,
+       enum dss_clk_source clk_src)
+ {
+       const u8 ctrl_bits[] = {
+               [OMAP_DSS_CHANNEL_LCD] = 0,
+               [OMAP_DSS_CHANNEL_LCD2] = 12,
+               [OMAP_DSS_CHANNEL_LCD3] = 19,
+       };
+       const enum dss_clk_source allowed_plls[] = {
+               [OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1,
+               [OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_FCK,
+               [OMAP_DSS_CHANNEL_LCD3] = DSS_CLK_SRC_PLL2_1,
+       };
+       u8 ctrl_bit = ctrl_bits[channel];
+       if (clk_src == DSS_CLK_SRC_FCK) {
+               /* LCDx_CLK_SWITCH */
+               REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
+               return -EINVAL;
+       }
+       if (WARN_ON(allowed_plls[channel] != clk_src))
+               return -EINVAL;
+       REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
+       return 0;
+ }
+ static int dss_lcd_clk_mux_omap4(enum omap_channel channel,
+       enum dss_clk_source clk_src)
+ {
+       const u8 ctrl_bits[] = {
+               [OMAP_DSS_CHANNEL_LCD] = 0,
+               [OMAP_DSS_CHANNEL_LCD2] = 12,
+       };
+       const enum dss_clk_source allowed_plls[] = {
+               [OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1,
+               [OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_PLL2_1,
+       };
+       u8 ctrl_bit = ctrl_bits[channel];
+       if (clk_src == DSS_CLK_SRC_FCK) {
+               /* LCDx_CLK_SWITCH */
+               REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
+               return 0;
+       }
+       if (WARN_ON(allowed_plls[channel] != clk_src))
+               return -EINVAL;
+       REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
+       return 0;
+ }
  void dss_select_lcd_clk_source(enum omap_channel channel,
-               enum omap_dss_clk_source clk_src)
+               enum dss_clk_source clk_src)
  {
-       int b, ix, pos;
+       int idx = dss_get_channel_index(channel);
+       int r;
  
        if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
                dss_select_dispc_clk_source(clk_src);
+               dss.lcd_clk_source[idx] = clk_src;
                return;
        }
  
-       switch (clk_src) {
-       case OMAP_DSS_CLK_SRC_FCK:
-               b = 0;
-               break;
-       case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
-               BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
-               b = 1;
-               break;
-       case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
-               BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
-                      channel != OMAP_DSS_CHANNEL_LCD3);
-               b = 1;
-               break;
-       default:
-               BUG();
+       r = dss.feat->select_lcd_source(channel, clk_src);
+       if (r)
                return;
-       }
-       pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
-            (channel == OMAP_DSS_CHANNEL_LCD2 ? 12 : 19);
-       REG_FLD_MOD(DSS_CONTROL, b, pos, pos);  /* LCDx_CLK_SWITCH */
  
-       ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
-           (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
-       dss.lcd_clk_source[ix] = clk_src;
+       dss.lcd_clk_source[idx] = clk_src;
  }
  
- enum omap_dss_clk_source dss_get_dispc_clk_source(void)
+ enum dss_clk_source dss_get_dispc_clk_source(void)
  {
        return dss.dispc_clk_source;
  }
  
- enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module)
+ enum dss_clk_source dss_get_dsi_clk_source(int dsi_module)
  {
        return dss.dsi_clk_source[dsi_module];
  }
  
- enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
+ enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
  {
        if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
-               int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
-                       (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
-               return dss.lcd_clk_source[ix];
+               int idx = dss_get_channel_index(channel);
+               return dss.lcd_clk_source[idx];
        } else {
                /* LCD_CLK source is the same as DISPC_FCLK source for
                 * OMAP2 and OMAP3 */
@@@ -859,6 -953,7 +954,7 @@@ static const struct dss_features omap44
        .dpi_select_source      =       &dss_dpi_select_source_omap4,
        .ports                  =       omap2plus_ports,
        .num_ports              =       ARRAY_SIZE(omap2plus_ports),
+       .select_lcd_source      =       &dss_lcd_clk_mux_omap4,
  };
  
  static const struct dss_features omap54xx_dss_feats = {
        .dpi_select_source      =       &dss_dpi_select_source_omap5,
        .ports                  =       omap2plus_ports,
        .num_ports              =       ARRAY_SIZE(omap2plus_ports),
+       .select_lcd_source      =       &dss_lcd_clk_mux_omap5,
  };
  
  static const struct dss_features am43xx_dss_feats = {
@@@ -886,6 -982,7 +983,7 @@@ static const struct dss_features dra7xx
        .dpi_select_source      =       &dss_dpi_select_source_dra7xx,
        .ports                  =       dra7xx_ports,
        .num_ports              =       ARRAY_SIZE(dra7xx_ports),
+       .select_lcd_source      =       &dss_lcd_clk_mux_dra7,
  };
  
  static int dss_init_features(struct platform_device *pdev)
@@@ -1143,18 -1240,18 +1241,18 @@@ static int dss_bind(struct device *dev
        /* Select DPLL */
        REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
  
-       dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
+       dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
  
  #ifdef CONFIG_OMAP2_DSS_VENC
        REG_FLD_MOD(DSS_CONTROL, 1, 4, 4);      /* venc dac demen */
        REG_FLD_MOD(DSS_CONTROL, 1, 3, 3);      /* venc clock 4x enable */
        REG_FLD_MOD(DSS_CONTROL, 0, 2, 2);      /* venc clock mode = normal */
  #endif
-       dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
-       dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
-       dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
-       dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
-       dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
+       dss.dsi_clk_source[0] = DSS_CLK_SRC_FCK;
+       dss.dsi_clk_source[1] = DSS_CLK_SRC_FCK;
+       dss.dispc_clk_source = DSS_CLK_SRC_FCK;
+       dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
+       dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
  
        rev = dss_read_reg(DSS_REVISION);
        printk(KERN_INFO "OMAP DSS rev %d.%d\n",
index 4d46cdf7a0374e85946700295f2c40da91f248c0,b1a8926c5b8166e5a8189e8753f0abb78432921a..ca4abb49924284750026272d4d7c90fc050f0a6d
@@@ -33,7 -33,6 +33,7 @@@
  #include <linux/gpio.h>
  #include <linux/regulator/consumer.h>
  #include <linux/component.h>
 +#include <linux/of.h>
  #include <video/omapdss.h>
  #include <sound/omap-hdmi-audio.h>
  
@@@ -101,6 -100,7 +101,6 @@@ static irqreturn_t hdmi_irq_handler(in
  
  static int hdmi_init_regulator(void)
  {
 -      int r;
        struct regulator *reg;
  
        if (hdmi.vdda_reg != NULL)
                return PTR_ERR(reg);
        }
  
 -      if (regulator_can_change_voltage(reg)) {
 -              r = regulator_set_voltage(reg, 1800000, 1800000);
 -              if (r) {
 -                      devm_regulator_put(reg);
 -                      DSSWARN("can't set the regulator voltage\n");
 -                      return r;
 -              }
 -      }
 -
        hdmi.vdda_reg = reg;
  
        return 0;
@@@ -177,7 -186,11 +177,11 @@@ static int hdmi_power_on_full(struct om
        if (p->double_pixel)
                pc *= 2;
  
-       hdmi_pll_compute(&hdmi.pll, pc, &hdmi_cinfo);
+       /* DSS_HDMI_TCLK is bitclk / 10 */
+       pc *= 10;
+       dss_pll_calc_b(&hdmi.pll.pll, clk_get_rate(hdmi.pll.pll.clkin),
+               pc, &hdmi_cinfo);
  
        r = dss_pll_enable(&hdmi.pll.pll);
        if (r) {
index e129245eb8a9f56c989b342aca9ad25e15abfc8d,33998f7f51abd407f0570d499a6ff3ff36c1b6a0..cbcf4bb5248c8155eded8902694dd8b31525fe5c
@@@ -38,7 -38,6 +38,7 @@@
  #include <linux/gpio.h>
  #include <linux/regulator/consumer.h>
  #include <linux/component.h>
 +#include <linux/of.h>
  #include <video/omapdss.h>
  #include <sound/omap-hdmi-audio.h>
  
@@@ -132,6 -131,15 +132,6 @@@ static int hdmi_init_regulator(void
                return PTR_ERR(reg);
        }
  
 -      if (regulator_can_change_voltage(reg)) {
 -              r = regulator_set_voltage(reg, 1800000, 1800000);
 -              if (r) {
 -                      devm_regulator_put(reg);
 -                      DSSWARN("can't set the regulator voltage\n");
 -                      return r;
 -              }
 -      }
 -
        hdmi.vdda_reg = reg;
  
        return 0;
@@@ -190,7 -198,11 +190,11 @@@ static int hdmi_power_on_full(struct om
        if (p->double_pixel)
                pc *= 2;
  
-       hdmi_pll_compute(&hdmi.pll, pc, &hdmi_cinfo);
+       /* DSS_HDMI_TCLK is bitclk / 10 */
+       pc *= 10;
+       dss_pll_calc_b(&hdmi.pll.pll, clk_get_rate(hdmi.pll.pll.clkin),
+               pc, &hdmi_cinfo);
  
        /* disable and clear irqs */
        hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
index f1015e8b82675ffe21f420c375e2ef429b3d88a1,ac866d23c2dc372e1073f21f67423e0e30ec611a..dc0212a9754eb2e9f9c3b09da8422b5951814228
@@@ -16,7 -16,7 +16,8 @@@
  #include <linux/io.h>
  #include <linux/platform_device.h>
  #include <linux/clk.h>
 +#include <linux/seq_file.h>
+ #include <linux/pm_runtime.h>
  
  #include <video/omapdss.h>
  
@@@ -39,71 -39,14 +40,14 @@@ void hdmi_pll_dump(struct hdmi_pll_dat
        DUMPPLL(PLLCTRL_CFG4);
  }
  
- void hdmi_pll_compute(struct hdmi_pll_data *pll,
-       unsigned long target_tmds, struct dss_pll_clock_info *pi)
- {
-       unsigned long fint, clkdco, clkout;
-       unsigned long target_bitclk, target_clkdco;
-       unsigned long min_dco;
-       unsigned n, m, mf, m2, sd;
-       unsigned long clkin;
-       const struct dss_pll_hw *hw = pll->pll.hw;
-       clkin = clk_get_rate(pll->pll.clkin);
-       DSSDBG("clkin %lu, target tmds %lu\n", clkin, target_tmds);
-       target_bitclk = target_tmds * 10;
-       /* Fint */
-       n = DIV_ROUND_UP(clkin, hw->fint_max);
-       fint = clkin / n;
-       /* adjust m2 so that the clkdco will be high enough */
-       min_dco = roundup(hw->clkdco_min, fint);
-       m2 = DIV_ROUND_UP(min_dco, target_bitclk);
-       if (m2 == 0)
-               m2 = 1;
-       target_clkdco = target_bitclk * m2;
-       m = target_clkdco / fint;
-       clkdco = fint * m;
-       /* adjust clkdco with fractional mf */
-       if (WARN_ON(target_clkdco - clkdco > fint))
-               mf = 0;
-       else
-               mf = (u32)div_u64(262144ull * (target_clkdco - clkdco), fint);
-       if (mf > 0)
-               clkdco += (u32)div_u64((u64)mf * fint, 262144);
-       clkout = clkdco / m2;
-       /* sigma-delta */
-       sd = DIV_ROUND_UP(fint * m, 250000000);
-       DSSDBG("N = %u, M = %u, M.f = %u, M2 = %u, SD = %u\n",
-               n, m, mf, m2, sd);
-       DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout);
-       pi->n = n;
-       pi->m = m;
-       pi->mf = mf;
-       pi->mX[0] = m2;
-       pi->sd = sd;
-       pi->fint = fint;
-       pi->clkdco = clkdco;
-       pi->clkout[0] = clkout;
- }
  static int hdmi_pll_enable(struct dss_pll *dsspll)
  {
        struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
        struct hdmi_wp_data *wp = pll->wp;
-       u16 r = 0;
+       int r;
+       r = pm_runtime_get_sync(&pll->pdev->dev);
+       WARN_ON(r < 0);
  
        dss_ctrl_pll_enable(DSS_PLL_HDMI, true);
  
@@@ -118,10 -61,14 +62,14 @@@ static void hdmi_pll_disable(struct dss
  {
        struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
        struct hdmi_wp_data *wp = pll->wp;
+       int r;
  
        hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
  
        dss_ctrl_pll_enable(DSS_PLL_HDMI, false);
+       r = pm_runtime_put_sync(&pll->pdev->dev);
+       WARN_ON(r < 0 && r != -ENOSYS);
  }
  
  static const struct dss_pll_ops dsi_pll_ops = {
  };
  
  static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = {
+       .type = DSS_PLL_TYPE_B,
        .n_max = 255,
        .m_min = 20,
        .m_max = 4095,
  };
  
  static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = {
+       .type = DSS_PLL_TYPE_B,
        .n_max = 255,
        .m_min = 20,
        .m_max = 2045,
@@@ -225,6 -176,7 +177,7 @@@ int hdmi_pll_init(struct platform_devic
        int r;
        struct resource *res;
  
+       pll->pdev = pdev;
        pll->wp = wp;
  
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll");
This page took 0.14612 seconds and 4 git commands to generate.