diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-09-25 10:26:28 +0200 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-09-25 10:26:28 +0200 |
commit | 406f7b8baa8f92d88dac448a9dc0dbeb3e330874 (patch) | |
tree | 9abc90f8338cb2c886e263d64a1d6fe8f389ee3d /drivers/video | |
parent | Merge omapdss single-dssdev series (diff) | |
parent | OMAPDSS: DSI: make OMAP2_DSS_DSI depend on ARCH_OMAP5 (diff) | |
download | linux-406f7b8baa8f92d88dac448a9dc0dbeb3e330874.tar.xz linux-406f7b8baa8f92d88dac448a9dc0dbeb3e330874.zip |
Merge OMAP5 DSS changes to omapdss
This series adds basic OMAP5 DSS functionality, mainly related to DSS core, DPI
and DSI.
* omap5-dss:
OMAPDSS: DSI: make OMAP2_DSS_DSI depend on ARCH_OMAP5
OMAPDSS: DSI: Add code to disable PHY DCC
OMAPDSS: DSI: Add new linebuffer size for OMAP5
OMAPDSS: DSI: Add FEAT_DSI_PLL_REFSEL
OMAPDSS: DSI: Add FEAT_DSI_PLL_SELFREQDCO
OMAPDSS: Add support for DPI source selection
OMAPDSS: move dss feats to the end of dss.c
OMAPDSS: Add basic omap5 features to dss and dispc
OMAPDSS: DSI: improve DSI clock calcs for DISPC
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/omap2/dss/Kconfig | 2 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 2 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dpi.c | 5 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 167 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.c | 121 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 1 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.c | 96 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.h | 3 |
8 files changed, 337 insertions, 60 deletions
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index b337a8469fd8..80f5390aa136 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig @@ -84,7 +84,7 @@ config OMAP2_DSS_SDI config OMAP2_DSS_DSI bool "DSI support" - depends on ARCH_OMAP3 || ARCH_OMAP4 + depends on ARCH_OMAP3 || ARCH_OMAP4 || ARCH_OMAP5 default n help MIPI DSI (Display Serial Interface) support. diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index d512c389741e..e52c57789383 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -3829,6 +3829,8 @@ static int __init dispc_init_features(struct device *dev) src = &omap34xx_rev3_0_dispc_feats; } else if (cpu_is_omap44xx()) { src = &omap44xx_dispc_feats; + } else if (soc_is_omap54xx()) { + src = &omap44xx_dispc_feats; } else { return -ENODEV; } diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index fac19d39ab18..f6800e19bbcb 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -203,6 +203,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) if (r) goto err_get_dispc; + r = dss_dpi_select_source(dssdev->channel); + if (r) + goto err_src_sel; + if (dpi_use_dsi_pll(dssdev)) { r = dsi_runtime_get(dpi.dsidev); if (r) @@ -237,6 +241,7 @@ err_dsi_pll_init: if (dpi_use_dsi_pll(dssdev)) dsi_runtime_put(dpi.dsidev); err_get_dsi: +err_src_sel: dispc_runtime_put(); err_get_dispc: if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 1dd019cf9649..4d748139315d 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1454,26 +1454,17 @@ found: } static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev, - unsigned long req_clk, struct dsi_clock_info *cinfo) + unsigned long req_clkin4ddr, struct dsi_clock_info *cinfo) { struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); struct dsi_clock_info cur, best; - unsigned long dss_sys_clk, max_dss_fck, max_dsi_fck; - unsigned long req_clkin4ddr; DSSDBG("dsi_pll_calc_ddrfreq\n"); - dss_sys_clk = clk_get_rate(dsi->sys_clk); - - max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); - max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK); - memset(&best, 0, sizeof(best)); memset(&cur, 0, sizeof(cur)); - cur.clkin = dss_sys_clk; - - req_clkin4ddr = req_clk * 4; + cur.clkin = clk_get_rate(dsi->sys_clk); for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { cur.fint = cur.clkin / cur.regn; @@ -1503,18 +1494,107 @@ static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev, } } found: - best.regm_dispc = DIV_ROUND_UP(best.clkin4ddr, max_dss_fck); - best.dsi_pll_hsdiv_dispc_clk = best.clkin4ddr / best.regm_dispc; - - best.regm_dsi = DIV_ROUND_UP(best.clkin4ddr, max_dsi_fck); - best.dsi_pll_hsdiv_dsi_clk = best.clkin4ddr / best.regm_dsi; - if (cinfo) *cinfo = best; return 0; } +static void dsi_pll_calc_dsi_fck(struct platform_device *dsidev, + struct dsi_clock_info *cinfo) +{ + unsigned long max_dsi_fck; + + max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK); + + cinfo->regm_dsi = DIV_ROUND_UP(cinfo->clkin4ddr, max_dsi_fck); + cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi; +} + +static int dsi_pll_calc_dispc_fck(struct platform_device *dsidev, + unsigned long req_pck, struct dsi_clock_info *cinfo, + struct dispc_clock_info *dispc_cinfo) +{ + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + unsigned regm_dispc, best_regm_dispc; + unsigned long dispc_clk, best_dispc_clk; + int min_fck_per_pck; + unsigned long max_dss_fck; + struct dispc_clock_info best_dispc; + bool match; + + max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); + + min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; + + if (min_fck_per_pck && + req_pck * min_fck_per_pck > max_dss_fck) { + DSSERR("Requested pixel clock not possible with the current " + "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " + "the constraint off.\n"); + min_fck_per_pck = 0; + } + +retry: + best_regm_dispc = 0; + best_dispc_clk = 0; + memset(&best_dispc, 0, sizeof(best_dispc)); + match = false; + + for (regm_dispc = 1; regm_dispc < dsi->regm_dispc_max; ++regm_dispc) { + struct dispc_clock_info cur_dispc; + + dispc_clk = cinfo->clkin4ddr / regm_dispc; + + /* this will narrow down the search a bit, + * but still give pixclocks below what was + * requested */ + if (dispc_clk < req_pck) + break; + + if (dispc_clk > max_dss_fck) + continue; + + if (min_fck_per_pck && dispc_clk < req_pck * min_fck_per_pck) + continue; + + match = true; + + dispc_find_clk_divs(req_pck, dispc_clk, &cur_dispc); + + if (abs(cur_dispc.pck - req_pck) < + abs(best_dispc.pck - req_pck)) { + best_regm_dispc = regm_dispc; + best_dispc_clk = dispc_clk; + best_dispc = cur_dispc; + + if (cur_dispc.pck == req_pck) + goto found; + } + } + + if (!match) { + if (min_fck_per_pck) { + DSSERR("Could not find suitable clock settings.\n" + "Turning FCK/PCK constraint off and" + "trying again.\n"); + min_fck_per_pck = 0; + goto retry; + } + + DSSERR("Could not find suitable clock settings.\n"); + + return -EINVAL; + } +found: + cinfo->regm_dispc = best_regm_dispc; + cinfo->dsi_pll_hsdiv_dispc_clk = best_dispc_clk; + + *dispc_cinfo = best_dispc; + + return 0; +} + int dsi_pll_set_clock_div(struct platform_device *dsidev, struct dsi_clock_info *cinfo) { @@ -1591,21 +1671,27 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev, BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max); + l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); + if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) { f = cinfo->fint < 1000000 ? 0x3 : cinfo->fint < 1250000 ? 0x4 : cinfo->fint < 1500000 ? 0x5 : cinfo->fint < 1750000 ? 0x6 : 0x7; - } - l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); - - if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ + } else if (dss_has_feature(FEAT_DSI_PLL_SELFREQDCO)) { + f = cinfo->clkin4ddr < 1000000000 ? 0x2 : 0x4; + + l = FLD_MOD(l, f, 4, 1); /* PLL_SELFREQDCO */ + } + l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ + if (dss_has_feature(FEAT_DSI_PLL_REFSEL)) + l = FLD_MOD(l, 3, 22, 21); /* REF_SYSCLK = sysclk */ dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ @@ -2069,6 +2155,8 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev) return 1194 * 3; /* 1194x24 bits */ case 6: return 1365 * 3; /* 1365x24 bits */ + case 7: + return 1920 * 3; /* 1920x24 bits */ default: BUG(); return 0; @@ -2204,6 +2292,13 @@ static void dsi_cio_timings(struct platform_device *dsidev) r = FLD_MOD(r, tlpx_half, 22, 16); r = FLD_MOD(r, tclk_trail, 15, 8); r = FLD_MOD(r, tclk_zero, 7, 0); + + if (dss_has_feature(FEAT_DSI_PHY_DCC)) { + r = FLD_MOD(r, 0, 21, 21); /* DCCEN = disable */ + r = FLD_MOD(r, 1, 22, 22); /* CLKINP_DIVBY2EN = enable */ + r = FLD_MOD(r, 1, 23, 23); /* CLKINP_SEL = enable */ + } + dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r); r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2); @@ -4188,33 +4283,35 @@ int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev, mutex_lock(&dsi->lock); - r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk, &cinfo); + /* Calculate PLL output clock */ + r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk * 4, &cinfo); if (r) goto err; - dssdev->clocks.dsi.regn = cinfo.regn; - dssdev->clocks.dsi.regm = cinfo.regm; - dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc; - dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi; + /* Calculate PLL's DSI clock */ + dsi_pll_calc_dsi_fck(dsidev, &cinfo); + /* Calculate PLL's DISPC clock and pck & lck divs */ + pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp; + DSSDBG("finding dispc dividers for pck %lu\n", pck); + r = dsi_pll_calc_dispc_fck(dsidev, pck, &cinfo, &dispc_cinfo); + if (r) + goto err; + /* Calculate LP clock */ dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk; lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2); - dssdev->clocks.dsi.lp_clk_div = lp_clk_div; - - /* pck = TxByteClkHS * datalanes * 8 / bitsperpixel */ - - pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp; - - DSSDBG("finding dispc dividers for pck %lu\n", pck); + dssdev->clocks.dsi.regn = cinfo.regn; + dssdev->clocks.dsi.regm = cinfo.regm; + dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc; + dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi; - dispc_find_clk_divs(pck, cinfo.dsi_pll_hsdiv_dispc_clk, &dispc_cinfo); + dssdev->clocks.dsi.lp_clk_div = lp_clk_div; dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div; dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div; - dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK; dssdev->clocks.dispc.channel.lcd_clk_src = diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 759dbee48342..2ab1c3e96553 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -69,6 +69,7 @@ struct dss_features { u8 fck_div_max; u8 dss_fck_multiplier; const char *clk_name; + int (*dpi_select_source)(enum omap_channel channel); }; static struct { @@ -99,30 +100,6 @@ static const char * const dss_generic_clk_source_names[] = { [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK", }; -static const struct dss_features omap24xx_dss_feats __initconst = { - .fck_div_max = 16, - .dss_fck_multiplier = 2, - .clk_name = NULL, -}; - -static const struct dss_features omap34xx_dss_feats __initconst = { - .fck_div_max = 16, - .dss_fck_multiplier = 2, - .clk_name = "dpll4_m4_ck", -}; - -static const struct dss_features omap3630_dss_feats __initconst = { - .fck_div_max = 32, - .dss_fck_multiplier = 1, - .clk_name = "dpll4_m4_ck", -}; - -static const struct dss_features omap44xx_dss_feats __initconst = { - .fck_div_max = 32, - .dss_fck_multiplier = 1, - .clk_name = "dpll_per_m5x2_ck", -}; - static inline void dss_write_reg(const struct dss_reg idx, u32 val) { __raw_writel(val, dss.base + idx.idx); @@ -647,6 +624,65 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void) return REG_GET(DSS_CONTROL, 15, 15); } +static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel) +{ + if (channel != OMAP_DSS_CHANNEL_LCD) + return -EINVAL; + + return 0; +} + +static int dss_dpi_select_source_omap4(enum omap_channel channel) +{ + int val; + + switch (channel) { + case OMAP_DSS_CHANNEL_LCD2: + val = 0; + break; + case OMAP_DSS_CHANNEL_DIGIT: + val = 1; + break; + default: + return -EINVAL; + } + + REG_FLD_MOD(DSS_CONTROL, val, 17, 17); + + return 0; +} + +static int dss_dpi_select_source_omap5(enum omap_channel channel) +{ + int val; + + switch (channel) { + case OMAP_DSS_CHANNEL_LCD: + val = 1; + break; + case OMAP_DSS_CHANNEL_LCD2: + val = 2; + break; + case OMAP_DSS_CHANNEL_LCD3: + val = 3; + break; + case OMAP_DSS_CHANNEL_DIGIT: + val = 0; + break; + default: + return -EINVAL; + } + + REG_FLD_MOD(DSS_CONTROL, val, 17, 16); + + return 0; +} + +int dss_dpi_select_source(enum omap_channel channel) +{ + return dss.feat->dpi_select_source(channel); +} + static int dss_get_clocks(void) { struct clk *clk; @@ -721,6 +757,41 @@ void dss_debug_dump_clocks(struct seq_file *s) } #endif +static const struct dss_features omap24xx_dss_feats __initconst = { + .fck_div_max = 16, + .dss_fck_multiplier = 2, + .clk_name = NULL, + .dpi_select_source = &dss_dpi_select_source_omap2_omap3, +}; + +static const struct dss_features omap34xx_dss_feats __initconst = { + .fck_div_max = 16, + .dss_fck_multiplier = 2, + .clk_name = "dpll4_m4_ck", + .dpi_select_source = &dss_dpi_select_source_omap2_omap3, +}; + +static const struct dss_features omap3630_dss_feats __initconst = { + .fck_div_max = 32, + .dss_fck_multiplier = 1, + .clk_name = "dpll4_m4_ck", + .dpi_select_source = &dss_dpi_select_source_omap2_omap3, +}; + +static const struct dss_features omap44xx_dss_feats __initconst = { + .fck_div_max = 32, + .dss_fck_multiplier = 1, + .clk_name = "dpll_per_m5x2_ck", + .dpi_select_source = &dss_dpi_select_source_omap4, +}; + +static const struct dss_features omap54xx_dss_feats __initconst = { + .fck_div_max = 64, + .dss_fck_multiplier = 1, + .clk_name = "dpll_per_h12x2_ck", + .dpi_select_source = &dss_dpi_select_source_omap5, +}; + static int __init dss_init_features(struct device *dev) { const struct dss_features *src; @@ -740,6 +811,8 @@ static int __init dss_init_features(struct device *dev) src = &omap3630_dss_feats; else if (cpu_is_omap44xx()) src = &omap44xx_dss_feats; + else if (soc_is_omap54xx()) + src = &omap54xx_dss_feats; else return -ENODEV; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 417d30571747..40c36cafec6e 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -280,6 +280,7 @@ void dss_overlay_kobj_uninit(struct omap_overlay *ovl); int dss_init_platform_driver(void) __init; void dss_uninit_platform_driver(void); +int dss_dpi_select_source(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); diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 47c15304fe87..406913949e2c 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -106,6 +106,21 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = { [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 }, }; +static const struct dss_reg_field omap5_dss_reg_fields[] = { + [FEAT_REG_FIRHINC] = { 12, 0 }, + [FEAT_REG_FIRVINC] = { 28, 16 }, + [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 }, + [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 }, + [FEAT_REG_FIFOSIZE] = { 15, 0 }, + [FEAT_REG_HORIZONTALACCU] = { 10, 0 }, + [FEAT_REG_VERTICALACCU] = { 26, 16 }, + [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 }, + [FEAT_REG_DSIPLL_REGN] = { 8, 1 }, + [FEAT_REG_DSIPLL_REGM] = { 20, 9 }, + [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 }, + [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 }, +}; + static const enum omap_display_type omap2_dss_supported_displays[] = { /* OMAP_DSS_CHANNEL_LCD */ OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI, @@ -144,6 +159,19 @@ static const enum omap_display_type omap4_dss_supported_displays[] = { OMAP_DISPLAY_TYPE_DSI, }; +static const enum omap_display_type omap5_dss_supported_displays[] = { + /* OMAP_DSS_CHANNEL_LCD */ + OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | + OMAP_DISPLAY_TYPE_DSI, + + /* OMAP_DSS_CHANNEL_DIGIT */ + OMAP_DISPLAY_TYPE_HDMI | OMAP_DISPLAY_TYPE_DPI, + + /* OMAP_DSS_CHANNEL_LCD2 */ + OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | + OMAP_DISPLAY_TYPE_DSI, +}; + static const enum omap_color_mode omap2_dss_supported_color_modes[] = { /* OMAP_DSS_GFX */ OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | @@ -298,6 +326,14 @@ static const char * const omap4_dss_clk_source_names[] = { [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, 173000000 }, [FEAT_PARAM_DSS_PCD] = { 2, 255 }, @@ -349,6 +385,22 @@ static const struct dss_param_range omap4_dss_param_range[] = { [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, }; +static const struct dss_param_range omap5_dss_param_range[] = { + [FEAT_PARAM_DSS_FCK] = { 0, 200000000 }, + [FEAT_PARAM_DSS_PCD] = { 1, 255 }, + [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 }, + [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 }, + [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 }, + [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 }, + [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 }, + [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, + [FEAT_PARAM_DSI_FCK] = { 0, 170000000 }, + [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, + [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, + [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, + [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, +}; + static const enum dss_feat_id omap2_dss_feat_list[] = { FEAT_LCDENABLEPOL, FEAT_LCDENABLESIGNAL, @@ -469,6 +521,28 @@ static const enum dss_feat_id omap4_dss_feat_list[] = { FEAT_BURST_2D, }; +static const enum dss_feat_id omap5_dss_feat_list[] = { + FEAT_MGR_LCD2, + FEAT_CORE_CLK_DIV, + FEAT_LCD_CLK_SRC, + FEAT_DSI_DCS_CMD_CONFIG_VC, + FEAT_DSI_VC_OCP_WIDTH, + FEAT_DSI_GNQ, + FEAT_HDMI_CTS_SWMODE, + FEAT_HDMI_AUDIO_USE_MCLK, + FEAT_HANDLE_UV_SEPARATE, + FEAT_ATTR2, + FEAT_CPR, + FEAT_PRELOAD, + FEAT_FIR_COEF_V, + FEAT_ALPHA_FREE_ZORDER, + FEAT_FIFO_MERGE, + FEAT_BURST_2D, + FEAT_DSI_PLL_SELFREQDCO, + FEAT_DSI_PLL_REFSEL, + FEAT_DSI_PHY_DCC, +}; + /* OMAP2 DSS Features */ static const struct omap_dss_features omap2_dss_features = { .reg_fields = omap2_dss_reg_fields, @@ -612,6 +686,26 @@ static const struct omap_dss_features omap4_dss_features = { .burst_size_unit = 16, }; +/* OMAP5 DSS Features */ +static const struct omap_dss_features omap5_dss_features = { + .reg_fields = omap5_dss_reg_fields, + .num_reg_fields = ARRAY_SIZE(omap5_dss_reg_fields), + + .features = omap5_dss_feat_list, + .num_features = ARRAY_SIZE(omap5_dss_feat_list), + + .num_mgrs = 3, + .num_ovls = 4, + .supported_displays = omap5_dss_supported_displays, + .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, + .burst_size_unit = 16, +}; + #if defined(CONFIG_OMAP4_DSS_HDMI) /* HDMI OMAP4 Functions*/ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { @@ -754,6 +848,8 @@ void dss_features_init(void) omap_current_dss_features = &omap4430_es2_0_1_2_dss_features; else if (cpu_is_omap44xx()) omap_current_dss_features = &omap4_dss_features; + else if (soc_is_omap54xx()) + omap_current_dss_features = &omap5_dss_features; else DSSWARN("Unsupported OMAP version"); } diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index b81d603310a8..aacad863fa22 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -65,6 +65,9 @@ enum dss_feat_id { /* An unknown HW bug causing the normal FIFO thresholds not to work */ FEAT_OMAP3_DSI_FIFO_BUG, FEAT_BURST_2D, + FEAT_DSI_PLL_SELFREQDCO, + FEAT_DSI_PLL_REFSEL, + FEAT_DSI_PHY_DCC, }; /* DSS register field id */ |