]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
Merge branch '4.8/omapdrm-pll' (omapdrm PLL work)
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Mon, 6 Jun 2016 07:16:51 +0000 (10:16 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
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.

16 files changed:
drivers/gpu/drm/omapdrm/dss/dispc.c
drivers/gpu/drm/omapdrm/dss/dpi.c
drivers/gpu/drm/omapdrm/dss/dsi.c
drivers/gpu/drm/omapdrm/dss/dss.c
drivers/gpu/drm/omapdrm/dss/dss.h
drivers/gpu/drm/omapdrm/dss/dss_features.c
drivers/gpu/drm/omapdrm/dss/dss_features.h
drivers/gpu/drm/omapdrm/dss/hdmi.h
drivers/gpu/drm/omapdrm/dss/hdmi4.c
drivers/gpu/drm/omapdrm/dss/hdmi5.c
drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
drivers/gpu/drm/omapdrm/dss/pll.c
drivers/gpu/drm/omapdrm/dss/video-pll.c
drivers/video/fbdev/omap2/omapfb/dss/dss.h
drivers/video/fbdev/omap2/omapfb/dss/manager.c
include/video/omapdss.h

index f83608b69e68342a1f1c779bfd13f2ac1a9c4d4e..7b78da6d51cf5dc3b20664deeac3aa34a3051fa6 100644 (file)
@@ -3299,30 +3299,21 @@ static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div,
 
 static unsigned long dispc_fclk_rate(void)
 {
-       struct dss_pll *pll;
-       unsigned long r = 0;
+       unsigned long r;
+       enum dss_clk_source src;
+
+       src = dss_get_dispc_clk_source();
 
-       switch (dss_get_dispc_clk_source()) {
-       case OMAP_DSS_CLK_SRC_FCK:
+       if (src == DSS_CLK_SRC_FCK) {
                r = dss_get_dispc_clk_rate();
-               break;
-       case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
-               pll = dss_pll_find("dsi0");
-               if (!pll)
-                       pll = dss_pll_find("video0");
+       } else {
+               struct dss_pll *pll;
+               unsigned clkout_idx;
 
-               r = pll->cinfo.clkout[0];
-               break;
-       case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
-               pll = dss_pll_find("dsi1");
-               if (!pll)
-                       pll = dss_pll_find("video1");
+               pll = dss_pll_find_by_src(src);
+               clkout_idx = dss_pll_get_clkout_idx_for_src(src);
 
-               r = pll->cinfo.clkout[0];
-               break;
-       default:
-               BUG();
-               return 0;
+               r = pll->cinfo.clkout[clkout_idx];
        }
 
        return r;
@@ -3330,43 +3321,31 @@ static unsigned long dispc_fclk_rate(void)
 
 static unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
 {
-       struct dss_pll *pll;
        int lcd;
        unsigned long r;
-       u32 l;
+       enum dss_clk_source src;
 
-       if (dss_mgr_is_lcd(channel)) {
-               l = dispc_read_reg(DISPC_DIVISORo(channel));
-
-               lcd = FLD_GET(l, 23, 16);
+       /* for TV, LCLK rate is the FCLK rate */
+       if (!dss_mgr_is_lcd(channel))
+               return dispc_fclk_rate();
 
-               switch (dss_get_lcd_clk_source(channel)) {
-               case OMAP_DSS_CLK_SRC_FCK:
-                       r = dss_get_dispc_clk_rate();
-                       break;
-               case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
-                       pll = dss_pll_find("dsi0");
-                       if (!pll)
-                               pll = dss_pll_find("video0");
+       src = dss_get_lcd_clk_source(channel);
 
-                       r = pll->cinfo.clkout[0];
-                       break;
-               case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
-                       pll = dss_pll_find("dsi1");
-                       if (!pll)
-                               pll = dss_pll_find("video1");
+       if (src == DSS_CLK_SRC_FCK) {
+               r = dss_get_dispc_clk_rate();
+       } else {
+               struct dss_pll *pll;
+               unsigned clkout_idx;
 
-                       r = pll->cinfo.clkout[0];
-                       break;
-               default:
-                       BUG();
-                       return 0;
-               }
+               pll = dss_pll_find_by_src(src);
+               clkout_idx = dss_pll_get_clkout_idx_for_src(src);
 
-               return r / lcd;
-       } else {
-               return dispc_fclk_rate();
+               r = pll->cinfo.clkout[clkout_idx];
        }
+
+       lcd = REG_GET(DISPC_DIVISORo(channel), 23, 16);
+
+       return r / lcd;
 }
 
 static unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
@@ -3426,15 +3405,14 @@ static unsigned long dispc_plane_lclk_rate(enum omap_plane plane)
 static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
 {
        int lcd, pcd;
-       enum omap_dss_clk_source lcd_clk_src;
+       enum dss_clk_source lcd_clk_src;
 
        seq_printf(s, "- %s -\n", mgr_desc[channel].name);
 
        lcd_clk_src = dss_get_lcd_clk_source(channel);
 
-       seq_printf(s, "%s clk source = %s (%s)\n", mgr_desc[channel].name,
-               dss_get_generic_clk_source_name(lcd_clk_src),
-               dss_feat_get_clk_source_name(lcd_clk_src));
+       seq_printf(s, "%s clk source = %s\n", mgr_desc[channel].name,
+               dss_get_clk_source_name(lcd_clk_src));
 
        dispc_mgr_get_lcd_divisor(channel, &lcd, &pcd);
 
@@ -3448,16 +3426,15 @@ void dispc_dump_clocks(struct seq_file *s)
 {
        int lcd;
        u32 l;
-       enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
+       enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
 
        if (dispc_runtime_get())
                return;
 
        seq_printf(s, "- DISPC -\n");
 
-       seq_printf(s, "dispc fclk source = %s (%s)\n",
-                       dss_get_generic_clk_source_name(dispc_clk_src),
-                       dss_feat_get_clk_source_name(dispc_clk_src));
+       seq_printf(s, "dispc fclk source = %s\n",
+                       dss_get_clk_source_name(dispc_clk_src));
 
        seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
 
index 97ea602578849c966ec0f50e69c725fb666f5018..db72b507384b72cf4feb6047de4d678cad865cd6 100644 (file)
 #include "dss.h"
 #include "dss_features.h"
 
-#define HSDIV_DISPC    0
-
 struct dpi_data {
        struct platform_device *pdev;
 
        struct regulator *vdds_dsi_reg;
+       enum dss_clk_source clk_src;
        struct dss_pll *pll;
 
        struct mutex lock;
@@ -69,7 +68,7 @@ static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
        return dev_get_drvdata(&pdev->dev);
 }
 
-static struct dss_pll *dpi_get_pll(enum omap_channel channel)
+static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel)
 {
        /*
         * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
@@ -83,64 +82,51 @@ static struct dss_pll *dpi_get_pll(enum omap_channel channel)
        case OMAPDSS_VER_OMAP3630:
        case OMAPDSS_VER_AM35xx:
        case OMAPDSS_VER_AM43xx:
-               return NULL;
+               return DSS_CLK_SRC_FCK;
 
        case OMAPDSS_VER_OMAP4430_ES1:
        case OMAPDSS_VER_OMAP4430_ES2:
        case OMAPDSS_VER_OMAP4:
                switch (channel) {
                case OMAP_DSS_CHANNEL_LCD:
-                       return dss_pll_find("dsi0");
+                       return DSS_CLK_SRC_PLL1_1;
                case OMAP_DSS_CHANNEL_LCD2:
-                       return dss_pll_find("dsi1");
+                       return DSS_CLK_SRC_PLL2_1;
                default:
-                       return NULL;
+                       return DSS_CLK_SRC_FCK;
                }
 
        case OMAPDSS_VER_OMAP5:
                switch (channel) {
                case OMAP_DSS_CHANNEL_LCD:
-                       return dss_pll_find("dsi0");
+                       return DSS_CLK_SRC_PLL1_1;
                case OMAP_DSS_CHANNEL_LCD3:
-                       return dss_pll_find("dsi1");
+                       return DSS_CLK_SRC_PLL2_1;
+               case OMAP_DSS_CHANNEL_LCD2:
                default:
-                       return NULL;
+                       return DSS_CLK_SRC_FCK;
                }
 
        case OMAPDSS_VER_DRA7xx:
                switch (channel) {
                case OMAP_DSS_CHANNEL_LCD:
+                       return DSS_CLK_SRC_PLL1_1;
                case OMAP_DSS_CHANNEL_LCD2:
-                       return dss_pll_find("video0");
+                       return DSS_CLK_SRC_PLL1_3;
                case OMAP_DSS_CHANNEL_LCD3:
-                       return dss_pll_find("video1");
+                       return DSS_CLK_SRC_PLL2_1;
                default:
-                       return NULL;
+                       return DSS_CLK_SRC_FCK;
                }
 
        default:
-               return NULL;
-       }
-}
-
-static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel)
-{
-       switch (channel) {
-       case OMAP_DSS_CHANNEL_LCD:
-               return OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC;
-       case OMAP_DSS_CHANNEL_LCD2:
-               return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
-       case OMAP_DSS_CHANNEL_LCD3:
-               return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
-       default:
-               /* this shouldn't happen */
-               WARN_ON(1);
-               return OMAP_DSS_CLK_SRC_FCK;
+               return DSS_CLK_SRC_FCK;
        }
 }
 
 struct dpi_clk_calc_ctx {
        struct dss_pll *pll;
+       unsigned clkout_idx;
 
        /* inputs */
 
@@ -148,7 +134,7 @@ struct dpi_clk_calc_ctx {
 
        /* outputs */
 
-       struct dss_pll_clock_info dsi_cinfo;
+       struct dss_pll_clock_info pll_cinfo;
        unsigned long fck;
        struct dispc_clock_info dispc_cinfo;
 };
@@ -193,8 +179,8 @@ static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
        if (m_dispc > 1 && m_dispc % 2 != 0 && ctx->pck_min >= 100000000)
                return false;
 
-       ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc;
-       ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc;
+       ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc;
+       ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc;
 
        return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max,
                        dpi_calc_dispc_cb, ctx);
@@ -207,12 +193,12 @@ static bool dpi_calc_pll_cb(int n, int m, unsigned long fint,
 {
        struct dpi_clk_calc_ctx *ctx = data;
 
-       ctx->dsi_cinfo.n = n;
-       ctx->dsi_cinfo.m = m;
-       ctx->dsi_cinfo.fint = fint;
-       ctx->dsi_cinfo.clkdco = clkdco;
+       ctx->pll_cinfo.n = n;
+       ctx->pll_cinfo.m = m;
+       ctx->pll_cinfo.fint = fint;
+       ctx->pll_cinfo.clkdco = clkdco;
 
-       return dss_pll_hsdiv_calc(ctx->pll, clkdco,
+       return dss_pll_hsdiv_calc_a(ctx->pll, clkdco,
                ctx->pck_min, dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
                dpi_calc_hsdiv_cb, ctx);
 }
@@ -227,25 +213,39 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
                        dpi_calc_dispc_cb, ctx);
 }
 
-static bool dpi_dsi_clk_calc(struct dpi_data *dpi, unsigned long pck,
+static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned long pck,
                struct dpi_clk_calc_ctx *ctx)
 {
        unsigned long clkin;
-       unsigned long pll_min, pll_max;
 
        memset(ctx, 0, sizeof(*ctx));
        ctx->pll = dpi->pll;
-       ctx->pck_min = pck - 1000;
-       ctx->pck_max = pck + 1000;
+       ctx->clkout_idx = dss_pll_get_clkout_idx_for_src(dpi->clk_src);
 
-       pll_min = 0;
-       pll_max = 0;
+       clkin = clk_get_rate(dpi->pll->clkin);
 
-       clkin = clk_get_rate(ctx->pll->clkin);
+       if (dpi->pll->hw->type == DSS_PLL_TYPE_A) {
+               unsigned long pll_min, pll_max;
 
-       return dss_pll_calc(ctx->pll, clkin,
-                       pll_min, pll_max,
-                       dpi_calc_pll_cb, ctx);
+               ctx->pck_min = pck - 1000;
+               ctx->pck_max = pck + 1000;
+
+               pll_min = 0;
+               pll_max = 0;
+
+               return dss_pll_calc_a(ctx->pll, clkin,
+                               pll_min, pll_max,
+                               dpi_calc_pll_cb, ctx);
+       } else { /* DSS_PLL_TYPE_B */
+               dss_pll_calc_b(dpi->pll, clkin, pck, &ctx->pll_cinfo);
+
+               ctx->dispc_cinfo.lck_div = 1;
+               ctx->dispc_cinfo.pck_div = 1;
+               ctx->dispc_cinfo.lck = ctx->pll_cinfo.clkout[0];
+               ctx->dispc_cinfo.pck = ctx->dispc_cinfo.lck;
+
+               return true;
+       }
 }
 
 static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
@@ -279,7 +279,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
 
 
 
-static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel,
+static int dpi_set_pll_clk(struct dpi_data *dpi, enum omap_channel channel,
                unsigned long pck_req, unsigned long *fck, int *lck_div,
                int *pck_div)
 {
@@ -287,20 +287,19 @@ static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel,
        int r;
        bool ok;
 
-       ok = dpi_dsi_clk_calc(dpi, pck_req, &ctx);
+       ok = dpi_pll_clk_calc(dpi, pck_req, &ctx);
        if (!ok)
                return -EINVAL;
 
-       r = dss_pll_set_config(dpi->pll, &ctx.dsi_cinfo);
+       r = dss_pll_set_config(dpi->pll, &ctx.pll_cinfo);
        if (r)
                return r;
 
-       dss_select_lcd_clk_source(channel,
-                       dpi_get_alt_clk_src(channel));
+       dss_select_lcd_clk_source(channel, dpi->clk_src);
 
        dpi->mgr_config.clock_info = ctx.dispc_cinfo;
 
-       *fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC];
+       *fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
        *lck_div = ctx.dispc_cinfo.lck_div;
        *pck_div = ctx.dispc_cinfo.pck_div;
 
@@ -342,7 +341,7 @@ static int dpi_set_mode(struct dpi_data *dpi)
        int r = 0;
 
        if (dpi->pll)
-               r = dpi_set_dsi_clk(dpi, channel, t->pixelclock, &fck,
+               r = dpi_set_pll_clk(dpi, channel, t->pixelclock, &fck,
                                &lck_div, &pck_div);
        else
                r = dpi_set_dispc_clk(dpi, t->pixelclock, &fck,
@@ -419,7 +418,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
        if (dpi->pll) {
                r = dss_pll_enable(dpi->pll);
                if (r)
-                       goto err_dsi_pll_init;
+                       goto err_pll_init;
        }
 
        r = dpi_set_mode(dpi);
@@ -442,7 +441,7 @@ err_mgr_enable:
 err_set_mode:
        if (dpi->pll)
                dss_pll_disable(dpi->pll);
-err_dsi_pll_init:
+err_pll_init:
 err_src_sel:
        dispc_runtime_put();
 err_get_dispc:
@@ -465,7 +464,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev)
        dss_mgr_disable(channel);
 
        if (dpi->pll) {
-               dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK);
+               dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
                dss_pll_disable(dpi->pll);
        }
 
@@ -524,11 +523,11 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
                return -EINVAL;
 
        if (dpi->pll) {
-               ok = dpi_dsi_clk_calc(dpi, timings->pixelclock, &ctx);
+               ok = dpi_pll_clk_calc(dpi, timings->pixelclock, &ctx);
                if (!ok)
                        return -EINVAL;
 
-               fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC];
+               fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
        } else {
                ok = dpi_dss_clk_calc(timings->pixelclock, &ctx);
                if (!ok)
@@ -558,7 +557,7 @@ static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
        mutex_unlock(&dpi->lock);
 }
 
-static int dpi_verify_dsi_pll(struct dss_pll *pll)
+static int dpi_verify_pll(struct dss_pll *pll)
 {
        int r;
 
@@ -602,16 +601,14 @@ static void dpi_init_pll(struct dpi_data *dpi)
        if (dpi->pll)
                return;
 
-       pll = dpi_get_pll(dpi->output.dispc_channel);
+       dpi->clk_src = dpi_get_clk_src(dpi->output.dispc_channel);
+
+       pll = dss_pll_find_by_src(dpi->clk_src);
        if (!pll)
                return;
 
-       /* On DRA7 we need to set a mux to use the PLL */
-       if (omapdss_get_version() == OMAPDSS_VER_DRA7xx)
-               dss_ctrl_pll_set_control_mux(pll->id, dpi->output.dispc_channel);
-
-       if (dpi_verify_dsi_pll(pll)) {
-               DSSWARN("DSI PLL not operational\n");
+       if (dpi_verify_pll(pll)) {
+               DSSWARN("PLL not operational\n");
                return;
        }
 
index 9ed8272e54ae183240c7560f35f969470acb6e5e..0a634438ba3b97da41e9aca2de55f7f335502c88 100644 (file)
@@ -1262,7 +1262,7 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
        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 +1475,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
 {
        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;
 
@@ -1495,28 +1495,27 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
                        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 +4101,8 @@ static int dsi_display_init_dispc(struct platform_device *dsidev,
        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 +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 +4162,7 @@ static void dsi_display_uninit_dispc(struct platform_device *dsidev,
                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 +4196,8 @@ static int dsi_display_init_dsi(struct platform_device *dsidev)
                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");
 
@@ -4230,7 +4229,7 @@ static int dsi_display_init_dsi(struct platform_device *dsidev)
 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 +4251,7 @@ static void dsi_display_uninit_dsi(struct platform_device *dsidev,
        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 +4452,7 @@ static bool dsi_cm_calc_pll_cb(int n, int m, unsigned long fint,
        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 +4491,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
        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 +4750,7 @@ static bool dsi_vm_calc_pll_cb(int n, int m, unsigned long fint,
        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 +4792,7 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
                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 +5138,8 @@ static const struct dss_pll_ops dsi_pll_ops = {
 };
 
 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,
@@ -5164,6 +5165,8 @@ static const struct dss_pll_hw dss_omap3_dsi_pll_hw = {
 };
 
 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,
@@ -5189,6 +5192,8 @@ static const struct dss_pll_hw dss_omap4_dsi_pll_hw = {
 };
 
 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..6ac54c35227ed36f93520d9e8666a1146e6e05d1 100644 (file)
@@ -76,6 +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 +94,9 @@ static struct {
        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)];
@@ -106,11 +108,14 @@ static struct {
 } 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 +208,70 @@ void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable)
                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 +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())
@@ -369,12 +376,11 @@ void dss_dump_clocks(struct seq_file *s)
 
        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 +409,42 @@ static void dss_dump_regs(struct seq_file *s)
 #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:
@@ -431,19 +460,19 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
 }
 
 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;
@@ -458,59 +487,125 @@ void dss_select_dsi_clk_source(int dsi_module,
        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 +954,7 @@ static const struct dss_features omap44xx_dss_feats = {
        .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 = {
@@ -868,6 +964,7 @@ 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 +983,7 @@ static const struct dss_features dra7xx_dss_feats = {
        .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 +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 38e6ab50142d42bf988df7d294219b64fef5bcb6..4fd06dc41cb3ac8ebcb895cd4f88ccd45b71e600 100644 (file)
@@ -102,6 +102,20 @@ enum dss_writeback_channel {
        DSS_WB_LCD3_MGR =       7,
 };
 
+enum dss_clk_source {
+       DSS_CLK_SRC_FCK = 0,
+
+       DSS_CLK_SRC_PLL1_1,
+       DSS_CLK_SRC_PLL1_2,
+       DSS_CLK_SRC_PLL1_3,
+
+       DSS_CLK_SRC_PLL2_1,
+       DSS_CLK_SRC_PLL2_2,
+       DSS_CLK_SRC_PLL2_3,
+
+       DSS_CLK_SRC_HDMI_PLL,
+};
+
 enum dss_pll_id {
        DSS_PLL_DSI1,
        DSS_PLL_DSI2,
@@ -114,6 +128,11 @@ struct dss_pll;
 
 #define DSS_PLL_MAX_HSDIVS 4
 
+enum dss_pll_type {
+       DSS_PLL_TYPE_A,
+       DSS_PLL_TYPE_B,
+};
+
 /*
  * Type-A PLLs: clkout[]/mX[] refer to hsdiv outputs m4, m5, m6, m7.
  * Type-B PLLs: clkout[0] refers to m2.
@@ -140,6 +159,8 @@ struct dss_pll_ops {
 };
 
 struct dss_pll_hw {
+       enum dss_pll_type type;
+
        unsigned n_max;
        unsigned m_min;
        unsigned m_max;
@@ -227,7 +248,7 @@ unsigned long dss_get_dispc_clk_rate(void);
 int dss_dpi_select_source(int port, enum omap_channel channel);
 void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
 enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
-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);
 void dss_dump_clocks(struct seq_file *s);
 
 /* DSS VIDEO PLL */
@@ -244,20 +265,18 @@ void dss_debug_dump_clocks(struct seq_file *s);
 #endif
 
 void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable);
-void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id,
-       enum omap_channel channel);
 
 void dss_sdi_init(int datapairs);
 int dss_sdi_enable(void);
 void dss_sdi_disable(void);
 
 void dss_select_dsi_clk_source(int dsi_module,
-               enum omap_dss_clk_source clk_src);
+               enum dss_clk_source clk_src);
 void dss_select_lcd_clk_source(enum omap_channel channel,
-               enum omap_dss_clk_source clk_src);
-enum omap_dss_clk_source dss_get_dispc_clk_source(void);
-enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module);
-enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
+               enum dss_clk_source clk_src);
+enum dss_clk_source dss_get_dispc_clk_source(void);
+enum dss_clk_source dss_get_dsi_clk_source(int dsi_module);
+enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
 
 void dss_set_venc_output(enum omap_dss_venc_type type);
 void dss_set_dac_pwrdn_bgz(bool enable);
@@ -409,17 +428,23 @@ typedef bool (*dss_hsdiv_calc_func)(int m_dispc, unsigned long dispc,
 int dss_pll_register(struct dss_pll *pll);
 void dss_pll_unregister(struct dss_pll *pll);
 struct dss_pll *dss_pll_find(const char *name);
+struct dss_pll *dss_pll_find_by_src(enum dss_clk_source src);
+unsigned dss_pll_get_clkout_idx_for_src(enum dss_clk_source src);
 int dss_pll_enable(struct dss_pll *pll);
 void dss_pll_disable(struct dss_pll *pll);
 int dss_pll_set_config(struct dss_pll *pll,
                const struct dss_pll_clock_info *cinfo);
 
-bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco,
+bool dss_pll_hsdiv_calc_a(const struct dss_pll *pll, unsigned long clkdco,
                unsigned long out_min, unsigned long out_max,
                dss_hsdiv_calc_func func, void *data);
-bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin,
+bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
                unsigned long pll_min, unsigned long pll_max,
                dss_pll_calc_func func, void *data);
+
+bool dss_pll_calc_b(const struct dss_pll *pll, unsigned long clkin,
+       unsigned long target_clkout, struct dss_pll_clock_info *cinfo);
+
 int dss_pll_write_config_type_a(struct dss_pll *pll,
                const struct dss_pll_clock_info *cinfo);
 int dss_pll_write_config_type_b(struct dss_pll *pll,
index c886a2927f73f77d5e6054eec26f5d9d61427ee3..c025d44ae164fa35c25a24da6b0bcf99f4017f50 100644 (file)
@@ -50,7 +50,6 @@ struct omap_dss_features {
        const enum omap_dss_output_id *supported_outputs;
        const enum omap_color_mode *supported_color_modes;
        const enum omap_overlay_caps *overlay_caps;
-       const char * const *clksrc_names;
        const struct dss_param_range *dss_params;
 
        const enum omap_dss_rotation_type supported_rotation_types;
@@ -389,34 +388,6 @@ static const enum omap_overlay_caps omap4_dss_overlay_caps[] = {
                OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
 };
 
-static const char * const omap2_dss_clk_source_names[] = {
-       [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC]  = "N/A",
-       [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI]    = "N/A",
-       [OMAP_DSS_CLK_SRC_FCK]                  = "DSS_FCLK1",
-};
-
-static const char * const omap3_dss_clk_source_names[] = {
-       [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC]  = "DSI1_PLL_FCLK",
-       [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI]    = "DSI2_PLL_FCLK",
-       [OMAP_DSS_CLK_SRC_FCK]                  = "DSS1_ALWON_FCLK",
-};
-
-static const char * const omap4_dss_clk_source_names[] = {
-       [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC]  = "PLL1_CLK1",
-       [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI]    = "PLL1_CLK2",
-       [OMAP_DSS_CLK_SRC_FCK]                  = "DSS_FCLK",
-       [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "PLL2_CLK1",
-       [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI]   = "PLL2_CLK2",
-};
-
-static const char * const omap5_dss_clk_source_names[] = {
-       [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC]  = "DPLL_DSI1_A_CLK1",
-       [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI]    = "DPLL_DSI1_A_CLK2",
-       [OMAP_DSS_CLK_SRC_FCK]                  = "DSS_CLK",
-       [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DPLL_DSI1_C_CLK1",
-       [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI]   = "DPLL_DSI1_C_CLK2",
-};
-
 static const struct dss_param_range omap2_dss_param_range[] = {
        [FEAT_PARAM_DSS_FCK]                    = { 0, 133000000 },
        [FEAT_PARAM_DSS_PCD]                    = { 2, 255 },
@@ -631,7 +602,6 @@ static const struct omap_dss_features omap2_dss_features = {
        .supported_outputs = omap2_dss_supported_outputs,
        .supported_color_modes = omap2_dss_supported_color_modes,
        .overlay_caps = omap2_dss_overlay_caps,
-       .clksrc_names = omap2_dss_clk_source_names,
        .dss_params = omap2_dss_param_range,
        .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
        .buffer_size_unit = 1,
@@ -652,7 +622,6 @@ static const struct omap_dss_features omap3430_dss_features = {
        .supported_outputs = omap3430_dss_supported_outputs,
        .supported_color_modes = omap3_dss_supported_color_modes,
        .overlay_caps = omap3430_dss_overlay_caps,
-       .clksrc_names = omap3_dss_clk_source_names,
        .dss_params = omap3_dss_param_range,
        .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
        .buffer_size_unit = 1,
@@ -676,7 +645,6 @@ static const struct omap_dss_features am35xx_dss_features = {
        .supported_outputs = omap3430_dss_supported_outputs,
        .supported_color_modes = omap3_dss_supported_color_modes,
        .overlay_caps = omap3430_dss_overlay_caps,
-       .clksrc_names = omap3_dss_clk_source_names,
        .dss_params = omap3_dss_param_range,
        .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
        .buffer_size_unit = 1,
@@ -696,7 +664,6 @@ static const struct omap_dss_features am43xx_dss_features = {
        .supported_outputs = am43xx_dss_supported_outputs,
        .supported_color_modes = omap3_dss_supported_color_modes,
        .overlay_caps = omap3430_dss_overlay_caps,
-       .clksrc_names = omap2_dss_clk_source_names,
        .dss_params = am43xx_dss_param_range,
        .supported_rotation_types = OMAP_DSS_ROT_DMA,
        .buffer_size_unit = 1,
@@ -716,7 +683,6 @@ static const struct omap_dss_features omap3630_dss_features = {
        .supported_outputs = omap3630_dss_supported_outputs,
        .supported_color_modes = omap3_dss_supported_color_modes,
        .overlay_caps = omap3630_dss_overlay_caps,
-       .clksrc_names = omap3_dss_clk_source_names,
        .dss_params = omap3_dss_param_range,
        .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
        .buffer_size_unit = 1,
@@ -738,7 +704,6 @@ static const struct omap_dss_features omap4430_es1_0_dss_features  = {
        .supported_outputs = omap4_dss_supported_outputs,
        .supported_color_modes = omap4_dss_supported_color_modes,
        .overlay_caps = omap4_dss_overlay_caps,
-       .clksrc_names = omap4_dss_clk_source_names,
        .dss_params = omap4_dss_param_range,
        .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
        .buffer_size_unit = 16,
@@ -759,7 +724,6 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
        .supported_outputs = omap4_dss_supported_outputs,
        .supported_color_modes = omap4_dss_supported_color_modes,
        .overlay_caps = omap4_dss_overlay_caps,
-       .clksrc_names = omap4_dss_clk_source_names,
        .dss_params = omap4_dss_param_range,
        .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
        .buffer_size_unit = 16,
@@ -780,7 +744,6 @@ static const struct omap_dss_features omap4_dss_features = {
        .supported_outputs = omap4_dss_supported_outputs,
        .supported_color_modes = omap4_dss_supported_color_modes,
        .overlay_caps = omap4_dss_overlay_caps,
-       .clksrc_names = omap4_dss_clk_source_names,
        .dss_params = omap4_dss_param_range,
        .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
        .buffer_size_unit = 16,
@@ -801,7 +764,6 @@ static const struct omap_dss_features omap5_dss_features = {
        .supported_outputs = omap5_dss_supported_outputs,
        .supported_color_modes = omap4_dss_supported_color_modes,
        .overlay_caps = omap4_dss_overlay_caps,
-       .clksrc_names = omap5_dss_clk_source_names,
        .dss_params = omap5_dss_param_range,
        .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
        .buffer_size_unit = 16,
@@ -859,11 +821,6 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
                        color_mode;
 }
 
-const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id)
-{
-       return omap_current_dss_features->clksrc_names[id];
-}
-
 u32 dss_feat_get_buffer_size_unit(void)
 {
        return omap_current_dss_features->buffer_size_unit;
index 3d67d39f192ff1d5b0ff2cc30c7071fab0683524..bb4b7f0e642be8a9028fcdac5b41d287ba7c1cc6 100644 (file)
@@ -91,7 +91,6 @@ unsigned long dss_feat_get_param_max(enum dss_range_param param);
 enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
 bool dss_feat_color_mode_supported(enum omap_plane plane,
                enum omap_color_mode color_mode);
-const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
 
 u32 dss_feat_get_buffer_size_unit(void);       /* in bytes */
 u32 dss_feat_get_burst_size_unit(void);                /* in bytes */
index 53616b02b61371b1eb0d6c0c6819cb931cac39a9..597ee204d699d0c490ba83309d88b3ea426a34dc 100644 (file)
@@ -240,6 +240,7 @@ struct hdmi_pll_data {
 
        void __iomem *base;
 
+       struct platform_device *pdev;
        struct hdmi_wp_data *wp;
 };
 
@@ -306,8 +307,6 @@ phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp);
 
 /* HDMI PLL funcs */
 void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s);
-void hdmi_pll_compute(struct hdmi_pll_data *pll,
-       unsigned long target_tmds, struct dss_pll_clock_info *pi);
 int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
        struct hdmi_wp_data *wp);
 void hdmi_pll_uninit(struct hdmi_pll_data *hpll);
index 4d46cdf7a0374e85946700295f2c40da91f248c0..ca4abb49924284750026272d4d7c90fc050f0a6d 100644 (file)
@@ -177,7 +177,11 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
        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..cbcf4bb5248c8155eded8902694dd8b31525fe5c 100644 (file)
@@ -190,7 +190,11 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
        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..dc0212a9754eb2e9f9c3b09da8422b5951814228 100644 (file)
@@ -17,6 +17,7 @@
 #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 +40,14 @@ void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s)
        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 +62,14 @@ static void hdmi_pll_disable(struct dss_pll *dsspll)
 {
        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 = {
@@ -131,6 +79,8 @@ 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,
@@ -154,6 +104,8 @@ static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = {
 };
 
 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 +177,7 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
        int r;
        struct resource *res;
 
+       pll->pdev = pdev;
        pll->wp = wp;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll");
index f974ddcd3b6e97563f455c3b4196e6641d7ed041..4768a85e6c73dafa8e7e2ae95adc24e04a95e730 100644 (file)
@@ -76,6 +76,59 @@ struct dss_pll *dss_pll_find(const char *name)
        return NULL;
 }
 
+struct dss_pll *dss_pll_find_by_src(enum dss_clk_source src)
+{
+       struct dss_pll *pll;
+
+       switch (src) {
+       default:
+       case DSS_CLK_SRC_FCK:
+               return NULL;
+
+       case DSS_CLK_SRC_HDMI_PLL:
+               return dss_pll_find("hdmi");
+
+       case DSS_CLK_SRC_PLL1_1:
+       case DSS_CLK_SRC_PLL1_2:
+       case DSS_CLK_SRC_PLL1_3:
+               pll = dss_pll_find("dsi0");
+               if (!pll)
+                       pll = dss_pll_find("video0");
+               return pll;
+
+       case DSS_CLK_SRC_PLL2_1:
+       case DSS_CLK_SRC_PLL2_2:
+       case DSS_CLK_SRC_PLL2_3:
+               pll = dss_pll_find("dsi1");
+               if (!pll)
+                       pll = dss_pll_find("video1");
+               return pll;
+       }
+}
+
+unsigned dss_pll_get_clkout_idx_for_src(enum dss_clk_source src)
+{
+       switch (src) {
+       case DSS_CLK_SRC_HDMI_PLL:
+               return 0;
+
+       case DSS_CLK_SRC_PLL1_1:
+       case DSS_CLK_SRC_PLL2_1:
+               return 0;
+
+       case DSS_CLK_SRC_PLL1_2:
+       case DSS_CLK_SRC_PLL2_2:
+               return 1;
+
+       case DSS_CLK_SRC_PLL1_3:
+       case DSS_CLK_SRC_PLL2_3:
+               return 2;
+
+       default:
+               return 0;
+       }
+}
+
 int dss_pll_enable(struct dss_pll *pll)
 {
        int r;
@@ -129,7 +182,7 @@ int dss_pll_set_config(struct dss_pll *pll, const struct dss_pll_clock_info *cin
        return 0;
 }
 
-bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco,
+bool dss_pll_hsdiv_calc_a(const struct dss_pll *pll, unsigned long clkdco,
                unsigned long out_min, unsigned long out_max,
                dss_hsdiv_calc_func func, void *data)
 {
@@ -154,7 +207,11 @@ bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco,
        return false;
 }
 
-bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin,
+/*
+ * clkdco = clkin / n * m * 2
+ * clkoutX = clkdco / mX
+ */
+bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
                unsigned long pll_min, unsigned long pll_max,
                dss_pll_calc_func func, void *data)
 {
@@ -195,6 +252,71 @@ bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin,
        return false;
 }
 
+/*
+ * This calculates a PLL config that will provide the target_clkout rate
+ * for clkout. Additionally clkdco rate will be the same as clkout rate
+ * when clkout rate is >= min_clkdco.
+ *
+ * clkdco = clkin / n * m + clkin / n * mf / 262144
+ * clkout = clkdco / m2
+ */
+bool dss_pll_calc_b(const struct dss_pll *pll, unsigned long clkin,
+       unsigned long target_clkout, struct dss_pll_clock_info *cinfo)
+{
+       unsigned long fint, clkdco, clkout;
+       unsigned long target_clkdco;
+       unsigned long min_dco;
+       unsigned n, m, mf, m2, sd;
+       const struct dss_pll_hw *hw = pll->hw;
+
+       DSSDBG("clkin %lu, target clkout %lu\n", clkin, target_clkout);
+
+       /* 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_clkout);
+       if (m2 == 0)
+               m2 = 1;
+
+       target_clkdco = target_clkout * 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);
+
+       cinfo->n = n;
+       cinfo->m = m;
+       cinfo->mf = mf;
+       cinfo->mX[0] = m2;
+       cinfo->sd = sd;
+
+       cinfo->fint = fint;
+       cinfo->clkdco = clkdco;
+       cinfo->clkout[0] = clkout;
+
+       return true;
+}
+
 static int wait_for_bit_change(void __iomem *reg, int bitnum, int value)
 {
        unsigned long timeout;
index b1ec59e42940c22ef2b63042dd4a523917bea64f..c13e1accda17ebd59b2d0bb269413956f86414e4 100644 (file)
@@ -108,6 +108,8 @@ static const struct dss_pll_ops dss_pll_ops = {
 };
 
 static const struct dss_pll_hw dss_dra7_video_pll_hw = {
+       .type = DSS_PLL_TYPE_A,
+
        .n_max = (1 << 8) - 1,
        .m_max = (1 << 12) - 1,
        .mX_max = (1 << 5) - 1,
@@ -124,6 +126,10 @@ static const struct dss_pll_hw dss_dra7_video_pll_hw = {
        .mX_lsb[0] = 21,
        .mX_msb[1] = 30,
        .mX_lsb[1] = 26,
+       .mX_msb[2] = 4,
+       .mX_lsb[2] = 0,
+       .mX_msb[3] = 9,
+       .mX_lsb[3] = 5,
 
        .has_refsel = true,
 };
index 0184a8461df1b0e7355cbb323149a66f752530b8..a3cc0ca8f9d240d3b5646e3eda4fc4193033fe81 100644 (file)
 #define FLD_MOD(orig, val, start, end) \
        (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
 
+enum omap_dss_clk_source {
+       OMAP_DSS_CLK_SRC_FCK = 0,               /* OMAP2/3: DSS1_ALWON_FCLK
+                                                * OMAP4: DSS_FCLK */
+       OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC,   /* OMAP3: DSI1_PLL_FCLK
+                                                * OMAP4: PLL1_CLK1 */
+       OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,     /* OMAP3: DSI2_PLL_FCLK
+                                                * OMAP4: PLL1_CLK2 */
+       OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC,  /* OMAP4: PLL2_CLK1 */
+       OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI,    /* OMAP4: PLL2_CLK2 */
+};
+
 enum dss_io_pad_mode {
        DSS_IO_PAD_MODE_RESET,
        DSS_IO_PAD_MODE_RFBI,
index 08a67f4f6a20e2599d3039f63ccf4681ad8bf5c6..11f67ac88089e85737ccf5d4030682093fd8b570 100644 (file)
@@ -69,7 +69,6 @@ int dss_init_overlay_managers(void)
                        break;
                }
 
-               mgr->caps = 0;
                mgr->supported_displays =
                        dss_feat_get_supported_displays(mgr->id);
                mgr->supported_outputs =
index 8e14ad7327c98af67e4f8ac18bfc07122a99ef77..6bd9d03b103080a0c09461785a222aad965d8799 100644 (file)
@@ -195,25 +195,6 @@ enum omap_overlay_caps {
        OMAP_DSS_OVL_CAP_REPLICATION = 1 << 5,
 };
 
-enum omap_overlay_manager_caps {
-       OMAP_DSS_DUMMY_VALUE, /* add a dummy value to prevent compiler error */
-};
-
-enum omap_dss_clk_source {
-       OMAP_DSS_CLK_SRC_FCK = 0,               /* OMAP2/3: DSS1_ALWON_FCLK
-                                                * OMAP4: DSS_FCLK */
-       OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC,   /* OMAP3: DSI1_PLL_FCLK
-                                                * OMAP4: PLL1_CLK1 */
-       OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,     /* OMAP3: DSI2_PLL_FCLK
-                                                * OMAP4: PLL1_CLK2 */
-       OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC,  /* OMAP4: PLL2_CLK1 */
-       OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI,    /* OMAP4: PLL2_CLK2 */
-};
-
-enum omap_hdmi_flags {
-       OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
-};
-
 enum omap_dss_output_id {
        OMAP_DSS_OUTPUT_DPI     = 1 << 0,
        OMAP_DSS_OUTPUT_DBI     = 1 << 1,
@@ -463,7 +444,6 @@ struct omap_overlay_manager {
        /* static fields */
        const char *name;
        enum omap_channel id;
-       enum omap_overlay_manager_caps caps;
        struct list_head overlays;
        enum omap_display_type supported_displays;
        enum omap_dss_output_id supported_outputs;