* [PATCH 01/22] OMAPDSS: DSI: wait for hsdiv clocks when enabling PLL
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
At the moment we have two functions to wait for the HSDIV clocks to get
active, dsi_wait_pll_hsdiv_dispc_active and
dsi_wait_pll_hsdiv_dsi_active. Instead of such inconvenient functions,
let's just make sure that the hsdiv clocks are active after the pll has
been enabled.
This patch adds code to dsi_pll_set_clock_div() to wait until HSDIV
clocks are active.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dsi.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 0793bc67a275..fe8196b17a5e 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -1514,6 +1514,20 @@ static void dsi_pll_calc_dsi_fck(struct dsi_clock_info *cinfo)
cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi;
}
+static int dsi_wait_hsdiv_ack(struct platform_device *dsidev, u32 hsdiv_ack_mask)
+{
+ int t = 100;
+
+ while (t-- > 0) {
+ u32 v = dsi_read_reg(dsidev, DSI_PLL_STATUS);
+ v &= hsdiv_ack_mask;
+ if (v = hsdiv_ack_mask)
+ return 0;
+ }
+
+ return -ETIMEDOUT;
+}
+
int dsi_pll_set_clock_div(struct platform_device *dsidev,
struct dsi_clock_info *cinfo)
{
@@ -1646,6 +1660,13 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */
dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
+ r = dsi_wait_hsdiv_ack(dsidev, BIT(7) | BIT(8));
+ if (r) {
+ DSSERR("failed to enable HSDIV clocks: %d\n", r);
+ goto err;
+ }
+
+
DSSDBG("PLL config done\n");
err:
return r;
--
2.1.3
^ permalink raw reply related
* [PATCH 02/22] OMAPDSS: DSI: remove unused hsdiv wait funcs
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
With the previous patch "OMAPDSS: DSI: wait for hsdiv clocks when
enabling PLL", dsi_wait_pll_hsdiv_dispc_active and
dsi_wait_pll_hsdiv_dsi_active are no longer needed, so they and the
callers can be removed.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dsi.c | 15 ---------------
drivers/video/fbdev/omap2/dss/dss.c | 15 ---------------
drivers/video/fbdev/omap2/dss/dss.h | 8 --------
3 files changed, 38 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index fe8196b17a5e..b7acdcd76f73 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -5255,21 +5255,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)
{
diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index 5f6942c5df1c..702c495083ed 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -296,7 +296,6 @@ static void dss_dump_regs(struct seq_file *s)
static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
{
- struct platform_device *dsidev;
int b;
u8 start, end;
@@ -306,13 +305,9 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
break;
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
b = 1;
- dsidev = dsi_get_dsidev_from_id(0);
- dsi_wait_pll_hsdiv_dispc_active(dsidev);
break;
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
b = 2;
- dsidev = dsi_get_dsidev_from_id(1);
- dsi_wait_pll_hsdiv_dispc_active(dsidev);
break;
default:
BUG();
@@ -329,7 +324,6 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
void dss_select_dsi_clk_source(int dsi_module,
enum omap_dss_clk_source clk_src)
{
- struct platform_device *dsidev;
int b, pos;
switch (clk_src) {
@@ -339,14 +333,10 @@ void dss_select_dsi_clk_source(int dsi_module,
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
BUG_ON(dsi_module != 0);
b = 1;
- dsidev = dsi_get_dsidev_from_id(0);
- dsi_wait_pll_hsdiv_dsi_active(dsidev);
break;
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI:
BUG_ON(dsi_module != 1);
b = 1;
- dsidev = dsi_get_dsidev_from_id(1);
- dsi_wait_pll_hsdiv_dsi_active(dsidev);
break;
default:
BUG();
@@ -362,7 +352,6 @@ void dss_select_dsi_clk_source(int dsi_module,
void dss_select_lcd_clk_source(enum omap_channel channel,
enum omap_dss_clk_source clk_src)
{
- struct platform_device *dsidev;
int b, ix, pos;
if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
@@ -377,15 +366,11 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
b = 1;
- dsidev = dsi_get_dsidev_from_id(0);
- dsi_wait_pll_hsdiv_dispc_active(dsidev);
break;
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
channel != OMAP_DSS_CHANNEL_LCD3);
b = 1;
- dsidev = dsi_get_dsidev_from_id(1);
- dsi_wait_pll_hsdiv_dispc_active(dsidev);
break;
default:
BUG();
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index b70d7dfbfcfb..4617b4d9f78d 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -299,8 +299,6 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
bool enable_hsdiv);
void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
-void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev);
-void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
struct platform_device *dsi_get_dsidev_from_id(int module);
#else
static inline int dsi_runtime_get(struct platform_device *dsidev)
@@ -336,12 +334,6 @@ static inline void dsi_pll_uninit(struct platform_device *dsidev,
bool disconnect_lanes)
{
}
-static inline void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev)
-{
-}
-static inline void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
-{
-}
static inline struct platform_device *dsi_get_dsidev_from_id(int module)
{
return NULL;
--
2.1.3
^ permalink raw reply related
* [PATCH 03/22] OMAPDSS: DSI: always power on hsclk & hsdiv
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
The DSS PLL has support to power on the PLL's highspeed clock output
and HSDIV output separately. In practice both need to powered on, as in
most OMAP's that's the only working configuration. We already do that in
dsi_pll_init(), by overriding the passed arguments so that both are
always powered.
Simplify the code by removing the support for choosing which outputs to
power on.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dpi.c | 4 ++--
drivers/video/fbdev/omap2/dss/dsi.c | 23 +++--------------------
drivers/video/fbdev/omap2/dss/dss.h | 6 ++----
3 files changed, 7 insertions(+), 26 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index ebc294f8dfdb..aa095c4927ec 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -405,7 +405,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_get_dsi;
- r = dsi_pll_init(dpi->dsidev, 0, 1);
+ r = dsi_pll_init(dpi->dsidev);
if (r)
goto err_dsi_pll_init;
}
@@ -557,7 +557,7 @@ static int dpi_verify_dsi_pll(struct platform_device *dsidev)
if (r)
return r;
- r = dsi_pll_init(dsidev, 0, 1);
+ r = dsi_pll_init(dsidev);
if (r) {
dsi_runtime_put(dsidev);
return r;
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index b7acdcd76f73..0083f6500949 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -1672,21 +1672,13 @@ err:
return r;
}
-int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
- bool enable_hsdiv)
+int dsi_pll_init(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int r = 0;
- enum dsi_pll_power_state pwstate;
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);
if (r)
return r;
@@ -1718,16 +1710,7 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
* fill the whole display. No idea about this */
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)
goto err1;
@@ -4487,7 +4470,7 @@ static int dsi_display_init_dsi(struct platform_device *dsidev)
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int r;
- r = dsi_pll_init(dsidev, true, true);
+ r = dsi_pll_init(dsidev);
if (r)
goto err0;
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 4617b4d9f78d..2defcaedbef5 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -296,8 +296,7 @@ bool dsi_pll_calc(struct platform_device *dsidev, unsigned long clkin,
unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
int dsi_pll_set_clock_div(struct platform_device *dsidev,
struct dsi_clock_info *cinfo);
-int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
- bool enable_hsdiv);
+int dsi_pll_init(struct platform_device *dsidev);
void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
struct platform_device *dsi_get_dsidev_from_id(int module);
#else
@@ -324,8 +323,7 @@ static inline int dsi_pll_set_clock_div(struct platform_device *dsidev,
WARN("%s: DSI not compiled in\n", __func__);
return -ENODEV;
}
-static inline int dsi_pll_init(struct platform_device *dsidev,
- bool enable_hsclk, bool enable_hsdiv)
+static inline int dsi_pll_init(struct platform_device *dsidev)
{
WARN("%s: DSI not compiled in\n", __func__);
return -ENODEV;
--
2.1.3
^ permalink raw reply related
* [PATCH 04/22] OMAPDSS: DSI: separate LP clock info from dsi_clock_info
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
struct dsi_clock_info represents the clocks handled by the DSI, mostly
PLL related clocks. In an effort to create common PLL code, we need to
remove all the non-PLL items from dsi_clock_info.
This patch removes LP clock related fields from dsi_clock_info, and
creates a new struct dsi_lp_clock_info for holding clock info for the LP
clock.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dsi.c | 30 +++++++++++++++++++-----------
drivers/video/fbdev/omap2/dss/dss.h | 2 --
2 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 0083f6500949..1c5a15581669 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -287,6 +287,11 @@ struct dsi_clk_calc_ctx {
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 platform_device *pdev;
void __iomem *proto_base;
@@ -307,6 +312,9 @@ struct dsi_data {
struct dsi_clock_info current_cinfo;
+ struct dsi_lp_clock_info user_lp_cinfo;
+ struct dsi_lp_clock_info current_lp_cinfo;
+
bool vdds_dsi_enabled;
struct regulator *vdds_dsi_reg;
@@ -1293,10 +1301,10 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
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 long lp_clk;
@@ -1306,8 +1314,8 @@ static int dsi_lp_clock_calc(struct dsi_clock_info *cinfo,
if (lp_clk < lp_clk_min || lp_clk > lp_clk_max)
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;
}
@@ -1319,7 +1327,7 @@ static int dsi_set_lp_clk_divisor(struct platform_device *dsidev)
unsigned lp_clk_div;
unsigned long lp_clk;
- 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)
return -EINVAL;
@@ -1329,8 +1337,8 @@ static int dsi_set_lp_clk_divisor(struct platform_device *dsidev)
lp_clk = dsi_fclk / 2 / lp_clk_div;
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 */
REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0);
@@ -1801,7 +1809,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *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);
}
@@ -5110,8 +5118,8 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
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.dsi_pll_hsdiv_dsi_clk,
+ config->lp_clk_min, config->lp_clk_max, &dsi->user_lp_cinfo);
if (r) {
DSSERR("failed to find suitable DSI LP clock settings\n");
goto err;
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 2defcaedbef5..712592d2e5f7 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -119,7 +119,6 @@ struct dsi_clock_info {
* OMAP4: PLLx_CLK1 */
unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
* OMAP4: PLLx_CLK2 */
- unsigned long lp_clk;
/* dividers */
u16 regn;
@@ -128,7 +127,6 @@ struct dsi_clock_info {
* OMAP4: REGM4 */
u16 regm_dsi; /* OMAP3: REGM4
* OMAP4: REGM5 */
- u16 lp_clk_div;
};
struct dss_lcd_mgr_config {
--
2.1.3
^ permalink raw reply related
* [PATCH 05/22] OMAPDSS: DSI: remove clkin from dsi_clock_info
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
struct dsi_clock_info contains clkin field, which is the rate of the
PLL's input clock. This field is not needed, as it can be easily
retrieved by using the clk_get_rate().
This patch removes the clkin field.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dpi.c | 1 -
drivers/video/fbdev/omap2/dss/dsi.c | 13 ++++---------
drivers/video/fbdev/omap2/dss/dss.h | 1 -
3 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index aa095c4927ec..91f18ab72007 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -223,7 +223,6 @@ static bool dpi_dsi_clk_calc(struct dpi_data *dpi, unsigned long pck,
ctx->dsidev = dpi->dsidev;
ctx->pck_min = pck - 1000;
ctx->pck_max = pck + 1000;
- ctx->dsi_cinfo.clkin = clkin;
pll_min = 0;
pll_max = 0;
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 1c5a15581669..deab4135ddc0 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -1486,8 +1486,7 @@ static int dsi_calc_clock_rates(struct platform_device *dsidev,
if (cinfo->regm_dsi > dsi->regm_dsi_max)
return -EINVAL;
- cinfo->clkin = clk_get_rate(dsi->sys_clk);
- cinfo->fint = cinfo->clkin / cinfo->regn;
+ cinfo->fint = clk_get_rate(dsi->sys_clk) / cinfo->regn;
if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min)
return -EINVAL;
@@ -1548,7 +1547,6 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
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 @@ -1563,13 +1561,13 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
DSSDBG("DSI Fint %ld\n", cinfo->fint);
- DSSDBG("clkin rate %ld\n", cinfo->clkin);
+ DSSDBG("clkin rate %ld\n", clk_get_rate(dsi->sys_clk));
/* DSIPHY = CLKIN4DDR */
DSSDBG("CLKIN4DDR = 2 * %d / %d * %lu = %lu\n",
cinfo->regm,
cinfo->regn,
- cinfo->clkin,
+ clk_get_rate(dsi->sys_clk),
cinfo->clkin4ddr);
DSSDBG("Data rate on 1 DSI lane %ld Mbps\n",
@@ -1771,7 +1769,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
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(dsi->sys_clk));
seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn);
@@ -4780,7 +4778,6 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
ctx->req_pck_min = pck;
ctx->req_pck_nom = pck;
ctx->req_pck_max = pck * 3 / 2;
- ctx->dsi_cinfo.clkin = clkin;
pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4);
pll_max = cfg->hs_clk_max * 4;
@@ -5066,8 +5063,6 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
ctx->dsidev = dsi->pdev;
ctx->config = cfg;
- ctx->dsi_cinfo.clkin = clkin;
-
/* these limits should come from the panel driver */
ctx->req_pck_min = t->pixelclock - 1000;
ctx->req_pck_nom = t->pixelclock;
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 712592d2e5f7..45e255ecff29 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -114,7 +114,6 @@ struct dsi_clock_info {
/* rates that we get with dividers below */
unsigned long fint;
unsigned long clkin4ddr;
- unsigned long clkin;
unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK
* OMAP4: PLLx_CLK1 */
unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
--
2.1.3
^ permalink raw reply related
* [PATCH 06/22] OMAPDSS: DSI: remove pll_locked field
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
We have pll_locked field in struct dsi_data, but it doesn't have any
meaningful use anymore, and can be removed.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dsi.c | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index deab4135ddc0..37517e407f37 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -329,8 +329,6 @@ struct dsi_data {
struct mutex lock;
struct semaphore bus_lock;
- unsigned pll_locked;
-
spinlock_t irq_lock;
struct dsi_isr_tables isr_tables;
/* space for a copy used by the interrupt handler */
@@ -1206,11 +1204,6 @@ static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
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)
@@ -1647,8 +1640,6 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
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 */
@@ -1739,7 +1730,6 @@ void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- dsi->pll_locked = 0;
dsi_pll_power(dsidev, DSI_PLL_POWER_OFF);
if (disconnect_lanes) {
WARN_ON(!dsi->vdds_dsi_enabled);
--
2.1.3
^ permalink raw reply related
* [PATCH 07/22] OMAPDSS: DSI: use struct copy instead of individual field copy
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
Now that dsi_clock_info only contains information about the PLL, we can
just copy the whole struct when storing the clock information, instead
of copying individual fields.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dsi.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 37517e407f37..b0a3c9ed1341 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -1540,17 +1540,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
DSSDBG("DSI PLL clock config starts");
- 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;
+ dsi->current_cinfo = *cinfo;
DSSDBG("DSI Fint %ld\n", cinfo->fint);
--
2.1.3
^ permalink raw reply related
* [PATCH 08/22] OMAPDSS: DSI: rename clkin4ddr to clkdco
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
We are creating a common DSS PLL code, so rename 'clkin4ddr' field,
which is DSI specific name, to 'clkdco' which is a generic name.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dpi.c | 2 +-
drivers/video/fbdev/omap2/dss/dsi.c | 36 ++++++++++++++++++------------------
drivers/video/fbdev/omap2/dss/dss.h | 2 +-
3 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index 91f18ab72007..f6a14c80bd0b 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -195,7 +195,7 @@ static bool dpi_calc_pll_cb(int regn, int regm, unsigned long fint,
ctx->dsi_cinfo.regn = regn;
ctx->dsi_cinfo.regm = regm;
ctx->dsi_cinfo.fint = fint;
- ctx->dsi_cinfo.clkin4ddr = pll;
+ ctx->dsi_cinfo.clkdco = pll;
return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->pck_min,
dpi_calc_hsdiv_cb, ctx);
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index b0a3c9ed1341..5996ffd6dff1 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -1275,7 +1275,7 @@ static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- return dsi->current_cinfo.clkin4ddr / 16;
+ return dsi->current_cinfo.clkdco / 16;
}
static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
@@ -1484,20 +1484,20 @@ static int dsi_calc_clock_rates(struct platform_device *dsidev,
if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min)
return -EINVAL;
- cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint;
+ cinfo->clkdco = 2 * cinfo->regm * cinfo->fint;
- if (cinfo->clkin4ddr > 1800 * 1000 * 1000)
+ if (cinfo->clkdco > 1800 * 1000 * 1000)
return -EINVAL;
if (cinfo->regm_dispc > 0)
cinfo->dsi_pll_hsdiv_dispc_clk - cinfo->clkin4ddr / cinfo->regm_dispc;
+ cinfo->clkdco / 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;
+ cinfo->clkdco / cinfo->regm_dsi;
else
cinfo->dsi_pll_hsdiv_dsi_clk = 0;
@@ -1510,8 +1510,8 @@ static void dsi_pll_calc_dsi_fck(struct dsi_clock_info *cinfo)
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->regm_dsi = DIV_ROUND_UP(cinfo->clkdco, max_dsi_fck);
+ cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkdco / cinfo->regm_dsi;
}
static int dsi_wait_hsdiv_ack(struct platform_device *dsidev, u32 hsdiv_ack_mask)
@@ -1551,12 +1551,12 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
cinfo->regm,
cinfo->regn,
clk_get_rate(dsi->sys_clk),
- cinfo->clkin4ddr);
+ cinfo->clkdco);
DSSDBG("Data rate on 1 DSI lane %ld Mbps\n",
- cinfo->clkin4ddr / 1000 / 1000 / 2);
+ cinfo->clkdco / 1000 / 1000 / 2);
- DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4);
+ DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkdco / 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),
@@ -1604,7 +1604,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
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;
+ f = cinfo->clkdco < 1000000000 ? 0x2 : 0x4;
l = FLD_MOD(l, f, 3, 1); /* PLL_SELFREQDCO */
}
@@ -1754,7 +1754,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn);
seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n",
- cinfo->clkin4ddr, cinfo->regm);
+ cinfo->clkdco, cinfo->regm);
seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16luregm_dispc %u\t(%s)\n",
dss_feat_get_clk_source_name(dsi_module = 0 ?
@@ -1783,7 +1783,7 @@ 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, "DDR_CLK\t\t%lu\n",
- cinfo->clkin4ddr / 4);
+ cinfo->clkdco / 4);
seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs(dsidev));
@@ -2122,7 +2122,7 @@ static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns)
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
/* convert time in ns to ddr ticks, rounding up */
- unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4;
+ unsigned long ddr_clk = dsi->current_cinfo.clkdco / 4;
return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000;
}
@@ -2130,7 +2130,7 @@ static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4;
+ unsigned long ddr_clk = dsi->current_cinfo.clkdco / 4;
return ddr * 1000 * 1000 / (ddr_clk / 1000);
}
@@ -4723,7 +4723,7 @@ static bool dsi_cm_calc_pll_cb(int regn, int regm, unsigned long fint,
ctx->dsi_cinfo.regn = regn;
ctx->dsi_cinfo.regm = regm;
ctx->dsi_cinfo.fint = fint;
- ctx->dsi_cinfo.clkin4ddr = pll;
+ ctx->dsi_cinfo.clkdco = pll;
return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min,
dsi_cm_calc_hsdiv_cb, ctx);
@@ -4773,7 +4773,7 @@ static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx)
const struct omap_dss_dsi_config *cfg = ctx->config;
int bitspp = dsi_get_pixel_size(cfg->pixel_format);
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 dispc_pck, req_pck_min, req_pck_nom, req_pck_max;
@@ -5019,7 +5019,7 @@ static bool dsi_vm_calc_pll_cb(int regn, int regm, unsigned long fint,
ctx->dsi_cinfo.regn = regn;
ctx->dsi_cinfo.regm = regm;
ctx->dsi_cinfo.fint = fint;
- ctx->dsi_cinfo.clkin4ddr = pll;
+ ctx->dsi_cinfo.clkdco = pll;
return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min,
dsi_vm_calc_hsdiv_cb, ctx);
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 45e255ecff29..e2f0196a083b 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -113,7 +113,7 @@ struct dispc_clock_info {
struct dsi_clock_info {
/* rates that we get with dividers below */
unsigned long fint;
- unsigned long clkin4ddr;
+ unsigned long clkdco;
unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK
* OMAP4: PLLx_CLK1 */
unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
--
2.1.3
^ permalink raw reply related
* [PATCH 09/22] OMAPDSS: DSI: turn hsdivs fields to arrays
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
We are creating a common DSS PLL code, so having fixed DSI specific
hsdiv fields in the clock information is not ok.
This patch changes the hsdiv fields to arrays, so that we can use all
the 4 possible hsdiv outputs (DSI only usees 2), and we have generic way
to access the hsdivs.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dpi.c | 10 +++---
drivers/video/fbdev/omap2/dss/dsi.c | 64 ++++++++++++++++++++-----------------
drivers/video/fbdev/omap2/dss/dss.h | 10 ++----
3 files changed, 42 insertions(+), 42 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index f6a14c80bd0b..0b9af5d3e650 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -37,6 +37,8 @@
#include "dss.h"
#include "dss_features.h"
+#define HSDIV_DISPC 0
+
struct dpi_data {
struct platform_device *pdev;
@@ -178,8 +180,8 @@ static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
if (regm_dispc > 1 && regm_dispc % 2 != 0 && ctx->pck_min >= 100000000)
return false;
- ctx->dsi_cinfo.regm_dispc = regm_dispc;
- ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc;
+ ctx->dsi_cinfo.regm_hsdiv[HSDIV_DISPC] = regm_dispc;
+ ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc;
return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max,
dpi_calc_dispc_cb, ctx);
@@ -284,7 +286,7 @@ static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel,
dpi->mgr_config.clock_info = ctx.dispc_cinfo;
- *fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
+ *fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC];
*lck_div = ctx.dispc_cinfo.lck_div;
*pck_div = ctx.dispc_cinfo.pck_div;
@@ -516,7 +518,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
if (!ok)
return -EINVAL;
- fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
+ fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC];
} else {
ok = dpi_dss_clk_calc(timings->pixelclock, &ctx);
if (!ok)
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 5996ffd6dff1..406af309f8ff 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -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);
+/* DSI PLL HSDIV indices */
+#define HSDIV_DISPC 0
+#define HSDIV_DSI 1
+
#define DSI_MAX_NR_ISRS 2
#define DSI_MAX_NR_LANES 5
@@ -1261,14 +1265,14 @@ unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- return dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk;
+ return dsi->current_cinfo.clkout[HSDIV_DISPC];
}
static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- return dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk;
+ return dsi->current_cinfo.clkout[HSDIV_DSI];
}
static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev)
@@ -1473,10 +1477,10 @@ static int dsi_calc_clock_rates(struct platform_device *dsidev,
if (cinfo->regm = 0 || cinfo->regm > dsi->regm_max)
return -EINVAL;
- if (cinfo->regm_dispc > dsi->regm_dispc_max)
+ if (cinfo->regm_hsdiv[HSDIV_DISPC] > dsi->regm_dispc_max)
return -EINVAL;
- if (cinfo->regm_dsi > dsi->regm_dsi_max)
+ if (cinfo->regm_hsdiv[HSDIV_DSI] > dsi->regm_dsi_max)
return -EINVAL;
cinfo->fint = clk_get_rate(dsi->sys_clk) / cinfo->regn;
@@ -1489,17 +1493,17 @@ static int dsi_calc_clock_rates(struct platform_device *dsidev,
if (cinfo->clkdco > 1800 * 1000 * 1000)
return -EINVAL;
- if (cinfo->regm_dispc > 0)
- cinfo->dsi_pll_hsdiv_dispc_clk - cinfo->clkdco / cinfo->regm_dispc;
+ if (cinfo->regm_hsdiv[HSDIV_DISPC])
+ cinfo->clkout[HSDIV_DISPC] + cinfo->clkdco / cinfo->regm_hsdiv[HSDIV_DISPC];
else
- cinfo->dsi_pll_hsdiv_dispc_clk = 0;
+ cinfo->clkout[HSDIV_DISPC] = 0;
- if (cinfo->regm_dsi > 0)
- cinfo->dsi_pll_hsdiv_dsi_clk - cinfo->clkdco / cinfo->regm_dsi;
+ if (cinfo->regm_hsdiv[HSDIV_DSI])
+ cinfo->clkout[HSDIV_DSI] + cinfo->clkdco / cinfo->regm_hsdiv[HSDIV_DSI];
else
- cinfo->dsi_pll_hsdiv_dsi_clk = 0;
+ cinfo->clkout[HSDIV_DSI] = 0;
return 0;
}
@@ -1510,8 +1514,8 @@ static void dsi_pll_calc_dsi_fck(struct dsi_clock_info *cinfo)
max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
- cinfo->regm_dsi = DIV_ROUND_UP(cinfo->clkdco, max_dsi_fck);
- cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkdco / cinfo->regm_dsi;
+ cinfo->regm_hsdiv[HSDIV_DSI] = DIV_ROUND_UP(cinfo->clkdco, max_dsi_fck);
+ cinfo->clkout[HSDIV_DSI] = cinfo->clkdco / cinfo->regm_hsdiv[HSDIV_DSI];
}
static int dsi_wait_hsdiv_ack(struct platform_device *dsidev, u32 hsdiv_ack_mask)
@@ -1558,14 +1562,14 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkdco / 4);
- DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc,
+ DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_hsdiv[HSDIV_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,
+ cinfo->clkout[HSDIV_DISPC]);
+ DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_hsdiv[HSDIV_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);
+ cinfo->clkout[HSDIV_DSI]);
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);
@@ -1584,10 +1588,10 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
/* 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_hsdiv[HSDIV_DISPC] > 0 ? cinfo->regm_hsdiv[HSDIV_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,
+ l = FLD_MOD(l, cinfo->regm_hsdiv[HSDIV_DSI] > 0 ? cinfo->regm_hsdiv[HSDIV_DSI] - 1 : 0,
regm_dsi_start, regm_dsi_end);
dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION1, l);
@@ -1760,8 +1764,8 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
dss_feat_get_clk_source_name(dsi_module = 0 ?
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC),
- cinfo->dsi_pll_hsdiv_dispc_clk,
- cinfo->regm_dispc,
+ cinfo->clkout[HSDIV_DISPC],
+ cinfo->regm_hsdiv[HSDIV_DISPC],
dispc_clk_src = OMAP_DSS_CLK_SRC_FCK ?
"off" : "on");
@@ -1769,8 +1773,8 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
dss_feat_get_clk_source_name(dsi_module = 0 ?
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI),
- cinfo->dsi_pll_hsdiv_dsi_clk,
- cinfo->regm_dsi,
+ cinfo->clkout[HSDIV_DSI],
+ cinfo->regm_hsdiv[HSDIV_DSI],
dsi_clk_src = OMAP_DSS_CLK_SRC_FCK ?
"off" : "on");
@@ -3720,7 +3724,7 @@ static void dsi_config_cmd_mode_interleaving(struct platform_device *dsidev)
struct omap_video_timings *timings = &dsi->timings;
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
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.regm_hsdiv[HSDIV_DSI] + 1;
int hsa_interleave_hs = 0, hsa_interleave_lp = 0;
int hfp_interleave_hs = 0, hfp_interleave_lp = 0;
int hbp_interleave_hs = 0, hbp_interleave_lp = 0;
@@ -4708,8 +4712,8 @@ static bool dsi_cm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
{
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.regm_hsdiv[HSDIV_DISPC] = regm_dispc;
+ ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc;
return dispc_div_calc(dispc, ctx->req_pck_min, ctx->req_pck_max,
dsi_cm_calc_dispc_cb, ctx);
@@ -4994,8 +4998,8 @@ static bool dsi_vm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
struct dsi_clk_calc_ctx *ctx = data;
unsigned long pck_max;
- ctx->dsi_cinfo.regm_dispc = regm_dispc;
- ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc;
+ ctx->dsi_cinfo.regm_hsdiv[HSDIV_DISPC] = regm_dispc;
+ ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc;
/*
* In burst mode we can let the dispc pck be arbitrarily high, but it
@@ -5093,7 +5097,7 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
dsi_pll_calc_dsi_fck(&ctx.dsi_cinfo);
- r = dsi_lp_clock_calc(ctx.dsi_cinfo.dsi_pll_hsdiv_dsi_clk,
+ 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) {
DSSERR("failed to find suitable DSI LP clock settings\n");
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index e2f0196a083b..e14a75b743a4 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -114,18 +114,12 @@ struct dsi_clock_info {
/* rates that we get with dividers below */
unsigned long fint;
unsigned long clkdco;
- unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK
- * OMAP4: PLLx_CLK1 */
- unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
- * OMAP4: PLLx_CLK2 */
+ unsigned long clkout[4];
/* dividers */
u16 regn;
u16 regm;
- u16 regm_dispc; /* OMAP3: REGM3
- * OMAP4: REGM4 */
- u16 regm_dsi; /* OMAP3: REGM4
- * OMAP4: REGM5 */
+ u16 regm_hsdiv[4];
};
struct dss_lcd_mgr_config {
--
2.1.3
^ permalink raw reply related
* [PATCH 10/22] OMAPDSS: DSI: features: combine dsi & dispc hsdivs
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
The HSDIV outputs of DSI PLL (and also other PLLs) all have the same
bit width for the divider value.
Simplify the code by merging HSDIV divider widths into one width.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dsi.c | 13 ++++++-------
drivers/video/fbdev/omap2/dss/dss_features.c | 12 ++++--------
drivers/video/fbdev/omap2/dss/dss_features.h | 3 +--
3 files changed, 11 insertions(+), 17 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 406af309f8ff..22cc91851e94 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -374,7 +374,7 @@ struct dsi_data {
#endif
/* DSI PLL Parameter Ranges */
unsigned long regm_max, regn_max;
- unsigned long regm_dispc_max, regm_dsi_max;
+ unsigned long regm_hsdiv_max;
unsigned long fint_min, fint_max;
unsigned long lpdiv_max;
@@ -1414,7 +1414,7 @@ bool dsi_hsdiv_calc(struct platform_device *dsidev, unsigned long pll,
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);
+ regm_stop = min(pll / out_min, dsi->regm_hsdiv_max);
for (regm = regm_start; regm <= regm_stop; ++regm) {
out = pll / regm;
@@ -1477,10 +1477,10 @@ static int dsi_calc_clock_rates(struct platform_device *dsidev,
if (cinfo->regm = 0 || cinfo->regm > dsi->regm_max)
return -EINVAL;
- if (cinfo->regm_hsdiv[HSDIV_DISPC] > dsi->regm_dispc_max)
+ if (cinfo->regm_hsdiv[HSDIV_DISPC] > dsi->regm_hsdiv_max)
return -EINVAL;
- if (cinfo->regm_hsdiv[HSDIV_DSI] > dsi->regm_dsi_max)
+ if (cinfo->regm_hsdiv[HSDIV_DSI] > dsi->regm_hsdiv_max)
return -EINVAL;
cinfo->fint = clk_get_rate(dsi->sys_clk) / cinfo->regn;
@@ -5232,9 +5232,8 @@ static void dsi_calc_clock_param_ranges(struct platform_device *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->regm_hsdiv_max + dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_HSDIV);
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);
diff --git a/drivers/video/fbdev/omap2/dss/dss_features.c b/drivers/video/fbdev/omap2/dss/dss_features.c
index 15088df7bd16..7e7fcf450342 100644
--- a/drivers/video/fbdev/omap2/dss/dss_features.c
+++ b/drivers/video/fbdev/omap2/dss/dss_features.c
@@ -439,8 +439,7 @@ static const struct dss_param_range omap2_dss_param_range[] = {
[FEAT_PARAM_DSS_PCD] = { 2, 255 },
[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_REGM_HSDIV] = { 0, 0 },
[FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
[FEAT_PARAM_DOWNSCALE] = { 1, 2 },
@@ -456,8 +455,7 @@ static const struct dss_param_range omap3_dss_param_range[] = {
[FEAT_PARAM_DSS_PCD] = { 1, 255 },
[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_REGM_HSDIV] = { 0, (1 << 4) - 1 },
[FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
[FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
@@ -477,8 +475,7 @@ static const struct dss_param_range omap4_dss_param_range[] = {
[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_REGM_HSDIV] = { 0, (1 << 5) - 1 },
[FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
[FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
@@ -491,8 +488,7 @@ static const struct dss_param_range omap5_dss_param_range[] = {
[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_REGM_HSDIV] = { 0, (1 << 5) - 1 },
[FEAT_PARAM_DSIPLL_FINT] = { 150000, 52000000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
[FEAT_PARAM_DSI_FCK] = { 0, 209250000 },
diff --git a/drivers/video/fbdev/omap2/dss/dss_features.h b/drivers/video/fbdev/omap2/dss/dss_features.h
index e3ef3b714896..05e8127d36b0 100644
--- a/drivers/video/fbdev/omap2/dss/dss_features.h
+++ b/drivers/video/fbdev/omap2/dss/dss_features.h
@@ -88,8 +88,7 @@ enum dss_range_param {
FEAT_PARAM_DSS_PCD,
FEAT_PARAM_DSIPLL_REGN,
FEAT_PARAM_DSIPLL_REGM,
- FEAT_PARAM_DSIPLL_REGM_DISPC,
- FEAT_PARAM_DSIPLL_REGM_DSI,
+ FEAT_PARAM_DSIPLL_REGM_HSDIV,
FEAT_PARAM_DSIPLL_FINT,
FEAT_PARAM_DSIPLL_LPDIV,
FEAT_PARAM_DSI_FCK,
--
2.1.3
^ permalink raw reply related
* [PATCH 11/22] OMAPDSS: DSI: dsi_runtime_get/put in pll_init
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
When DPI uses the DSI PLL for pixel clock, the DPI code will call
dsi_runtime_get/put to keep the DSI block enabled. A much simpler way to
handle this is to do dsi_runtime_get/put in DSI's dsi_pll_init() and
dsi_pll_uninit(), thus removing the need for DSI to call the runtime PM
functions.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dpi.c | 17 +----------------
drivers/video/fbdev/omap2/dss/dsi.c | 10 ++++++++--
drivers/video/fbdev/omap2/dss/dss.h | 10 ----------
3 files changed, 9 insertions(+), 28 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index 0b9af5d3e650..81dd5e61e75e 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -402,10 +402,6 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
goto err_src_sel;
if (dpi->dsidev) {
- r = dsi_runtime_get(dpi->dsidev);
- if (r)
- goto err_get_dsi;
-
r = dsi_pll_init(dpi->dsidev);
if (r)
goto err_dsi_pll_init;
@@ -432,9 +428,6 @@ err_set_mode:
if (dpi->dsidev)
dsi_pll_uninit(dpi->dsidev, true);
err_dsi_pll_init:
- if (dpi->dsidev)
- dsi_runtime_put(dpi->dsidev);
-err_get_dsi:
err_src_sel:
dispc_runtime_put();
err_get_dispc:
@@ -459,7 +452,6 @@ static void dpi_display_disable(struct omap_dss_device *dssdev)
if (dpi->dsidev) {
dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
dsi_pll_uninit(dpi->dsidev, true);
- dsi_runtime_put(dpi->dsidev);
}
dispc_runtime_put();
@@ -554,18 +546,11 @@ static int dpi_verify_dsi_pll(struct platform_device *dsidev)
/* do initial setup with the PLL to see if it is operational */
- r = dsi_runtime_get(dsidev);
- if (r)
- return r;
-
r = dsi_pll_init(dsidev);
- if (r) {
- dsi_runtime_put(dsidev);
+ if (r)
return r;
- }
dsi_pll_uninit(dsidev, true);
- dsi_runtime_put(dsidev);
return 0;
}
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 22cc91851e94..e8415b5e877e 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -1144,7 +1144,7 @@ static u32 dsi_get_errors(struct platform_device *dsidev)
return e;
}
-int dsi_runtime_get(struct platform_device *dsidev)
+static int dsi_runtime_get(struct platform_device *dsidev)
{
int r;
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -1156,7 +1156,7 @@ int dsi_runtime_get(struct platform_device *dsidev)
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);
int r;
@@ -1674,6 +1674,10 @@ int dsi_pll_init(struct platform_device *dsidev)
if (r)
return r;
+ r = dsi_runtime_get(dsidev);
+ if (r)
+ return r;
+
dsi_enable_pll_clock(dsidev, 1);
/*
* Note: SCP CLK is not required on OMAP3, but it is required on OMAP4.
@@ -1717,6 +1721,7 @@ err1:
err0:
dsi_disable_scp_clk(dsidev);
dsi_enable_pll_clock(dsidev, 0);
+ dsi_runtime_put(dsidev);
return r;
}
@@ -1733,6 +1738,7 @@ void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
dsi_disable_scp_clk(dsidev);
dsi_enable_pll_clock(dsidev, 0);
+ dsi_runtime_put(dsidev);
DSSDBG("PLL uninit done\n");
}
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index e14a75b743a4..4c268985235c 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -268,9 +268,6 @@ struct file_operations;
int dsi_init_platform_driver(void) __init;
void dsi_uninit_platform_driver(void) __exit;
-int dsi_runtime_get(struct platform_device *dsidev);
-void dsi_runtime_put(struct platform_device *dsidev);
-
void dsi_dump_clocks(struct seq_file *s);
void dsi_irq_handler(void);
@@ -291,13 +288,6 @@ int dsi_pll_init(struct platform_device *dsidev);
void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
struct platform_device *dsi_get_dsidev_from_id(int module);
#else
-static inline int dsi_runtime_get(struct platform_device *dsidev)
-{
- return 0;
-}
-static inline void dsi_runtime_put(struct platform_device *dsidev)
-{
-}
static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
{
WARN("%s: DSI not compiled in, returning pixel_size as 0\n", __func__);
--
2.1.3
^ permalink raw reply related
* [PATCH 12/22] OMAPDSS: Add common PLL code
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
OMAP DSS currently contains two different PLLs: DSI PLL (Type A PLL) and
HDMI PLL (Type B PLL). When DRA7 support is added, we will also support
Video PLLs (Type A).
The driver currently handles all PLLs totally separately. This patch
adds common DSS PLL code, which
a) lets us have common code for the PLLs
b) lets the users of the PLLs use a common API, instead of DSI API or
HDMI API.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/Makefile | 2 +-
drivers/video/fbdev/omap2/dss/dss.h | 88 ++++++++
drivers/video/fbdev/omap2/dss/pll.c | 378 +++++++++++++++++++++++++++++++++
3 files changed, 467 insertions(+), 1 deletion(-)
create mode 100644 drivers/video/fbdev/omap2/dss/pll.c
diff --git a/drivers/video/fbdev/omap2/dss/Makefile b/drivers/video/fbdev/omap2/dss/Makefile
index 245f933060ee..2ea9d382354c 100644
--- a/drivers/video/fbdev/omap2/dss/Makefile
+++ b/drivers/video/fbdev/omap2/dss/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
# Core DSS files
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
- output.o dss-of.o
+ output.o dss-of.o pll.o
# DSS compat layer files
omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \
dispc-compat.o display-sysfs.o
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 4c268985235c..8563e2bc702c 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -100,6 +100,69 @@ enum dss_writeback_channel {
DSS_WB_LCD3_MGR = 7,
};
+struct dss_pll;
+
+#define DSS_PLL_MAX_HSDIVS 4
+
+/*
+ * Type-A PLLs: clkout[]/mX[] refer to hsdiv outputs m4, m5, m6, m7.
+ * Type-B PLLs: clkout[0] refers to m2.
+ */
+struct dss_pll_clock_info {
+ /* rates that we get with dividers below */
+ unsigned long fint;
+ unsigned long clkdco;
+ unsigned long clkout[DSS_PLL_MAX_HSDIVS];
+
+ /* dividers */
+ u16 n;
+ u16 m;
+ u32 mf;
+ u16 mX[DSS_PLL_MAX_HSDIVS];
+ u16 sd;
+};
+
+struct dss_pll_ops {
+ int (*enable)(struct dss_pll *pll);
+ void (*disable)(struct dss_pll *pll);
+ int (*set_config)(struct dss_pll *pll,
+ const struct dss_pll_clock_info *cinfo);
+};
+
+struct dss_pll_hw {
+ unsigned n_max;
+ unsigned m_min;
+ unsigned m_max;
+ unsigned mX_max;
+
+ unsigned long fint_min, fint_max;
+ unsigned long clkdco_min, clkdco_low, clkdco_max;
+
+ u8 n_msb, n_lsb;
+ u8 m_msb, m_lsb;
+ u8 mX_msb[DSS_PLL_MAX_HSDIVS], mX_lsb[DSS_PLL_MAX_HSDIVS];
+
+ bool has_stopmode;
+ bool has_freqsel;
+ bool has_selfreqdco;
+ bool has_refsel;
+};
+
+struct dss_pll {
+ const char *name;
+
+ struct clk *clkin;
+ struct regulator *regulator;
+
+ void __iomem *base;
+
+ const struct dss_pll_hw *hw;
+
+ const struct dss_pll_ops *ops;
+
+ struct dss_pll_clock_info cinfo;
+};
+
struct dispc_clock_info {
/* rates that we get with dividers below */
unsigned long lck;
@@ -435,4 +498,29 @@ static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr)
}
#endif
+/* PLL */
+typedef bool (*dss_pll_calc_func)(int n, int m, unsigned long fint,
+ unsigned long clkdco, void *data);
+typedef bool (*dss_hsdiv_calc_func)(int m_dispc, unsigned long dispc,
+ void *data);
+
+int dss_pll_register(struct dss_pll *pll);
+void dss_pll_unregister(struct dss_pll *pll);
+struct dss_pll *dss_pll_find(const char *name);
+int dss_pll_enable(struct dss_pll *pll);
+void dss_pll_disable(struct dss_pll *pll);
+int dss_pll_set_config(struct dss_pll *pll,
+ const struct dss_pll_clock_info *cinfo);
+
+bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco,
+ unsigned long out_min, unsigned long out_max,
+ dss_hsdiv_calc_func func, void *data);
+bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin,
+ unsigned long pll_min, unsigned long pll_max,
+ dss_pll_calc_func func, void *data);
+int dss_pll_write_config_type_a(struct dss_pll *pll,
+ const struct dss_pll_clock_info *cinfo);
+int dss_pll_write_config_type_b(struct dss_pll *pll,
+ const struct dss_pll_clock_info *cinfo);
+
#endif
diff --git a/drivers/video/fbdev/omap2/dss/pll.c b/drivers/video/fbdev/omap2/dss/pll.c
new file mode 100644
index 000000000000..50bc62c5d367
--- /dev/null
+++ b/drivers/video/fbdev/omap2/dss/pll.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2014 Texas Instruments Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "PLL"
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sched.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+#define PLL_CONTROL 0x0000
+#define PLL_STATUS 0x0004
+#define PLL_GO 0x0008
+#define PLL_CONFIGURATION1 0x000C
+#define PLL_CONFIGURATION2 0x0010
+#define PLL_CONFIGURATION3 0x0014
+#define PLL_SSC_CONFIGURATION1 0x0018
+#define PLL_SSC_CONFIGURATION2 0x001C
+#define PLL_CONFIGURATION4 0x0020
+
+static struct dss_pll *dss_plls[4];
+
+int dss_pll_register(struct dss_pll *pll)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
+ if (!dss_plls[i]) {
+ dss_plls[i] = pll;
+ return 0;
+ }
+ }
+
+ return -EBUSY;
+}
+
+void dss_pll_unregister(struct dss_pll *pll)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
+ if (dss_plls[i] = pll) {
+ dss_plls[i] = NULL;
+ return;
+ }
+ }
+}
+
+struct dss_pll *dss_pll_find(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
+ if (dss_plls[i] && strcmp(dss_plls[i]->name, name) = 0)
+ return dss_plls[i];
+ }
+
+ return NULL;
+}
+
+int dss_pll_enable(struct dss_pll *pll)
+{
+ int r;
+
+ r = clk_prepare_enable(pll->clkin);
+ if (r)
+ return r;
+
+ if (pll->regulator) {
+ r = regulator_enable(pll->regulator);
+ if (r)
+ goto err_reg;
+ }
+
+ r = pll->ops->enable(pll);
+ if (r)
+ goto err_enable;
+
+ return 0;
+
+err_enable:
+ regulator_disable(pll->regulator);
+err_reg:
+ clk_disable_unprepare(pll->clkin);
+ return r;
+}
+
+void dss_pll_disable(struct dss_pll *pll)
+{
+ pll->ops->disable(pll);
+
+ if (pll->regulator)
+ regulator_disable(pll->regulator);
+
+ clk_disable_unprepare(pll->clkin);
+
+ memset(&pll->cinfo, 0, sizeof(pll->cinfo));
+}
+
+int dss_pll_set_config(struct dss_pll *pll, const struct dss_pll_clock_info *cinfo)
+{
+ int r;
+
+ r = pll->ops->set_config(pll, cinfo);
+ if (r)
+ return r;
+
+ pll->cinfo = *cinfo;
+
+ return 0;
+}
+
+bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco,
+ unsigned long out_min, unsigned long out_max,
+ dss_hsdiv_calc_func func, void *data)
+{
+ const struct dss_pll_hw *hw = pll->hw;
+ int m, m_start, m_stop;
+ unsigned long out;
+
+ out_min = out_min ? out_min : 1;
+ out_max = out_max ? out_max : ULONG_MAX;
+
+ m_start = max(DIV_ROUND_UP(clkdco, out_max), 1ul);
+
+ m_stop = min((unsigned)(clkdco / out_min), hw->mX_max);
+
+ for (m = m_start; m <= m_stop; ++m) {
+ out = clkdco / m;
+
+ if (func(m, out, data))
+ return true;
+ }
+
+ return false;
+}
+
+bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin,
+ unsigned long pll_min, unsigned long pll_max,
+ dss_pll_calc_func func, void *data)
+{
+ const struct dss_pll_hw *hw = pll->hw;
+ int n, n_start, n_stop;
+ int m, m_start, m_stop;
+ unsigned long fint, clkdco;
+ unsigned long pll_hw_max;
+ unsigned long fint_hw_min, fint_hw_max;
+
+ pll_hw_max = hw->clkdco_max;
+
+ fint_hw_min = hw->fint_min;
+ fint_hw_max = hw->fint_max;
+
+ n_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
+ n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max);
+
+ pll_max = pll_max ? pll_max : ULONG_MAX;
+
+ for (n = n_start; n <= n_stop; ++n) {
+ fint = clkin / n;
+
+ m_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
+ 1ul);
+ m_stop = min3((unsigned)(pll_max / fint / 2),
+ (unsigned)(pll_hw_max / fint / 2),
+ hw->m_max);
+
+ for (m = m_start; m <= m_stop; ++m) {
+ clkdco = 2 * m * fint;
+
+ if (func(n, m, fint, clkdco, data))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static int wait_for_bit_change(void __iomem *reg, int bitnum, int value)
+{
+ unsigned long timeout;
+ ktime_t wait;
+ int t;
+
+ /* first busyloop to see if the bit changes right away */
+ t = 100;
+ while (t-- > 0) {
+ if (FLD_GET(readl_relaxed(reg), bitnum, bitnum) = value)
+ return value;
+ }
+
+ /* then loop for 500ms, sleeping for 1ms in between */
+ timeout = jiffies + msecs_to_jiffies(500);
+ while (time_before(jiffies, timeout)) {
+ if (FLD_GET(readl_relaxed(reg), bitnum, bitnum) = value)
+ return value;
+
+ wait = ns_to_ktime(1000 * 1000);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
+ }
+
+ return !value;
+}
+
+static int dss_wait_hsdiv_ack(struct dss_pll *pll, u32 hsdiv_ack_mask)
+{
+ int t = 100;
+
+ while (t-- > 0) {
+ u32 v = readl_relaxed(pll->base + PLL_STATUS);
+ v &= hsdiv_ack_mask;
+ if (v = hsdiv_ack_mask)
+ return 0;
+ }
+
+ return -ETIMEDOUT;
+}
+
+int dss_pll_write_config_type_a(struct dss_pll *pll,
+ const struct dss_pll_clock_info *cinfo)
+{
+ const struct dss_pll_hw *hw = pll->hw;
+ void __iomem *base = pll->base;
+ int r = 0;
+ u32 l;
+
+ l = 0;
+ if (hw->has_stopmode)
+ l = FLD_MOD(l, 1, 0, 0); /* PLL_STOPMODE */
+ l = FLD_MOD(l, cinfo->n - 1, hw->n_msb, hw->n_lsb); /* PLL_REGN */
+ l = FLD_MOD(l, cinfo->m, hw->m_msb, hw->m_lsb); /* PLL_REGM */
+ /* M4 */
+ l = FLD_MOD(l, cinfo->mX[0] ? cinfo->mX[0] - 1 : 0,
+ hw->mX_msb[0], hw->mX_lsb[0]);
+ /* M5 */
+ l = FLD_MOD(l, cinfo->mX[1] ? cinfo->mX[1] - 1 : 0,
+ hw->mX_msb[1], hw->mX_lsb[1]);
+ writel_relaxed(l, base + PLL_CONFIGURATION1);
+
+ l = 0;
+ /* M6 */
+ l = FLD_MOD(l, cinfo->mX[2] ? cinfo->mX[2] - 1 : 0,
+ hw->mX_msb[2], hw->mX_lsb[2]);
+ /* M7 */
+ l = FLD_MOD(l, cinfo->mX[3] ? cinfo->mX[3] - 1 : 0,
+ hw->mX_msb[3], hw->mX_lsb[3]);
+ writel_relaxed(l, base + PLL_CONFIGURATION3);
+
+ l = readl_relaxed(base + PLL_CONFIGURATION2);
+ if (hw->has_freqsel) {
+ u32 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); /* PLL_FREQSEL */
+ } else if (hw->has_selfreqdco) {
+ u32 f = cinfo->clkdco < hw->clkdco_low ? 0x2 : 0x4;
+
+ l = FLD_MOD(l, f, 3, 1); /* PLL_SELFREQDCO */
+ }
+ l = FLD_MOD(l, 1, 13, 13); /* PLL_REFEN */
+ l = FLD_MOD(l, 0, 14, 14); /* PHY_CLKINEN */
+ l = FLD_MOD(l, 0, 16, 16); /* M4_CLOCK_EN */
+ l = FLD_MOD(l, 0, 18, 18); /* M5_CLOCK_EN */
+ l = FLD_MOD(l, 1, 20, 20); /* HSDIVBYPASS */
+ if (hw->has_refsel)
+ l = FLD_MOD(l, 3, 22, 21); /* REFSEL = sysclk */
+ l = FLD_MOD(l, 0, 23, 23); /* M6_CLOCK_EN */
+ l = FLD_MOD(l, 0, 25, 25); /* M7_CLOCK_EN */
+ writel_relaxed(l, base + PLL_CONFIGURATION2);
+
+ writel_relaxed(1, base + PLL_GO); /* PLL_GO */
+
+ if (wait_for_bit_change(base + PLL_GO, 0, 0) != 0) {
+ DSSERR("DSS DPLL GO bit not going down.\n");
+ r = -EIO;
+ goto err;
+ }
+
+ if (wait_for_bit_change(base + PLL_STATUS, 1, 1) != 1) {
+ DSSERR("cannot lock DSS DPLL\n");
+ r = -EIO;
+ goto err;
+ }
+
+ l = readl_relaxed(base + PLL_CONFIGURATION2);
+ l = FLD_MOD(l, 1, 14, 14); /* PHY_CLKINEN */
+ l = FLD_MOD(l, cinfo->mX[0] ? 1 : 0, 16, 16); /* M4_CLOCK_EN */
+ l = FLD_MOD(l, cinfo->mX[1] ? 1 : 0, 18, 18); /* M5_CLOCK_EN */
+ l = FLD_MOD(l, 0, 20, 20); /* HSDIVBYPASS */
+ l = FLD_MOD(l, cinfo->mX[2] ? 1 : 0, 23, 23); /* M6_CLOCK_EN */
+ l = FLD_MOD(l, cinfo->mX[3] ? 1 : 0, 25, 25); /* M7_CLOCK_EN */
+ writel_relaxed(l, base + PLL_CONFIGURATION2);
+
+ r = dss_wait_hsdiv_ack(pll,
+ (cinfo->mX[0] ? BIT(7) : 0) |
+ (cinfo->mX[1] ? BIT(8) : 0) |
+ (cinfo->mX[2] ? BIT(10) : 0) |
+ (cinfo->mX[3] ? BIT(11) : 0));
+ if (r) {
+ DSSERR("failed to enable HSDIV clocks\n");
+ goto err;
+ }
+
+err:
+ return r;
+}
+
+int dss_pll_write_config_type_b(struct dss_pll *pll,
+ const struct dss_pll_clock_info *cinfo)
+{
+ const struct dss_pll_hw *hw = pll->hw;
+ void __iomem *base = pll->base;
+ u32 l;
+
+ l = 0;
+ l = FLD_MOD(l, cinfo->m, 20, 9); /* PLL_REGM */
+ l = FLD_MOD(l, cinfo->n - 1, 8, 1); /* PLL_REGN */
+ writel_relaxed(l, base + PLL_CONFIGURATION1);
+
+ l = readl_relaxed(base + PLL_CONFIGURATION2);
+ l = FLD_MOD(l, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
+ l = FLD_MOD(l, 0x1, 13, 13); /* PLL_REFEN */
+ l = FLD_MOD(l, 0x0, 14, 14); /* PHY_CLKINEN */
+ if (hw->has_refsel)
+ l = FLD_MOD(l, 0x3, 22, 21); /* REFSEL = SYSCLK */
+
+ /* PLL_SELFREQDCO */
+ if (cinfo->clkdco > hw->clkdco_low)
+ l = FLD_MOD(l, 0x4, 3, 1);
+ else
+ l = FLD_MOD(l, 0x2, 3, 1);
+ writel_relaxed(l, base + PLL_CONFIGURATION2);
+
+ l = readl_relaxed(base + PLL_CONFIGURATION3);
+ l = FLD_MOD(l, cinfo->sd, 17, 10); /* PLL_REGSD */
+ writel_relaxed(l, base + PLL_CONFIGURATION3);
+
+ l = readl_relaxed(base + PLL_CONFIGURATION4);
+ l = FLD_MOD(l, cinfo->mX[0], 24, 18); /* PLL_REGM2 */
+ l = FLD_MOD(l, cinfo->mf, 17, 0); /* PLL_REGM_F */
+ writel_relaxed(l, base + PLL_CONFIGURATION4);
+
+ writel_relaxed(1, base + PLL_GO); /* PLL_GO */
+
+ if (wait_for_bit_change(base + PLL_GO, 0, 0) != 0) {
+ DSSERR("DSS DPLL GO bit not going down.\n");
+ return -EIO;
+ }
+
+ if (wait_for_bit_change(base + PLL_STATUS, 1, 1) != 1) {
+ DSSERR("cannot lock DSS DPLL\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
--
2.1.3
^ permalink raw reply related
* [PATCH 13/22] OMAPDSS: DSI: use common DSS PLL support
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
Now that we have the common DSS PLL support, change DSI to use it. This
results in quite a lot of changes, but almost all of them are trivial
name changes.
The functions to calculate and program the PLL settings can be removed
from dsi.c, as the common PLL API contains the same functionality.
We also need to create struct dss_pll_hw entries for PLL hardware
features for different OMAP platforms, instead of using the
dss_features.c as the old code does.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dispc.c | 20 +-
drivers/video/fbdev/omap2/dss/dpi.c | 82 ++---
drivers/video/fbdev/omap2/dss/dsi.c | 566 ++++++++++++----------------------
drivers/video/fbdev/omap2/dss/dss.h | 76 -----
4 files changed, 255 insertions(+), 489 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 0e9a74bb9fc2..0729c08ac75a 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -3028,7 +3028,7 @@ static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div,
unsigned long dispc_fclk_rate(void)
{
- struct platform_device *dsidev;
+ struct dss_pll *pll;
unsigned long r = 0;
switch (dss_get_dispc_clk_source()) {
@@ -3036,12 +3036,12 @@ unsigned long dispc_fclk_rate(void)
r = dss_get_dispc_clk_rate();
break;
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
- dsidev = dsi_get_dsidev_from_id(0);
- r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
+ pll = dss_pll_find("dsi0");
+ r = pll->cinfo.clkout[0];
break;
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
- dsidev = dsi_get_dsidev_from_id(1);
- r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
+ pll = dss_pll_find("dsi1");
+ r = pll->cinfo.clkout[0];
break;
default:
BUG();
@@ -3053,7 +3053,7 @@ unsigned long dispc_fclk_rate(void)
unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
{
- struct platform_device *dsidev;
+ struct dss_pll *pll;
int lcd;
unsigned long r;
u32 l;
@@ -3068,12 +3068,12 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
r = dss_get_dispc_clk_rate();
break;
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
- dsidev = dsi_get_dsidev_from_id(0);
- r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
+ pll = dss_pll_find("dsi0");
+ r = pll->cinfo.clkout[0];
break;
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
- dsidev = dsi_get_dsidev_from_id(1);
- r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
+ pll = dss_pll_find("dsi1");
+ r = pll->cinfo.clkout[0];
break;
default:
BUG();
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index 81dd5e61e75e..2edf5caa002f 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -31,6 +31,7 @@
#include <linux/regulator/consumer.h>
#include <linux/string.h>
#include <linux/of.h>
+#include <linux/clk.h>
#include <video/omapdss.h>
@@ -43,7 +44,7 @@ struct dpi_data {
struct platform_device *pdev;
struct regulator *vdds_dsi_reg;
- struct platform_device *dsidev;
+ struct dss_pll *pll;
struct mutex lock;
@@ -67,7 +68,7 @@ static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
return dev_get_drvdata(&pdev->dev);
}
-static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
+static struct dss_pll *dpi_get_pll(enum omap_channel channel)
{
/*
* XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
@@ -88,9 +89,9 @@ static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
case OMAPDSS_VER_OMAP4:
switch (channel) {
case OMAP_DSS_CHANNEL_LCD:
- return dsi_get_dsidev_from_id(0);
+ return dss_pll_find("dsi0");
case OMAP_DSS_CHANNEL_LCD2:
- return dsi_get_dsidev_from_id(1);
+ return dss_pll_find("dsi1");
default:
return NULL;
}
@@ -98,9 +99,9 @@ static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
case OMAPDSS_VER_OMAP5:
switch (channel) {
case OMAP_DSS_CHANNEL_LCD:
- return dsi_get_dsidev_from_id(0);
+ return dss_pll_find("dsi0");
case OMAP_DSS_CHANNEL_LCD3:
- return dsi_get_dsidev_from_id(1);
+ return dss_pll_find("dsi1");
default:
return NULL;
}
@@ -127,7 +128,7 @@ static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel)
}
struct dpi_clk_calc_ctx {
- struct platform_device *dsidev;
+ struct dss_pll *pll;
/* inputs */
@@ -135,7 +136,7 @@ struct dpi_clk_calc_ctx {
/* outputs */
- struct dsi_clock_info dsi_cinfo;
+ struct dss_pll_clock_info dsi_cinfo;
unsigned long fck;
struct dispc_clock_info dispc_cinfo;
};
@@ -167,7 +168,7 @@ static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
}
-static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
+static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
void *data)
{
struct dpi_clk_calc_ctx *ctx = data;
@@ -177,10 +178,10 @@ static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
* shifted. So skip all odd dividers when the pixel clock is on the
* higher side.
*/
- if (regm_dispc > 1 && regm_dispc % 2 != 0 && ctx->pck_min >= 100000000)
+ if (m_dispc > 1 && m_dispc % 2 != 0 && ctx->pck_min >= 100000000)
return false;
- ctx->dsi_cinfo.regm_hsdiv[HSDIV_DISPC] = regm_dispc;
+ ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc;
ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc;
return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max,
@@ -188,19 +189,20 @@ static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
}
-static bool dpi_calc_pll_cb(int regn, int regm, unsigned long fint,
- unsigned long pll,
+static bool dpi_calc_pll_cb(int n, int m, unsigned long fint,
+ unsigned long clkdco,
void *data)
{
struct dpi_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.clkdco = pll;
+ ctx->dsi_cinfo.clkdco = clkdco;
- return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->pck_min,
- dpi_calc_hsdiv_cb, ctx);
+ return dss_pll_hsdiv_calc(ctx->pll, clkdco,
+ ctx->pck_min, dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
+ dpi_calc_hsdiv_cb, ctx);
}
static bool dpi_calc_dss_cb(unsigned long fck, void *data)
@@ -219,17 +221,17 @@ static bool dpi_dsi_clk_calc(struct dpi_data *dpi, unsigned long pck,
unsigned long clkin;
unsigned long pll_min, pll_max;
- clkin = dsi_get_pll_clkin(dpi->dsidev);
-
memset(ctx, 0, sizeof(*ctx));
- ctx->dsidev = dpi->dsidev;
+ ctx->pll = dpi->pll;
ctx->pck_min = pck - 1000;
ctx->pck_max = pck + 1000;
pll_min = 0;
pll_max = 0;
- return dsi_pll_calc(dpi->dsidev, clkin,
+ clkin = clk_get_rate(ctx->pll->clkin);
+
+ return dss_pll_calc(ctx->pll, clkin,
pll_min, pll_max,
dpi_calc_pll_cb, ctx);
}
@@ -277,7 +279,7 @@ static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel,
if (!ok)
return -EINVAL;
- r = dsi_pll_set_clock_div(dpi->dsidev, &ctx.dsi_cinfo);
+ r = dss_pll_set_config(dpi->pll, &ctx.dsi_cinfo);
if (r)
return r;
@@ -327,7 +329,7 @@ static int dpi_set_mode(struct dpi_data *dpi)
unsigned long pck;
int r = 0;
- if (dpi->dsidev)
+ if (dpi->pll)
r = dpi_set_dsi_clk(dpi, mgr->id, t->pixelclock, &fck,
&lck_div, &pck_div);
else
@@ -401,8 +403,8 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_src_sel;
- if (dpi->dsidev) {
- r = dsi_pll_init(dpi->dsidev);
+ if (dpi->pll) {
+ r = dss_pll_enable(dpi->pll);
if (r)
goto err_dsi_pll_init;
}
@@ -425,8 +427,8 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
err_mgr_enable:
err_set_mode:
- if (dpi->dsidev)
- dsi_pll_uninit(dpi->dsidev, true);
+ if (dpi->pll)
+ dss_pll_disable(dpi->pll);
err_dsi_pll_init:
err_src_sel:
dispc_runtime_put();
@@ -449,9 +451,9 @@ static void dpi_display_disable(struct omap_dss_device *dssdev)
dss_mgr_disable(mgr);
- if (dpi->dsidev) {
+ if (dpi->pll) {
dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
- dsi_pll_uninit(dpi->dsidev, true);
+ dss_pll_disable(dpi->pll);
}
dispc_runtime_put();
@@ -505,7 +507,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
if (timings->pixelclock = 0)
return -EINVAL;
- if (dpi->dsidev) {
+ if (dpi->pll) {
ok = dpi_dsi_clk_calc(dpi, timings->pixelclock, &ctx);
if (!ok)
return -EINVAL;
@@ -540,17 +542,17 @@ static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
mutex_unlock(&dpi->lock);
}
-static int dpi_verify_dsi_pll(struct platform_device *dsidev)
+static int dpi_verify_dsi_pll(struct dss_pll *pll)
{
int r;
/* do initial setup with the PLL to see if it is operational */
- r = dsi_pll_init(dsidev);
+ r = dss_pll_enable(pll);
if (r)
return r;
- dsi_pll_uninit(dsidev, true);
+ dss_pll_disable(pll);
return 0;
}
@@ -579,21 +581,21 @@ static int dpi_init_regulator(struct dpi_data *dpi)
static void dpi_init_pll(struct dpi_data *dpi)
{
- struct platform_device *dsidev;
+ struct dss_pll *pll;
- if (dpi->dsidev)
+ if (dpi->pll)
return;
- dsidev = dpi_get_dsidev(dpi->output.dispc_channel);
- if (!dsidev)
+ pll = dpi_get_pll(dpi->output.dispc_channel);
+ if (!pll)
return;
- if (dpi_verify_dsi_pll(dsidev)) {
+ if (dpi_verify_dsi_pll(pll)) {
DSSWARN("DSI PLL not operational\n");
return;
}
- dpi->dsidev = dsidev;
+ dpi->pll = pll;
}
/*
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index e8415b5e877e..73af35159468 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -275,6 +275,7 @@ struct dsi_isr_tables {
struct dsi_clk_calc_ctx {
struct platform_device *dsidev;
+ struct dss_pll *pll;
/* inputs */
@@ -284,7 +285,7 @@ struct dsi_clk_calc_ctx {
/* outputs */
- struct dsi_clock_info dsi_cinfo;
+ struct dss_pll_clock_info dsi_cinfo;
struct dispc_clock_info dispc_cinfo;
struct omap_video_timings dispc_vm;
@@ -309,16 +310,15 @@ struct dsi_data {
bool is_enabled;
struct clk *dss_clk;
- struct clk *sys_clk;
struct dispc_clock_info user_dispc_cinfo;
- struct dsi_clock_info user_dsi_cinfo;
-
- struct dsi_clock_info current_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 dss_pll pll;
+
bool vdds_dsi_enabled;
struct regulator *vdds_dsi_reg;
@@ -357,7 +357,7 @@ struct dsi_data {
unsigned long cache_req_pck;
unsigned long cache_clk_freq;
- struct dsi_clock_info cache_cinfo;
+ struct dss_pll_clock_info cache_cinfo;
u32 errors;
spinlock_t errors_lock;
@@ -372,11 +372,6 @@ struct dsi_data {
spinlock_t irq_stats_lock;
struct dsi_irq_stats irq_stats;
#endif
- /* DSI PLL Parameter Ranges */
- unsigned long regm_max, regn_max;
- unsigned long regm_hsdiv_max;
- unsigned long fint_min, fint_max;
- unsigned long lpdiv_max;
unsigned num_lanes_supported;
unsigned line_buffer_size;
@@ -422,7 +417,7 @@ static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss
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;
enum omap_dss_output_id id;
@@ -1198,18 +1193,6 @@ static int dsi_regulator_init(struct platform_device *dsidev)
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);
-}
-
static void _dsi_print_reset_status(struct platform_device *dsidev)
{
u32 l;
@@ -1261,25 +1244,25 @@ static inline int dsi_if_enable(struct platform_device *dsidev, bool enable)
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);
- return dsi->current_cinfo.clkout[HSDIV_DISPC];
+ return dsi->pll.cinfo.clkout[HSDIV_DISPC];
}
static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- return dsi->current_cinfo.clkout[HSDIV_DSI];
+ return dsi->pll.cinfo.clkout[HSDIV_DSI];
}
static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- return dsi->current_cinfo.clkdco / 16;
+ return dsi->pll.cinfo.clkdco / 16;
}
static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
@@ -1323,10 +1306,12 @@ static int dsi_set_lp_clk_divisor(struct platform_device *dsidev)
unsigned long dsi_fclk;
unsigned lp_clk_div;
unsigned long lp_clk;
+ unsigned lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
+
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;
dsi_fclk = dsi_fclk_rate(dsidev);
@@ -1396,276 +1381,21 @@ static int dsi_pll_power(struct platform_device *dsidev,
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_hsdiv_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_hsdiv[HSDIV_DISPC] > dsi->regm_hsdiv_max)
- return -EINVAL;
-
- if (cinfo->regm_hsdiv[HSDIV_DSI] > dsi->regm_hsdiv_max)
- return -EINVAL;
-
- cinfo->fint = clk_get_rate(dsi->sys_clk) / cinfo->regn;
-
- if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min)
- return -EINVAL;
-
- cinfo->clkdco = 2 * cinfo->regm * cinfo->fint;
- if (cinfo->clkdco > 1800 * 1000 * 1000)
- return -EINVAL;
-
- if (cinfo->regm_hsdiv[HSDIV_DISPC])
- cinfo->clkout[HSDIV_DISPC] - cinfo->clkdco / cinfo->regm_hsdiv[HSDIV_DISPC];
- else
- cinfo->clkout[HSDIV_DISPC] = 0;
-
- if (cinfo->regm_hsdiv[HSDIV_DSI])
- cinfo->clkout[HSDIV_DSI] - cinfo->clkdco / cinfo->regm_hsdiv[HSDIV_DSI];
- else
- cinfo->clkout[HSDIV_DSI] = 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;
max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
- cinfo->regm_hsdiv[HSDIV_DSI] = DIV_ROUND_UP(cinfo->clkdco, max_dsi_fck);
- cinfo->clkout[HSDIV_DSI] = cinfo->clkdco / cinfo->regm_hsdiv[HSDIV_DSI];
+ cinfo->mX[HSDIV_DSI] = DIV_ROUND_UP(cinfo->clkdco, max_dsi_fck);
+ cinfo->clkout[HSDIV_DSI] = cinfo->clkdco / cinfo->mX[HSDIV_DSI];
}
-static int dsi_wait_hsdiv_ack(struct platform_device *dsidev, u32 hsdiv_ack_mask)
+static int dsi_pll_enable(struct dss_pll *pll)
{
- int t = 100;
-
- while (t-- > 0) {
- u32 v = dsi_read_reg(dsidev, DSI_PLL_STATUS);
- v &= hsdiv_ack_mask;
- if (v = hsdiv_ack_mask)
- return 0;
- }
-
- return -ETIMEDOUT;
-}
-
-int dsi_pll_set_clock_div(struct platform_device *dsidev,
- struct dsi_clock_info *cinfo)
-{
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- 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 = *cinfo;
-
- DSSDBG("DSI Fint %ld\n", cinfo->fint);
-
- DSSDBG("clkin rate %ld\n", clk_get_rate(dsi->sys_clk));
-
- /* DSIPHY = CLKIN4DDR */
- DSSDBG("CLKIN4DDR = 2 * %d / %d * %lu = %lu\n",
- cinfo->regm,
- cinfo->regn,
- clk_get_rate(dsi->sys_clk),
- cinfo->clkdco);
-
- DSSDBG("Data rate on 1 DSI lane %ld Mbps\n",
- cinfo->clkdco / 1000 / 1000 / 2);
-
- DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkdco / 4);
-
- DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_hsdiv[HSDIV_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->clkout[HSDIV_DISPC]);
- DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_hsdiv[HSDIV_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->clkout[HSDIV_DSI]);
-
- 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_hsdiv[HSDIV_DISPC] > 0 ? cinfo->regm_hsdiv[HSDIV_DISPC] - 1 : 0,
- regm_dispc_start, regm_dispc_end);
- /* DSIPROTO_CLOCK_DIV */
- l = FLD_MOD(l, cinfo->regm_hsdiv[HSDIV_DSI] > 0 ? cinfo->regm_hsdiv[HSDIV_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->clkdco < 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;
- }
-
- 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);
-
- r = dsi_wait_hsdiv_ack(dsidev, BIT(7) | BIT(8));
- if (r) {
- DSSERR("failed to enable HSDIV clocks: %d\n", r);
- goto err;
- }
-
-
- DSSDBG("PLL config done\n");
-err:
- return r;
-}
-
-int dsi_pll_init(struct platform_device *dsidev)
-{
- 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;
DSSDBG("PLL init\n");
@@ -1678,7 +1408,6 @@ int dsi_pll_init(struct platform_device *dsidev)
if (r)
return r;
- dsi_enable_pll_clock(dsidev, 1);
/*
* Note: SCP CLK is not required on OMAP3, but it is required on OMAP4.
*/
@@ -1720,12 +1449,11 @@ err1:
}
err0:
dsi_disable_scp_clk(dsidev);
- dsi_enable_pll_clock(dsidev, 0);
dsi_runtime_put(dsidev);
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);
@@ -1737,19 +1465,27 @@ void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
}
dsi_disable_scp_clk(dsidev);
- dsi_enable_pll_clock(dsidev, 0);
dsi_runtime_put(dsidev);
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,
struct seq_file *s)
{
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;
int dsi_module = dsi->module_id;
+ struct dss_pll *pll = &dsi->pll;
dispc_clk_src = dss_get_dispc_clk_source();
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 pll clkin\t%lu\n", clk_get_rate(dsi->sys_clk));
+ 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->clkdco, 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 ?
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC),
cinfo->clkout[HSDIV_DISPC],
- cinfo->regm_hsdiv[HSDIV_DISPC],
+ cinfo->mX[HSDIV_DISPC],
dispc_clk_src = OMAP_DSS_CLK_SRC_FCK ?
"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 ?
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI),
cinfo->clkout[HSDIV_DSI],
- cinfo->regm_hsdiv[HSDIV_DSI],
+ cinfo->mX[HSDIV_DSI],
dsi_clk_src = OMAP_DSS_CLK_SRC_FCK ?
"off" : "on");
@@ -2132,7 +1868,7 @@ static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns)
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
/* convert time in ns to ddr ticks, rounding up */
- unsigned long ddr_clk = dsi->current_cinfo.clkdco / 4;
+ unsigned long ddr_clk = dsi->pll.cinfo.clkdco / 4;
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);
- unsigned long ddr_clk = dsi->current_cinfo.clkdco / 4;
+ unsigned long ddr_clk = dsi->pll.cinfo.clkdco / 4;
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;
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
int ndl = dsi->num_lanes_used - 1;
- int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.regm_hsdiv[HSDIV_DSI] + 1;
+ int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.mX[HSDIV_DSI] + 1;
int hsa_interleave_hs = 0, hsa_interleave_lp = 0;
int hfp_interleave_hs = 0, hfp_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)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- struct dsi_clock_info cinfo;
+ struct dss_pll_clock_info cinfo;
int r;
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) {
DSSERR("Failed to set dsi clocks\n");
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);
int r;
- r = dsi_pll_init(dsidev);
+ r = dss_pll_enable(&dsi->pll);
if (r)
goto err0;
@@ -4510,7 +4240,7 @@ err3:
err2:
dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
err1:
- dsi_pll_uninit(dsidev, true);
+ dss_pll_disable(&dsi->pll);
err0:
return r;
}
@@ -4551,8 +4281,6 @@ static int dsi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_get_dsi;
- dsi_enable_pll_clock(dsidev, 1);
-
_dsi_initialize_irq(dsidev);
r = dsi_display_init_dsi(dsidev);
@@ -4564,7 +4292,6 @@ static int dsi_display_enable(struct omap_dss_device *dssdev)
return 0;
err_init_dsi:
- dsi_enable_pll_clock(dsidev, 0);
dsi_runtime_put(dsidev);
err_get_dsi:
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_runtime_put(dsidev);
- dsi_enable_pll_clock(dsidev, 0);
mutex_unlock(&dsi->lock);
}
@@ -4713,29 +4439,30 @@ static bool dsi_cm_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
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)
{
struct dsi_clk_calc_ctx *ctx = data;
- ctx->dsi_cinfo.regm_hsdiv[HSDIV_DISPC] = regm_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,
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;
- 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.clkdco = 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);
}
@@ -4748,7 +4475,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
unsigned long pll_min, pll_max;
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);
ndl = dsi->num_lanes_used - 1;
@@ -4764,6 +4491,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
memset(ctx, 0, sizeof(*ctx));
ctx->dsidev = dsi->pdev;
+ ctx->pll = &dsi->pll;
ctx->config = cfg;
ctx->req_pck_min = pck;
ctx->req_pck_nom = pck;
@@ -4772,7 +4500,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4);
pll_max = cfg->hs_clk_max * 4;
- return dsi_pll_calc(dsi->pdev, clkin,
+ return dss_pll_calc(ctx->pll, clkin,
pll_min, pll_max,
dsi_cm_calc_pll_cb, ctx);
}
@@ -4998,13 +4726,13 @@ static bool dsi_vm_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
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)
{
struct dsi_clk_calc_ctx *ctx = data;
unsigned long pck_max;
- ctx->dsi_cinfo.regm_hsdiv[HSDIV_DISPC] = regm_dispc;
+ ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc;
ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc;
/*
@@ -5021,17 +4749,18 @@ static bool dsi_vm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
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;
- 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.clkdco = 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);
}
@@ -5047,10 +4776,11 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
int bitspp = dsi_get_pixel_size(cfg->pixel_format);
unsigned long byteclk_min;
- clkin = clk_get_rate(dsi->sys_clk);
+ clkin = clk_get_rate(dsi->pll.clkin);
memset(ctx, 0, sizeof(*ctx));
ctx->dsidev = dsi->pdev;
+ ctx->pll = &dsi->pll;
ctx->config = cfg;
/* these limits should come from the panel driver */
@@ -5071,7 +4801,7 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
pll_max = byteclk_max * 4 * 4;
}
- return dsi_pll_calc(dsi->pdev, clkin,
+ return dss_pll_calc(ctx->pll, clkin,
pll_min, pll_max,
dsi_vm_calc_pll_cb, ctx);
}
@@ -5232,19 +4962,6 @@ static void dsi_release_vc(struct omap_dss_device *dssdev, int channel)
}
-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_hsdiv_max - dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_HSDIV);
- 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)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -5258,14 +4975,6 @@ static int dsi_get_clocks(struct platform_device *dsidev)
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;
}
@@ -5434,6 +5143,135 @@ err:
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 */
static int omap_dsihw_probe(struct platform_device *dsidev)
{
@@ -5579,12 +5417,12 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
dsi->vc[i].vc_id = 0;
}
- dsi_calc_clock_param_ranges(dsidev);
-
r = dsi_get_clocks(dsidev);
if (r)
return r;
+ dsi_init_pll_data(dsidev);
+
pm_runtime_enable(&dsidev->dev);
r = dsi_runtime_get(dsidev);
@@ -5653,6 +5491,8 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
WARN_ON(dsi->scp_clk_refcount > 0);
+ dss_pll_unregister(&dsi->pll);
+
dsi_uninit_output(dsidev);
pm_runtime_disable(&dsidev->dev);
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 8563e2bc702c..14fb0c23f4a2 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -173,18 +173,6 @@ struct dispc_clock_info {
u16 pck_div;
};
-struct dsi_clock_info {
- /* rates that we get with dividers below */
- unsigned long fint;
- unsigned long clkdco;
- unsigned long clkout[4];
-
- /* dividers */
- u16 regn;
- u16 regm;
- u16 regm_hsdiv[4];
-};
-
struct dss_lcd_mgr_config {
enum dss_io_pad_mode io_pad_mode;
@@ -318,11 +306,6 @@ static inline void __exit sdi_uninit_port(struct device_node *port)
/* DSI */
-typedef bool (*dsi_pll_calc_func)(int regn, int regm, unsigned long fint,
- unsigned long pll, void *data);
-typedef bool (*dsi_hsdiv_calc_func)(int regm_dispc, unsigned long dispc,
- void *data);
-
#ifdef CONFIG_OMAP2_DSS_DSI
struct dentry;
@@ -336,71 +319,12 @@ void dsi_dump_clocks(struct seq_file *s);
void dsi_irq_handler(void);
u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt);
-unsigned long dsi_get_pll_clkin(struct platform_device *dsidev);
-
-bool dsi_hsdiv_calc(struct platform_device *dsidev, unsigned long pll,
- unsigned long out_min, dsi_hsdiv_calc_func func, void *data);
-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);
-
-unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
-int dsi_pll_set_clock_div(struct platform_device *dsidev,
- struct dsi_clock_info *cinfo);
-int dsi_pll_init(struct platform_device *dsidev);
-void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
-struct platform_device *dsi_get_dsidev_from_id(int module);
#else
static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
{
WARN("%s: DSI not compiled in, returning pixel_size as 0\n", __func__);
return 0;
}
-static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
-{
- WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
- return 0;
-}
-static inline int dsi_pll_set_clock_div(struct platform_device *dsidev,
- struct dsi_clock_info *cinfo)
-{
- WARN("%s: DSI not compiled in\n", __func__);
- return -ENODEV;
-}
-static inline int dsi_pll_init(struct platform_device *dsidev)
-{
- WARN("%s: DSI not compiled in\n", __func__);
- return -ENODEV;
-}
-static inline void dsi_pll_uninit(struct platform_device *dsidev,
- bool disconnect_lanes)
-{
-}
-static inline struct platform_device *dsi_get_dsidev_from_id(int module)
-{
- return NULL;
-}
-
-static inline unsigned long dsi_get_pll_clkin(struct platform_device *dsidev)
-{
- return 0;
-}
-
-static inline bool dsi_hsdiv_calc(struct platform_device *dsidev,
- unsigned long pll, unsigned long out_min,
- dsi_hsdiv_calc_func func, void *data)
-{
- return false;
-}
-
-static inline 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)
-{
- return false;
-}
-
#endif
/* DPI */
--
2.1.3
^ permalink raw reply related
* [PATCH 14/22] OMAPDSS: HDMI: fix setting REFSEL
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
Only OMAP5+ has REFSEL field, but at the moment it's set also on OMAP4.
Fix this by adding a "has_refsel" field, and setting the REFSEL based on
that.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/hdmi.h | 8 --------
drivers/video/fbdev/omap2/dss/hdmi_pll.c | 8 ++++----
2 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
index 262771b9b76b..4bbc9d206f4a 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -101,13 +101,6 @@ enum hdmi_core_hdmi_dvi {
HDMI_HDMI = 1
};
-enum hdmi_clk_refsel {
- HDMI_REFSEL_PCLK = 0,
- HDMI_REFSEL_REF1 = 1,
- HDMI_REFSEL_REF2 = 2,
- HDMI_REFSEL_SYSCLK = 3
-};
-
enum hdmi_packing_mode {
HDMI_PACK_10b_RGB_YUV444 = 0,
HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
@@ -199,7 +192,6 @@ struct hdmi_pll_info {
u16 regm2;
u16 regsd;
u16 dcofreq;
- enum hdmi_clk_refsel refsel;
};
struct hdmi_audio_format {
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
index 6d92bb32fe51..b28d41a08a8f 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
@@ -24,6 +24,7 @@
#define HDMI_DEFAULT_REGM2 1
struct hdmi_pll_features {
+ bool has_refsel;
bool sys_reset;
/* this is a hack, need to replace it with a better computation of M2 */
bool bound_dcofreq;
@@ -96,9 +97,6 @@ void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy)
pi->dcofreq = phy > 1000 * 100;
pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10;
- /* Set the reference clock to sysclk reference */
- pi->refsel = HDMI_REFSEL_SYSCLK;
-
DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
}
@@ -122,7 +120,8 @@ static int hdmi_pll_config(struct hdmi_pll_data *pll)
r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
- r = FLD_MOD(r, fmt->refsel, 22, 21); /* REFSEL */
+ if (pll_feat->has_refsel)
+ r = FLD_MOD(r, 0x3, 22, 21); /* REFSEL = SYSCLK */
if (fmt->dcofreq)
r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
@@ -222,6 +221,7 @@ static const struct hdmi_pll_features omap44xx_pll_feats = {
};
static const struct hdmi_pll_features omap54xx_pll_feats = {
+ .has_refsel = true,
.sys_reset = true,
.bound_dcofreq = true,
.fint_min = 620000,
--
2.1.3
^ permalink raw reply related
* [PATCH 15/22] OMAPDSS: HDMI5: disable interlace modes
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
We don't support interlace modes properly on OMAP5+ HDMI, so we need to
reject interlace timings.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/hdmi5.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c
index 169b764bb9d4..c053d692ec16 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -290,6 +290,10 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
{
struct omap_dss_device *out = &hdmi.output;
+ /* TODO: proper interlace support */
+ if (timings->interlace)
+ return -EINVAL;
+
if (!dispc_mgr_timings_ok(out->dispc_channel, timings))
return -EINVAL;
--
2.1.3
^ permalink raw reply related
* [PATCH 16/22] OMAPDSS: HDMI: rewrite HDMI PLL calculation code
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
The code calculating HDMI PLL parameters has always been very confusing.
Now that we are implementing a common PLL library for the DSS, it's
important that the PLL code is understandable.
This patch rewrites the calculation code, and removes a few hacks that
were used there.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/hdmi.h | 10 +++-
drivers/video/fbdev/omap2/dss/hdmi4.c | 9 +--
drivers/video/fbdev/omap2/dss/hdmi5.c | 9 +--
drivers/video/fbdev/omap2/dss/hdmi_phy.c | 31 ++++-------
drivers/video/fbdev/omap2/dss/hdmi_pll.c | 95 ++++++++++++++++----------------
5 files changed, 71 insertions(+), 83 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
index 4bbc9d206f4a..4b9bf0804a48 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -191,7 +191,9 @@ struct hdmi_pll_info {
u32 regmf;
u16 regm2;
u16 regsd;
- u16 dcofreq;
+
+ unsigned long clkdco;
+ unsigned long clkout;
};
struct hdmi_audio_format {
@@ -313,11 +315,13 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp);
int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp);
void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp);
void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s);
-void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy);
+void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin,
+ unsigned long target_tmds);
int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll);
/* HDMI PHY funcs */
-int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg);
+int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
+ unsigned long lfbitclk);
void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s);
int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy);
int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 9a8713ca090c..1f2fbccaff1f 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -180,7 +180,6 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
int r;
struct omap_video_timings *p;
struct omap_overlay_manager *mgr = hdmi.output.manager;
- unsigned long phy;
struct hdmi_wp_data *wp = &hdmi.wp;
r = hdmi_power_on_core(dssdev);
@@ -195,10 +194,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
- /* the functions below use kHz pixel clock. TODO: change to Hz */
- phy = p->pixelclock / 1000;
-
- hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy);
+ hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), p->pixelclock);
/* config the PLL and PHY hdmi_set_pll_pwrfirst */
r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp);
@@ -207,7 +203,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
goto err_pll_enable;
}
- r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg);
+ r = hdmi_phy_configure(&hdmi.phy, hdmi.pll.info.clkdco,
+ hdmi.pll.info.clkout);
if (r) {
DSSDBG("Failed to configure PHY\n");
goto err_phy_cfg;
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c
index c053d692ec16..e8ca9106c8af 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -198,7 +198,6 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
int r;
struct omap_video_timings *p;
struct omap_overlay_manager *mgr = hdmi.output.manager;
- unsigned long phy;
r = hdmi_power_on_core(dssdev);
if (r)
@@ -208,10 +207,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
- /* the functions below use kHz pixel clock. TODO: change to Hz */
- phy = p->pixelclock / 1000;
-
- hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy);
+ hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), p->pixelclock);
/* disable and clear irqs */
hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
@@ -225,7 +221,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
goto err_pll_enable;
}
- r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg);
+ r = hdmi_phy_configure(&hdmi.phy, hdmi.pll.info.clkdco,
+ hdmi.pll.info.clkout);
if (r) {
DSSDBG("Failed to start PHY\n");
goto err_phy_cfg;
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_phy.c b/drivers/video/fbdev/omap2/dss/hdmi_phy.c
index e007ac892d79..bc9e07d2afbe 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_phy.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_phy.c
@@ -20,9 +20,7 @@
struct hdmi_phy_features {
bool bist_ctrl;
- bool calc_freqout;
bool ldo_voltage;
- unsigned long dcofreq_min;
unsigned long max_phy;
};
@@ -132,7 +130,8 @@ static void hdmi_phy_configure_lanes(struct hdmi_phy_data *phy)
REG_FLD_MOD(phy->base, HDMI_TXPHY_PAD_CFG_CTRL, pol_val, 30, 27);
}
-int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg)
+int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
+ unsigned long lfbitclk)
{
u8 freqout;
@@ -149,20 +148,16 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg)
if (phy_feat->bist_ctrl)
REG_FLD_MOD(phy->base, HDMI_TXPHY_BIST_CONTROL, 1, 11, 11);
- if (phy_feat->calc_freqout) {
- /* DCOCLK/10 is pixel clock, compare pclk with DCOCLK_MIN/10 */
- u32 dco_min = phy_feat->dcofreq_min / 10;
- u32 pclk = cfg->timings.pixelclock;
-
- if (pclk < dco_min)
- freqout = 0;
- else if ((pclk >= dco_min) && (pclk < phy_feat->max_phy))
- freqout = 1;
- else
- freqout = 2;
- } else {
+ /*
+ * If the hfbitclk != lfbitclk, it means the lfbitclk was configured
+ * to be used for TMDS.
+ */
+ if (hfbitclk != lfbitclk)
+ freqout = 0;
+ else if (hfbitclk / 10 < phy_feat->max_phy)
freqout = 1;
- }
+ else
+ freqout = 2;
/*
* Write to phy address 0 to configure the clock
@@ -184,17 +179,13 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg)
static const struct hdmi_phy_features omap44xx_phy_feats = {
.bist_ctrl = false,
- .calc_freqout = false,
.ldo_voltage = true,
- .dcofreq_min = 500000000,
.max_phy = 185675000,
};
static const struct hdmi_phy_features omap54xx_phy_feats = {
.bist_ctrl = true,
- .calc_freqout = true,
.ldo_voltage = false,
- .dcofreq_min = 750000000,
.max_phy = 186000000,
};
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
index b28d41a08a8f..f04d435c4c0f 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
@@ -20,14 +20,9 @@
#include "dss.h"
#include "hdmi.h"
-#define HDMI_DEFAULT_REGN 16
-#define HDMI_DEFAULT_REGM2 1
-
struct hdmi_pll_features {
bool has_refsel;
bool sys_reset;
- /* this is a hack, need to replace it with a better computation of M2 */
- bool bound_dcofreq;
unsigned long fint_min, fint_max;
u16 regm_max;
unsigned long dcofreq_low_min, dcofreq_low_max;
@@ -52,55 +47,61 @@ void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s)
DUMPPLL(PLLCTRL_CFG4);
}
-void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy)
+void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin,
+ unsigned long target_tmds)
{
struct hdmi_pll_info *pi = &pll->info;
- unsigned long refclk;
- u32 mf;
+ unsigned long fint, clkdco, clkout;
+ unsigned long target_bitclk, target_clkdco;
+ unsigned long min_dco;
+ unsigned n, m, mf, m2, sd;
+
+ DSSDBG("clkin %lu, target tmds %lu\n", clkin, target_tmds);
+
+ target_bitclk = target_tmds * 10;
- /* use our funky units */
- clkin /= 10000;
+ /* Fint */
+ n = DIV_ROUND_UP(clkin, pll_feat->fint_max);
+ fint = clkin / n;
- /*
- * Input clock is predivided by N + 1
- * out put of which is reference clk
- */
+ /* adjust m2 so that the clkdco will be high enough */
+ min_dco = roundup(pll_feat->dcofreq_low_min, fint);
+ m2 = DIV_ROUND_UP(min_dco, target_bitclk);
+ if (m2 = 0)
+ m2 = 1;
- pi->regn = HDMI_DEFAULT_REGN;
+ target_clkdco = target_bitclk * m2;
+ m = target_clkdco / fint;
- refclk = clkin / pi->regn;
+ clkdco = fint * m;
- /* temorary hack to make sure DCO freq isn't calculated too low */
- if (pll_feat->bound_dcofreq && phy <= 65000)
- pi->regm2 = 3;
+ /* adjust clkdco with fractional mf */
+ if (WARN_ON(target_clkdco - clkdco > fint))
+ mf = 0;
else
- pi->regm2 = HDMI_DEFAULT_REGM2;
-
- /*
- * multiplier is pixel_clk/ref_clk
- * Multiplying by 100 to avoid fractional part removal
- */
- pi->regm = phy * pi->regm2 / refclk;
-
- /*
- * fractional multiplier is remainder of the difference between
- * multiplier and actual phy(required pixel clock thus should be
- * multiplied by 2^18(262144) divided by the reference clock
- */
- mf = (phy - pi->regm / pi->regm2 * refclk) * 262144;
- pi->regmf = pi->regm2 * mf / refclk;
-
- /*
- * Dcofreq should be set to 1 if required pixel clock
- * is greater than 1000MHz
- */
- pi->dcofreq = phy > 1000 * 100;
- pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10;
-
- DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
- DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
-}
+ mf = (u32)div_u64(262144ull * (target_clkdco - clkdco), fint);
+
+ if (mf > 0)
+ clkdco += (u32)div_u64((u64)mf * fint, 262144);
+ clkout = clkdco / m2;
+
+ /* sigma-delta */
+ sd = DIV_ROUND_UP(fint * m, 250000000);
+
+ DSSDBG("N = %u, M = %u, M.f = %u, M2 = %u, SD = %u\n",
+ n, m, mf, m2, sd);
+ DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout);
+
+ pi->regn = n;
+ pi->regm = m;
+ pi->regmf = mf;
+ pi->regm2 = m2;
+ pi->regsd = sd;
+
+ pi->clkdco = clkdco;
+ pi->clkout = clkout;
+}
static int hdmi_pll_config(struct hdmi_pll_data *pll)
{
@@ -123,7 +124,7 @@ static int hdmi_pll_config(struct hdmi_pll_data *pll)
if (pll_feat->has_refsel)
r = FLD_MOD(r, 0x3, 22, 21); /* REFSEL = SYSCLK */
- if (fmt->dcofreq)
+ if (fmt->clkdco > pll_feat->dcofreq_low_max)
r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
else
r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
@@ -210,7 +211,6 @@ void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
static const struct hdmi_pll_features omap44xx_pll_feats = {
.sys_reset = false,
- .bound_dcofreq = false,
.fint_min = 500000,
.fint_max = 2500000,
.regm_max = 4095,
@@ -223,7 +223,6 @@ static const struct hdmi_pll_features omap44xx_pll_feats = {
static const struct hdmi_pll_features omap54xx_pll_feats = {
.has_refsel = true,
.sys_reset = true,
- .bound_dcofreq = true,
.fint_min = 620000,
.fint_max = 2500000,
.regm_max = 2046,
--
2.1.3
^ permalink raw reply related
* [PATCH 17/22] OMAPDSS: HDMI: Remove HDMI PLL reset
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
The SYSRESET bits in HDMI PLL do not reset the PLL itself, but only
affect the power used for the PLL.
Afaik there is no reason to use the SYSRESET bits, and we don't use it
in the other PLLs, so let's remove the HDMI PLL reset to make the PLL
code simpler and similar to other PLLs.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/hdmi_pll.c | 19 -------------------
1 file changed, 19 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
index f04d435c4c0f..0942bdc8dfa6 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
@@ -166,21 +166,6 @@ static int hdmi_pll_config(struct hdmi_pll_data *pll)
return 0;
}
-static int hdmi_pll_reset(struct hdmi_pll_data *pll)
-{
- /* SYSRESET controlled by power FSM */
- REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, pll_feat->sys_reset, 3, 3);
-
- /* READ 0x0 reset is in progress */
- if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1)
- != 1) {
- DSSERR("Failed to sysreset PLL\n");
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
{
u16 r = 0;
@@ -193,10 +178,6 @@ int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
if (r)
return r;
- r = hdmi_pll_reset(pll);
- if (r)
- return r;
-
r = hdmi_pll_config(pll);
if (r)
return r;
--
2.1.3
^ permalink raw reply related
* [PATCH 18/22] OMAPDSS: HDMI: store WP pointer to hdmi_pll_data
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
HDMI PLL code needs the pointer to the WP block so that it can manage
its power. Currently this is passed as a function parameter to
hdmi_pll_enable and hdmi_pll_disable. To make the PLL function adhere to
the DSS PLL API, we need to remove the WP parameter.
This patch stores the WP pointer to hdmi_pll_data in hdmi_pll_init, so
that it's available when needed.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/hdmi.h | 9 ++++++---
drivers/video/fbdev/omap2/dss/hdmi4.c | 8 ++++----
drivers/video/fbdev/omap2/dss/hdmi5.c | 8 ++++----
drivers/video/fbdev/omap2/dss/hdmi_pll.c | 12 +++++++++---
4 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
index 4b9bf0804a48..03761ecb81a6 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -248,6 +248,8 @@ struct hdmi_wp_data {
struct hdmi_pll_data {
void __iomem *base;
+ struct hdmi_wp_data *wp;
+
struct hdmi_pll_info info;
};
@@ -312,12 +314,13 @@ void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp);
/* HDMI PLL funcs */
-int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp);
-void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp);
+int hdmi_pll_enable(struct hdmi_pll_data *pll);
+void hdmi_pll_disable(struct hdmi_pll_data *pll);
void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s);
void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin,
unsigned long target_tmds);
-int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll);
+int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
+ struct hdmi_wp_data *wp);
/* HDMI PHY funcs */
int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 1f2fbccaff1f..2094b6eae99e 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -197,7 +197,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), p->pixelclock);
/* config the PLL and PHY hdmi_set_pll_pwrfirst */
- r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp);
+ r = hdmi_pll_enable(&hdmi.pll);
if (r) {
DSSDBG("Failed to lock PLL\n");
goto err_pll_enable;
@@ -241,7 +241,7 @@ err_vid_enable:
err_phy_cfg:
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
err_phy_pwr:
- hdmi_pll_disable(&hdmi.pll, &hdmi.wp);
+ hdmi_pll_disable(&hdmi.pll);
err_pll_enable:
hdmi_power_off_core(dssdev);
return -EIO;
@@ -259,7 +259,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
- hdmi_pll_disable(&hdmi.pll, &hdmi.wp);
+ hdmi_pll_disable(&hdmi.pll);
hdmi_power_off_core(dssdev);
}
@@ -688,7 +688,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
if (r)
return r;
- r = hdmi_pll_init(pdev, &hdmi.pll);
+ r = hdmi_pll_init(pdev, &hdmi.pll, &hdmi.wp);
if (r)
return r;
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c
index e8ca9106c8af..fb8c14507a4d 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -215,7 +215,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
hdmi_wp_get_irqstatus(&hdmi.wp));
/* config the PLL and PHY hdmi_set_pll_pwrfirst */
- r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp);
+ r = hdmi_pll_enable(&hdmi.pll);
if (r) {
DSSDBG("Failed to lock PLL\n");
goto err_pll_enable;
@@ -259,7 +259,7 @@ err_vid_enable:
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
err_phy_pwr:
err_phy_cfg:
- hdmi_pll_disable(&hdmi.pll, &hdmi.wp);
+ hdmi_pll_disable(&hdmi.pll);
err_pll_enable:
hdmi_power_off_core(dssdev);
return -EIO;
@@ -277,7 +277,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
- hdmi_pll_disable(&hdmi.pll, &hdmi.wp);
+ hdmi_pll_disable(&hdmi.pll);
hdmi_power_off_core(dssdev);
}
@@ -717,7 +717,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
if (r)
return r;
- r = hdmi_pll_init(pdev, &hdmi.pll);
+ r = hdmi_pll_init(pdev, &hdmi.pll, &hdmi.wp);
if (r)
return r;
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
index 0942bdc8dfa6..190bede1dcb9 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
@@ -166,8 +166,9 @@ static int hdmi_pll_config(struct hdmi_pll_data *pll)
return 0;
}
-int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
+int hdmi_pll_enable(struct hdmi_pll_data *pll)
{
+ struct hdmi_wp_data *wp = pll->wp;
u16 r = 0;
r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
@@ -185,8 +186,10 @@ int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
return 0;
}
-void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
+void hdmi_pll_disable(struct hdmi_pll_data *pll)
{
+ struct hdmi_wp_data *wp = pll->wp;
+
hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
}
@@ -245,11 +248,14 @@ static int hdmi_pll_init_features(struct platform_device *pdev)
return 0;
}
-int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll)
+int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
+ struct hdmi_wp_data *wp)
{
int r;
struct resource *res;
+ pll->wp = wp;
+
r = hdmi_pll_init_features(pdev);
if (r)
return r;
--
2.1.3
^ permalink raw reply related
* [PATCH 19/22] OMAPDSS: HDMI: split PLL enable & config
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
At the moment we have one function, hdmi_pll_enable, which enables the
PLL and writes the PLL configuration to registers.
To make the HDMI PLL ahere to the DSS PLL API, split the hdmi_pll_enable
into two parts: hdmi_pll_enable which enables the PLL HW, and
hdmi_pll_set_config which writes the config.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/hdmi.h | 1 +
drivers/video/fbdev/omap2/dss/hdmi4.c | 10 ++++++++--
drivers/video/fbdev/omap2/dss/hdmi5.c | 10 ++++++++--
drivers/video/fbdev/omap2/dss/hdmi_pll.c | 6 +-----
4 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
index 03761ecb81a6..7595274a9bcf 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -316,6 +316,7 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp);
/* HDMI PLL funcs */
int hdmi_pll_enable(struct hdmi_pll_data *pll);
void hdmi_pll_disable(struct hdmi_pll_data *pll);
+int hdmi_pll_set_config(struct hdmi_pll_data *pll);
void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s);
void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin,
unsigned long target_tmds);
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 2094b6eae99e..98aa910241b8 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -196,13 +196,18 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), p->pixelclock);
- /* config the PLL and PHY hdmi_set_pll_pwrfirst */
r = hdmi_pll_enable(&hdmi.pll);
if (r) {
- DSSDBG("Failed to lock PLL\n");
+ DSSERR("Failed to enable PLL\n");
goto err_pll_enable;
}
+ r = hdmi_pll_set_config(&hdmi.pll);
+ if (r) {
+ DSSERR("Failed to configure PLL\n");
+ goto err_pll_cfg;
+ }
+
r = hdmi_phy_configure(&hdmi.phy, hdmi.pll.info.clkdco,
hdmi.pll.info.clkout);
if (r) {
@@ -241,6 +246,7 @@ err_vid_enable:
err_phy_cfg:
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
err_phy_pwr:
+err_pll_cfg:
hdmi_pll_disable(&hdmi.pll);
err_pll_enable:
hdmi_power_off_core(dssdev);
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c
index fb8c14507a4d..facc4e070520 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -214,13 +214,18 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
hdmi_wp_set_irqstatus(&hdmi.wp,
hdmi_wp_get_irqstatus(&hdmi.wp));
- /* config the PLL and PHY hdmi_set_pll_pwrfirst */
r = hdmi_pll_enable(&hdmi.pll);
if (r) {
- DSSDBG("Failed to lock PLL\n");
+ DSSERR("Failed to enable PLL\n");
goto err_pll_enable;
}
+ r = hdmi_pll_set_config(&hdmi.pll);
+ if (r) {
+ DSSERR("Failed to configure PLL\n");
+ goto err_pll_cfg;
+ }
+
r = hdmi_phy_configure(&hdmi.phy, hdmi.pll.info.clkdco,
hdmi.pll.info.clkout);
if (r) {
@@ -259,6 +264,7 @@ err_vid_enable:
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
err_phy_pwr:
err_phy_cfg:
+err_pll_cfg:
hdmi_pll_disable(&hdmi.pll);
err_pll_enable:
hdmi_power_off_core(dssdev);
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
index 190bede1dcb9..c14c3d132513 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
@@ -103,7 +103,7 @@ void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin,
pi->clkout = clkout;
}
-static int hdmi_pll_config(struct hdmi_pll_data *pll)
+int hdmi_pll_set_config(struct hdmi_pll_data *pll)
{
u32 r;
struct hdmi_pll_info *fmt = &pll->info;
@@ -179,10 +179,6 @@ int hdmi_pll_enable(struct hdmi_pll_data *pll)
if (r)
return r;
- r = hdmi_pll_config(pll);
- if (r)
- return r;
-
return 0;
}
--
2.1.3
^ permalink raw reply related
* [PATCH 20/22] OMAPDSS: HDMI: remove extra poweroff
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
hdmi_pll_enable powers off the PLL as the first thing it does. Right
after that, it enables the PLL powers.
The initial power-off is pointless, so let's remove it.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/hdmi_pll.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
index c14c3d132513..92d22252f86a 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
@@ -171,10 +171,6 @@ int hdmi_pll_enable(struct hdmi_pll_data *pll)
struct hdmi_wp_data *wp = pll->wp;
u16 r = 0;
- r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
- if (r)
- return r;
-
r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
if (r)
return r;
--
2.1.3
^ permalink raw reply related
* [PATCH 21/22] OMAPDSS: HDMI: use common DSS PLL support
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
Now that we have the common DSS PLL support, change HDMI to use it. This
results in quite a lot of changes, but almost all of them are trivial
name changes.
The function to program the PLL settings can be removed from hdmi_pll.c,
as the common PLL API contains the same functionality.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/hdmi.h | 24 +---
drivers/video/fbdev/omap2/dss/hdmi4.c | 55 +++-----
drivers/video/fbdev/omap2/dss/hdmi5.c | 56 +++-----
drivers/video/fbdev/omap2/dss/hdmi_pll.c | 225 ++++++++++++++-----------------
4 files changed, 146 insertions(+), 214 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
index 7595274a9bcf..3c42823e934b 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -184,18 +184,6 @@ struct hdmi_config {
enum hdmi_core_hdmi_dvi hdmi_dvi_mode;
};
-/* HDMI PLL structure */
-struct hdmi_pll_info {
- u16 regn;
- u16 regm;
- u32 regmf;
- u16 regm2;
- u16 regsd;
-
- unsigned long clkdco;
- unsigned long clkout;
-};
-
struct hdmi_audio_format {
enum hdmi_stereo_channels stereo_channels;
u8 active_chnnls_msk;
@@ -246,11 +234,11 @@ struct hdmi_wp_data {
};
struct hdmi_pll_data {
+ struct dss_pll pll;
+
void __iomem *base;
struct hdmi_wp_data *wp;
-
- struct hdmi_pll_info info;
};
struct hdmi_phy_data {
@@ -314,14 +302,12 @@ void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp);
/* HDMI PLL funcs */
-int hdmi_pll_enable(struct hdmi_pll_data *pll);
-void hdmi_pll_disable(struct hdmi_pll_data *pll);
-int hdmi_pll_set_config(struct hdmi_pll_data *pll);
void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s);
-void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin,
- unsigned long target_tmds);
+void hdmi_pll_compute(struct hdmi_pll_data *pll,
+ unsigned long target_tmds, struct dss_pll_clock_info *pi);
int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
struct hdmi_wp_data *wp);
+void hdmi_pll_uninit(struct hdmi_pll_data *hpll);
/* HDMI PHY funcs */
int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 98aa910241b8..46dcc71ce058 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -49,7 +49,6 @@ static struct {
struct hdmi_config cfg;
- struct clk *sys_clk;
struct regulator *vdda_hdmi_dac_reg;
bool core_enabled;
@@ -181,6 +180,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
struct omap_video_timings *p;
struct omap_overlay_manager *mgr = hdmi.output.manager;
struct hdmi_wp_data *wp = &hdmi.wp;
+ struct dss_pll_clock_info hdmi_cinfo = { 0 };
r = hdmi_power_on_core(dssdev);
if (r)
@@ -194,22 +194,22 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
- hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), p->pixelclock);
+ hdmi_pll_compute(&hdmi.pll, p->pixelclock, &hdmi_cinfo);
- r = hdmi_pll_enable(&hdmi.pll);
+ r = dss_pll_enable(&hdmi.pll.pll);
if (r) {
DSSERR("Failed to enable PLL\n");
goto err_pll_enable;
}
- r = hdmi_pll_set_config(&hdmi.pll);
+ r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo);
if (r) {
DSSERR("Failed to configure PLL\n");
goto err_pll_cfg;
}
- r = hdmi_phy_configure(&hdmi.phy, hdmi.pll.info.clkdco,
- hdmi.pll.info.clkout);
+ r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco,
+ hdmi_cinfo.clkout[0]);
if (r) {
DSSDBG("Failed to configure PHY\n");
goto err_phy_cfg;
@@ -247,7 +247,7 @@ err_phy_cfg:
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
err_phy_pwr:
err_pll_cfg:
- hdmi_pll_disable(&hdmi.pll);
+ dss_pll_disable(&hdmi.pll.pll);
err_pll_enable:
hdmi_power_off_core(dssdev);
return -EIO;
@@ -265,7 +265,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
- hdmi_pll_disable(&hdmi.pll);
+ dss_pll_disable(&hdmi.pll.pll);
hdmi_power_off_core(dssdev);
}
@@ -407,21 +407,6 @@ static void hdmi_core_disable(struct omap_dss_device *dssdev)
mutex_unlock(&hdmi.lock);
}
-static int hdmi_get_clocks(struct platform_device *pdev)
-{
- struct clk *clk;
-
- clk = devm_clk_get(&pdev->dev, "sys_clk");
- if (IS_ERR(clk)) {
- DSSERR("can't get sys_clk\n");
- return PTR_ERR(clk);
- }
-
- hdmi.sys_clk = clk;
-
- return 0;
-}
-
static int hdmi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
@@ -700,22 +685,17 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
r = hdmi_phy_init(pdev, &hdmi.phy);
if (r)
- return r;
+ goto err;
r = hdmi4_core_init(pdev, &hdmi.core);
if (r)
- return r;
-
- r = hdmi_get_clocks(pdev);
- if (r) {
- DSSERR("can't get clocks\n");
- return r;
- }
+ goto err;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
DSSERR("platform_get_irq failed\n");
- return -ENODEV;
+ r = -ENODEV;
+ goto err;
}
r = devm_request_threaded_irq(&pdev->dev, irq,
@@ -723,7 +703,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
if (r) {
DSSERR("HDMI IRQ request failed\n");
- return r;
+ goto err;
}
pm_runtime_enable(&pdev->dev);
@@ -733,12 +713,17 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
return 0;
+err:
+ hdmi_pll_uninit(&hdmi.pll);
+ return r;
}
static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
{
hdmi_uninit_output(pdev);
+ hdmi_pll_uninit(&hdmi.pll);
+
pm_runtime_disable(&pdev->dev);
return 0;
@@ -746,8 +731,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
static int hdmi_runtime_suspend(struct device *dev)
{
- clk_disable_unprepare(hdmi.sys_clk);
-
dispc_runtime_put();
return 0;
@@ -761,8 +744,6 @@ static int hdmi_runtime_resume(struct device *dev)
if (r < 0)
return r;
- clk_prepare_enable(hdmi.sys_clk);
-
return 0;
}
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c
index facc4e070520..67facf87b370 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -54,8 +54,8 @@ static struct {
struct hdmi_config cfg;
- struct clk *sys_clk;
struct regulator *vdda_reg;
+ struct clk *sys_clk;
bool core_enabled;
@@ -198,6 +198,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
int r;
struct omap_video_timings *p;
struct omap_overlay_manager *mgr = hdmi.output.manager;
+ struct dss_pll_clock_info hdmi_cinfo = { 0 };
r = hdmi_power_on_core(dssdev);
if (r)
@@ -207,27 +208,27 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
- hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), p->pixelclock);
+ hdmi_pll_compute(&hdmi.pll, p->pixelclock, &hdmi_cinfo);
/* disable and clear irqs */
hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
hdmi_wp_set_irqstatus(&hdmi.wp,
hdmi_wp_get_irqstatus(&hdmi.wp));
- r = hdmi_pll_enable(&hdmi.pll);
+ r = dss_pll_enable(&hdmi.pll.pll);
if (r) {
DSSERR("Failed to enable PLL\n");
goto err_pll_enable;
}
- r = hdmi_pll_set_config(&hdmi.pll);
+ r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo);
if (r) {
DSSERR("Failed to configure PLL\n");
goto err_pll_cfg;
}
- r = hdmi_phy_configure(&hdmi.phy, hdmi.pll.info.clkdco,
- hdmi.pll.info.clkout);
+ r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco,
+ hdmi_cinfo.clkout[0]);
if (r) {
DSSDBG("Failed to start PHY\n");
goto err_phy_cfg;
@@ -265,7 +266,7 @@ err_vid_enable:
err_phy_pwr:
err_phy_cfg:
err_pll_cfg:
- hdmi_pll_disable(&hdmi.pll);
+ dss_pll_disable(&hdmi.pll.pll);
err_pll_enable:
hdmi_power_off_core(dssdev);
return -EIO;
@@ -283,7 +284,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
- hdmi_pll_disable(&hdmi.pll);
+ dss_pll_disable(&hdmi.pll.pll);
hdmi_power_off_core(dssdev);
}
@@ -436,21 +437,6 @@ static void hdmi_core_disable(struct omap_dss_device *dssdev)
mutex_unlock(&hdmi.lock);
}
-static int hdmi_get_clocks(struct platform_device *pdev)
-{
- struct clk *clk;
-
- clk = devm_clk_get(&pdev->dev, "sys_clk");
- if (IS_ERR(clk)) {
- DSSERR("can't get sys_clk\n");
- return PTR_ERR(clk);
- }
-
- hdmi.sys_clk = clk;
-
- return 0;
-}
-
static int hdmi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
@@ -729,22 +715,17 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
r = hdmi_phy_init(pdev, &hdmi.phy);
if (r)
- return r;
+ goto err;
r = hdmi5_core_init(pdev, &hdmi.core);
if (r)
- return r;
-
- r = hdmi_get_clocks(pdev);
- if (r) {
- DSSERR("can't get clocks\n");
- return r;
- }
+ goto err;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
DSSERR("platform_get_irq failed\n");
- return -ENODEV;
+ r = -ENODEV;
+ goto err;
}
r = devm_request_threaded_irq(&pdev->dev, irq,
@@ -752,7 +733,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
if (r) {
DSSERR("HDMI IRQ request failed\n");
- return r;
+ goto err;
}
pm_runtime_enable(&pdev->dev);
@@ -762,12 +743,17 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
return 0;
+err:
+ hdmi_pll_uninit(&hdmi.pll);
+ return r;
}
static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
{
hdmi_uninit_output(pdev);
+ hdmi_pll_uninit(&hdmi.pll);
+
pm_runtime_disable(&pdev->dev);
return 0;
@@ -775,8 +761,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
static int hdmi_runtime_suspend(struct device *dev)
{
- clk_disable_unprepare(hdmi.sys_clk);
-
dispc_runtime_put();
return 0;
@@ -790,8 +774,6 @@ static int hdmi_runtime_resume(struct device *dev)
if (r < 0)
return r;
- clk_prepare_enable(hdmi.sys_clk);
-
return 0;
}
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
index 92d22252f86a..87accdb59c81 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
@@ -15,22 +15,13 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
+
#include <video/omapdss.h>
#include "dss.h"
#include "hdmi.h"
-struct hdmi_pll_features {
- bool has_refsel;
- bool sys_reset;
- unsigned long fint_min, fint_max;
- u16 regm_max;
- unsigned long dcofreq_low_min, dcofreq_low_max;
- unsigned long dcofreq_high_min, dcofreq_high_max;
-};
-
-static const struct hdmi_pll_features *pll_feat;
-
void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s)
{
#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\
@@ -47,25 +38,28 @@ void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s)
DUMPPLL(PLLCTRL_CFG4);
}
-void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin,
- unsigned long target_tmds)
+void hdmi_pll_compute(struct hdmi_pll_data *pll,
+ unsigned long target_tmds, struct dss_pll_clock_info *pi)
{
- struct hdmi_pll_info *pi = &pll->info;
unsigned long fint, clkdco, clkout;
unsigned long target_bitclk, target_clkdco;
unsigned long min_dco;
unsigned n, m, mf, m2, sd;
+ unsigned long clkin;
+ const struct dss_pll_hw *hw = pll->pll.hw;
+
+ clkin = clk_get_rate(pll->pll.clkin);
DSSDBG("clkin %lu, target tmds %lu\n", clkin, target_tmds);
target_bitclk = target_tmds * 10;
/* Fint */
- n = DIV_ROUND_UP(clkin, pll_feat->fint_max);
+ n = DIV_ROUND_UP(clkin, hw->fint_max);
fint = clkin / n;
/* adjust m2 so that the clkdco will be high enough */
- min_dco = roundup(pll_feat->dcofreq_low_min, fint);
+ min_dco = roundup(hw->clkdco_min, fint);
m2 = DIV_ROUND_UP(min_dco, target_bitclk);
if (m2 = 0)
m2 = 1;
@@ -93,81 +87,20 @@ void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin,
n, m, mf, m2, sd);
DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout);
- pi->regn = n;
- pi->regm = m;
- pi->regmf = mf;
- pi->regm2 = m2;
- pi->regsd = sd;
+ pi->n = n;
+ pi->m = m;
+ pi->mf = mf;
+ pi->mX[0] = m2;
+ pi->sd = sd;
+ pi->fint = fint;
pi->clkdco = clkdco;
- pi->clkout = clkout;
-}
-
-int hdmi_pll_set_config(struct hdmi_pll_data *pll)
-{
- u32 r;
- struct hdmi_pll_info *fmt = &pll->info;
-
- /* PLL start always use manual mode */
- REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
-
- r = hdmi_read_reg(pll->base, PLLCTRL_CFG1);
- r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
- r = FLD_MOD(r, fmt->regn - 1, 8, 1); /* CFG1_PLL_REGN */
- hdmi_write_reg(pll->base, PLLCTRL_CFG1, r);
-
- r = hdmi_read_reg(pll->base, PLLCTRL_CFG2);
-
- r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
- r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
- r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
- if (pll_feat->has_refsel)
- r = FLD_MOD(r, 0x3, 22, 21); /* REFSEL = SYSCLK */
-
- if (fmt->clkdco > pll_feat->dcofreq_low_max)
- r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
- else
- r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
-
- hdmi_write_reg(pll->base, PLLCTRL_CFG2, r);
-
- REG_FLD_MOD(pll->base, PLLCTRL_CFG3, fmt->regsd, 17, 10);
-
- r = hdmi_read_reg(pll->base, PLLCTRL_CFG4);
- r = FLD_MOD(r, fmt->regm2, 24, 18);
- r = FLD_MOD(r, fmt->regmf, 17, 0);
- hdmi_write_reg(pll->base, PLLCTRL_CFG4, r);
-
- /* go now */
- REG_FLD_MOD(pll->base, PLLCTRL_PLL_GO, 0x1, 0, 0);
-
- /* wait for bit change */
- if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO,
- 0, 0, 0) != 0) {
- DSSERR("PLL GO bit not clearing\n");
- return -ETIMEDOUT;
- }
-
- /* Wait till the lock bit is set in PLL status */
- if (hdmi_wait_for_bit_change(pll->base,
- PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
- DSSERR("cannot lock PLL\n");
- DSSERR("CFG1 0x%x\n",
- hdmi_read_reg(pll->base, PLLCTRL_CFG1));
- DSSERR("CFG2 0x%x\n",
- hdmi_read_reg(pll->base, PLLCTRL_CFG2));
- DSSERR("CFG4 0x%x\n",
- hdmi_read_reg(pll->base, PLLCTRL_CFG4));
- return -ETIMEDOUT;
- }
-
- DSSDBG("PLL locked!\n");
-
- return 0;
+ pi->clkout[0] = clkout;
}
-int hdmi_pll_enable(struct hdmi_pll_data *pll)
+static int hdmi_pll_enable(struct dss_pll *dsspll)
{
+ struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
struct hdmi_wp_data *wp = pll->wp;
u16 r = 0;
@@ -178,64 +111,105 @@ int hdmi_pll_enable(struct hdmi_pll_data *pll)
return 0;
}
-void hdmi_pll_disable(struct hdmi_pll_data *pll)
+static void hdmi_pll_disable(struct dss_pll *dsspll)
{
+ struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
struct hdmi_wp_data *wp = pll->wp;
hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
}
-static const struct hdmi_pll_features omap44xx_pll_feats = {
- .sys_reset = false,
- .fint_min = 500000,
- .fint_max = 2500000,
- .regm_max = 4095,
- .dcofreq_low_min = 500000000,
- .dcofreq_low_max = 1000000000,
- .dcofreq_high_min = 1000000000,
- .dcofreq_high_max = 2000000000,
+static const struct dss_pll_ops dsi_pll_ops = {
+ .enable = hdmi_pll_enable,
+ .disable = hdmi_pll_disable,
+ .set_config = dss_pll_write_config_type_b,
+};
+
+static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = {
+ .n_max = 255,
+ .m_min = 20,
+ .m_max = 4095,
+ .mX_max = 127,
+ .fint_min = 500000,
+ .fint_max = 2500000,
+ .clkdco_max = 1800000000,
+
+ .clkdco_min = 500000000,
+ .clkdco_low = 1000000000,
+ .clkdco_max = 2000000000,
+
+ .n_msb = 8,
+ .n_lsb = 1,
+ .m_msb = 20,
+ .m_lsb = 9,
+
+ .mX_msb[0] = 24,
+ .mX_lsb[0] = 18,
+
+ .has_selfreqdco = true,
};
-static const struct hdmi_pll_features omap54xx_pll_feats = {
- .has_refsel = true,
- .sys_reset = true,
- .fint_min = 620000,
- .fint_max = 2500000,
- .regm_max = 2046,
- .dcofreq_low_min = 750000000,
- .dcofreq_low_max = 1500000000,
- .dcofreq_high_min = 1250000000,
- .dcofreq_high_max = 2500000000UL,
+static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = {
+ .n_max = 255,
+ .m_min = 20,
+ .m_max = 2045,
+ .mX_max = 127,
+ .fint_min = 620000,
+ .fint_max = 2500000,
+ .clkdco_max = 1800000000,
+
+ .clkdco_min = 750000000,
+ .clkdco_low = 1500000000,
+ .clkdco_max = 2500000000UL,
+
+ .n_msb = 8,
+ .n_lsb = 1,
+ .m_msb = 20,
+ .m_lsb = 9,
+
+ .mX_msb[0] = 24,
+ .mX_lsb[0] = 18,
+
+ .has_selfreqdco = true,
+ .has_refsel = true,
};
-static int hdmi_pll_init_features(struct platform_device *pdev)
+static int dsi_init_pll_data(struct platform_device *pdev, struct hdmi_pll_data *hpll)
{
- struct hdmi_pll_features *dst;
- const struct hdmi_pll_features *src;
+ struct dss_pll *pll = &hpll->pll;
+ struct clk *clk;
+ int r;
- dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
- if (!dst) {
- dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n");
- return -ENOMEM;
+ clk = devm_clk_get(&pdev->dev, "sys_clk");
+ if (IS_ERR(clk)) {
+ DSSERR("can't get sys_clk\n");
+ return PTR_ERR(clk);
}
+ pll->name = "hdmi";
+ pll->base = hpll->base;
+ pll->clkin = clk;
+
switch (omapdss_get_version()) {
case OMAPDSS_VER_OMAP4430_ES1:
case OMAPDSS_VER_OMAP4430_ES2:
case OMAPDSS_VER_OMAP4:
- src = &omap44xx_pll_feats;
+ pll->hw = &dss_omap4_hdmi_pll_hw;
break;
case OMAPDSS_VER_OMAP5:
- src = &omap54xx_pll_feats;
+ pll->hw = &dss_omap5_hdmi_pll_hw;
break;
default:
return -ENODEV;
}
- memcpy(dst, src, sizeof(*dst));
- pll_feat = dst;
+ pll->ops = &dsi_pll_ops;
+
+ r = dss_pll_register(pll);
+ if (r)
+ return r;
return 0;
}
@@ -248,10 +222,6 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
pll->wp = wp;
- r = hdmi_pll_init_features(pdev);
- if (r)
- return r;
-
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll");
if (!res) {
DSSERR("can't get PLL mem resource\n");
@@ -264,5 +234,18 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
return PTR_ERR(pll->base);
}
+ r = dsi_init_pll_data(pdev, pll);
+ if (r) {
+ DSSERR("failed to init HDMI PLL\n");
+ return r;
+ }
+
return 0;
}
+
+void hdmi_pll_uninit(struct hdmi_pll_data *hpll)
+{
+ struct dss_pll *pll = &hpll->pll;
+
+ dss_pll_unregister(pll);
+}
--
2.1.3
^ permalink raw reply related
* [PATCH 22/22] OMAPDSS: features: remove unused DSI PLL features
From: Tomi Valkeinen @ 2014-11-12 11:52 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1415793144-11723-1-git-send-email-tomi.valkeinen@ti.com>
Now that the DSS has the common DSS PLL, we no longer use the DSI PLL
feature flags from dss_features.c.
Remove all the unused feature flags.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dss_features.c | 38 ----------------------------
drivers/video/fbdev/omap2/dss/dss_features.h | 11 --------
2 files changed, 49 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dss_features.c b/drivers/video/fbdev/omap2/dss/dss_features.c
index 7e7fcf450342..0e3da809473c 100644
--- a/drivers/video/fbdev/omap2/dss/dss_features.c
+++ b/drivers/video/fbdev/omap2/dss/dss_features.c
@@ -72,10 +72,6 @@ static const struct dss_reg_field omap2_dss_reg_fields[] = {
[FEAT_REG_HORIZONTALACCU] = { 9, 0 },
[FEAT_REG_VERTICALACCU] = { 25, 16 },
[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[] = {
@@ -87,10 +83,6 @@ static const struct dss_reg_field omap3_dss_reg_fields[] = {
[FEAT_REG_HORIZONTALACCU] = { 9, 0 },
[FEAT_REG_VERTICALACCU] = { 25, 16 },
[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 am43xx_dss_reg_fields[] = {
@@ -113,10 +105,6 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = {
[FEAT_REG_HORIZONTALACCU] = { 10, 0 },
[FEAT_REG_VERTICALACCU] = { 26, 16 },
[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 struct dss_reg_field omap5_dss_reg_fields[] = {
@@ -128,10 +116,6 @@ static const struct dss_reg_field omap5_dss_reg_fields[] = {
[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[] = {
@@ -437,11 +421,6 @@ static const char * const omap5_dss_clk_source_names[] = {
static const struct dss_param_range omap2_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 133000000 },
[FEAT_PARAM_DSS_PCD] = { 2, 255 },
- [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
- [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
- [FEAT_PARAM_DSIPLL_REGM_HSDIV] = { 0, 0 },
- [FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
- [FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
[FEAT_PARAM_DOWNSCALE] = { 1, 2 },
/*
* Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
@@ -453,10 +432,6 @@ static const struct dss_param_range omap2_dss_param_range[] = {
static const struct dss_param_range omap3_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
[FEAT_PARAM_DSS_PCD] = { 1, 255 },
- [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
- [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
- [FEAT_PARAM_DSIPLL_REGM_HSDIV] = { 0, (1 << 4) - 1 },
- [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
[FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
@@ -473,10 +448,6 @@ static const struct dss_param_range am43xx_dss_param_range[] = {
static const struct dss_param_range omap4_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
[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_HSDIV] = { 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 },
@@ -486,10 +457,6 @@ static const struct dss_param_range omap4_dss_param_range[] = {
static const struct dss_param_range omap5_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 209250000 },
[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_HSDIV] = { 0, (1 << 5) - 1 },
- [FEAT_PARAM_DSIPLL_FINT] = { 150000, 52000000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
[FEAT_PARAM_DSI_FCK] = { 0, 209250000 },
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
@@ -513,7 +480,6 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
FEAT_LINEBUFFERSPLIT,
FEAT_ROWREPEATENABLE,
FEAT_RESIZECONF,
- FEAT_DSI_PLL_FREQSEL,
FEAT_DSI_REVERSE_TXCLKESC,
FEAT_VENC_REQUIRES_TV_DAC_CLK,
FEAT_CPR,
@@ -533,7 +499,6 @@ static const enum dss_feat_id am35xx_dss_feat_list[] = {
FEAT_LINEBUFFERSPLIT,
FEAT_ROWREPEATENABLE,
FEAT_RESIZECONF,
- FEAT_DSI_PLL_FREQSEL,
FEAT_DSI_REVERSE_TXCLKESC,
FEAT_VENC_REQUIRES_TV_DAC_CLK,
FEAT_CPR,
@@ -568,7 +533,6 @@ static const enum dss_feat_id omap3630_dss_feat_list[] = {
FEAT_ROWREPEATENABLE,
FEAT_RESIZECONF,
FEAT_DSI_PLL_PWR_BUG,
- FEAT_DSI_PLL_FREQSEL,
FEAT_CPR,
FEAT_PRELOAD,
FEAT_FIR_COEF_V,
@@ -650,8 +614,6 @@ static const enum dss_feat_id omap5_dss_feat_list[] = {
FEAT_ALPHA_FREE_ZORDER,
FEAT_FIFO_MERGE,
FEAT_BURST_2D,
- FEAT_DSI_PLL_SELFREQDCO,
- FEAT_DSI_PLL_REFSEL,
FEAT_DSI_PHY_DCC,
FEAT_MFLAG,
};
diff --git a/drivers/video/fbdev/omap2/dss/dss_features.h b/drivers/video/fbdev/omap2/dss/dss_features.h
index 05e8127d36b0..100f7a2d0638 100644
--- a/drivers/video/fbdev/omap2/dss/dss_features.h
+++ b/drivers/video/fbdev/omap2/dss/dss_features.h
@@ -41,7 +41,6 @@ enum dss_feat_id {
FEAT_LCD_CLK_SRC,
/* DSI-PLL power command 0x3 is not working */
FEAT_DSI_PLL_PWR_BUG,
- FEAT_DSI_PLL_FREQSEL,
FEAT_DSI_DCS_CMD_CONFIG_VC,
FEAT_DSI_VC_OCP_WIDTH,
FEAT_DSI_REVERSE_TXCLKESC,
@@ -61,8 +60,6 @@ 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,
FEAT_MFLAG,
};
@@ -77,19 +74,11 @@ enum dss_feat_reg_field {
FEAT_REG_HORIZONTALACCU,
FEAT_REG_VERTICALACCU,
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 {
FEAT_PARAM_DSS_FCK,
FEAT_PARAM_DSS_PCD,
- FEAT_PARAM_DSIPLL_REGN,
- FEAT_PARAM_DSIPLL_REGM,
- FEAT_PARAM_DSIPLL_REGM_HSDIV,
- FEAT_PARAM_DSIPLL_FINT,
FEAT_PARAM_DSIPLL_LPDIV,
FEAT_PARAM_DSI_FCK,
FEAT_PARAM_DOWNSCALE,
--
2.1.3
^ permalink raw reply related
* Re: [PATCH v7 10/20] ASoC: omap-hdmi-audio: Add platform device for OMAP HDMI audio support
From: Peter Ujfalusi @ 2014-11-12 12:03 UTC (permalink / raw)
To: Jyri Sarha, alsa-devel, linux-fbdev, linux-omap
Cc: broonie, liam.r.girdwood, tomi.valkeinen
In-Reply-To: <0296c0174b951e083064f49762122a703a1ac2f9.1415786458.git.jsarha@ti.com>
On 11/12/2014 12:49 PM, Jyri Sarha wrote:
> The platform device should only be registered from OMAPDSS HDMI
> driver. The platform driver registers and unregisters all ASoC
> components needed for OMAP HDMI audio.
>
> The hdmi audio driver implements cpu-dai component using the callbacks
> provided by OMAPDSS and registers the component under DSS HDMI
> device. Omap-pcm is registered for platform component also under DSS
> HDMI device. Dummy codec is used as as codec component. The hdmi audio
> driver implements also the card and registers it under its own
> platform device.
>
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
Acked-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
> include/sound/omap-hdmi-audio.h | 43 ++++
> sound/soc/omap/Kconfig | 15 ++
> sound/soc/omap/Makefile | 2 +
> sound/soc/omap/omap-hdmi-audio.c | 407 ++++++++++++++++++++++++++++++++++++++
> 4 files changed, 467 insertions(+)
> create mode 100644 include/sound/omap-hdmi-audio.h
> create mode 100644 sound/soc/omap/omap-hdmi-audio.c
>
> diff --git a/include/sound/omap-hdmi-audio.h b/include/sound/omap-hdmi-audio.h
> new file mode 100644
> index 0000000..afdb416
> --- /dev/null
> +++ b/include/sound/omap-hdmi-audio.h
> @@ -0,0 +1,43 @@
> +/*
> + * hdmi-audio.c -- OMAP4+ DSS HDMI audio support library
> + *
> + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
> + *
> + * Author: Jyri Sarha <jsarha@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + */
> +
> +#include <video/omapdss.h>
> +
> +#ifndef __OMAP_HDMI_AUDIO_H__
> +#define __OMAP_HDMI_AUDIO_H__
> +
> +struct omap_hdmi_audio_ops {
> + int (*audio_startup)(struct device *dev,
> + void (*abort_cb)(struct device *dev));
> + int (*audio_shutdown)(struct device *dev);
> + int (*audio_start)(struct device *dev);
> + void (*audio_stop)(struct device *dev);
> + int (*audio_config)(struct device *dev,
> + struct omap_dss_audio *dss_audio);
> +};
> +
> +/* HDMI audio initalization data */
> +struct omap_hdmi_audio_pdata {
> + struct device *dev;
> + enum omapdss_version dss_version;
> + phys_addr_t audio_dma_addr;
> +
> + const struct omap_hdmi_audio_ops *ops;
> +};
> +
> +#endif /* __OMAP_HDMI_AUDIO_H__ */
> diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
> index d44463a..2b32b3e 100644
> --- a/sound/soc/omap/Kconfig
> +++ b/sound/soc/omap/Kconfig
> @@ -15,6 +15,21 @@ config SND_OMAP_SOC_MCPDM
> config SND_OMAP_SOC_HDMI
> tristate
>
> +config SND_OMAP_SOC_HDMI_AUDIO
> + tristate "HDMI audio support for OMAP4+ based SoCs"
> + depends on SND_OMAP_SOC
> + help
> + For HDMI audio to work OMAPDSS HDMI support should be
> + enabled.
> + The hdmi audio driver implements cpu-dai component using the
> + callbacks provided by OMAPDSS and registers the component
> + under DSS HDMI device. Omap-pcm is registered for platform
> + component also under DSS HDMI device. Dummy codec is used as
> + as codec component. The hdmi audio driver implements also
> + the card and registers it under its own platform device.
> + The device for the dirver is registered by OMAPDSS hdmi
> + driver.
> +
> config SND_OMAP_SOC_N810
> tristate "SoC Audio support for Nokia N810"
> depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C
> diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
> index a725905..40688a6 100644
> --- a/sound/soc/omap/Makefile
> +++ b/sound/soc/omap/Makefile
> @@ -4,12 +4,14 @@ snd-soc-omap-dmic-objs := omap-dmic.o
> snd-soc-omap-mcbsp-objs := omap-mcbsp.o mcbsp.o
> snd-soc-omap-mcpdm-objs := omap-mcpdm.o
> snd-soc-omap-hdmi-objs := omap-hdmi.o
> +snd-soc-omap-hdmi-audio-objs := omap-hdmi-audio.o
>
> obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o
> obj-$(CONFIG_SND_OMAP_SOC_DMIC) += snd-soc-omap-dmic.o
> obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
> obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
> obj-$(CONFIG_SND_OMAP_SOC_HDMI) += snd-soc-omap-hdmi.o
> +obj-$(CONFIG_SND_OMAP_SOC_HDMI_AUDIO) += snd-soc-omap-hdmi-audio.o
>
> # OMAP Machine Support
> snd-soc-n810-objs := n810.o
> diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
> new file mode 100644
> index 0000000..3f9ac7d
> --- /dev/null
> +++ b/sound/soc/omap/omap-hdmi-audio.c
> @@ -0,0 +1,407 @@
> +/*
> + * omap-hdmi-audio.c -- OMAP4+ DSS HDMI audio support library
> + *
> + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
> + *
> + * Author: Jyri Sarha <jsarha@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/err.h>
> +#include <linux/string.h>
> +#include <linux/platform_device.h>
> +#include <sound/soc.h>
> +#include <sound/pcm_params.h>
> +#include <sound/dmaengine_pcm.h>
> +#include <uapi/sound/asound.h>
> +#include <sound/asoundef.h>
> +#include <sound/omap-pcm.h>
> +#include <sound/omap-hdmi-audio.h>
> +#include <video/omapdss.h>
> +
> +#define DRV_NAME "omap-hdmi-audio"
> +
> +struct hdmi_audio_data {
> + struct snd_soc_card *card;
> +
> + const struct omap_hdmi_audio_ops *ops;
> + struct device *dssdev;
> + struct snd_dmaengine_dai_dma_data dma_data;
> + struct omap_dss_audio dss_audio;
> + struct snd_aes_iec958 iec;
> + struct snd_cea_861_aud_if cea;
> +
> + struct mutex current_stream_lock;
> + struct snd_pcm_substream *current_stream;
> +};
> +
> +static
> +struct hdmi_audio_data *card_drvdata_substream(struct snd_pcm_substream *ss)
> +{
> + struct snd_soc_pcm_runtime *rtd = ss->private_data;
> +
> + return snd_soc_card_get_drvdata(rtd->card);
> +}
> +
> +static void hdmi_dai_abort(struct device *dev)
> +{
> + struct hdmi_audio_data *ad = dev_get_drvdata(dev);
> +
> + mutex_lock(&ad->current_stream_lock);
> + if (ad->current_stream && ad->current_stream->runtime &&
> + snd_pcm_running(ad->current_stream)) {
> + dev_err(dev, "HDMI display disabled, aborting playback\n");
> + snd_pcm_stream_lock_irq(ad->current_stream);
> + snd_pcm_stop(ad->current_stream, SNDRV_PCM_STATE_DISCONNECTED);
> + snd_pcm_stream_unlock_irq(ad->current_stream);
> + }
> + mutex_unlock(&ad->current_stream_lock);
> +}
> +
> +static int hdmi_dai_startup(struct snd_pcm_substream *substream,
> + struct snd_soc_dai *dai)
> +{
> + struct hdmi_audio_data *ad = card_drvdata_substream(substream);
> + int ret;
> + /*
> + * Make sure that the period bytes are multiple of the DMA packet size.
> + * Largest packet size we use is 32 32-bit words = 128 bytes
> + */
> + ret = snd_pcm_hw_constraint_step(substream->runtime, 0,
> + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128);
> + if (ret < 0) {
> + dev_err(dai->dev, "could not apply constraint\n");
> + return ret;
> + }
> +
> + snd_soc_dai_set_dma_data(dai, substream, &ad->dma_data);
> +
> + mutex_lock(&ad->current_stream_lock);
> + ad->current_stream = substream;
> + mutex_unlock(&ad->current_stream_lock);
> +
> + ret = ad->ops->audio_startup(ad->dssdev, hdmi_dai_abort);
> +
> + if (ret) {
> + mutex_lock(&ad->current_stream_lock);
> + ad->current_stream = NULL;
> + mutex_unlock(&ad->current_stream_lock);
> + }
> +
> + return ret;
> +}
> +
> +static int hdmi_dai_hw_params(struct snd_pcm_substream *substream,
> + struct snd_pcm_hw_params *params,
> + struct snd_soc_dai *dai)
> +{
> + struct hdmi_audio_data *ad = card_drvdata_substream(substream);
> + struct snd_aes_iec958 *iec = &ad->iec;
> + struct snd_cea_861_aud_if *cea = &ad->cea;
> +
> + WARN_ON(ad->current_stream != substream);
> +
> + switch (params_format(params)) {
> + case SNDRV_PCM_FORMAT_S16_LE:
> + ad->dma_data.maxburst = 16;
> + break;
> + case SNDRV_PCM_FORMAT_S24_LE:
> + ad->dma_data.maxburst = 32;
> + break;
> + default:
> + dev_err(dai->dev, "format not supported!\n");
> + return -EINVAL;
> + }
> +
> + ad->dss_audio.iec = iec;
> + ad->dss_audio.cea = cea;
> + /*
> + * fill the IEC-60958 channel status word
> + */
> + /* initialize the word bytes */
> + memset(iec->status, 0, sizeof(iec->status));
> +
> + /* specify IEC-60958-3 (commercial use) */
> + iec->status[0] &= ~IEC958_AES0_PROFESSIONAL;
> +
> + /* specify that the audio is LPCM*/
> + iec->status[0] &= ~IEC958_AES0_NONAUDIO;
> +
> + iec->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
> +
> + iec->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE;
> +
> + iec->status[0] |= IEC958_AES1_PRO_MODE_NOTID;
> +
> + iec->status[1] = IEC958_AES1_CON_GENERAL;
> +
> + iec->status[2] |= IEC958_AES2_CON_SOURCE_UNSPEC;
> +
> + iec->status[2] |= IEC958_AES2_CON_CHANNEL_UNSPEC;
> +
> + switch (params_rate(params)) {
> + case 32000:
> + iec->status[3] |= IEC958_AES3_CON_FS_32000;
> + break;
> + case 44100:
> + iec->status[3] |= IEC958_AES3_CON_FS_44100;
> + break;
> + case 48000:
> + iec->status[3] |= IEC958_AES3_CON_FS_48000;
> + break;
> + case 88200:
> + iec->status[3] |= IEC958_AES3_CON_FS_88200;
> + break;
> + case 96000:
> + iec->status[3] |= IEC958_AES3_CON_FS_96000;
> + break;
> + case 176400:
> + iec->status[3] |= IEC958_AES3_CON_FS_176400;
> + break;
> + case 192000:
> + iec->status[3] |= IEC958_AES3_CON_FS_192000;
> + break;
> + default:
> + dev_err(dai->dev, "rate not supported!\n");
> + return -EINVAL;
> + }
> +
> + /* specify the clock accuracy */
> + iec->status[3] |= IEC958_AES3_CON_CLOCK_1000PPM;
> +
> + /*
> + * specify the word length. The same word length value can mean
> + * two different lengths. Hence, we need to specify the maximum
> + * word length as well.
> + */
> + switch (params_format(params)) {
> + case SNDRV_PCM_FORMAT_S16_LE:
> + iec->status[4] |= IEC958_AES4_CON_WORDLEN_20_16;
> + iec->status[4] &= ~IEC958_AES4_CON_MAX_WORDLEN_24;
> + break;
> + case SNDRV_PCM_FORMAT_S24_LE:
> + iec->status[4] |= IEC958_AES4_CON_WORDLEN_24_20;
> + iec->status[4] |= IEC958_AES4_CON_MAX_WORDLEN_24;
> + break;
> + default:
> + dev_err(dai->dev, "format not supported!\n");
> + return -EINVAL;
> + }
> +
> + /*
> + * Fill the CEA-861 audio infoframe (see spec for details)
> + */
> +
> + cea->db1_ct_cc = (params_channels(params) - 1)
> + & CEA861_AUDIO_INFOFRAME_DB1CC;
> + cea->db1_ct_cc |= CEA861_AUDIO_INFOFRAME_DB1CT_FROM_STREAM;
> +
> + cea->db2_sf_ss = CEA861_AUDIO_INFOFRAME_DB2SF_FROM_STREAM;
> + cea->db2_sf_ss |= CEA861_AUDIO_INFOFRAME_DB2SS_FROM_STREAM;
> +
> + cea->db3 = 0; /* not used, all zeros */
> +
> + /*
> + * The OMAP HDMI IP requires to use the 8-channel channel code when
> + * transmitting more than two channels.
> + */
> + if (params_channels(params) = 2)
> + cea->db4_ca = 0x0;
> + else
> + cea->db4_ca = 0x13;
> +
> + cea->db5_dminh_lsv = CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PROHIBITED;
> + /* the expression is trivial but makes clear what we are doing */
> + cea->db5_dminh_lsv |= (0 & CEA861_AUDIO_INFOFRAME_DB5_LSV);
> +
> + return ad->ops->audio_config(ad->dssdev, &ad->dss_audio);
> +}
> +
> +static int hdmi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
> + struct snd_soc_dai *dai)
> +{
> + struct hdmi_audio_data *ad = card_drvdata_substream(substream);
> + int err = 0;
> +
> + WARN_ON(ad->current_stream != substream);
> +
> + switch (cmd) {
> + case SNDRV_PCM_TRIGGER_START:
> + case SNDRV_PCM_TRIGGER_RESUME:
> + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
> + err = ad->ops->audio_start(ad->dssdev);
> + break;
> + case SNDRV_PCM_TRIGGER_STOP:
> + case SNDRV_PCM_TRIGGER_SUSPEND:
> + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
> + ad->ops->audio_stop(ad->dssdev);
> + break;
> + default:
> + err = -EINVAL;
> + }
> + return err;
> +}
> +
> +static void hdmi_dai_shutdown(struct snd_pcm_substream *substream,
> + struct snd_soc_dai *dai)
> +{
> + struct hdmi_audio_data *ad = card_drvdata_substream(substream);
> +
> + WARN_ON(ad->current_stream != substream);
> +
> + ad->ops->audio_shutdown(ad->dssdev);
> +
> + mutex_lock(&ad->current_stream_lock);
> + ad->current_stream = NULL;
> + mutex_unlock(&ad->current_stream_lock);
> +}
> +
> +static const struct snd_soc_dai_ops hdmi_dai_ops = {
> + .startup = hdmi_dai_startup,
> + .hw_params = hdmi_dai_hw_params,
> + .trigger = hdmi_dai_trigger,
> + .shutdown = hdmi_dai_shutdown,
> +};
> +
> +static const struct snd_soc_component_driver omap_hdmi_component = {
> + .name = "omapdss_hdmi",
> +};
> +
> +static struct snd_soc_dai_driver omap5_hdmi_dai = {
> + .name = "omap5-hdmi-dai",
> + .playback = {
> + .channels_min = 2,
> + .channels_max = 8,
> + .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
> + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
> + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
> + SNDRV_PCM_RATE_192000),
> + .formats = SNDRV_PCM_FMTBIT_S16_LE,
> + },
> + .ops = &hdmi_dai_ops,
> +};
> +
> +static struct snd_soc_dai_driver omap4_hdmi_dai = {
> + .name = "omap4-hdmi-dai",
> + .playback = {
> + .channels_min = 2,
> + .channels_max = 8,
> + .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
> + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
> + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
> + SNDRV_PCM_RATE_192000),
> + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
> + },
> + .ops = &hdmi_dai_ops,
> +};
> +
> +static int omap_hdmi_audio_probe(struct platform_device *pdev)
> +{
> + struct omap_hdmi_audio_pdata *ha = pdev->dev.platform_data;
> + struct device *dev = &pdev->dev;
> + struct hdmi_audio_data *ad;
> + struct snd_soc_dai_driver *dai_drv;
> + struct snd_soc_card *card;
> + int ret;
> +
> + if (!ha) {
> + dev_err(dev, "No platform data\n");
> + return -EINVAL;
> + }
> +
> + ad = devm_kzalloc(dev, sizeof(*ad), GFP_KERNEL);
> + if (!ad)
> + return -ENOMEM;
> + ad->dssdev = ha->dev;
> + ad->ops = ha->ops;
> + ad->dma_data.addr = ha->audio_dma_addr;
> + ad->dma_data.filter_data = "audio_tx";
> + ad->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> + mutex_init(&ad->current_stream_lock);
> +
> + switch (ha->dss_version) {
> + case OMAPDSS_VER_OMAP4430_ES1:
> + case OMAPDSS_VER_OMAP4430_ES2:
> + case OMAPDSS_VER_OMAP4:
> + dai_drv = &omap4_hdmi_dai;
> + break;
> + case OMAPDSS_VER_OMAP5:
> + dai_drv = &omap5_hdmi_dai;
> + break;
> + default:
> + return -EINVAL;
> + }
> + ret = snd_soc_register_component(ad->dssdev, &omap_hdmi_component,
> + dai_drv, 1);
> + if (ret)
> + return ret;
> +
> + ret = omap_pcm_platform_register(ad->dssdev);
> + if (ret)
> + return ret;
> +
> + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
> + card->name = devm_kasprintf(dev, GFP_KERNEL,
> + "HDMI %s", dev_name(ad->dssdev));
> + card->owner = THIS_MODULE;
> + card->dai_link > + devm_kzalloc(dev, sizeof(*(card->dai_link)), GFP_KERNEL);
> + card->dai_link->name = card->name;
> + card->dai_link->stream_name = card->name;
> + card->dai_link->cpu_dai_name = dev_name(ad->dssdev);
> + card->dai_link->platform_name = dev_name(ad->dssdev);
> + card->dai_link->codec_name = "snd-soc-dummy";
> + card->dai_link->codec_dai_name = "snd-soc-dummy-dai";
> + card->num_links = 1;
> + card->dev = dev;
> +
> + ret = snd_soc_register_card(card);
> + if (ret) {
> + dev_err(dev, "snd_soc_register_card failed (%d)\n", ret);
> + snd_soc_unregister_component(ad->dssdev);
> + return ret;
> + }
> +
> + ad->card = card;
> + snd_soc_card_set_drvdata(card, ad);
> +
> + dev_set_drvdata(dev, ad);
> +
> + return 0;
> +}
> +
> +static int omap_hdmi_audio_remove(struct platform_device *pdev)
> +{
> + struct hdmi_audio_data *ad = platform_get_drvdata(pdev);
> +
> + snd_soc_unregister_card(ad->card);
> + snd_soc_unregister_component(ad->dssdev);
> + return 0;
> +}
> +
> +static struct platform_driver hdmi_audio_driver = {
> + .driver = {
> + .name = DRV_NAME,
> + .owner = THIS_MODULE,
> + },
> + .probe = omap_hdmi_audio_probe,
> + .remove = omap_hdmi_audio_remove,
> +};
> +
> +module_platform_driver(hdmi_audio_driver);
> +
> +MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
> +MODULE_DESCRIPTION("OMAP HDMI Audio Driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:" DRV_NAME);
>
--
Péter
^ permalink raw reply
* Re: [PATCH v7 18/20] ASoC: omap: Remove obsolete HDMI audio code and Kconfig options
From: Peter Ujfalusi @ 2014-11-12 12:04 UTC (permalink / raw)
To: Jyri Sarha, alsa-devel, linux-fbdev, linux-omap
Cc: broonie, liam.r.girdwood, tomi.valkeinen
In-Reply-To: <3b82bfccc11f3aefd34db578944b5447fcfa1d85.1415786458.git.jsarha@ti.com>
On 11/12/2014 12:49 PM, Jyri Sarha wrote:
> Removes omap-hdmi DAI driver, omap-hdmi-card driver, the related
> Kconfig options, and Makefile entries. The HDMI DAI drivers has been
> integrated directly to OMAP4+ HDMI drivers and simple-card driver is
> used instead of omap-hdmi-card driver.
>
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
Acked-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
> sound/soc/omap/Kconfig | 13 --
> sound/soc/omap/Makefile | 4 -
> sound/soc/omap/omap-hdmi-card.c | 87 ----------
> sound/soc/omap/omap-hdmi.c | 364 ---------------------------------------
> sound/soc/omap/omap-hdmi.h | 38 ----
> 5 files changed, 506 deletions(-)
> delete mode 100644 sound/soc/omap/omap-hdmi-card.c
> delete mode 100644 sound/soc/omap/omap-hdmi.c
> delete mode 100644 sound/soc/omap/omap-hdmi.h
>
> diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
> index 2b32b3e..3dfcadf 100644
> --- a/sound/soc/omap/Kconfig
> +++ b/sound/soc/omap/Kconfig
> @@ -12,9 +12,6 @@ config SND_OMAP_SOC_MCBSP
> config SND_OMAP_SOC_MCPDM
> tristate
>
> -config SND_OMAP_SOC_HDMI
> - tristate
> -
> config SND_OMAP_SOC_HDMI_AUDIO
> tristate "HDMI audio support for OMAP4+ based SoCs"
> depends on SND_OMAP_SOC
> @@ -115,16 +112,6 @@ config SND_OMAP_SOC_OMAP_ABE_TWL6040
> - PandaBoard (4430)
> - PandaBoardES (4460)
>
> -config SND_OMAP_SOC_OMAP_HDMI
> - tristate "SoC Audio support for Texas Instruments OMAP HDMI"
> - depends on SND_OMAP_SOC && OMAP4_DSS_HDMI && OMAP2_DSS
> - select SND_OMAP_SOC_HDMI
> - select SND_SOC_HDMI_CODEC
> - select OMAP4_DSS_HDMI_AUDIO
> - help
> - Say Y if you want to add support for SoC HDMI audio on Texas Instruments
> - OMAP4 chips
> -
> config SND_OMAP_SOC_OMAP3_PANDORA
> tristate "SoC Audio support for OMAP3 Pandora"
> depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA
> diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
> index 40688a6..db36fbd 100644
> --- a/sound/soc/omap/Makefile
> +++ b/sound/soc/omap/Makefile
> @@ -3,14 +3,12 @@ snd-soc-omap-objs := omap-pcm.o
> snd-soc-omap-dmic-objs := omap-dmic.o
> snd-soc-omap-mcbsp-objs := omap-mcbsp.o mcbsp.o
> snd-soc-omap-mcpdm-objs := omap-mcpdm.o
> -snd-soc-omap-hdmi-objs := omap-hdmi.o
> snd-soc-omap-hdmi-audio-objs := omap-hdmi-audio.o
>
> obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o
> obj-$(CONFIG_SND_OMAP_SOC_DMIC) += snd-soc-omap-dmic.o
> obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
> obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
> -obj-$(CONFIG_SND_OMAP_SOC_HDMI) += snd-soc-omap-hdmi.o
> obj-$(CONFIG_SND_OMAP_SOC_HDMI_AUDIO) += snd-soc-omap-hdmi-audio.o
>
> # OMAP Machine Support
> @@ -22,7 +20,6 @@ snd-soc-am3517evm-objs := am3517evm.o
> snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o
> snd-soc-omap-twl4030-objs := omap-twl4030.o
> snd-soc-omap3pandora-objs := omap3pandora.o
> -snd-soc-omap-hdmi-card-objs := omap-hdmi-card.o
>
> obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
> obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o
> @@ -32,4 +29,3 @@ obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
> obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
> obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o
> obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
> -obj-$(CONFIG_SND_OMAP_SOC_OMAP_HDMI) += snd-soc-omap-hdmi-card.o
> diff --git a/sound/soc/omap/omap-hdmi-card.c b/sound/soc/omap/omap-hdmi-card.c
> deleted file mode 100644
> index f649fe8..0000000
> --- a/sound/soc/omap/omap-hdmi-card.c
> +++ /dev/null
> @@ -1,87 +0,0 @@
> -/*
> - * omap-hdmi-card.c
> - *
> - * OMAP ALSA SoC machine driver for TI OMAP HDMI
> - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
> - * Author: Ricardo Neri <ricardo.neri@ti.com>
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License
> - * version 2 as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful, but
> - * WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - * General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
> - * 02110-1301 USA
> - *
> - */
> -
> -#include <linux/module.h>
> -#include <sound/pcm.h>
> -#include <sound/soc.h>
> -#include <asm/mach-types.h>
> -#include <video/omapdss.h>
> -
> -#define DRV_NAME "omap-hdmi-audio"
> -
> -static struct snd_soc_dai_link omap_hdmi_dai = {
> - .name = "HDMI",
> - .stream_name = "HDMI",
> - .cpu_dai_name = "omap-hdmi-audio-dai",
> - .platform_name = "omap-hdmi-audio-dai",
> - .codec_name = "hdmi-audio-codec",
> - .codec_dai_name = "hdmi-hifi",
> -};
> -
> -static struct snd_soc_card snd_soc_omap_hdmi = {
> - .name = "OMAPHDMI",
> - .owner = THIS_MODULE,
> - .dai_link = &omap_hdmi_dai,
> - .num_links = 1,
> -};
> -
> -static int omap_hdmi_probe(struct platform_device *pdev)
> -{
> - struct snd_soc_card *card = &snd_soc_omap_hdmi;
> - int ret;
> -
> - card->dev = &pdev->dev;
> -
> - ret = snd_soc_register_card(card);
> - if (ret) {
> - dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
> - card->dev = NULL;
> - return ret;
> - }
> - return 0;
> -}
> -
> -static int omap_hdmi_remove(struct platform_device *pdev)
> -{
> - struct snd_soc_card *card = platform_get_drvdata(pdev);
> -
> - snd_soc_unregister_card(card);
> - card->dev = NULL;
> - return 0;
> -}
> -
> -static struct platform_driver omap_hdmi_driver = {
> - .driver = {
> - .name = DRV_NAME,
> - .owner = THIS_MODULE,
> - },
> - .probe = omap_hdmi_probe,
> - .remove = omap_hdmi_remove,
> -};
> -
> -module_platform_driver(omap_hdmi_driver);
> -
> -MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
> -MODULE_DESCRIPTION("OMAP HDMI machine ASoC driver");
> -MODULE_LICENSE("GPL");
> -MODULE_ALIAS("platform:" DRV_NAME);
> diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c
> deleted file mode 100644
> index eb9c392..0000000
> --- a/sound/soc/omap/omap-hdmi.c
> +++ /dev/null
> @@ -1,364 +0,0 @@
> -/*
> - * omap-hdmi.c
> - *
> - * OMAP ALSA SoC DAI driver for HDMI audio on OMAP4 processors.
> - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
> - * Authors: Jorge Candelaria <jorge.candelaria@ti.com>
> - * Ricardo Neri <ricardo.neri@ti.com>
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License
> - * version 2 as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful, but
> - * WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - * General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
> - * 02110-1301 USA
> - *
> - */
> -
> -#include <linux/init.h>
> -#include <linux/module.h>
> -#include <linux/device.h>
> -#include <sound/core.h>
> -#include <sound/pcm.h>
> -#include <sound/pcm_params.h>
> -#include <sound/initval.h>
> -#include <sound/soc.h>
> -#include <sound/asound.h>
> -#include <sound/asoundef.h>
> -#include <sound/dmaengine_pcm.h>
> -#include <video/omapdss.h>
> -#include <sound/omap-pcm.h>
> -
> -#include "omap-hdmi.h"
> -
> -#define DRV_NAME "omap-hdmi-audio-dai"
> -
> -struct hdmi_priv {
> - struct snd_dmaengine_dai_dma_data dma_data;
> - unsigned int dma_req;
> - struct omap_dss_audio dss_audio;
> - struct snd_aes_iec958 iec;
> - struct snd_cea_861_aud_if cea;
> - struct omap_dss_device *dssdev;
> -};
> -
> -static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream,
> - struct snd_soc_dai *dai)
> -{
> - struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
> - int err;
> - /*
> - * Make sure that the period bytes are multiple of the DMA packet size.
> - * Largest packet size we use is 32 32-bit words = 128 bytes
> - */
> - err = snd_pcm_hw_constraint_step(substream->runtime, 0,
> - SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128);
> - if (err < 0) {
> - dev_err(dai->dev, "could not apply constraint\n");
> - return err;
> - }
> -
> - if (!priv->dssdev->driver->audio_supported(priv->dssdev)) {
> - dev_err(dai->dev, "audio not supported\n");
> - return -ENODEV;
> - }
> -
> - snd_soc_dai_set_dma_data(dai, substream, &priv->dma_data);
> -
> - return 0;
> -}
> -
> -static int omap_hdmi_dai_prepare(struct snd_pcm_substream *substream,
> - struct snd_soc_dai *dai)
> -{
> - struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
> -
> - return priv->dssdev->driver->audio_enable(priv->dssdev);
> -}
> -
> -static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
> - struct snd_pcm_hw_params *params,
> - struct snd_soc_dai *dai)
> -{
> - struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
> - struct snd_aes_iec958 *iec = &priv->iec;
> - struct snd_cea_861_aud_if *cea = &priv->cea;
> - int err = 0;
> -
> - switch (params_format(params)) {
> - case SNDRV_PCM_FORMAT_S16_LE:
> - priv->dma_data.maxburst = 16;
> - break;
> - case SNDRV_PCM_FORMAT_S24_LE:
> - priv->dma_data.maxburst = 32;
> - break;
> - default:
> - dev_err(dai->dev, "format not supported!\n");
> - return -EINVAL;
> - }
> -
> - /*
> - * fill the IEC-60958 channel status word
> - */
> - /* initialize the word bytes */
> - memset(iec->status, 0, sizeof(iec->status));
> -
> - /* specify IEC-60958-3 (commercial use) */
> - iec->status[0] &= ~IEC958_AES0_PROFESSIONAL;
> -
> - /* specify that the audio is LPCM*/
> - iec->status[0] &= ~IEC958_AES0_NONAUDIO;
> -
> - iec->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
> -
> - iec->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE;
> -
> - iec->status[0] |= IEC958_AES1_PRO_MODE_NOTID;
> -
> - iec->status[1] = IEC958_AES1_CON_GENERAL;
> -
> - iec->status[2] |= IEC958_AES2_CON_SOURCE_UNSPEC;
> -
> - iec->status[2] |= IEC958_AES2_CON_CHANNEL_UNSPEC;
> -
> - switch (params_rate(params)) {
> - case 32000:
> - iec->status[3] |= IEC958_AES3_CON_FS_32000;
> - break;
> - case 44100:
> - iec->status[3] |= IEC958_AES3_CON_FS_44100;
> - break;
> - case 48000:
> - iec->status[3] |= IEC958_AES3_CON_FS_48000;
> - break;
> - case 88200:
> - iec->status[3] |= IEC958_AES3_CON_FS_88200;
> - break;
> - case 96000:
> - iec->status[3] |= IEC958_AES3_CON_FS_96000;
> - break;
> - case 176400:
> - iec->status[3] |= IEC958_AES3_CON_FS_176400;
> - break;
> - case 192000:
> - iec->status[3] |= IEC958_AES3_CON_FS_192000;
> - break;
> - default:
> - dev_err(dai->dev, "rate not supported!\n");
> - return -EINVAL;
> - }
> -
> - /* specify the clock accuracy */
> - iec->status[3] |= IEC958_AES3_CON_CLOCK_1000PPM;
> -
> - /*
> - * specify the word length. The same word length value can mean
> - * two different lengths. Hence, we need to specify the maximum
> - * word length as well.
> - */
> - switch (params_format(params)) {
> - case SNDRV_PCM_FORMAT_S16_LE:
> - iec->status[4] |= IEC958_AES4_CON_WORDLEN_20_16;
> - iec->status[4] &= ~IEC958_AES4_CON_MAX_WORDLEN_24;
> - break;
> - case SNDRV_PCM_FORMAT_S24_LE:
> - iec->status[4] |= IEC958_AES4_CON_WORDLEN_24_20;
> - iec->status[4] |= IEC958_AES4_CON_MAX_WORDLEN_24;
> - break;
> - default:
> - dev_err(dai->dev, "format not supported!\n");
> - return -EINVAL;
> - }
> -
> - /*
> - * Fill the CEA-861 audio infoframe (see spec for details)
> - */
> -
> - cea->db1_ct_cc = (params_channels(params) - 1)
> - & CEA861_AUDIO_INFOFRAME_DB1CC;
> - cea->db1_ct_cc |= CEA861_AUDIO_INFOFRAME_DB1CT_FROM_STREAM;
> -
> - cea->db2_sf_ss = CEA861_AUDIO_INFOFRAME_DB2SF_FROM_STREAM;
> - cea->db2_sf_ss |= CEA861_AUDIO_INFOFRAME_DB2SS_FROM_STREAM;
> -
> - cea->db3 = 0; /* not used, all zeros */
> -
> - /*
> - * The OMAP HDMI IP requires to use the 8-channel channel code when
> - * transmitting more than two channels.
> - */
> - if (params_channels(params) = 2)
> - cea->db4_ca = 0x0;
> - else
> - cea->db4_ca = 0x13;
> -
> - cea->db5_dminh_lsv = CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PROHIBITED;
> - /* the expression is trivial but makes clear what we are doing */
> - cea->db5_dminh_lsv |= (0 & CEA861_AUDIO_INFOFRAME_DB5_LSV);
> -
> - priv->dss_audio.iec = iec;
> - priv->dss_audio.cea = cea;
> -
> - err = priv->dssdev->driver->audio_config(priv->dssdev,
> - &priv->dss_audio);
> -
> - return err;
> -}
> -
> -static int omap_hdmi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
> - struct snd_soc_dai *dai)
> -{
> - struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
> - int err = 0;
> -
> - switch (cmd) {
> - case SNDRV_PCM_TRIGGER_START:
> - case SNDRV_PCM_TRIGGER_RESUME:
> - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
> - err = priv->dssdev->driver->audio_start(priv->dssdev);
> - break;
> - case SNDRV_PCM_TRIGGER_STOP:
> - case SNDRV_PCM_TRIGGER_SUSPEND:
> - case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
> - priv->dssdev->driver->audio_stop(priv->dssdev);
> - break;
> - default:
> - err = -EINVAL;
> - }
> - return err;
> -}
> -
> -static void omap_hdmi_dai_shutdown(struct snd_pcm_substream *substream,
> - struct snd_soc_dai *dai)
> -{
> - struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
> -
> - priv->dssdev->driver->audio_disable(priv->dssdev);
> -}
> -
> -static const struct snd_soc_dai_ops omap_hdmi_dai_ops = {
> - .startup = omap_hdmi_dai_startup,
> - .hw_params = omap_hdmi_dai_hw_params,
> - .prepare = omap_hdmi_dai_prepare,
> - .trigger = omap_hdmi_dai_trigger,
> - .shutdown = omap_hdmi_dai_shutdown,
> -};
> -
> -static struct snd_soc_dai_driver omap_hdmi_dai = {
> - .playback = {
> - .channels_min = 2,
> - .channels_max = 8,
> - .rates = OMAP_HDMI_RATES,
> - .formats = OMAP_HDMI_FORMATS,
> - },
> - .ops = &omap_hdmi_dai_ops,
> -};
> -
> -static const struct snd_soc_component_driver omap_hdmi_component = {
> - .name = DRV_NAME,
> -};
> -
> -static int omap_hdmi_probe(struct platform_device *pdev)
> -{
> - int ret;
> - struct resource *hdmi_rsrc;
> - struct hdmi_priv *hdmi_data;
> - bool hdmi_dev_found = false;
> -
> - hdmi_data = devm_kzalloc(&pdev->dev, sizeof(*hdmi_data), GFP_KERNEL);
> - if (hdmi_data = NULL) {
> - dev_err(&pdev->dev, "Cannot allocate memory for HDMI data\n");
> - return -ENOMEM;
> - }
> -
> - hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - if (!hdmi_rsrc) {
> - dev_err(&pdev->dev, "Cannot obtain IORESOURCE_MEM HDMI\n");
> - return -ENODEV;
> - }
> -
> - hdmi_data->dma_data.addr = hdmi_rsrc->start + OMAP_HDMI_AUDIO_DMA_PORT;
> -
> - hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0);
> - if (!hdmi_rsrc) {
> - dev_err(&pdev->dev, "Cannot obtain IORESOURCE_DMA HDMI\n");
> - return -ENODEV;
> - }
> -
> - hdmi_data->dma_req = hdmi_rsrc->start;
> - hdmi_data->dma_data.filter_data = &hdmi_data->dma_req;
> - hdmi_data->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> -
> - /*
> - * TODO: We assume that there is only one DSS HDMI device. Future
> - * OMAP implementations may support more than one HDMI devices and
> - * we should provided separate audio support for all of them.
> - */
> - /* Find an HDMI device. */
> - for_each_dss_dev(hdmi_data->dssdev) {
> - omap_dss_get_device(hdmi_data->dssdev);
> -
> - if (!hdmi_data->dssdev->driver) {
> - omap_dss_put_device(hdmi_data->dssdev);
> - continue;
> - }
> -
> - if (hdmi_data->dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
> - hdmi_dev_found = true;
> - break;
> - }
> - }
> -
> - if (!hdmi_dev_found) {
> - dev_err(&pdev->dev, "no driver for HDMI display found\n");
> - return -ENODEV;
> - }
> -
> - dev_set_drvdata(&pdev->dev, hdmi_data);
> - ret = snd_soc_register_component(&pdev->dev, &omap_hdmi_component,
> - &omap_hdmi_dai, 1);
> -
> - if (ret)
> - return ret;
> -
> - return omap_pcm_platform_register(&pdev->dev);
> -}
> -
> -static int omap_hdmi_remove(struct platform_device *pdev)
> -{
> - struct hdmi_priv *hdmi_data = dev_get_drvdata(&pdev->dev);
> -
> - snd_soc_unregister_component(&pdev->dev);
> -
> - if (hdmi_data = NULL) {
> - dev_err(&pdev->dev, "cannot obtain HDMi data\n");
> - return -ENODEV;
> - }
> -
> - omap_dss_put_device(hdmi_data->dssdev);
> - return 0;
> -}
> -
> -static struct platform_driver hdmi_dai_driver = {
> - .driver = {
> - .name = DRV_NAME,
> - .owner = THIS_MODULE,
> - },
> - .probe = omap_hdmi_probe,
> - .remove = omap_hdmi_remove,
> -};
> -
> -module_platform_driver(hdmi_dai_driver);
> -
> -MODULE_AUTHOR("Jorge Candelaria <jorge.candelaria@ti.com>");
> -MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
> -MODULE_DESCRIPTION("OMAP HDMI SoC Interface");
> -MODULE_LICENSE("GPL");
> -MODULE_ALIAS("platform:" DRV_NAME);
> diff --git a/sound/soc/omap/omap-hdmi.h b/sound/soc/omap/omap-hdmi.h
> deleted file mode 100644
> index 6ad2bf4..0000000
> --- a/sound/soc/omap/omap-hdmi.h
> +++ /dev/null
> @@ -1,38 +0,0 @@
> -/*
> - * omap-hdmi.h
> - *
> - * Definitions for OMAP ALSA SoC DAI driver for HDMI audio on OMAP4 processors.
> - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
> - * Authors: Jorge Candelaria <jorge.candelaria@ti.com>
> - * Ricardo Neri <ricardo.neri@ti.com>
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License
> - * version 2 as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful, but
> - * WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - * General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
> - * 02110-1301 USA
> - *
> - */
> -
> -#ifndef __OMAP_HDMI_H__
> -#define __OMAP_HDMI_H__
> -
> -#define OMAP_HDMI_AUDIO_DMA_PORT 0x8c
> -
> -#define OMAP_HDMI_RATES (SNDRV_PCM_RATE_32000 | \
> - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
> - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
> - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
> -
> -#define OMAP_HDMI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
> - SNDRV_PCM_FMTBIT_S24_LE)
> -
> -#endif
>
--
Péter
^ permalink raw reply
* Re: [PATCH 4/4] arm: dts: omap3-gta04: Add static configuration for devconf1 register
From: Tomi Valkeinen @ 2014-11-12 12:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1415051968-4878-5-git-send-email-marek@goldelico.com>
[-- Attachment #1: Type: text/plain, Size: 2183 bytes --]
Hi,
On 03/11/14 23:59, Marek Belisko wrote:
> gta04 board need for tvout enabled 2 bits in devconf1 register (tvbypass and acbias).
> Add single pinmux entry and enable it.
>
> Signed-off-by: Marek Belisko <marek@goldelico.com>
> ---
> arch/arm/boot/dts/omap3-gta04.dtsi | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi
> index e4d05f0..a456d37 100644
> --- a/arch/arm/boot/dts/omap3-gta04.dtsi
> +++ b/arch/arm/boot/dts/omap3-gta04.dtsi
> @@ -118,6 +118,17 @@
> };
> };
> };
> +
> + /* pinmux for devconf1 */
> + control_devconf1: pinmux@480022d8 {
> + compatible = "pinctrl-single";
> + reg = <0x480022d8 4>; /* single register */
> + #address-cells = <1>;
> + #size-cells = <0>;
> + pinctrl-single,bit-per-mux;
> + pinctrl-single,register-width = <32>;
> + pinctrl-single,function-mask = <0xfc0bd5>;
> + };
> };
>
> &omap3_pmx_core {
> @@ -497,3 +508,14 @@
> };
> };
> };
> +
> +&control_devconf1 {
> + pinctrl-name = "default";
> + pinctrl-0 = < &tv_acbias_pins>;
> +
> + tv_acbias_pins: pinmux_tv_acbias_pins {
> + pinctrl-single,bits = <
> + 0 0x40800 0x40800
I think it would be good to have a comment in the .dts above, mentioning
that TVOUTBYPASS and TVACEN bits are being set.
> + >;
> + };
> +};
>
OMAP3630 seems to have CONTROL_AVDAC1 and CONTROL_AVDAC2 registers. Did
you check if the SoC you use have those? It looks like they need
configuration also, if the exist.
So, I don't think tvbypass and acbias are really pinmux stuff, but it
does seem like an easy way to handle the devconf1 register, and I don't
see any issues with the setting being fixed.
However, devconf1 register seems to have bits for many devices,
including mcbsp, mmc, and even some "Force MPU writes to be nonposted" bit.
And, with a quick grep, I see CONTROL_DEVCONF1 touched in multiple
places in the kernel. I wonder if adding a pinmux entry for it could
cause some rather odd problems.
Tony, any idea about this? How should CONTROL_DEVCONFx registers be
accessed?
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox