Commit 406f7b8b authored by Tomi Valkeinen's avatar Tomi Valkeinen

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
parents c0ca7c38 99588589
...@@ -84,7 +84,7 @@ config OMAP2_DSS_SDI ...@@ -84,7 +84,7 @@ config OMAP2_DSS_SDI
config OMAP2_DSS_DSI config OMAP2_DSS_DSI
bool "DSI support" bool "DSI support"
depends on ARCH_OMAP3 || ARCH_OMAP4 depends on ARCH_OMAP3 || ARCH_OMAP4 || ARCH_OMAP5
default n default n
help help
MIPI DSI (Display Serial Interface) support. MIPI DSI (Display Serial Interface) support.
......
...@@ -3829,6 +3829,8 @@ static int __init dispc_init_features(struct device *dev) ...@@ -3829,6 +3829,8 @@ static int __init dispc_init_features(struct device *dev)
src = &omap34xx_rev3_0_dispc_feats; src = &omap34xx_rev3_0_dispc_feats;
} else if (cpu_is_omap44xx()) { } else if (cpu_is_omap44xx()) {
src = &omap44xx_dispc_feats; src = &omap44xx_dispc_feats;
} else if (soc_is_omap54xx()) {
src = &omap44xx_dispc_feats;
} else { } else {
return -ENODEV; return -ENODEV;
} }
......
...@@ -203,6 +203,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) ...@@ -203,6 +203,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
if (r) if (r)
goto err_get_dispc; goto err_get_dispc;
r = dss_dpi_select_source(dssdev->channel);
if (r)
goto err_src_sel;
if (dpi_use_dsi_pll(dssdev)) { if (dpi_use_dsi_pll(dssdev)) {
r = dsi_runtime_get(dpi.dsidev); r = dsi_runtime_get(dpi.dsidev);
if (r) if (r)
...@@ -237,6 +241,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) ...@@ -237,6 +241,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
if (dpi_use_dsi_pll(dssdev)) if (dpi_use_dsi_pll(dssdev))
dsi_runtime_put(dpi.dsidev); dsi_runtime_put(dpi.dsidev);
err_get_dsi: err_get_dsi:
err_src_sel:
dispc_runtime_put(); dispc_runtime_put();
err_get_dispc: err_get_dispc:
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
......
...@@ -1454,26 +1454,17 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, ...@@ -1454,26 +1454,17 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
} }
static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev, 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_data *dsi = dsi_get_dsidrv_data(dsidev);
struct dsi_clock_info cur, best; 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"); 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(&best, 0, sizeof(best));
memset(&cur, 0, sizeof(cur)); memset(&cur, 0, sizeof(cur));
cur.clkin = dss_sys_clk; cur.clkin = clk_get_rate(dsi->sys_clk);
req_clkin4ddr = req_clk * 4;
for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
cur.fint = cur.clkin / cur.regn; cur.fint = cur.clkin / cur.regn;
...@@ -1503,18 +1494,107 @@ static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev, ...@@ -1503,18 +1494,107 @@ static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev,
} }
} }
found: 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) if (cinfo)
*cinfo = best; *cinfo = best;
return 0; 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, int dsi_pll_set_clock_div(struct platform_device *dsidev,
struct dsi_clock_info *cinfo) struct dsi_clock_info *cinfo)
{ {
...@@ -1591,21 +1671,27 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev, ...@@ -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); 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)) { if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) {
f = cinfo->fint < 1000000 ? 0x3 : f = cinfo->fint < 1000000 ? 0x3 :
cinfo->fint < 1250000 ? 0x4 : cinfo->fint < 1250000 ? 0x4 :
cinfo->fint < 1500000 ? 0x5 : cinfo->fint < 1500000 ? 0x5 :
cinfo->fint < 1750000 ? 0x6 : cinfo->fint < 1750000 ? 0x6 :
0x7; 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 */ 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, 1, 13, 13); /* DSI_PLL_REFEN */
l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */
l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ 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); dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ 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) ...@@ -2069,6 +2155,8 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
return 1194 * 3; /* 1194x24 bits */ return 1194 * 3; /* 1194x24 bits */
case 6: case 6:
return 1365 * 3; /* 1365x24 bits */ return 1365 * 3; /* 1365x24 bits */
case 7:
return 1920 * 3; /* 1920x24 bits */
default: default:
BUG(); BUG();
return 0; return 0;
...@@ -2204,6 +2292,13 @@ static void dsi_cio_timings(struct platform_device *dsidev) ...@@ -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, tlpx_half, 22, 16);
r = FLD_MOD(r, tclk_trail, 15, 8); r = FLD_MOD(r, tclk_trail, 15, 8);
r = FLD_MOD(r, tclk_zero, 7, 0); 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); dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r);
r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2); r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2);
...@@ -4188,33 +4283,35 @@ int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev, ...@@ -4188,33 +4283,35 @@ int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
mutex_lock(&dsi->lock); 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) if (r)
goto err; goto err;
dssdev->clocks.dsi.regn = cinfo.regn; /* Calculate PLL's DSI clock */
dssdev->clocks.dsi.regm = cinfo.regm; dsi_pll_calc_dsi_fck(dsidev, &cinfo);
dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc;
dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi;
/* 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; dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk;
lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2); lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2);
dssdev->clocks.dsi.lp_clk_div = lp_clk_div; dssdev->clocks.dsi.regn = cinfo.regn;
dssdev->clocks.dsi.regm = cinfo.regm;
/* pck = TxByteClkHS * datalanes * 8 / bitsperpixel */ dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc;
dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi;
pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp;
DSSDBG("finding dispc dividers for pck %lu\n", pck);
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.lck_div = dispc_cinfo.lck_div;
dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_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.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK;
dssdev->clocks.dispc.channel.lcd_clk_src = dssdev->clocks.dispc.channel.lcd_clk_src =
......
...@@ -69,6 +69,7 @@ struct dss_features { ...@@ -69,6 +69,7 @@ struct dss_features {
u8 fck_div_max; u8 fck_div_max;
u8 dss_fck_multiplier; u8 dss_fck_multiplier;
const char *clk_name; const char *clk_name;
int (*dpi_select_source)(enum omap_channel channel);
}; };
static struct { static struct {
...@@ -99,30 +100,6 @@ static const char * const dss_generic_clk_source_names[] = { ...@@ -99,30 +100,6 @@ static const char * const dss_generic_clk_source_names[] = {
[OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK", [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) static inline void dss_write_reg(const struct dss_reg idx, u32 val)
{ {
__raw_writel(val, dss.base + idx.idx); __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) ...@@ -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); 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) static int dss_get_clocks(void)
{ {
struct clk *clk; struct clk *clk;
...@@ -721,6 +757,41 @@ void dss_debug_dump_clocks(struct seq_file *s) ...@@ -721,6 +757,41 @@ void dss_debug_dump_clocks(struct seq_file *s)
} }
#endif #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) static int __init dss_init_features(struct device *dev)
{ {
const struct dss_features *src; const struct dss_features *src;
...@@ -740,6 +811,8 @@ static int __init dss_init_features(struct device *dev) ...@@ -740,6 +811,8 @@ static int __init dss_init_features(struct device *dev)
src = &omap3630_dss_feats; src = &omap3630_dss_feats;
else if (cpu_is_omap44xx()) else if (cpu_is_omap44xx())
src = &omap44xx_dss_feats; src = &omap44xx_dss_feats;
else if (soc_is_omap54xx())
src = &omap54xx_dss_feats;
else else
return -ENODEV; return -ENODEV;
......
...@@ -280,6 +280,7 @@ void dss_overlay_kobj_uninit(struct omap_overlay *ovl); ...@@ -280,6 +280,7 @@ void dss_overlay_kobj_uninit(struct omap_overlay *ovl);
int dss_init_platform_driver(void) __init; int dss_init_platform_driver(void) __init;
void dss_uninit_platform_driver(void); 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); 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); 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_generic_clk_source_name(enum omap_dss_clk_source clk_src);
......
...@@ -106,6 +106,21 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = { ...@@ -106,6 +106,21 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = {
[FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 }, [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[] = { static const enum omap_display_type omap2_dss_supported_displays[] = {
/* OMAP_DSS_CHANNEL_LCD */ /* OMAP_DSS_CHANNEL_LCD */
OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI, OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
...@@ -144,6 +159,19 @@ static const enum omap_display_type omap4_dss_supported_displays[] = { ...@@ -144,6 +159,19 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
OMAP_DISPLAY_TYPE_DSI, 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[] = { static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
/* OMAP_DSS_GFX */ /* OMAP_DSS_GFX */
OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
...@@ -298,6 +326,14 @@ static const char * const omap4_dss_clk_source_names[] = { ...@@ -298,6 +326,14 @@ static const char * const omap4_dss_clk_source_names[] = {
[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2", [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[] = { static const struct dss_param_range omap2_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
[FEAT_PARAM_DSS_PCD] = { 2, 255 }, [FEAT_PARAM_DSS_PCD] = { 2, 255 },
...@@ -349,6 +385,22 @@ static const struct dss_param_range omap4_dss_param_range[] = { ...@@ -349,6 +385,22 @@ static const struct dss_param_range omap4_dss_param_range[] = {
[FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, [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[] = { static const enum dss_feat_id omap2_dss_feat_list[] = {
FEAT_LCDENABLEPOL, FEAT_LCDENABLEPOL,
FEAT_LCDENABLESIGNAL, FEAT_LCDENABLESIGNAL,
...@@ -469,6 +521,28 @@ static const enum dss_feat_id omap4_dss_feat_list[] = { ...@@ -469,6 +521,28 @@ static const enum dss_feat_id omap4_dss_feat_list[] = {
FEAT_BURST_2D, 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 */ /* OMAP2 DSS Features */
static const struct omap_dss_features omap2_dss_features = { static const struct omap_dss_features omap2_dss_features = {
.reg_fields = omap2_dss_reg_fields, .reg_fields = omap2_dss_reg_fields,
...@@ -612,6 +686,26 @@ static const struct omap_dss_features omap4_dss_features = { ...@@ -612,6 +686,26 @@ static const struct omap_dss_features omap4_dss_features = {
.burst_size_unit = 16, .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) #if defined(CONFIG_OMAP4_DSS_HDMI)
/* HDMI OMAP4 Functions*/ /* HDMI OMAP4 Functions*/
static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
...@@ -754,6 +848,8 @@ void dss_features_init(void) ...@@ -754,6 +848,8 @@ void dss_features_init(void)
omap_current_dss_features = &omap4430_es2_0_1_2_dss_features; omap_current_dss_features = &omap4430_es2_0_1_2_dss_features;
else if (cpu_is_omap44xx()) else if (cpu_is_omap44xx())
omap_current_dss_features = &omap4_dss_features; omap_current_dss_features = &omap4_dss_features;
else if (soc_is_omap54xx())
omap_current_dss_features = &omap5_dss_features;
else else
DSSWARN("Unsupported OMAP version"); DSSWARN("Unsupported OMAP version");
} }
...@@ -65,6 +65,9 @@ enum dss_feat_id { ...@@ -65,6 +65,9 @@ enum dss_feat_id {
/* An unknown HW bug causing the normal FIFO thresholds not to work */ /* An unknown HW bug causing the normal FIFO thresholds not to work */
FEAT_OMAP3_DSI_FIFO_BUG, FEAT_OMAP3_DSI_FIFO_BUG,
FEAT_BURST_2D, FEAT_BURST_2D,
FEAT_DSI_PLL_SELFREQDCO,
FEAT_DSI_PLL_REFSEL,
FEAT_DSI_PHY_DCC,
}; };
/* DSS register field id */ /* DSS register field id */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment