Commit 49641116 authored by Taneja, Archit's avatar Taneja, Archit Committed by Tomi Valkeinen

OMAP: DSS2: FEATURES: DSI PLL parameter cleanup

The DSI PLL parameters (regm, regn, regm_dispc, regm_dsi, fint) have different
fields and also different Max values on OMAP3 and OMAP4. Use dss features to
calculate the register fields and min/max values based on current OMAP revision.
Signed-off-by: default avatarArchit Taneja <archit@ti.com>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent 31ef8237
...@@ -185,14 +185,6 @@ struct dsi_reg { u16 idx; }; ...@@ -185,14 +185,6 @@ struct dsi_reg { u16 idx; };
#define DSI_DT_RX_SHORT_READ_1 0x21 #define DSI_DT_RX_SHORT_READ_1 0x21
#define DSI_DT_RX_SHORT_READ_2 0x22 #define DSI_DT_RX_SHORT_READ_2 0x22
#define FINT_MAX 2100000
#define FINT_MIN 750000
#define REGN_MAX (1 << 7)
#define REGM_MAX ((1 << 11) - 1)
#define REGM_DISPC_MAX (1 << 4)
#define REGM_DSI_MAX (1 << 4)
#define LP_DIV_MAX ((1 << 13) - 1)
enum fifo_size { enum fifo_size {
DSI_FIFO_SIZE_0 = 0, DSI_FIFO_SIZE_0 = 0,
DSI_FIFO_SIZE_32 = 1, DSI_FIFO_SIZE_32 = 1,
...@@ -277,6 +269,11 @@ static struct ...@@ -277,6 +269,11 @@ static struct
spinlock_t irq_stats_lock; spinlock_t irq_stats_lock;
struct dsi_irq_stats irq_stats; struct dsi_irq_stats irq_stats;
#endif #endif
/* DSI PLL Parameter Ranges */
unsigned long regm_max, regn_max;
unsigned long regm_dispc_max, regm_dsi_max;
unsigned long fint_min, fint_max;
unsigned long lpdiv_max;
} dsi; } dsi;
#ifdef DEBUG #ifdef DEBUG
...@@ -751,7 +748,7 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) ...@@ -751,7 +748,7 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
lp_clk_div = dssdev->phy.dsi.div.lp_clk_div; lp_clk_div = dssdev->phy.dsi.div.lp_clk_div;
if (lp_clk_div == 0 || lp_clk_div > LP_DIV_MAX) if (lp_clk_div == 0 || lp_clk_div > dsi.lpdiv_max)
return -EINVAL; return -EINVAL;
dsi_fclk = dsi_fclk_rate(); dsi_fclk = dsi_fclk_rate();
...@@ -801,16 +798,16 @@ static int dsi_pll_power(enum dsi_pll_power_state state) ...@@ -801,16 +798,16 @@ static int dsi_pll_power(enum dsi_pll_power_state state)
static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
struct dsi_clock_info *cinfo) struct dsi_clock_info *cinfo)
{ {
if (cinfo->regn == 0 || cinfo->regn > REGN_MAX) if (cinfo->regn == 0 || cinfo->regn > dsi.regn_max)
return -EINVAL; return -EINVAL;
if (cinfo->regm == 0 || cinfo->regm > REGM_MAX) if (cinfo->regm == 0 || cinfo->regm > dsi.regm_max)
return -EINVAL; return -EINVAL;
if (cinfo->regm_dispc > REGM_DISPC_MAX) if (cinfo->regm_dispc > dsi.regm_dispc_max)
return -EINVAL; return -EINVAL;
if (cinfo->regm_dsi > REGM_DSI_MAX) if (cinfo->regm_dsi > dsi.regm_dsi_max)
return -EINVAL; return -EINVAL;
if (cinfo->use_sys_clk) { if (cinfo->use_sys_clk) {
...@@ -829,7 +826,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, ...@@ -829,7 +826,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1)); cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1));
if (cinfo->fint > FINT_MAX || cinfo->fint < FINT_MIN) if (cinfo->fint > dsi.fint_max || cinfo->fint < dsi.fint_min)
return -EINVAL; return -EINVAL;
cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint; cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint;
...@@ -899,17 +896,17 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, ...@@ -899,17 +896,17 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
/* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */
/* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */
/* To reduce PLL lock time, keep Fint high (around 2 MHz) */ /* To reduce PLL lock time, keep Fint high (around 2 MHz) */
for (cur.regn = 1; cur.regn < REGN_MAX; ++cur.regn) { for (cur.regn = 1; cur.regn < dsi.regn_max; ++cur.regn) {
if (cur.highfreq == 0) if (cur.highfreq == 0)
cur.fint = cur.clkin / cur.regn; cur.fint = cur.clkin / cur.regn;
else else
cur.fint = cur.clkin / (2 * cur.regn); cur.fint = cur.clkin / (2 * cur.regn);
if (cur.fint > FINT_MAX || cur.fint < FINT_MIN) if (cur.fint > dsi.fint_max || cur.fint < dsi.fint_min)
continue; continue;
/* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */
for (cur.regm = 1; cur.regm < REGM_MAX; ++cur.regm) { for (cur.regm = 1; cur.regm < dsi.regm_max; ++cur.regm) {
unsigned long a, b; unsigned long a, b;
a = 2 * cur.regm * (cur.clkin/1000); a = 2 * cur.regm * (cur.clkin/1000);
...@@ -921,7 +918,7 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, ...@@ -921,7 +918,7 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
/* dsi_pll_hsdiv_dispc_clk(MHz) = /* dsi_pll_hsdiv_dispc_clk(MHz) =
* DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */ * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */
for (cur.regm_dispc = 1; cur.regm_dispc < REGM_DISPC_MAX; for (cur.regm_dispc = 1; cur.regm_dispc < dsi.regm_dispc_max;
++cur.regm_dispc) { ++cur.regm_dispc) {
struct dispc_clock_info cur_dispc; struct dispc_clock_info cur_dispc;
cur.dsi_pll_hsdiv_dispc_clk = cur.dsi_pll_hsdiv_dispc_clk =
...@@ -994,6 +991,8 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) ...@@ -994,6 +991,8 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
int r = 0; int r = 0;
u32 l; u32 l;
int f; int f;
u8 regn_start, regn_end, regm_start, regm_end;
u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
DSSDBGF(); DSSDBGF();
...@@ -1038,19 +1037,30 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) ...@@ -1038,19 +1037,30 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
cinfo->dsi_pll_hsdiv_dsi_clk); cinfo->dsi_pll_hsdiv_dsi_clk);
dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, &regn_start, &regn_end);
dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM, &regm_start, &regm_end);
dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DISPC, &regm_dispc_start,
&regm_dispc_end);
dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, &regm_dsi_start,
&regm_dsi_end);
REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */
l = dsi_read_reg(DSI_PLL_CONFIGURATION1); l = dsi_read_reg(DSI_PLL_CONFIGURATION1);
l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */
l = FLD_MOD(l, cinfo->regn - 1, 7, 1); /* DSI_PLL_REGN */ /* DSI_PLL_REGN */
l = FLD_MOD(l, cinfo->regm, 18, 8); /* DSI_PLL_REGM */ l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end);
/* DSI_PLL_REGM */
l = FLD_MOD(l, cinfo->regm, regm_start, regm_end);
/* DSI_CLOCK_DIV */
l = FLD_MOD(l, cinfo->regm_dispc > 0 ? cinfo->regm_dispc - 1 : 0, l = FLD_MOD(l, cinfo->regm_dispc > 0 ? cinfo->regm_dispc - 1 : 0,
22, 19); /* DSI_CLOCK_DIV */ regm_dispc_start, regm_dispc_end);
/* DSIPROTO_CLOCK_DIV */
l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0, l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0,
26, 23); /* DSIPROTO_CLOCK_DIV */ regm_dsi_start, regm_dsi_end);
dsi_write_reg(DSI_PLL_CONFIGURATION1, l); dsi_write_reg(DSI_PLL_CONFIGURATION1, l);
BUG_ON(cinfo->fint < 750000 || cinfo->fint > 2100000); BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max);
if (cinfo->fint < 1000000) if (cinfo->fint < 1000000)
f = 0x3; f = 0x3;
else if (cinfo->fint < 1250000) else if (cinfo->fint < 1250000)
...@@ -3333,6 +3343,17 @@ void dsi_wait_pll_hsdiv_dsi_active(void) ...@@ -3333,6 +3343,17 @@ void dsi_wait_pll_hsdiv_dsi_active(void)
dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI)); dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI));
} }
static void dsi_calc_clock_param_ranges(void)
{
dsi.regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN);
dsi.regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM);
dsi.regm_dispc_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC);
dsi.regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI);
dsi.fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT);
dsi.fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT);
dsi.lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
}
static int dsi_init(struct platform_device *pdev) static int dsi_init(struct platform_device *pdev)
{ {
u32 rev; u32 rev;
...@@ -3397,6 +3418,8 @@ static int dsi_init(struct platform_device *pdev) ...@@ -3397,6 +3418,8 @@ static int dsi_init(struct platform_device *pdev)
dsi.vc[i].vc_id = 0; dsi.vc[i].vc_id = 0;
} }
dsi_calc_clock_param_ranges();
enable_clocks(1); enable_clocks(1);
rev = dsi_read_reg(DSI_REVISION); rev = dsi_read_reg(DSI_REVISION);
......
...@@ -55,36 +55,48 @@ struct omap_dss_features { ...@@ -55,36 +55,48 @@ struct omap_dss_features {
static struct omap_dss_features *omap_current_dss_features; static struct omap_dss_features *omap_current_dss_features;
static const struct dss_reg_field omap2_dss_reg_fields[] = { static const struct dss_reg_field omap2_dss_reg_fields[] = {
[FEAT_REG_FIRHINC] = { 11, 0 }, [FEAT_REG_FIRHINC] = { 11, 0 },
[FEAT_REG_FIRVINC] = { 27, 16 }, [FEAT_REG_FIRVINC] = { 27, 16 },
[FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 }, [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 },
[FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 }, [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 },
[FEAT_REG_FIFOSIZE] = { 8, 0 }, [FEAT_REG_FIFOSIZE] = { 8, 0 },
[FEAT_REG_HORIZONTALACCU] = { 9, 0 }, [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
[FEAT_REG_VERTICALACCU] = { 25, 16 }, [FEAT_REG_VERTICALACCU] = { 25, 16 },
[FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 }, [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
[FEAT_REG_DSIPLL_REGN] = { 0, 0 },
[FEAT_REG_DSIPLL_REGM] = { 0, 0 },
[FEAT_REG_DSIPLL_REGM_DISPC] = { 0, 0 },
[FEAT_REG_DSIPLL_REGM_DSI] = { 0, 0 },
}; };
static const struct dss_reg_field omap3_dss_reg_fields[] = { static const struct dss_reg_field omap3_dss_reg_fields[] = {
[FEAT_REG_FIRHINC] = { 12, 0 }, [FEAT_REG_FIRHINC] = { 12, 0 },
[FEAT_REG_FIRVINC] = { 28, 16 }, [FEAT_REG_FIRVINC] = { 28, 16 },
[FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 }, [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
[FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 }, [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
[FEAT_REG_FIFOSIZE] = { 10, 0 }, [FEAT_REG_FIFOSIZE] = { 10, 0 },
[FEAT_REG_HORIZONTALACCU] = { 9, 0 }, [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
[FEAT_REG_VERTICALACCU] = { 25, 16 }, [FEAT_REG_VERTICALACCU] = { 25, 16 },
[FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 }, [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
[FEAT_REG_DSIPLL_REGN] = { 7, 1 },
[FEAT_REG_DSIPLL_REGM] = { 18, 8 },
[FEAT_REG_DSIPLL_REGM_DISPC] = { 22, 19 },
[FEAT_REG_DSIPLL_REGM_DSI] = { 26, 23 },
}; };
static const struct dss_reg_field omap4_dss_reg_fields[] = { static const struct dss_reg_field omap4_dss_reg_fields[] = {
[FEAT_REG_FIRHINC] = { 12, 0 }, [FEAT_REG_FIRHINC] = { 12, 0 },
[FEAT_REG_FIRVINC] = { 28, 16 }, [FEAT_REG_FIRVINC] = { 28, 16 },
[FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 }, [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
[FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 }, [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
[FEAT_REG_FIFOSIZE] = { 15, 0 }, [FEAT_REG_FIFOSIZE] = { 15, 0 },
[FEAT_REG_HORIZONTALACCU] = { 10, 0 }, [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
[FEAT_REG_VERTICALACCU] = { 26, 16 }, [FEAT_REG_VERTICALACCU] = { 26, 16 },
[FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 }, [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
[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[] = {
...@@ -184,15 +196,33 @@ static const char * const omap4_dss_clk_source_names[] = { ...@@ -184,15 +196,33 @@ static const char * const omap4_dss_clk_source_names[] = {
}; };
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_DSIPLL_REGN] = { 0, 0 },
[FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
[FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
}; };
static const struct dss_param_range omap3_dss_param_range[] = { static const struct dss_param_range omap3_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
[FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
[FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
[FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
}; };
static const struct dss_param_range omap4_dss_param_range[] = { static const struct dss_param_range omap4_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 186000000 }, [FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
[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 },
}; };
/* OMAP2 DSS Features */ /* OMAP2 DSS Features */
......
...@@ -52,10 +52,20 @@ enum dss_feat_reg_field { ...@@ -52,10 +52,20 @@ enum dss_feat_reg_field {
FEAT_REG_HORIZONTALACCU, FEAT_REG_HORIZONTALACCU,
FEAT_REG_VERTICALACCU, FEAT_REG_VERTICALACCU,
FEAT_REG_DISPC_CLK_SWITCH, FEAT_REG_DISPC_CLK_SWITCH,
FEAT_REG_DSIPLL_REGN,
FEAT_REG_DSIPLL_REGM,
FEAT_REG_DSIPLL_REGM_DISPC,
FEAT_REG_DSIPLL_REGM_DSI,
}; };
enum dss_range_param { enum dss_range_param {
FEAT_PARAM_DSS_FCK, FEAT_PARAM_DSS_FCK,
FEAT_PARAM_DSIPLL_REGN,
FEAT_PARAM_DSIPLL_REGM,
FEAT_PARAM_DSIPLL_REGM_DISPC,
FEAT_PARAM_DSIPLL_REGM_DSI,
FEAT_PARAM_DSIPLL_FINT,
FEAT_PARAM_DSIPLL_LPDIV,
}; };
/* DSS Feature Functions */ /* DSS Feature Functions */
......
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