|
@@ -219,6 +219,10 @@ static void dsi_display_uninit_dispc(struct platform_device *dsidev,
|
|
|
|
|
|
static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
|
|
static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
|
|
|
|
|
|
|
|
+/* DSI PLL HSDIV indices */
|
|
|
|
+#define HSDIV_DISPC 0
|
|
|
|
+#define HSDIV_DSI 1
|
|
|
|
+
|
|
#define DSI_MAX_NR_ISRS 2
|
|
#define DSI_MAX_NR_ISRS 2
|
|
#define DSI_MAX_NR_LANES 5
|
|
#define DSI_MAX_NR_LANES 5
|
|
|
|
|
|
@@ -271,6 +275,7 @@ struct dsi_isr_tables {
|
|
|
|
|
|
struct dsi_clk_calc_ctx {
|
|
struct dsi_clk_calc_ctx {
|
|
struct platform_device *dsidev;
|
|
struct platform_device *dsidev;
|
|
|
|
+ struct dss_pll *pll;
|
|
|
|
|
|
/* inputs */
|
|
/* inputs */
|
|
|
|
|
|
@@ -280,13 +285,18 @@ struct dsi_clk_calc_ctx {
|
|
|
|
|
|
/* outputs */
|
|
/* outputs */
|
|
|
|
|
|
- struct dsi_clock_info dsi_cinfo;
|
|
|
|
|
|
+ struct dss_pll_clock_info dsi_cinfo;
|
|
struct dispc_clock_info dispc_cinfo;
|
|
struct dispc_clock_info dispc_cinfo;
|
|
|
|
|
|
struct omap_video_timings dispc_vm;
|
|
struct omap_video_timings dispc_vm;
|
|
struct omap_dss_dsi_videomode_timings dsi_vm;
|
|
struct omap_dss_dsi_videomode_timings dsi_vm;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+struct dsi_lp_clock_info {
|
|
|
|
+ unsigned long lp_clk;
|
|
|
|
+ u16 lp_clk_div;
|
|
|
|
+};
|
|
|
|
+
|
|
struct dsi_data {
|
|
struct dsi_data {
|
|
struct platform_device *pdev;
|
|
struct platform_device *pdev;
|
|
void __iomem *proto_base;
|
|
void __iomem *proto_base;
|
|
@@ -300,12 +310,14 @@ struct dsi_data {
|
|
bool is_enabled;
|
|
bool is_enabled;
|
|
|
|
|
|
struct clk *dss_clk;
|
|
struct clk *dss_clk;
|
|
- struct clk *sys_clk;
|
|
|
|
|
|
|
|
struct dispc_clock_info user_dispc_cinfo;
|
|
struct dispc_clock_info user_dispc_cinfo;
|
|
- struct dsi_clock_info user_dsi_cinfo;
|
|
|
|
|
|
+ struct dss_pll_clock_info user_dsi_cinfo;
|
|
|
|
+
|
|
|
|
+ struct dsi_lp_clock_info user_lp_cinfo;
|
|
|
|
+ struct dsi_lp_clock_info current_lp_cinfo;
|
|
|
|
|
|
- struct dsi_clock_info current_cinfo;
|
|
|
|
|
|
+ struct dss_pll pll;
|
|
|
|
|
|
bool vdds_dsi_enabled;
|
|
bool vdds_dsi_enabled;
|
|
struct regulator *vdds_dsi_reg;
|
|
struct regulator *vdds_dsi_reg;
|
|
@@ -321,8 +333,6 @@ struct dsi_data {
|
|
struct mutex lock;
|
|
struct mutex lock;
|
|
struct semaphore bus_lock;
|
|
struct semaphore bus_lock;
|
|
|
|
|
|
- unsigned pll_locked;
|
|
|
|
-
|
|
|
|
spinlock_t irq_lock;
|
|
spinlock_t irq_lock;
|
|
struct dsi_isr_tables isr_tables;
|
|
struct dsi_isr_tables isr_tables;
|
|
/* space for a copy used by the interrupt handler */
|
|
/* space for a copy used by the interrupt handler */
|
|
@@ -347,7 +357,7 @@ struct dsi_data {
|
|
|
|
|
|
unsigned long cache_req_pck;
|
|
unsigned long cache_req_pck;
|
|
unsigned long cache_clk_freq;
|
|
unsigned long cache_clk_freq;
|
|
- struct dsi_clock_info cache_cinfo;
|
|
|
|
|
|
+ struct dss_pll_clock_info cache_cinfo;
|
|
|
|
|
|
u32 errors;
|
|
u32 errors;
|
|
spinlock_t errors_lock;
|
|
spinlock_t errors_lock;
|
|
@@ -362,11 +372,6 @@ struct dsi_data {
|
|
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;
|
|
|
|
|
|
|
|
unsigned num_lanes_supported;
|
|
unsigned num_lanes_supported;
|
|
unsigned line_buffer_size;
|
|
unsigned line_buffer_size;
|
|
@@ -412,7 +417,7 @@ static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss
|
|
return to_platform_device(dssdev->dev);
|
|
return to_platform_device(dssdev->dev);
|
|
}
|
|
}
|
|
|
|
|
|
-struct platform_device *dsi_get_dsidev_from_id(int module)
|
|
|
|
|
|
+static struct platform_device *dsi_get_dsidev_from_id(int module)
|
|
{
|
|
{
|
|
struct omap_dss_device *out;
|
|
struct omap_dss_device *out;
|
|
enum omap_dss_output_id id;
|
|
enum omap_dss_output_id id;
|
|
@@ -1134,7 +1139,7 @@ static u32 dsi_get_errors(struct platform_device *dsidev)
|
|
return e;
|
|
return e;
|
|
}
|
|
}
|
|
|
|
|
|
-int dsi_runtime_get(struct platform_device *dsidev)
|
|
|
|
|
|
+static int dsi_runtime_get(struct platform_device *dsidev)
|
|
{
|
|
{
|
|
int r;
|
|
int r;
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
@@ -1146,7 +1151,7 @@ int dsi_runtime_get(struct platform_device *dsidev)
|
|
return r < 0 ? r : 0;
|
|
return r < 0 ? r : 0;
|
|
}
|
|
}
|
|
|
|
|
|
-void dsi_runtime_put(struct platform_device *dsidev)
|
|
|
|
|
|
+static void dsi_runtime_put(struct platform_device *dsidev)
|
|
{
|
|
{
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
int r;
|
|
int r;
|
|
@@ -1188,23 +1193,6 @@ static int dsi_regulator_init(struct platform_device *dsidev)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-/* source clock for DSI PLL. this could also be PCLKFREE */
|
|
|
|
-static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
|
|
|
|
- bool enable)
|
|
|
|
-{
|
|
|
|
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
-
|
|
|
|
- if (enable)
|
|
|
|
- clk_prepare_enable(dsi->sys_clk);
|
|
|
|
- else
|
|
|
|
- clk_disable_unprepare(dsi->sys_clk);
|
|
|
|
-
|
|
|
|
- if (enable && dsi->pll_locked) {
|
|
|
|
- if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1)
|
|
|
|
- DSSERR("cannot lock PLL when enabling clocks\n");
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void _dsi_print_reset_status(struct platform_device *dsidev)
|
|
static void _dsi_print_reset_status(struct platform_device *dsidev)
|
|
{
|
|
{
|
|
u32 l;
|
|
u32 l;
|
|
@@ -1256,25 +1244,25 @@ static inline int dsi_if_enable(struct platform_device *dsidev, bool enable)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
|
|
|
|
|
|
+static unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
|
|
{
|
|
{
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
|
|
- return dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk;
|
|
|
|
|
|
+ return dsi->pll.cinfo.clkout[HSDIV_DISPC];
|
|
}
|
|
}
|
|
|
|
|
|
static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev)
|
|
static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev)
|
|
{
|
|
{
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
|
|
- return dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk;
|
|
|
|
|
|
+ return dsi->pll.cinfo.clkout[HSDIV_DSI];
|
|
}
|
|
}
|
|
|
|
|
|
static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev)
|
|
static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev)
|
|
{
|
|
{
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
|
|
- return dsi->current_cinfo.clkin4ddr / 16;
|
|
|
|
|
|
+ return dsi->pll.cinfo.clkdco / 16;
|
|
}
|
|
}
|
|
|
|
|
|
static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
|
|
static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
|
|
@@ -1293,10 +1281,10 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
|
|
return r;
|
|
return r;
|
|
}
|
|
}
|
|
|
|
|
|
-static int dsi_lp_clock_calc(struct dsi_clock_info *cinfo,
|
|
|
|
- unsigned long lp_clk_min, unsigned long lp_clk_max)
|
|
|
|
|
|
+static int dsi_lp_clock_calc(unsigned long dsi_fclk,
|
|
|
|
+ unsigned long lp_clk_min, unsigned long lp_clk_max,
|
|
|
|
+ struct dsi_lp_clock_info *lp_cinfo)
|
|
{
|
|
{
|
|
- unsigned long dsi_fclk = cinfo->dsi_pll_hsdiv_dsi_clk;
|
|
|
|
unsigned lp_clk_div;
|
|
unsigned lp_clk_div;
|
|
unsigned long lp_clk;
|
|
unsigned long lp_clk;
|
|
|
|
|
|
@@ -1306,8 +1294,8 @@ static int dsi_lp_clock_calc(struct dsi_clock_info *cinfo,
|
|
if (lp_clk < lp_clk_min || lp_clk > lp_clk_max)
|
|
if (lp_clk < lp_clk_min || lp_clk > lp_clk_max)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- cinfo->lp_clk_div = lp_clk_div;
|
|
|
|
- cinfo->lp_clk = lp_clk;
|
|
|
|
|
|
+ lp_cinfo->lp_clk_div = lp_clk_div;
|
|
|
|
+ lp_cinfo->lp_clk = lp_clk;
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1318,10 +1306,12 @@ static int dsi_set_lp_clk_divisor(struct platform_device *dsidev)
|
|
unsigned long dsi_fclk;
|
|
unsigned long dsi_fclk;
|
|
unsigned lp_clk_div;
|
|
unsigned lp_clk_div;
|
|
unsigned long lp_clk;
|
|
unsigned long lp_clk;
|
|
|
|
+ unsigned lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
|
|
|
|
+
|
|
|
|
|
|
- lp_clk_div = dsi->user_dsi_cinfo.lp_clk_div;
|
|
|
|
|
|
+ lp_clk_div = dsi->user_lp_cinfo.lp_clk_div;
|
|
|
|
|
|
- if (lp_clk_div == 0 || lp_clk_div > dsi->lpdiv_max)
|
|
|
|
|
|
+ if (lp_clk_div == 0 || lp_clk_div > lpdiv_max)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
dsi_fclk = dsi_fclk_rate(dsidev);
|
|
dsi_fclk = dsi_fclk_rate(dsidev);
|
|
@@ -1329,8 +1319,8 @@ static int dsi_set_lp_clk_divisor(struct platform_device *dsidev)
|
|
lp_clk = dsi_fclk / 2 / lp_clk_div;
|
|
lp_clk = dsi_fclk / 2 / lp_clk_div;
|
|
|
|
|
|
DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk);
|
|
DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk);
|
|
- dsi->current_cinfo.lp_clk = lp_clk;
|
|
|
|
- dsi->current_cinfo.lp_clk_div = lp_clk_div;
|
|
|
|
|
|
+ dsi->current_lp_cinfo.lp_clk = lp_clk;
|
|
|
|
+ dsi->current_lp_cinfo.lp_clk_div = lp_clk_div;
|
|
|
|
|
|
/* LP_CLK_DIVISOR */
|
|
/* LP_CLK_DIVISOR */
|
|
REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0);
|
|
REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0);
|
|
@@ -1391,286 +1381,33 @@ static int dsi_pll_power(struct platform_device *dsidev,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-unsigned long dsi_get_pll_clkin(struct platform_device *dsidev)
|
|
|
|
-{
|
|
|
|
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
- return clk_get_rate(dsi->sys_clk);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool dsi_hsdiv_calc(struct platform_device *dsidev, unsigned long pll,
|
|
|
|
- unsigned long out_min, dsi_hsdiv_calc_func func, void *data)
|
|
|
|
-{
|
|
|
|
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
- int regm, regm_start, regm_stop;
|
|
|
|
- unsigned long out_max;
|
|
|
|
- unsigned long out;
|
|
|
|
-
|
|
|
|
- out_min = out_min ? out_min : 1;
|
|
|
|
- out_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
|
|
|
|
-
|
|
|
|
- regm_start = max(DIV_ROUND_UP(pll, out_max), 1ul);
|
|
|
|
- regm_stop = min(pll / out_min, dsi->regm_dispc_max);
|
|
|
|
-
|
|
|
|
- for (regm = regm_start; regm <= regm_stop; ++regm) {
|
|
|
|
- out = pll / regm;
|
|
|
|
-
|
|
|
|
- if (func(regm, out, data))
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool dsi_pll_calc(struct platform_device *dsidev, unsigned long clkin,
|
|
|
|
- unsigned long pll_min, unsigned long pll_max,
|
|
|
|
- dsi_pll_calc_func func, void *data)
|
|
|
|
-{
|
|
|
|
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
- int regn, regn_start, regn_stop;
|
|
|
|
- int regm, regm_start, regm_stop;
|
|
|
|
- unsigned long fint, pll;
|
|
|
|
- const unsigned long pll_hw_max = 1800000000;
|
|
|
|
- unsigned long fint_hw_min, fint_hw_max;
|
|
|
|
-
|
|
|
|
- fint_hw_min = dsi->fint_min;
|
|
|
|
- fint_hw_max = dsi->fint_max;
|
|
|
|
|
|
|
|
- regn_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
|
|
|
|
- regn_stop = min(clkin / fint_hw_min, dsi->regn_max);
|
|
|
|
-
|
|
|
|
- pll_max = pll_max ? pll_max : ULONG_MAX;
|
|
|
|
-
|
|
|
|
- for (regn = regn_start; regn <= regn_stop; ++regn) {
|
|
|
|
- fint = clkin / regn;
|
|
|
|
-
|
|
|
|
- regm_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
|
|
|
|
- 1ul);
|
|
|
|
- regm_stop = min3(pll_max / fint / 2,
|
|
|
|
- pll_hw_max / fint / 2,
|
|
|
|
- dsi->regm_max);
|
|
|
|
-
|
|
|
|
- for (regm = regm_start; regm <= regm_stop; ++regm) {
|
|
|
|
- pll = 2 * regm * fint;
|
|
|
|
-
|
|
|
|
- if (func(regn, regm, fint, pll, data))
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* calculate clock rates using dividers in cinfo */
|
|
|
|
-static int dsi_calc_clock_rates(struct platform_device *dsidev,
|
|
|
|
- struct dsi_clock_info *cinfo)
|
|
|
|
-{
|
|
|
|
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
-
|
|
|
|
- if (cinfo->regn == 0 || cinfo->regn > dsi->regn_max)
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
- if (cinfo->regm == 0 || cinfo->regm > dsi->regm_max)
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
- if (cinfo->regm_dispc > dsi->regm_dispc_max)
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
- if (cinfo->regm_dsi > dsi->regm_dsi_max)
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
- cinfo->clkin = clk_get_rate(dsi->sys_clk);
|
|
|
|
- cinfo->fint = cinfo->clkin / cinfo->regn;
|
|
|
|
-
|
|
|
|
- if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min)
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
- cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint;
|
|
|
|
-
|
|
|
|
- if (cinfo->clkin4ddr > 1800 * 1000 * 1000)
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
- if (cinfo->regm_dispc > 0)
|
|
|
|
- cinfo->dsi_pll_hsdiv_dispc_clk =
|
|
|
|
- cinfo->clkin4ddr / cinfo->regm_dispc;
|
|
|
|
- else
|
|
|
|
- cinfo->dsi_pll_hsdiv_dispc_clk = 0;
|
|
|
|
-
|
|
|
|
- if (cinfo->regm_dsi > 0)
|
|
|
|
- cinfo->dsi_pll_hsdiv_dsi_clk =
|
|
|
|
- cinfo->clkin4ddr / cinfo->regm_dsi;
|
|
|
|
- else
|
|
|
|
- cinfo->dsi_pll_hsdiv_dsi_clk = 0;
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void dsi_pll_calc_dsi_fck(struct dsi_clock_info *cinfo)
|
|
|
|
|
|
+static void dsi_pll_calc_dsi_fck(struct dss_pll_clock_info *cinfo)
|
|
{
|
|
{
|
|
unsigned long max_dsi_fck;
|
|
unsigned long max_dsi_fck;
|
|
|
|
|
|
max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_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;
|
|
|
|
|
|
+ cinfo->mX[HSDIV_DSI] = DIV_ROUND_UP(cinfo->clkdco, max_dsi_fck);
|
|
|
|
+ cinfo->clkout[HSDIV_DSI] = cinfo->clkdco / cinfo->mX[HSDIV_DSI];
|
|
}
|
|
}
|
|
|
|
|
|
-int dsi_pll_set_clock_div(struct platform_device *dsidev,
|
|
|
|
- struct dsi_clock_info *cinfo)
|
|
|
|
|
|
+static int dsi_pll_enable(struct dss_pll *pll)
|
|
{
|
|
{
|
|
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
|
|
+ struct dsi_data *dsi = container_of(pll, struct dsi_data, pll);
|
|
|
|
+ struct platform_device *dsidev = dsi->pdev;
|
|
int r = 0;
|
|
int r = 0;
|
|
- u32 l;
|
|
|
|
- int f = 0;
|
|
|
|
- u8 regn_start, regn_end, regm_start, regm_end;
|
|
|
|
- u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
|
|
|
|
-
|
|
|
|
- DSSDBG("DSI PLL clock config starts");
|
|
|
|
-
|
|
|
|
- dsi->current_cinfo.clkin = cinfo->clkin;
|
|
|
|
- dsi->current_cinfo.fint = cinfo->fint;
|
|
|
|
- dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr;
|
|
|
|
- dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk =
|
|
|
|
- cinfo->dsi_pll_hsdiv_dispc_clk;
|
|
|
|
- dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk =
|
|
|
|
- cinfo->dsi_pll_hsdiv_dsi_clk;
|
|
|
|
-
|
|
|
|
- dsi->current_cinfo.regn = cinfo->regn;
|
|
|
|
- dsi->current_cinfo.regm = cinfo->regm;
|
|
|
|
- dsi->current_cinfo.regm_dispc = cinfo->regm_dispc;
|
|
|
|
- dsi->current_cinfo.regm_dsi = cinfo->regm_dsi;
|
|
|
|
-
|
|
|
|
- DSSDBG("DSI Fint %ld\n", cinfo->fint);
|
|
|
|
-
|
|
|
|
- DSSDBG("clkin rate %ld\n", cinfo->clkin);
|
|
|
|
-
|
|
|
|
- /* DSIPHY == CLKIN4DDR */
|
|
|
|
- DSSDBG("CLKIN4DDR = 2 * %d / %d * %lu = %lu\n",
|
|
|
|
- cinfo->regm,
|
|
|
|
- cinfo->regn,
|
|
|
|
- cinfo->clkin,
|
|
|
|
- cinfo->clkin4ddr);
|
|
|
|
-
|
|
|
|
- DSSDBG("Data rate on 1 DSI lane %ld Mbps\n",
|
|
|
|
- cinfo->clkin4ddr / 1000 / 1000 / 2);
|
|
|
|
-
|
|
|
|
- DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4);
|
|
|
|
-
|
|
|
|
- DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc,
|
|
|
|
- dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
|
|
|
|
- dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
|
|
|
|
- cinfo->dsi_pll_hsdiv_dispc_clk);
|
|
|
|
- DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi,
|
|
|
|
- dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
|
|
|
|
- dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
|
|
|
|
- cinfo->dsi_pll_hsdiv_dsi_clk);
|
|
|
|
-
|
|
|
|
- dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, ®n_start, ®n_end);
|
|
|
|
- dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM, ®m_start, ®m_end);
|
|
|
|
- dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DISPC, ®m_dispc_start,
|
|
|
|
- ®m_dispc_end);
|
|
|
|
- dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, ®m_dsi_start,
|
|
|
|
- ®m_dsi_end);
|
|
|
|
-
|
|
|
|
- /* DSI_PLL_AUTOMODE = manual */
|
|
|
|
- REG_FLD_MOD(dsidev, DSI_PLL_CONTROL, 0, 0, 0);
|
|
|
|
-
|
|
|
|
- l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION1);
|
|
|
|
- l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */
|
|
|
|
- /* DSI_PLL_REGN */
|
|
|
|
- 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,
|
|
|
|
- regm_dispc_start, regm_dispc_end);
|
|
|
|
- /* DSIPROTO_CLOCK_DIV */
|
|
|
|
- l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0,
|
|
|
|
- regm_dsi_start, regm_dsi_end);
|
|
|
|
- dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION1, l);
|
|
|
|
-
|
|
|
|
- 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 = 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, 3, 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 */
|
|
|
|
-
|
|
|
|
- if (wait_for_bit_change(dsidev, DSI_PLL_GO, 0, 0) != 0) {
|
|
|
|
- DSSERR("dsi pll go bit not going down.\n");
|
|
|
|
- r = -EIO;
|
|
|
|
- goto err;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) {
|
|
|
|
- DSSERR("cannot lock PLL\n");
|
|
|
|
- r = -EIO;
|
|
|
|
- goto err;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- dsi->pll_locked = 1;
|
|
|
|
-
|
|
|
|
- l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
|
|
|
|
- l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */
|
|
|
|
- l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */
|
|
|
|
- l = FLD_MOD(l, 0, 6, 6); /* DSI_PLL_LOWCURRSTBY */
|
|
|
|
- l = FLD_MOD(l, 0, 7, 7); /* DSI_PLL_TIGHTPHASELOCK */
|
|
|
|
- l = FLD_MOD(l, 0, 8, 8); /* DSI_PLL_DRIFTGUARDEN */
|
|
|
|
- l = FLD_MOD(l, 0, 10, 9); /* DSI_PLL_LOCKSEL */
|
|
|
|
- l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */
|
|
|
|
- l = FLD_MOD(l, 1, 14, 14); /* DSIPHY_CLKINEN */
|
|
|
|
- l = FLD_MOD(l, 0, 15, 15); /* DSI_BYPASSEN */
|
|
|
|
- l = FLD_MOD(l, 1, 16, 16); /* DSS_CLOCK_EN */
|
|
|
|
- l = FLD_MOD(l, 0, 17, 17); /* DSS_CLOCK_PWDN */
|
|
|
|
- l = FLD_MOD(l, 1, 18, 18); /* DSI_PROTO_CLOCK_EN */
|
|
|
|
- l = FLD_MOD(l, 0, 19, 19); /* DSI_PROTO_CLOCK_PWDN */
|
|
|
|
- l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */
|
|
|
|
- dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
|
|
|
|
-
|
|
|
|
- DSSDBG("PLL config done\n");
|
|
|
|
-err:
|
|
|
|
- return r;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
|
|
|
|
- bool enable_hsdiv)
|
|
|
|
-{
|
|
|
|
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
- int r = 0;
|
|
|
|
- enum dsi_pll_power_state pwstate;
|
|
|
|
|
|
|
|
DSSDBG("PLL init\n");
|
|
DSSDBG("PLL init\n");
|
|
|
|
|
|
- /*
|
|
|
|
- * It seems that on many OMAPs we need to enable both to have a
|
|
|
|
- * functional HSDivider.
|
|
|
|
- */
|
|
|
|
- enable_hsclk = enable_hsdiv = true;
|
|
|
|
-
|
|
|
|
r = dsi_regulator_init(dsidev);
|
|
r = dsi_regulator_init(dsidev);
|
|
if (r)
|
|
if (r)
|
|
return r;
|
|
return r;
|
|
|
|
|
|
- dsi_enable_pll_clock(dsidev, 1);
|
|
|
|
|
|
+ r = dsi_runtime_get(dsidev);
|
|
|
|
+ if (r)
|
|
|
|
+ return r;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Note: SCP CLK is not required on OMAP3, but it is required on OMAP4.
|
|
* Note: SCP CLK is not required on OMAP3, but it is required on OMAP4.
|
|
*/
|
|
*/
|
|
@@ -1697,16 +1434,7 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
|
|
* fill the whole display. No idea about this */
|
|
* fill the whole display. No idea about this */
|
|
dispc_pck_free_enable(0);
|
|
dispc_pck_free_enable(0);
|
|
|
|
|
|
- if (enable_hsclk && enable_hsdiv)
|
|
|
|
- pwstate = DSI_PLL_POWER_ON_ALL;
|
|
|
|
- else if (enable_hsclk)
|
|
|
|
- pwstate = DSI_PLL_POWER_ON_HSCLK;
|
|
|
|
- else if (enable_hsdiv)
|
|
|
|
- pwstate = DSI_PLL_POWER_ON_DIV;
|
|
|
|
- else
|
|
|
|
- pwstate = DSI_PLL_POWER_OFF;
|
|
|
|
-
|
|
|
|
- r = dsi_pll_power(dsidev, pwstate);
|
|
|
|
|
|
+ r = dsi_pll_power(dsidev, DSI_PLL_POWER_ON_ALL);
|
|
|
|
|
|
if (r)
|
|
if (r)
|
|
goto err1;
|
|
goto err1;
|
|
@@ -1721,15 +1449,14 @@ err1:
|
|
}
|
|
}
|
|
err0:
|
|
err0:
|
|
dsi_disable_scp_clk(dsidev);
|
|
dsi_disable_scp_clk(dsidev);
|
|
- dsi_enable_pll_clock(dsidev, 0);
|
|
|
|
|
|
+ dsi_runtime_put(dsidev);
|
|
return r;
|
|
return r;
|
|
}
|
|
}
|
|
|
|
|
|
-void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
|
|
|
|
|
|
+static void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
|
|
{
|
|
{
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
|
|
- dsi->pll_locked = 0;
|
|
|
|
dsi_pll_power(dsidev, DSI_PLL_POWER_OFF);
|
|
dsi_pll_power(dsidev, DSI_PLL_POWER_OFF);
|
|
if (disconnect_lanes) {
|
|
if (disconnect_lanes) {
|
|
WARN_ON(!dsi->vdds_dsi_enabled);
|
|
WARN_ON(!dsi->vdds_dsi_enabled);
|
|
@@ -1738,18 +1465,27 @@ void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
|
|
}
|
|
}
|
|
|
|
|
|
dsi_disable_scp_clk(dsidev);
|
|
dsi_disable_scp_clk(dsidev);
|
|
- dsi_enable_pll_clock(dsidev, 0);
|
|
|
|
|
|
+ dsi_runtime_put(dsidev);
|
|
|
|
|
|
DSSDBG("PLL uninit done\n");
|
|
DSSDBG("PLL uninit done\n");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void dsi_pll_disable(struct dss_pll *pll)
|
|
|
|
+{
|
|
|
|
+ struct dsi_data *dsi = container_of(pll, struct dsi_data, pll);
|
|
|
|
+ struct platform_device *dsidev = dsi->pdev;
|
|
|
|
+
|
|
|
|
+ dsi_pll_uninit(dsidev, true);
|
|
|
|
+}
|
|
|
|
+
|
|
static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
|
|
static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
|
|
struct seq_file *s)
|
|
struct seq_file *s)
|
|
{
|
|
{
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
- struct dsi_clock_info *cinfo = &dsi->current_cinfo;
|
|
|
|
|
|
+ struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo;
|
|
enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
|
|
enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
|
|
int dsi_module = dsi->module_id;
|
|
int dsi_module = dsi->module_id;
|
|
|
|
+ struct dss_pll *pll = &dsi->pll;
|
|
|
|
|
|
dispc_clk_src = dss_get_dispc_clk_source();
|
|
dispc_clk_src = dss_get_dispc_clk_source();
|
|
dsi_clk_src = dss_get_dsi_clk_source(dsi_module);
|
|
dsi_clk_src = dss_get_dsi_clk_source(dsi_module);
|
|
@@ -1759,28 +1495,28 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
|
|
|
|
|
|
seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1);
|
|
seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1);
|
|
|
|
|
|
- seq_printf(s, "dsi pll clkin\t%lu\n", cinfo->clkin);
|
|
|
|
|
|
+ seq_printf(s, "dsi pll clkin\t%lu\n", clk_get_rate(pll->clkin));
|
|
|
|
|
|
- seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn);
|
|
|
|
|
|
+ seq_printf(s, "Fint\t\t%-16lun %u\n", cinfo->fint, cinfo->n);
|
|
|
|
|
|
- seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n",
|
|
|
|
- cinfo->clkin4ddr, cinfo->regm);
|
|
|
|
|
|
+ seq_printf(s, "CLKIN4DDR\t%-16lum %u\n",
|
|
|
|
+ cinfo->clkdco, cinfo->m);
|
|
|
|
|
|
- seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16luregm_dispc %u\t(%s)\n",
|
|
|
|
|
|
+ seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16lum_dispc %u\t(%s)\n",
|
|
dss_feat_get_clk_source_name(dsi_module == 0 ?
|
|
dss_feat_get_clk_source_name(dsi_module == 0 ?
|
|
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
|
|
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
|
|
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC),
|
|
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC),
|
|
- cinfo->dsi_pll_hsdiv_dispc_clk,
|
|
|
|
- cinfo->regm_dispc,
|
|
|
|
|
|
+ cinfo->clkout[HSDIV_DISPC],
|
|
|
|
+ cinfo->mX[HSDIV_DISPC],
|
|
dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ?
|
|
dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ?
|
|
"off" : "on");
|
|
"off" : "on");
|
|
|
|
|
|
- seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16luregm_dsi %u\t(%s)\n",
|
|
|
|
|
|
+ seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16lum_dsi %u\t(%s)\n",
|
|
dss_feat_get_clk_source_name(dsi_module == 0 ?
|
|
dss_feat_get_clk_source_name(dsi_module == 0 ?
|
|
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
|
|
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
|
|
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI),
|
|
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI),
|
|
- cinfo->dsi_pll_hsdiv_dsi_clk,
|
|
|
|
- cinfo->regm_dsi,
|
|
|
|
|
|
+ cinfo->clkout[HSDIV_DSI],
|
|
|
|
+ cinfo->mX[HSDIV_DSI],
|
|
dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ?
|
|
dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ?
|
|
"off" : "on");
|
|
"off" : "on");
|
|
|
|
|
|
@@ -1793,11 +1529,11 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
|
|
seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev));
|
|
seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev));
|
|
|
|
|
|
seq_printf(s, "DDR_CLK\t\t%lu\n",
|
|
seq_printf(s, "DDR_CLK\t\t%lu\n",
|
|
- cinfo->clkin4ddr / 4);
|
|
|
|
|
|
+ cinfo->clkdco / 4);
|
|
|
|
|
|
seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs(dsidev));
|
|
seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs(dsidev));
|
|
|
|
|
|
- seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk);
|
|
|
|
|
|
+ seq_printf(s, "LP_CLK\t\t%lu\n", dsi->current_lp_cinfo.lp_clk);
|
|
|
|
|
|
dsi_runtime_put(dsidev);
|
|
dsi_runtime_put(dsidev);
|
|
}
|
|
}
|
|
@@ -2132,7 +1868,7 @@ static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns)
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
|
|
/* convert time in ns to ddr ticks, rounding up */
|
|
/* convert time in ns to ddr ticks, rounding up */
|
|
- unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4;
|
|
|
|
|
|
+ unsigned long ddr_clk = dsi->pll.cinfo.clkdco / 4;
|
|
return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000;
|
|
return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2140,7 +1876,7 @@ static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr)
|
|
{
|
|
{
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
|
|
- unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4;
|
|
|
|
|
|
+ unsigned long ddr_clk = dsi->pll.cinfo.clkdco / 4;
|
|
return ddr * 1000 * 1000 / (ddr_clk / 1000);
|
|
return ddr * 1000 * 1000 / (ddr_clk / 1000);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3730,7 +3466,7 @@ static void dsi_config_cmd_mode_interleaving(struct platform_device *dsidev)
|
|
struct omap_video_timings *timings = &dsi->timings;
|
|
struct omap_video_timings *timings = &dsi->timings;
|
|
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
|
|
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
|
|
int ndl = dsi->num_lanes_used - 1;
|
|
int ndl = dsi->num_lanes_used - 1;
|
|
- int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.regm_dsi + 1;
|
|
|
|
|
|
+ int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.mX[HSDIV_DSI] + 1;
|
|
int hsa_interleave_hs = 0, hsa_interleave_lp = 0;
|
|
int hsa_interleave_hs = 0, hsa_interleave_lp = 0;
|
|
int hfp_interleave_hs = 0, hfp_interleave_lp = 0;
|
|
int hfp_interleave_hs = 0, hfp_interleave_lp = 0;
|
|
int hbp_interleave_hs = 0, hbp_interleave_lp = 0;
|
|
int hbp_interleave_hs = 0, hbp_interleave_lp = 0;
|
|
@@ -4441,18 +4177,12 @@ static void dsi_display_uninit_dispc(struct platform_device *dsidev,
|
|
static int dsi_configure_dsi_clocks(struct platform_device *dsidev)
|
|
static int dsi_configure_dsi_clocks(struct platform_device *dsidev)
|
|
{
|
|
{
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
- struct dsi_clock_info cinfo;
|
|
|
|
|
|
+ struct dss_pll_clock_info cinfo;
|
|
int r;
|
|
int r;
|
|
|
|
|
|
cinfo = dsi->user_dsi_cinfo;
|
|
cinfo = dsi->user_dsi_cinfo;
|
|
|
|
|
|
- r = dsi_calc_clock_rates(dsidev, &cinfo);
|
|
|
|
- if (r) {
|
|
|
|
- DSSERR("Failed to calc dsi clocks\n");
|
|
|
|
- return r;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- r = dsi_pll_set_clock_div(dsidev, &cinfo);
|
|
|
|
|
|
+ r = dss_pll_set_config(&dsi->pll, &cinfo);
|
|
if (r) {
|
|
if (r) {
|
|
DSSERR("Failed to set dsi clocks\n");
|
|
DSSERR("Failed to set dsi clocks\n");
|
|
return r;
|
|
return r;
|
|
@@ -4466,7 +4196,7 @@ static int dsi_display_init_dsi(struct platform_device *dsidev)
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
int r;
|
|
int r;
|
|
|
|
|
|
- r = dsi_pll_init(dsidev, true, true);
|
|
|
|
|
|
+ r = dss_pll_enable(&dsi->pll);
|
|
if (r)
|
|
if (r)
|
|
goto err0;
|
|
goto err0;
|
|
|
|
|
|
@@ -4510,7 +4240,7 @@ err3:
|
|
err2:
|
|
err2:
|
|
dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
|
|
dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
|
|
err1:
|
|
err1:
|
|
- dsi_pll_uninit(dsidev, true);
|
|
|
|
|
|
+ dss_pll_disable(&dsi->pll);
|
|
err0:
|
|
err0:
|
|
return r;
|
|
return r;
|
|
}
|
|
}
|
|
@@ -4551,8 +4281,6 @@ static int dsi_display_enable(struct omap_dss_device *dssdev)
|
|
if (r)
|
|
if (r)
|
|
goto err_get_dsi;
|
|
goto err_get_dsi;
|
|
|
|
|
|
- dsi_enable_pll_clock(dsidev, 1);
|
|
|
|
-
|
|
|
|
_dsi_initialize_irq(dsidev);
|
|
_dsi_initialize_irq(dsidev);
|
|
|
|
|
|
r = dsi_display_init_dsi(dsidev);
|
|
r = dsi_display_init_dsi(dsidev);
|
|
@@ -4564,7 +4292,6 @@ static int dsi_display_enable(struct omap_dss_device *dssdev)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
err_init_dsi:
|
|
err_init_dsi:
|
|
- dsi_enable_pll_clock(dsidev, 0);
|
|
|
|
dsi_runtime_put(dsidev);
|
|
dsi_runtime_put(dsidev);
|
|
err_get_dsi:
|
|
err_get_dsi:
|
|
mutex_unlock(&dsi->lock);
|
|
mutex_unlock(&dsi->lock);
|
|
@@ -4592,7 +4319,6 @@ static void dsi_display_disable(struct omap_dss_device *dssdev,
|
|
dsi_display_uninit_dsi(dsidev, disconnect_lanes, enter_ulps);
|
|
dsi_display_uninit_dsi(dsidev, disconnect_lanes, enter_ulps);
|
|
|
|
|
|
dsi_runtime_put(dsidev);
|
|
dsi_runtime_put(dsidev);
|
|
- dsi_enable_pll_clock(dsidev, 0);
|
|
|
|
|
|
|
|
mutex_unlock(&dsi->lock);
|
|
mutex_unlock(&dsi->lock);
|
|
}
|
|
}
|
|
@@ -4713,29 +4439,30 @@ static bool dsi_cm_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-static bool dsi_cm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
|
|
|
|
|
|
+static bool dsi_cm_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
|
|
void *data)
|
|
void *data)
|
|
{
|
|
{
|
|
struct dsi_clk_calc_ctx *ctx = data;
|
|
struct dsi_clk_calc_ctx *ctx = data;
|
|
|
|
|
|
- ctx->dsi_cinfo.regm_dispc = regm_dispc;
|
|
|
|
- ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc;
|
|
|
|
|
|
+ ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc;
|
|
|
|
+ ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc;
|
|
|
|
|
|
return dispc_div_calc(dispc, ctx->req_pck_min, ctx->req_pck_max,
|
|
return dispc_div_calc(dispc, ctx->req_pck_min, ctx->req_pck_max,
|
|
dsi_cm_calc_dispc_cb, ctx);
|
|
dsi_cm_calc_dispc_cb, ctx);
|
|
}
|
|
}
|
|
|
|
|
|
-static bool dsi_cm_calc_pll_cb(int regn, int regm, unsigned long fint,
|
|
|
|
- unsigned long pll, void *data)
|
|
|
|
|
|
+static bool dsi_cm_calc_pll_cb(int n, int m, unsigned long fint,
|
|
|
|
+ unsigned long clkdco, void *data)
|
|
{
|
|
{
|
|
struct dsi_clk_calc_ctx *ctx = data;
|
|
struct dsi_clk_calc_ctx *ctx = data;
|
|
|
|
|
|
- ctx->dsi_cinfo.regn = regn;
|
|
|
|
- ctx->dsi_cinfo.regm = regm;
|
|
|
|
|
|
+ ctx->dsi_cinfo.n = n;
|
|
|
|
+ ctx->dsi_cinfo.m = m;
|
|
ctx->dsi_cinfo.fint = fint;
|
|
ctx->dsi_cinfo.fint = fint;
|
|
- ctx->dsi_cinfo.clkin4ddr = pll;
|
|
|
|
|
|
+ ctx->dsi_cinfo.clkdco = clkdco;
|
|
|
|
|
|
- return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min,
|
|
|
|
|
|
+ return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min,
|
|
|
|
+ dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
|
|
dsi_cm_calc_hsdiv_cb, ctx);
|
|
dsi_cm_calc_hsdiv_cb, ctx);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -4748,7 +4475,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
|
|
unsigned long pll_min, pll_max;
|
|
unsigned long pll_min, pll_max;
|
|
unsigned long pck, txbyteclk;
|
|
unsigned long pck, txbyteclk;
|
|
|
|
|
|
- clkin = clk_get_rate(dsi->sys_clk);
|
|
|
|
|
|
+ clkin = clk_get_rate(dsi->pll.clkin);
|
|
bitspp = dsi_get_pixel_size(cfg->pixel_format);
|
|
bitspp = dsi_get_pixel_size(cfg->pixel_format);
|
|
ndl = dsi->num_lanes_used - 1;
|
|
ndl = dsi->num_lanes_used - 1;
|
|
|
|
|
|
@@ -4764,16 +4491,16 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
|
|
|
|
|
|
memset(ctx, 0, sizeof(*ctx));
|
|
memset(ctx, 0, sizeof(*ctx));
|
|
ctx->dsidev = dsi->pdev;
|
|
ctx->dsidev = dsi->pdev;
|
|
|
|
+ ctx->pll = &dsi->pll;
|
|
ctx->config = cfg;
|
|
ctx->config = cfg;
|
|
ctx->req_pck_min = pck;
|
|
ctx->req_pck_min = pck;
|
|
ctx->req_pck_nom = pck;
|
|
ctx->req_pck_nom = pck;
|
|
ctx->req_pck_max = pck * 3 / 2;
|
|
ctx->req_pck_max = pck * 3 / 2;
|
|
- ctx->dsi_cinfo.clkin = clkin;
|
|
|
|
|
|
|
|
pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4);
|
|
pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4);
|
|
pll_max = cfg->hs_clk_max * 4;
|
|
pll_max = cfg->hs_clk_max * 4;
|
|
|
|
|
|
- return dsi_pll_calc(dsi->pdev, clkin,
|
|
|
|
|
|
+ return dss_pll_calc(ctx->pll, clkin,
|
|
pll_min, pll_max,
|
|
pll_min, pll_max,
|
|
dsi_cm_calc_pll_cb, ctx);
|
|
dsi_cm_calc_pll_cb, ctx);
|
|
}
|
|
}
|
|
@@ -4784,7 +4511,7 @@ static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx)
|
|
const struct omap_dss_dsi_config *cfg = ctx->config;
|
|
const struct omap_dss_dsi_config *cfg = ctx->config;
|
|
int bitspp = dsi_get_pixel_size(cfg->pixel_format);
|
|
int bitspp = dsi_get_pixel_size(cfg->pixel_format);
|
|
int ndl = dsi->num_lanes_used - 1;
|
|
int ndl = dsi->num_lanes_used - 1;
|
|
- unsigned long hsclk = ctx->dsi_cinfo.clkin4ddr / 4;
|
|
|
|
|
|
+ unsigned long hsclk = ctx->dsi_cinfo.clkdco / 4;
|
|
unsigned long byteclk = hsclk / 4;
|
|
unsigned long byteclk = hsclk / 4;
|
|
|
|
|
|
unsigned long dispc_pck, req_pck_min, req_pck_nom, req_pck_max;
|
|
unsigned long dispc_pck, req_pck_min, req_pck_nom, req_pck_max;
|
|
@@ -4999,14 +4726,14 @@ static bool dsi_vm_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-static bool dsi_vm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
|
|
|
|
|
|
+static bool dsi_vm_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
|
|
void *data)
|
|
void *data)
|
|
{
|
|
{
|
|
struct dsi_clk_calc_ctx *ctx = data;
|
|
struct dsi_clk_calc_ctx *ctx = data;
|
|
unsigned long pck_max;
|
|
unsigned long pck_max;
|
|
|
|
|
|
- ctx->dsi_cinfo.regm_dispc = regm_dispc;
|
|
|
|
- ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc;
|
|
|
|
|
|
+ ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc;
|
|
|
|
+ ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc;
|
|
|
|
|
|
/*
|
|
/*
|
|
* In burst mode we can let the dispc pck be arbitrarily high, but it
|
|
* In burst mode we can let the dispc pck be arbitrarily high, but it
|
|
@@ -5022,17 +4749,18 @@ static bool dsi_vm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
|
|
dsi_vm_calc_dispc_cb, ctx);
|
|
dsi_vm_calc_dispc_cb, ctx);
|
|
}
|
|
}
|
|
|
|
|
|
-static bool dsi_vm_calc_pll_cb(int regn, int regm, unsigned long fint,
|
|
|
|
- unsigned long pll, void *data)
|
|
|
|
|
|
+static bool dsi_vm_calc_pll_cb(int n, int m, unsigned long fint,
|
|
|
|
+ unsigned long clkdco, void *data)
|
|
{
|
|
{
|
|
struct dsi_clk_calc_ctx *ctx = data;
|
|
struct dsi_clk_calc_ctx *ctx = data;
|
|
|
|
|
|
- ctx->dsi_cinfo.regn = regn;
|
|
|
|
- ctx->dsi_cinfo.regm = regm;
|
|
|
|
|
|
+ ctx->dsi_cinfo.n = n;
|
|
|
|
+ ctx->dsi_cinfo.m = m;
|
|
ctx->dsi_cinfo.fint = fint;
|
|
ctx->dsi_cinfo.fint = fint;
|
|
- ctx->dsi_cinfo.clkin4ddr = pll;
|
|
|
|
|
|
+ ctx->dsi_cinfo.clkdco = clkdco;
|
|
|
|
|
|
- return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min,
|
|
|
|
|
|
+ return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min,
|
|
|
|
+ dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
|
|
dsi_vm_calc_hsdiv_cb, ctx);
|
|
dsi_vm_calc_hsdiv_cb, ctx);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -5048,14 +4776,13 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
|
|
int bitspp = dsi_get_pixel_size(cfg->pixel_format);
|
|
int bitspp = dsi_get_pixel_size(cfg->pixel_format);
|
|
unsigned long byteclk_min;
|
|
unsigned long byteclk_min;
|
|
|
|
|
|
- clkin = clk_get_rate(dsi->sys_clk);
|
|
|
|
|
|
+ clkin = clk_get_rate(dsi->pll.clkin);
|
|
|
|
|
|
memset(ctx, 0, sizeof(*ctx));
|
|
memset(ctx, 0, sizeof(*ctx));
|
|
ctx->dsidev = dsi->pdev;
|
|
ctx->dsidev = dsi->pdev;
|
|
|
|
+ ctx->pll = &dsi->pll;
|
|
ctx->config = cfg;
|
|
ctx->config = cfg;
|
|
|
|
|
|
- ctx->dsi_cinfo.clkin = clkin;
|
|
|
|
-
|
|
|
|
/* these limits should come from the panel driver */
|
|
/* these limits should come from the panel driver */
|
|
ctx->req_pck_min = t->pixelclock - 1000;
|
|
ctx->req_pck_min = t->pixelclock - 1000;
|
|
ctx->req_pck_nom = t->pixelclock;
|
|
ctx->req_pck_nom = t->pixelclock;
|
|
@@ -5074,7 +4801,7 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
|
|
pll_max = byteclk_max * 4 * 4;
|
|
pll_max = byteclk_max * 4 * 4;
|
|
}
|
|
}
|
|
|
|
|
|
- return dsi_pll_calc(dsi->pdev, clkin,
|
|
|
|
|
|
+ return dss_pll_calc(ctx->pll, clkin,
|
|
pll_min, pll_max,
|
|
pll_min, pll_max,
|
|
dsi_vm_calc_pll_cb, ctx);
|
|
dsi_vm_calc_pll_cb, ctx);
|
|
}
|
|
}
|
|
@@ -5106,8 +4833,8 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
|
|
|
|
|
|
dsi_pll_calc_dsi_fck(&ctx.dsi_cinfo);
|
|
dsi_pll_calc_dsi_fck(&ctx.dsi_cinfo);
|
|
|
|
|
|
- r = dsi_lp_clock_calc(&ctx.dsi_cinfo, config->lp_clk_min,
|
|
|
|
- config->lp_clk_max);
|
|
|
|
|
|
+ r = dsi_lp_clock_calc(ctx.dsi_cinfo.clkout[HSDIV_DSI],
|
|
|
|
+ config->lp_clk_min, config->lp_clk_max, &dsi->user_lp_cinfo);
|
|
if (r) {
|
|
if (r) {
|
|
DSSERR("failed to find suitable DSI LP clock settings\n");
|
|
DSSERR("failed to find suitable DSI LP clock settings\n");
|
|
goto err;
|
|
goto err;
|
|
@@ -5234,35 +4961,6 @@ static void dsi_release_vc(struct omap_dss_device *dssdev, int channel)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev)
|
|
|
|
-{
|
|
|
|
- if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 7, 1) != 1)
|
|
|
|
- DSSERR("%s (%s) not active\n",
|
|
|
|
- dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
|
|
|
|
- dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC));
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
|
|
|
|
-{
|
|
|
|
- if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 8, 1) != 1)
|
|
|
|
- DSSERR("%s (%s) not active\n",
|
|
|
|
- dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
|
|
|
|
- dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI));
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void dsi_calc_clock_param_ranges(struct platform_device *dsidev)
|
|
|
|
-{
|
|
|
|
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
-
|
|
|
|
- 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_get_clocks(struct platform_device *dsidev)
|
|
static int dsi_get_clocks(struct platform_device *dsidev)
|
|
{
|
|
{
|
|
@@ -5277,14 +4975,6 @@ static int dsi_get_clocks(struct platform_device *dsidev)
|
|
|
|
|
|
dsi->dss_clk = clk;
|
|
dsi->dss_clk = clk;
|
|
|
|
|
|
- clk = devm_clk_get(&dsidev->dev, "sys_clk");
|
|
|
|
- if (IS_ERR(clk)) {
|
|
|
|
- DSSERR("can't get sys_clk\n");
|
|
|
|
- return PTR_ERR(clk);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- dsi->sys_clk = clk;
|
|
|
|
-
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -5453,6 +5143,135 @@ err:
|
|
return r;
|
|
return r;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static const struct dss_pll_ops dsi_pll_ops = {
|
|
|
|
+ .enable = dsi_pll_enable,
|
|
|
|
+ .disable = dsi_pll_disable,
|
|
|
|
+ .set_config = dss_pll_write_config_type_a,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct dss_pll_hw dss_omap3_dsi_pll_hw = {
|
|
|
|
+ .n_max = (1 << 7) - 1,
|
|
|
|
+ .m_max = (1 << 11) - 1,
|
|
|
|
+ .mX_max = (1 << 4) - 1,
|
|
|
|
+ .fint_min = 750000,
|
|
|
|
+ .fint_max = 2100000,
|
|
|
|
+ .clkdco_low = 1000000000,
|
|
|
|
+ .clkdco_max = 1800000000,
|
|
|
|
+
|
|
|
|
+ .n_msb = 7,
|
|
|
|
+ .n_lsb = 1,
|
|
|
|
+ .m_msb = 18,
|
|
|
|
+ .m_lsb = 8,
|
|
|
|
+
|
|
|
|
+ .mX_msb[0] = 22,
|
|
|
|
+ .mX_lsb[0] = 19,
|
|
|
|
+ .mX_msb[1] = 26,
|
|
|
|
+ .mX_lsb[1] = 23,
|
|
|
|
+
|
|
|
|
+ .has_stopmode = true,
|
|
|
|
+ .has_freqsel = true,
|
|
|
|
+ .has_selfreqdco = false,
|
|
|
|
+ .has_refsel = false,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct dss_pll_hw dss_omap4_dsi_pll_hw = {
|
|
|
|
+ .n_max = (1 << 8) - 1,
|
|
|
|
+ .m_max = (1 << 12) - 1,
|
|
|
|
+ .mX_max = (1 << 5) - 1,
|
|
|
|
+ .fint_min = 500000,
|
|
|
|
+ .fint_max = 2500000,
|
|
|
|
+ .clkdco_low = 1000000000,
|
|
|
|
+ .clkdco_max = 1800000000,
|
|
|
|
+
|
|
|
|
+ .n_msb = 8,
|
|
|
|
+ .n_lsb = 1,
|
|
|
|
+ .m_msb = 20,
|
|
|
|
+ .m_lsb = 9,
|
|
|
|
+
|
|
|
|
+ .mX_msb[0] = 25,
|
|
|
|
+ .mX_lsb[0] = 21,
|
|
|
|
+ .mX_msb[1] = 30,
|
|
|
|
+ .mX_lsb[1] = 26,
|
|
|
|
+
|
|
|
|
+ .has_stopmode = true,
|
|
|
|
+ .has_freqsel = false,
|
|
|
|
+ .has_selfreqdco = false,
|
|
|
|
+ .has_refsel = false,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct dss_pll_hw dss_omap5_dsi_pll_hw = {
|
|
|
|
+ .n_max = (1 << 8) - 1,
|
|
|
|
+ .m_max = (1 << 12) - 1,
|
|
|
|
+ .mX_max = (1 << 5) - 1,
|
|
|
|
+ .fint_min = 150000,
|
|
|
|
+ .fint_max = 52000000,
|
|
|
|
+ .clkdco_low = 1000000000,
|
|
|
|
+ .clkdco_max = 1800000000,
|
|
|
|
+
|
|
|
|
+ .n_msb = 8,
|
|
|
|
+ .n_lsb = 1,
|
|
|
|
+ .m_msb = 20,
|
|
|
|
+ .m_lsb = 9,
|
|
|
|
+
|
|
|
|
+ .mX_msb[0] = 25,
|
|
|
|
+ .mX_lsb[0] = 21,
|
|
|
|
+ .mX_msb[1] = 30,
|
|
|
|
+ .mX_lsb[1] = 26,
|
|
|
|
+
|
|
|
|
+ .has_stopmode = true,
|
|
|
|
+ .has_freqsel = false,
|
|
|
|
+ .has_selfreqdco = true,
|
|
|
|
+ .has_refsel = true,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static int dsi_init_pll_data(struct platform_device *dsidev)
|
|
|
|
+{
|
|
|
|
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
|
|
|
+ struct dss_pll *pll = &dsi->pll;
|
|
|
|
+ struct clk *clk;
|
|
|
|
+ int r;
|
|
|
|
+
|
|
|
|
+ clk = devm_clk_get(&dsidev->dev, "sys_clk");
|
|
|
|
+ if (IS_ERR(clk)) {
|
|
|
|
+ DSSERR("can't get sys_clk\n");
|
|
|
|
+ return PTR_ERR(clk);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pll->name = dsi->module_id == 0 ? "dsi0" : "dsi1";
|
|
|
|
+ pll->clkin = clk;
|
|
|
|
+ pll->base = dsi->pll_base;
|
|
|
|
+
|
|
|
|
+ switch (omapdss_get_version()) {
|
|
|
|
+ case OMAPDSS_VER_OMAP34xx_ES1:
|
|
|
|
+ case OMAPDSS_VER_OMAP34xx_ES3:
|
|
|
|
+ case OMAPDSS_VER_OMAP3630:
|
|
|
|
+ case OMAPDSS_VER_AM35xx:
|
|
|
|
+ pll->hw = &dss_omap3_dsi_pll_hw;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case OMAPDSS_VER_OMAP4430_ES1:
|
|
|
|
+ case OMAPDSS_VER_OMAP4430_ES2:
|
|
|
|
+ case OMAPDSS_VER_OMAP4:
|
|
|
|
+ pll->hw = &dss_omap4_dsi_pll_hw;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case OMAPDSS_VER_OMAP5:
|
|
|
|
+ pll->hw = &dss_omap5_dsi_pll_hw;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ return -ENODEV;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pll->ops = &dsi_pll_ops;
|
|
|
|
+
|
|
|
|
+ r = dss_pll_register(pll);
|
|
|
|
+ if (r)
|
|
|
|
+ return r;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
/* DSI1 HW IP initialisation */
|
|
/* DSI1 HW IP initialisation */
|
|
static int omap_dsihw_probe(struct platform_device *dsidev)
|
|
static int omap_dsihw_probe(struct platform_device *dsidev)
|
|
{
|
|
{
|
|
@@ -5598,12 +5417,12 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
|
|
dsi->vc[i].vc_id = 0;
|
|
dsi->vc[i].vc_id = 0;
|
|
}
|
|
}
|
|
|
|
|
|
- dsi_calc_clock_param_ranges(dsidev);
|
|
|
|
-
|
|
|
|
r = dsi_get_clocks(dsidev);
|
|
r = dsi_get_clocks(dsidev);
|
|
if (r)
|
|
if (r)
|
|
return r;
|
|
return r;
|
|
|
|
|
|
|
|
+ dsi_init_pll_data(dsidev);
|
|
|
|
+
|
|
pm_runtime_enable(&dsidev->dev);
|
|
pm_runtime_enable(&dsidev->dev);
|
|
|
|
|
|
r = dsi_runtime_get(dsidev);
|
|
r = dsi_runtime_get(dsidev);
|
|
@@ -5672,6 +5491,8 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
|
|
|
|
|
|
WARN_ON(dsi->scp_clk_refcount > 0);
|
|
WARN_ON(dsi->scp_clk_refcount > 0);
|
|
|
|
|
|
|
|
+ dss_pll_unregister(&dsi->pll);
|
|
|
|
+
|
|
dsi_uninit_output(dsidev);
|
|
dsi_uninit_output(dsidev);
|
|
|
|
|
|
pm_runtime_disable(&dsidev->dev);
|
|
pm_runtime_disable(&dsidev->dev);
|