From 96c401bcb83a182a4f332f2f64ee6530ba35511a Mon Sep 17 00:00:00 2001 From: Senthilvadivu Guruswamy Date: Mon, 24 Jan 2011 06:21:57 +0000 Subject: OMAP2, 3: DSS2: DSS: create platform_driver, move init, exit to driver Hwmod adaptation design requires each of the DSS HW IP to be a platform driver. So a platform_driver of DSS is created and init exit methods are moved from core.c to its driver probe,remove. pdev member has to be maintained by its own drivers. DSS platform driver is registered from inside omap_dss_probe, in the order desired. Signed-off-by: Senthilvadivu Guruswamy Signed-off-by: Sumit Semwal Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index b394951120a..37c4544e890 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -214,8 +214,8 @@ void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr); void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); /* DSS */ -int dss_init(bool skip_init); -void dss_exit(void); +int dss_init_platform_driver(void); +void dss_uninit_platform_driver(void); void dss_save_context(void); void dss_restore_context(void); -- cgit v1.2.3-70-g09d2 From 8b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551 Mon Sep 17 00:00:00 2001 From: Senthilvadivu Guruswamy Date: Mon, 24 Jan 2011 06:21:58 +0000 Subject: OMAP2, 3: DSS2: Move clocks from core driver to dss driver All clock management is moved to dss platform driver. clk_get/put APIs use dss device instead of core platform device. Hwmod adaptation design requires each of the DSS HW IP to be a platform driver. So the device name is changed from omapdss to omapdss_dss in 2420, 2430, 3xxx clock database files. Now the core driver "omapdss" only takes care of panel registration with the custom bus. core driver also uses the clk_enable() / clk_disable() APIs exposed by DSS for clock management. DSS driver would do clock management of clocks needed by DISPC, RFBI, DSI, VENC TODO: The clock content would be adapted to omap_hwmod in a seperate series. Signed-off-by: Senthilvadivu Guruswamy Signed-off-by: Sumit Semwal Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/clock2420_data.c | 8 +- arch/arm/mach-omap2/clock2430_data.c | 8 +- arch/arm/mach-omap2/clock3xxx_data.c | 14 +- drivers/video/omap2/dss/core.c | 343 +---------------------------------- drivers/video/omap2/dss/dss.c | 334 +++++++++++++++++++++++++++++++++- drivers/video/omap2/dss/dss.h | 13 +- 6 files changed, 360 insertions(+), 360 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c index 0a992bc8d0d..9ece62a44a3 100644 --- a/arch/arm/mach-omap2/clock2420_data.c +++ b/arch/arm/mach-omap2/clock2420_data.c @@ -1786,10 +1786,10 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_242X), CLK(NULL, "gfx_ick", &gfx_ick, CK_242X), /* DSS domain clocks */ - CLK("omapdss", "ick", &dss_ick, CK_242X), - CLK("omapdss", "dss1_fck", &dss1_fck, CK_242X), - CLK("omapdss", "dss2_fck", &dss2_fck, CK_242X), - CLK("omapdss", "tv_fck", &dss_54m_fck, CK_242X), + CLK("omapdss_dss", "ick", &dss_ick, CK_242X), + CLK("omapdss_dss", "dss1_fck", &dss1_fck, CK_242X), + CLK("omapdss_dss", "dss2_fck", &dss2_fck, CK_242X), + CLK("omapdss_dss", "tv_fck", &dss_54m_fck, CK_242X), /* L3 domain clocks */ CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X), CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X), diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c index 5c647ce05b0..61006ae7eac 100644 --- a/arch/arm/mach-omap2/clock2430_data.c +++ b/arch/arm/mach-omap2/clock2430_data.c @@ -1890,10 +1890,10 @@ static struct omap_clk omap2430_clks[] = { CLK(NULL, "mdm_ick", &mdm_ick, CK_243X), CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X), /* DSS domain clocks */ - CLK("omapdss", "ick", &dss_ick, CK_243X), - CLK("omapdss", "dss1_fck", &dss1_fck, CK_243X), - CLK("omapdss", "dss2_fck", &dss2_fck, CK_243X), - CLK("omapdss", "tv_fck", &dss_54m_fck, CK_243X), + CLK("omapdss_dss", "ick", &dss_ick, CK_243X), + CLK("omapdss_dss", "dss1_fck", &dss1_fck, CK_243X), + CLK("omapdss_dss", "dss2_fck", &dss2_fck, CK_243X), + CLK("omapdss_dss", "tv_fck", &dss_54m_fck, CK_243X), /* L3 domain clocks */ CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X), CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X), diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 052ac329282..2e47d16fce7 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3357,13 +3357,13 @@ static struct omap_clk omap3xxx_clks[] = { CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX), CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX), CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX), - CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1), - CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK("omapdss", "tv_fck", &dss_tv_fck, CK_3XXX), - CLK("omapdss", "video_fck", &dss_96m_fck, CK_3XXX), - CLK("omapdss", "dss2_fck", &dss2_alwon_fck, CK_3XXX), - CLK("omapdss", "ick", &dss_ick_3430es1, CK_3430ES1), - CLK("omapdss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), + CLK("omapdss_dss", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1), + CLK("omapdss_dss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), + CLK("omapdss_dss", "tv_fck", &dss_tv_fck, CK_3XXX), + CLK("omapdss_dss", "video_fck", &dss_96m_fck, CK_3XXX), + CLK("omapdss_dss", "dss2_fck", &dss2_alwon_fck, CK_3XXX), + CLK("omapdss_dss", "ick", &dss_ick_3430es1, CK_3430ES1), + CLK("omapdss_dss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX), CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX), CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX), diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index e399ca22e51..255935541d0 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -34,32 +34,18 @@ #include #include -#include #include "dss.h" #include "dss_features.h" static struct { struct platform_device *pdev; - int ctx_id; - - struct clk *dss_ick; - struct clk *dss1_fck; - struct clk *dss2_fck; - struct clk *dss_54m_fck; - struct clk *dss_96m_fck; - unsigned num_clks_enabled; struct regulator *vdds_dsi_reg; struct regulator *vdds_sdi_reg; struct regulator *vdda_dac_reg; } core; -static void dss_clk_enable_all_no_ctx(void); -static void dss_clk_disable_all_no_ctx(void); -static void dss_clk_enable_no_ctx(enum dss_clock clks); -static void dss_clk_disable_no_ctx(enum dss_clock clks); - static char *def_disp_name; module_param_named(def_disp, def_disp_name, charp, 0); MODULE_PARM_DESC(def_disp_name, "default display name"); @@ -69,297 +55,6 @@ unsigned int dss_debug; module_param_named(debug, dss_debug, bool, 0644); #endif -/* CONTEXT */ -static int dss_get_ctx_id(void) -{ - struct omap_dss_board_info *pdata = core.pdev->dev.platform_data; - int r; - - if (!pdata->get_last_off_on_transaction_id) - return 0; - r = pdata->get_last_off_on_transaction_id(&core.pdev->dev); - if (r < 0) { - dev_err(&core.pdev->dev, "getting transaction ID failed, " - "will force context restore\n"); - r = -1; - } - return r; -} - -int dss_need_ctx_restore(void) -{ - int id = dss_get_ctx_id(); - - if (id < 0 || id != core.ctx_id) { - DSSDBG("ctx id %d -> id %d\n", - core.ctx_id, id); - core.ctx_id = id; - return 1; - } else { - return 0; - } -} - -static void save_all_ctx(void) -{ - DSSDBG("save context\n"); - - dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1); - - dss_save_context(); - dispc_save_context(); -#ifdef CONFIG_OMAP2_DSS_DSI - dsi_save_context(); -#endif - - dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1); -} - -static void restore_all_ctx(void) -{ - DSSDBG("restore context\n"); - - dss_clk_enable_all_no_ctx(); - - dss_restore_context(); - dispc_restore_context(); -#ifdef CONFIG_OMAP2_DSS_DSI - dsi_restore_context(); -#endif - - dss_clk_disable_all_no_ctx(); -} - -#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) -/* CLOCKS */ -static void core_dump_clocks(struct seq_file *s) -{ - int i; - struct clk *clocks[5] = { - core.dss_ick, - core.dss1_fck, - core.dss2_fck, - core.dss_54m_fck, - core.dss_96m_fck - }; - - seq_printf(s, "- CORE -\n"); - - seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled); - - for (i = 0; i < 5; i++) { - if (!clocks[i]) - continue; - seq_printf(s, "%-15s\t%lu\t%d\n", - clocks[i]->name, - clk_get_rate(clocks[i]), - clocks[i]->usecount); - } -} -#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */ - -static int dss_get_clock(struct clk **clock, const char *clk_name) -{ - struct clk *clk; - - clk = clk_get(&core.pdev->dev, clk_name); - - if (IS_ERR(clk)) { - DSSERR("can't get clock %s", clk_name); - return PTR_ERR(clk); - } - - *clock = clk; - - DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk)); - - return 0; -} - -static int dss_get_clocks(void) -{ - int r; - - core.dss_ick = NULL; - core.dss1_fck = NULL; - core.dss2_fck = NULL; - core.dss_54m_fck = NULL; - core.dss_96m_fck = NULL; - - r = dss_get_clock(&core.dss_ick, "ick"); - if (r) - goto err; - - r = dss_get_clock(&core.dss1_fck, "dss1_fck"); - if (r) - goto err; - - r = dss_get_clock(&core.dss2_fck, "dss2_fck"); - if (r) - goto err; - - r = dss_get_clock(&core.dss_54m_fck, "tv_fck"); - if (r) - goto err; - - r = dss_get_clock(&core.dss_96m_fck, "video_fck"); - if (r) - goto err; - - return 0; - -err: - if (core.dss_ick) - clk_put(core.dss_ick); - if (core.dss1_fck) - clk_put(core.dss1_fck); - if (core.dss2_fck) - clk_put(core.dss2_fck); - if (core.dss_54m_fck) - clk_put(core.dss_54m_fck); - if (core.dss_96m_fck) - clk_put(core.dss_96m_fck); - - return r; -} - -static void dss_put_clocks(void) -{ - if (core.dss_96m_fck) - clk_put(core.dss_96m_fck); - clk_put(core.dss_54m_fck); - clk_put(core.dss1_fck); - clk_put(core.dss2_fck); - clk_put(core.dss_ick); -} - -unsigned long dss_clk_get_rate(enum dss_clock clk) -{ - switch (clk) { - case DSS_CLK_ICK: - return clk_get_rate(core.dss_ick); - case DSS_CLK_FCK1: - return clk_get_rate(core.dss1_fck); - case DSS_CLK_FCK2: - return clk_get_rate(core.dss2_fck); - case DSS_CLK_54M: - return clk_get_rate(core.dss_54m_fck); - case DSS_CLK_96M: - return clk_get_rate(core.dss_96m_fck); - } - - BUG(); - return 0; -} - -static unsigned count_clk_bits(enum dss_clock clks) -{ - unsigned num_clks = 0; - - if (clks & DSS_CLK_ICK) - ++num_clks; - if (clks & DSS_CLK_FCK1) - ++num_clks; - if (clks & DSS_CLK_FCK2) - ++num_clks; - if (clks & DSS_CLK_54M) - ++num_clks; - if (clks & DSS_CLK_96M) - ++num_clks; - - return num_clks; -} - -static void dss_clk_enable_no_ctx(enum dss_clock clks) -{ - unsigned num_clks = count_clk_bits(clks); - - if (clks & DSS_CLK_ICK) - clk_enable(core.dss_ick); - if (clks & DSS_CLK_FCK1) - clk_enable(core.dss1_fck); - if (clks & DSS_CLK_FCK2) - clk_enable(core.dss2_fck); - if (clks & DSS_CLK_54M) - clk_enable(core.dss_54m_fck); - if (clks & DSS_CLK_96M) - clk_enable(core.dss_96m_fck); - - core.num_clks_enabled += num_clks; -} - -void dss_clk_enable(enum dss_clock clks) -{ - bool check_ctx = core.num_clks_enabled == 0; - - dss_clk_enable_no_ctx(clks); - - if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore()) - restore_all_ctx(); -} - -static void dss_clk_disable_no_ctx(enum dss_clock clks) -{ - unsigned num_clks = count_clk_bits(clks); - - if (clks & DSS_CLK_ICK) - clk_disable(core.dss_ick); - if (clks & DSS_CLK_FCK1) - clk_disable(core.dss1_fck); - if (clks & DSS_CLK_FCK2) - clk_disable(core.dss2_fck); - if (clks & DSS_CLK_54M) - clk_disable(core.dss_54m_fck); - if (clks & DSS_CLK_96M) - clk_disable(core.dss_96m_fck); - - core.num_clks_enabled -= num_clks; -} - -void dss_clk_disable(enum dss_clock clks) -{ - if (cpu_is_omap34xx()) { - unsigned num_clks = count_clk_bits(clks); - - BUG_ON(core.num_clks_enabled < num_clks); - - if (core.num_clks_enabled == num_clks) - save_all_ctx(); - } - - dss_clk_disable_no_ctx(clks); -} - -static void dss_clk_enable_all_no_ctx(void) -{ - enum dss_clock clks; - - clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; - if (cpu_is_omap34xx()) - clks |= DSS_CLK_96M; - dss_clk_enable_no_ctx(clks); -} - -static void dss_clk_disable_all_no_ctx(void) -{ - enum dss_clock clks; - - clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; - if (cpu_is_omap34xx()) - clks |= DSS_CLK_96M; - dss_clk_disable_no_ctx(clks); -} - -static void dss_clk_disable_all(void) -{ - enum dss_clock clks; - - clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; - if (cpu_is_omap34xx()) - clks |= DSS_CLK_96M; - dss_clk_disable(clks); -} - /* REGULATORS */ struct regulator *dss_get_vdds_dsi(void) @@ -404,18 +99,7 @@ struct regulator *dss_get_vdda_dac(void) return reg; } -/* DEBUGFS */ #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) -static void dss_debug_dump_clocks(struct seq_file *s) -{ - core_dump_clocks(s); - dss_dump_clocks(s); - dispc_dump_clocks(s); -#ifdef CONFIG_OMAP2_DSS_DSI - dsi_dump_clocks(s); -#endif -} - static int dss_debug_show(struct seq_file *s, void *unused) { void (*func)(struct seq_file *) = s->private; @@ -508,21 +192,15 @@ static int omap_dss_probe(struct platform_device *pdev) dss_init_overlay_managers(pdev); dss_init_overlays(pdev); - r = dss_get_clocks(); - if (r) - goto err_clocks; - - dss_clk_enable_all_no_ctx(); - - core.ctx_id = dss_get_ctx_id(); - DSSDBG("initial ctx id %u\n", core.ctx_id); - r = dss_init_platform_driver(); if (r) { DSSERR("Failed to initialize DSS platform driver\n"); goto err_dss; } + /* keep clocks enabled to prevent context saves/restores during init */ + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + r = rfbi_init(); if (r) { DSSERR("Failed to initialize rfbi\n"); @@ -588,7 +266,7 @@ static int omap_dss_probe(struct platform_device *pdev) pdata->default_device = dssdev; } - dss_clk_disable_all(); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); return 0; @@ -611,9 +289,6 @@ err_dpi: err_rfbi: dss_uninit_platform_driver(); err_dss: - dss_clk_disable_all_no_ctx(); - dss_put_clocks(); -err_clocks: return r; } @@ -636,16 +311,6 @@ static int omap_dss_remove(struct platform_device *pdev) dss_uninit_platform_driver(); - /* - * As part of hwmod changes, DSS is not the only controller of dss - * clocks; hwmod framework itself will also enable clocks during hwmod - * init for dss, and autoidle is set in h/w for DSS. Hence, there's no - * need to disable clocks if their usecounts > 1. - */ - WARN_ON(core.num_clks_enabled > 0); - - dss_put_clocks(); - dss_uninit_overlays(pdev); dss_uninit_overlay_managers(pdev); diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 01406f48f43..72b395d69aa 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -31,6 +31,7 @@ #include #include +#include #include "dss.h" #define DSS_BASE 0x48050000 @@ -61,8 +62,15 @@ struct dss_reg { static struct { struct platform_device *pdev; void __iomem *base; + int ctx_id; struct clk *dpll4_m4_ck; + struct clk *dss_ick; + struct clk *dss1_fck; + struct clk *dss2_fck; + struct clk *dss_54m_fck; + struct clk *dss_96m_fck; + unsigned num_clks_enabled; unsigned long cache_req_pck; unsigned long cache_prate; @@ -75,6 +83,11 @@ static struct { u32 ctx[DSS_SZ_REGS / sizeof(u32)]; } dss; +static void dss_clk_enable_all_no_ctx(void); +static void dss_clk_disable_all_no_ctx(void); +static void dss_clk_enable_no_ctx(enum dss_clock clks); +static void dss_clk_disable_no_ctx(enum dss_clock clks); + static int _omap_dss_wait_reset(void); static inline void dss_write_reg(const struct dss_reg idx, u32 val) @@ -640,6 +653,301 @@ static void dss_exit(void) iounmap(dss.base); } +/* CONTEXT */ +static int dss_get_ctx_id(void) +{ + struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data; + int r; + + if (!pdata->board_data->get_last_off_on_transaction_id) + return 0; + r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev); + if (r < 0) { + dev_err(&dss.pdev->dev, "getting transaction ID failed, " + "will force context restore\n"); + r = -1; + } + return r; +} + +int dss_need_ctx_restore(void) +{ + int id = dss_get_ctx_id(); + + if (id < 0 || id != dss.ctx_id) { + DSSDBG("ctx id %d -> id %d\n", + dss.ctx_id, id); + dss.ctx_id = id; + return 1; + } else { + return 0; + } +} + +static void save_all_ctx(void) +{ + DSSDBG("save context\n"); + + dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1); + + dss_save_context(); + dispc_save_context(); +#ifdef CONFIG_OMAP2_DSS_DSI + dsi_save_context(); +#endif + + dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1); +} + +static void restore_all_ctx(void) +{ + DSSDBG("restore context\n"); + + dss_clk_enable_all_no_ctx(); + + dss_restore_context(); + dispc_restore_context(); +#ifdef CONFIG_OMAP2_DSS_DSI + dsi_restore_context(); +#endif + + dss_clk_disable_all_no_ctx(); +} + +static int dss_get_clock(struct clk **clock, const char *clk_name) +{ + struct clk *clk; + + clk = clk_get(&dss.pdev->dev, clk_name); + + if (IS_ERR(clk)) { + DSSERR("can't get clock %s", clk_name); + return PTR_ERR(clk); + } + + *clock = clk; + + DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk)); + + return 0; +} + +static int dss_get_clocks(void) +{ + int r; + + dss.dss_ick = NULL; + dss.dss1_fck = NULL; + dss.dss2_fck = NULL; + dss.dss_54m_fck = NULL; + dss.dss_96m_fck = NULL; + + r = dss_get_clock(&dss.dss_ick, "ick"); + if (r) + goto err; + + r = dss_get_clock(&dss.dss1_fck, "dss1_fck"); + if (r) + goto err; + + r = dss_get_clock(&dss.dss2_fck, "dss2_fck"); + if (r) + goto err; + + r = dss_get_clock(&dss.dss_54m_fck, "tv_fck"); + if (r) + goto err; + + r = dss_get_clock(&dss.dss_96m_fck, "video_fck"); + if (r) + goto err; + + return 0; + +err: + if (dss.dss_ick) + clk_put(dss.dss_ick); + if (dss.dss1_fck) + clk_put(dss.dss1_fck); + if (dss.dss2_fck) + clk_put(dss.dss2_fck); + if (dss.dss_54m_fck) + clk_put(dss.dss_54m_fck); + if (dss.dss_96m_fck) + clk_put(dss.dss_96m_fck); + + return r; +} + +static void dss_put_clocks(void) +{ + if (dss.dss_96m_fck) + clk_put(dss.dss_96m_fck); + clk_put(dss.dss_54m_fck); + clk_put(dss.dss1_fck); + clk_put(dss.dss2_fck); + clk_put(dss.dss_ick); +} + +unsigned long dss_clk_get_rate(enum dss_clock clk) +{ + switch (clk) { + case DSS_CLK_ICK: + return clk_get_rate(dss.dss_ick); + case DSS_CLK_FCK1: + return clk_get_rate(dss.dss1_fck); + case DSS_CLK_FCK2: + return clk_get_rate(dss.dss2_fck); + case DSS_CLK_54M: + return clk_get_rate(dss.dss_54m_fck); + case DSS_CLK_96M: + return clk_get_rate(dss.dss_96m_fck); + } + + BUG(); + return 0; +} + +static unsigned count_clk_bits(enum dss_clock clks) +{ + unsigned num_clks = 0; + + if (clks & DSS_CLK_ICK) + ++num_clks; + if (clks & DSS_CLK_FCK1) + ++num_clks; + if (clks & DSS_CLK_FCK2) + ++num_clks; + if (clks & DSS_CLK_54M) + ++num_clks; + if (clks & DSS_CLK_96M) + ++num_clks; + + return num_clks; +} + +static void dss_clk_enable_no_ctx(enum dss_clock clks) +{ + unsigned num_clks = count_clk_bits(clks); + + if (clks & DSS_CLK_ICK) + clk_enable(dss.dss_ick); + if (clks & DSS_CLK_FCK1) + clk_enable(dss.dss1_fck); + if (clks & DSS_CLK_FCK2) + clk_enable(dss.dss2_fck); + if (clks & DSS_CLK_54M) + clk_enable(dss.dss_54m_fck); + if (clks & DSS_CLK_96M) + clk_enable(dss.dss_96m_fck); + + dss.num_clks_enabled += num_clks; +} + +void dss_clk_enable(enum dss_clock clks) +{ + bool check_ctx = dss.num_clks_enabled == 0; + + dss_clk_enable_no_ctx(clks); + + if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore()) + restore_all_ctx(); +} + +static void dss_clk_disable_no_ctx(enum dss_clock clks) +{ + unsigned num_clks = count_clk_bits(clks); + + if (clks & DSS_CLK_ICK) + clk_disable(dss.dss_ick); + if (clks & DSS_CLK_FCK1) + clk_disable(dss.dss1_fck); + if (clks & DSS_CLK_FCK2) + clk_disable(dss.dss2_fck); + if (clks & DSS_CLK_54M) + clk_disable(dss.dss_54m_fck); + if (clks & DSS_CLK_96M) + clk_disable(dss.dss_96m_fck); + + dss.num_clks_enabled -= num_clks; +} + +void dss_clk_disable(enum dss_clock clks) +{ + if (cpu_is_omap34xx()) { + unsigned num_clks = count_clk_bits(clks); + + BUG_ON(dss.num_clks_enabled < num_clks); + + if (dss.num_clks_enabled == num_clks) + save_all_ctx(); + } + + dss_clk_disable_no_ctx(clks); +} + +static void dss_clk_enable_all_no_ctx(void) +{ + enum dss_clock clks; + + clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; + if (cpu_is_omap34xx()) + clks |= DSS_CLK_96M; + dss_clk_enable_no_ctx(clks); +} + +static void dss_clk_disable_all_no_ctx(void) +{ + enum dss_clock clks; + + clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; + if (cpu_is_omap34xx()) + clks |= DSS_CLK_96M; + dss_clk_disable_no_ctx(clks); +} + +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) +/* CLOCKS */ +static void core_dump_clocks(struct seq_file *s) +{ + int i; + struct clk *clocks[5] = { + dss.dss_ick, + dss.dss1_fck, + dss.dss2_fck, + dss.dss_54m_fck, + dss.dss_96m_fck + }; + + seq_printf(s, "- CORE -\n"); + + seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled); + + for (i = 0; i < 5; i++) { + if (!clocks[i]) + continue; + seq_printf(s, "%-15s\t%lu\t%d\n", + clocks[i]->name, + clk_get_rate(clocks[i]), + clocks[i]->usecount); + } +} +#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */ + +/* DEBUGFS */ +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) +void dss_debug_dump_clocks(struct seq_file *s) +{ + core_dump_clocks(s); + dss_dump_clocks(s); + dispc_dump_clocks(s); +#ifdef CONFIG_OMAP2_DSS_DSI + dsi_dump_clocks(s); +#endif +} +#endif + + /* DSS HW IP initialisation */ static int omap_dsshw_probe(struct platform_device *pdev) { @@ -648,6 +956,15 @@ static int omap_dsshw_probe(struct platform_device *pdev) dss.pdev = pdev; + r = dss_get_clocks(); + if (r) + goto err_clocks; + + dss_clk_enable_all_no_ctx(); + + dss.ctx_id = dss_get_ctx_id(); + DSSDBG("initial ctx id %u\n", dss.ctx_id); + #ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT /* DISPC_CONTROL */ if (omap_readl(0x48050440) & 1) /* LCD enabled? */ @@ -660,15 +977,30 @@ static int omap_dsshw_probe(struct platform_device *pdev) goto err_dss; } -err_dss: + dss_clk_disable_all_no_ctx(); + return 0; +err_dss: + dss_clk_disable_all_no_ctx(); + dss_put_clocks(); +err_clocks: return r; } static int omap_dsshw_remove(struct platform_device *pdev) { + dss_exit(); + /* + * As part of hwmod changes, DSS is not the only controller of dss + * clocks; hwmod framework itself will also enable clocks during hwmod + * init for dss, and autoidle is set in h/w for DSS. Hence, there's no + * need to disable clocks if their usecounts > 1. + */ + WARN_ON(dss.num_clks_enabled > 0); + + dss_put_clocks(); return 0; } diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 37c4544e890..c535ee1db3e 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -169,11 +169,6 @@ struct seq_file; struct platform_device; /* core */ -void dss_clk_enable(enum dss_clock clks); -void dss_clk_disable(enum dss_clock clks); -unsigned long dss_clk_get_rate(enum dss_clock clk); -int dss_need_ctx_restore(void); -void dss_dump_clocks(struct seq_file *s); struct bus_type *dss_get_bus(void); struct regulator *dss_get_vdds_dsi(void); struct regulator *dss_get_vdds_sdi(void); @@ -219,8 +214,16 @@ void dss_uninit_platform_driver(void); void dss_save_context(void); void dss_restore_context(void); +void dss_clk_enable(enum dss_clock clks); +void dss_clk_disable(enum dss_clock clks); +unsigned long dss_clk_get_rate(enum dss_clock clk); +int dss_need_ctx_restore(void); +void dss_dump_clocks(struct seq_file *s); void dss_dump_regs(struct seq_file *s); +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) +void dss_debug_dump_clocks(struct seq_file *s); +#endif void dss_sdi_init(u8 datapairs); int dss_sdi_enable(void); -- cgit v1.2.3-70-g09d2 From 3448d500f7002a5ee374ec92d954b1667cbf72a4 Mon Sep 17 00:00:00 2001 From: Senthilvadivu Guruswamy Date: Mon, 24 Jan 2011 06:21:59 +0000 Subject: OMAP2, 3: DSS2: RFBI: create platform_driver, move init, exit to driver Hwmod adaptation design requires each of the DSS HW IP to be a platform driver. So a platform_driver for RFBI is created and init exit methods are moved from core.c to its driver probe,remove. pdev member has to be maintained by its own drivers. RFBI platform driver is registered from inside omap_dss_probe, in the order desired. Signed-off-by: Senthilvadivu Guruswamy Signed-off-by: Sumit Semwal Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 8 +-- drivers/video/omap2/dss/dss.h | 8 +-- drivers/video/omap2/dss/rfbi.c | 110 ++++++++++++++++++++++++----------------- 3 files changed, 74 insertions(+), 52 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 255935541d0..8eef616fee0 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -201,9 +201,9 @@ static int omap_dss_probe(struct platform_device *pdev) /* keep clocks enabled to prevent context saves/restores during init */ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); - r = rfbi_init(); + r = rfbi_init_platform_driver(); if (r) { - DSSERR("Failed to initialize rfbi\n"); + DSSERR("Failed to initialize rfbi platform driver\n"); goto err_rfbi; } @@ -285,7 +285,7 @@ err_venc: err_dispc: dpi_exit(); err_dpi: - rfbi_exit(); + rfbi_uninit_platform_driver(); err_rfbi: dss_uninit_platform_driver(); err_dss: @@ -303,7 +303,7 @@ static int omap_dss_remove(struct platform_device *pdev) venc_exit(); dispc_exit(); dpi_exit(); - rfbi_exit(); + rfbi_uninit_platform_driver(); if (cpu_is_omap34xx()) { dsi_exit(); sdi_exit(); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index c535ee1db3e..0ba4bdbd6b0 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -428,8 +428,8 @@ static inline void venc_exit(void) /* RFBI */ #ifdef CONFIG_OMAP2_DSS_RFBI -int rfbi_init(void); -void rfbi_exit(void); +int rfbi_init_platform_driver(void); +void rfbi_uninit_platform_driver(void); void rfbi_dump_regs(struct seq_file *s); int rfbi_configure(int rfbi_module, int bpp, int lines); @@ -440,11 +440,11 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t); unsigned long rfbi_get_max_tx_rate(void); int rfbi_init_display(struct omap_dss_device *display); #else -static inline int rfbi_init(void) +static inline int rfbi_init_platform_driver(void) { return 0; } -static inline void rfbi_exit(void) +static inline void rfbi_uninit_platform_driver(void) { } #endif diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 10a2ffe0288..153f963e8e8 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -100,6 +100,7 @@ static int rfbi_convert_timings(struct rfbi_timings *t); static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); static struct { + struct platform_device *pdev; void __iomem *base; unsigned long l4_khz; @@ -957,50 +958,6 @@ void rfbi_dump_regs(struct seq_file *s) #undef DUMPREG } -int rfbi_init(void) -{ - u32 rev; - u32 l; - - spin_lock_init(&rfbi.cmd_lock); - - init_completion(&rfbi.cmd_done); - atomic_set(&rfbi.cmd_fifo_full, 0); - atomic_set(&rfbi.cmd_pending, 0); - - rfbi.base = ioremap(RFBI_BASE, SZ_256); - if (!rfbi.base) { - DSSERR("can't ioremap RFBI\n"); - return -ENOMEM; - } - - rfbi_enable_clocks(1); - - msleep(10); - - rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000; - - /* Enable autoidle and smart-idle */ - l = rfbi_read_reg(RFBI_SYSCONFIG); - l |= (1 << 0) | (2 << 3); - rfbi_write_reg(RFBI_SYSCONFIG, l); - - rev = rfbi_read_reg(RFBI_REVISION); - printk(KERN_INFO "OMAP RFBI rev %d.%d\n", - FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); - - rfbi_enable_clocks(0); - - return 0; -} - -void rfbi_exit(void) -{ - DSSDBG("rfbi_exit\n"); - - iounmap(rfbi.base); -} - int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) { int r; @@ -1056,3 +1013,68 @@ int rfbi_init_display(struct omap_dss_device *dssdev) dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; return 0; } + +/* RFBI HW IP initialisation */ +static int omap_rfbihw_probe(struct platform_device *pdev) +{ + u32 rev; + u32 l; + + rfbi.pdev = pdev; + + spin_lock_init(&rfbi.cmd_lock); + + init_completion(&rfbi.cmd_done); + atomic_set(&rfbi.cmd_fifo_full, 0); + atomic_set(&rfbi.cmd_pending, 0); + + rfbi.base = ioremap(RFBI_BASE, SZ_256); + if (!rfbi.base) { + DSSERR("can't ioremap RFBI\n"); + return -ENOMEM; + } + + rfbi_enable_clocks(1); + + msleep(10); + + rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000; + + /* Enable autoidle and smart-idle */ + l = rfbi_read_reg(RFBI_SYSCONFIG); + l |= (1 << 0) | (2 << 3); + rfbi_write_reg(RFBI_SYSCONFIG, l); + + rev = rfbi_read_reg(RFBI_REVISION); + printk(KERN_INFO "OMAP RFBI rev %d.%d\n", + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); + + rfbi_enable_clocks(0); + + return 0; +} + +static int omap_rfbihw_remove(struct platform_device *pdev) +{ + iounmap(rfbi.base); + return 0; +} + +static struct platform_driver omap_rfbihw_driver = { + .probe = omap_rfbihw_probe, + .remove = omap_rfbihw_remove, + .driver = { + .name = "omapdss_rfbi", + .owner = THIS_MODULE, + }, +}; + +int rfbi_init_platform_driver(void) +{ + return platform_driver_register(&omap_rfbihw_driver); +} + +void rfbi_uninit_platform_driver(void) +{ + return platform_driver_unregister(&omap_rfbihw_driver); +} -- cgit v1.2.3-70-g09d2 From 060b6d9cbab03f1379dbe00393ab26d6eb371ce2 Mon Sep 17 00:00:00 2001 From: Senthilvadivu Guruswamy Date: Mon, 24 Jan 2011 06:22:00 +0000 Subject: OMAP2, 3: DSS2: DISPC: create platform_driver, move init, exit to driver Hwmod adaptation design requires each of the DSS HW IP to be a platform driver. So a platform_driver for DISPC is created and init exit methods are moved from core.c to its driver probe,remove. pdev member has to be maintained by its own drivers. DISPC platform driver is registered from inside omap_dss_probe, in the order desired. Signed-off-by: Senthilvadivu Guruswamy Signed-off-by: Sumit Semwal Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 8 +-- drivers/video/omap2/dss/dispc.c | 105 ++++++++++++++++++++++++---------------- drivers/video/omap2/dss/dss.h | 4 +- 3 files changed, 70 insertions(+), 47 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 8eef616fee0..8b7eab83e41 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -213,9 +213,9 @@ static int omap_dss_probe(struct platform_device *pdev) goto err_dpi; } - r = dispc_init(); + r = dispc_init_platform_driver(); if (r) { - DSSERR("Failed to initialize dispc\n"); + DSSERR("Failed to initialize dispc platform driver\n"); goto err_dispc; } @@ -281,7 +281,7 @@ err_dsi: err_sdi: venc_exit(); err_venc: - dispc_exit(); + dispc_uninit_platform_driver(); err_dispc: dpi_exit(); err_dpi: @@ -301,7 +301,7 @@ static int omap_dss_remove(struct platform_device *pdev) dss_uninitialize_debugfs(); venc_exit(); - dispc_exit(); + dispc_uninit_platform_driver(); dpi_exit(); rfbi_uninit_platform_driver(); if (cpu_is_omap34xx()) { diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 9f8c69f16e6..28ad68b6be4 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -178,6 +178,7 @@ struct dispc_irq_stats { }; static struct { + struct platform_device *pdev; void __iomem *base; u32 fifo_size[3]; @@ -3269,47 +3270,6 @@ static void _omap_dispc_initial_config(void) dispc_read_plane_fifo_sizes(); } -int dispc_init(void) -{ - u32 rev; - - spin_lock_init(&dispc.irq_lock); - -#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS - spin_lock_init(&dispc.irq_stats_lock); - dispc.irq_stats.last_reset = jiffies; -#endif - - INIT_WORK(&dispc.error_work, dispc_error_worker); - - dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS); - if (!dispc.base) { - DSSERR("can't ioremap DISPC\n"); - return -ENOMEM; - } - - enable_clocks(1); - - _omap_dispc_initial_config(); - - _omap_dispc_initialize_irq(); - - dispc_save_context(); - - rev = dispc_read_reg(DISPC_REVISION); - printk(KERN_INFO "OMAP DISPC rev %d.%d\n", - FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); - - enable_clocks(0); - - return 0; -} - -void dispc_exit(void) -{ - iounmap(dispc.base); -} - int dispc_enable_plane(enum omap_plane plane, bool enable) { DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); @@ -3359,3 +3319,66 @@ int dispc_setup_plane(enum omap_plane plane, return r; } + +/* DISPC HW IP initialisation */ +static int omap_dispchw_probe(struct platform_device *pdev) +{ + u32 rev; + dispc.pdev = pdev; + + spin_lock_init(&dispc.irq_lock); + +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS + spin_lock_init(&dispc.irq_stats_lock); + dispc.irq_stats.last_reset = jiffies; +#endif + + INIT_WORK(&dispc.error_work, dispc_error_worker); + + dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS); + if (!dispc.base) { + DSSERR("can't ioremap DISPC\n"); + return -ENOMEM; + } + + enable_clocks(1); + + _omap_dispc_initial_config(); + + _omap_dispc_initialize_irq(); + + dispc_save_context(); + + rev = dispc_read_reg(DISPC_REVISION); + printk(KERN_INFO "OMAP DISPC rev %d.%d\n", + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); + + enable_clocks(0); + + return 0; +} + +static int omap_dispchw_remove(struct platform_device *pdev) +{ + iounmap(dispc.base); + return 0; +} + +static struct platform_driver omap_dispchw_driver = { + .probe = omap_dispchw_probe, + .remove = omap_dispchw_remove, + .driver = { + .name = "omapdss_dispc", + .owner = THIS_MODULE, + }, +}; + +int dispc_init_platform_driver(void) +{ + return platform_driver_register(&omap_dispchw_driver); +} + +void dispc_uninit_platform_driver(void) +{ + return platform_driver_unregister(&omap_dispchw_driver); +} diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 0ba4bdbd6b0..f4835c85db9 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -319,8 +319,8 @@ static inline void dpi_exit(void) #endif /* DISPC */ -int dispc_init(void); -void dispc_exit(void); +int dispc_init_platform_driver(void); +void dispc_uninit_platform_driver(void); void dispc_dump_clocks(struct seq_file *s); void dispc_dump_irqs(struct seq_file *s); void dispc_dump_regs(struct seq_file *s); -- cgit v1.2.3-70-g09d2 From 30ea50c9f5166a375b4dc0109d18a5d21bab5711 Mon Sep 17 00:00:00 2001 From: Senthilvadivu Guruswamy Date: Mon, 24 Jan 2011 06:22:01 +0000 Subject: OMAP2, 3: DSS2: VENC: create platform_driver, move init, exit to driver Hwmod adaptation design requires each of the DSS HW IP to be a platform driver. So a platform_driver for VENC is created and init exit methods are moved from core.c to its driver probe,remove. pdev member has to be maintained by its own drivers. Also, venc_vdda_dac reading is moved to venc.c. VENC platform driver is registered from inside omap_dss_probe, in the order desired. Signed-off-by: Senthilvadivu Guruswamy Signed-off-by: Sumit Semwal Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/board-3430sdp.c | 2 +- arch/arm/mach-omap2/board-cm-t35.c | 2 +- arch/arm/mach-omap2/board-devkit8000.c | 2 +- arch/arm/mach-omap2/board-omap3beagle.c | 2 +- arch/arm/mach-omap2/board-omap3evm.c | 2 +- arch/arm/mach-omap2/board-omap3pandora.c | 2 +- arch/arm/mach-omap2/board-omap3stalker.c | 2 +- arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +- arch/arm/mach-omap2/board-zoom-peripherals.c | 2 +- drivers/video/omap2/dss/core.c | 28 +------ drivers/video/omap2/dss/dss.h | 9 +-- drivers/video/omap2/dss/venc.c | 116 ++++++++++++++++++--------- 12 files changed, 93 insertions(+), 78 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index e018472861e..652e7c38c62 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -395,7 +395,7 @@ static struct regulator_consumer_supply sdp3430_vaux3_supplies[] = { }; static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = { - REGULATOR_SUPPLY("vdda_dac", "omapdss"), + REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"), }; /* VPLL2 for digital video outputs */ diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 27bea540ccb..e55fde0a720 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -488,7 +488,7 @@ static struct regulator_consumer_supply cm_t35_vsim_supply = { }; static struct regulator_consumer_supply cm_t35_vdac_supply = - REGULATOR_SUPPLY("vdda_dac", "omapdss"); + REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); static struct regulator_consumer_supply cm_t35_vdvi_supply = REGULATOR_SUPPLY("vdvi", "omapdss"); diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 728f27c5bcb..b64774b3d82 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -196,7 +196,7 @@ static struct omap_dss_board_info devkit8000_dss_data = { }; static struct regulator_consumer_supply devkit8000_vdda_dac_supply = - REGULATOR_SUPPLY("vdda_dac", "omapdss"); + REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); static uint32_t board_keymap[] = { KEY(0, 0, KEY_1), diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 20c5dbea895..2fad38f9e68 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -232,7 +232,7 @@ static struct omap_dss_board_info beagle_dss_data = { }; static struct regulator_consumer_supply beagle_vdac_supply = - REGULATOR_SUPPLY("vdda_dac", "omapdss"); + REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); static struct regulator_consumer_supply beagle_vdvi_supply = REGULATOR_SUPPLY("vdds_dsi", "omapdss"); diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index b65848c59e1..a6564b41b97 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -542,7 +542,7 @@ static struct twl4030_codec_data omap3evm_codec_data = { }; static struct regulator_consumer_supply omap3_evm_vdda_dac_supply = - REGULATOR_SUPPLY("vdda_dac", "omapdss"); + REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); /* VDAC for DSS driving S-Video */ static struct regulator_init_data omap3_evm_vdac = { diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 5386a8190ea..37de418edd2 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -342,7 +342,7 @@ static struct regulator_consumer_supply pandora_vmmc3_supply = REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"); static struct regulator_consumer_supply pandora_vdda_dac_supply = - REGULATOR_SUPPLY("vdda_dac", "omapdss"); + REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); static struct regulator_consumer_supply pandora_vdds_supplies[] = { REGULATOR_SUPPLY("vdds_sdi", "omapdss"), diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index 15ede8b4981..bd0eed85807 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c @@ -439,7 +439,7 @@ static struct twl4030_codec_data omap3stalker_codec_data = { }; static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply = - REGULATOR_SUPPLY("vdda_dac", "omapdss"); + REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); /* VDAC for DSS driving S-Video */ static struct regulator_init_data omap3_stalker_vdac = { diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 5f1900c532e..bbcb6775a6a 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -372,7 +372,7 @@ static struct regulator_consumer_supply rx51_vaux1_consumers[] = { }; static struct regulator_consumer_supply rx51_vdac_supply[] = { - REGULATOR_SUPPLY("vdda_dac", "omapdss"), + REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"), }; static struct regulator_init_data rx51_vaux1 = { diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 448ab60195d..405400c4762 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -230,7 +230,7 @@ static struct regulator_consumer_supply zoom_vpll2_supply = REGULATOR_SUPPLY("vdds_dsi", "omapdss"); static struct regulator_consumer_supply zoom_vdda_dac_supply = - REGULATOR_SUPPLY("vdda_dac", "omapdss"); + REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); static struct regulator_init_data zoom_vpll2 = { .constraints = { diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 8b7eab83e41..57c6303cb1c 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -43,7 +43,6 @@ static struct { struct regulator *vdds_dsi_reg; struct regulator *vdds_sdi_reg; - struct regulator *vdda_dac_reg; } core; static char *def_disp_name; @@ -85,20 +84,6 @@ struct regulator *dss_get_vdds_sdi(void) return reg; } -struct regulator *dss_get_vdda_dac(void) -{ - struct regulator *reg; - - if (core.vdda_dac_reg != NULL) - return core.vdda_dac_reg; - - reg = regulator_get(&core.pdev->dev, "vdda_dac"); - if (!IS_ERR(reg)) - core.vdda_dac_reg = reg; - - return reg; -} - #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) static int dss_debug_show(struct seq_file *s, void *unused) { @@ -219,9 +204,9 @@ static int omap_dss_probe(struct platform_device *pdev) goto err_dispc; } - r = venc_init(pdev); + r = venc_init_platform_driver(); if (r) { - DSSERR("Failed to initialize venc\n"); + DSSERR("Failed to initialize venc platform driver\n"); goto err_venc; } @@ -279,7 +264,7 @@ err_dsi: if (cpu_is_omap34xx()) sdi_exit(); err_sdi: - venc_exit(); + venc_uninit_platform_driver(); err_venc: dispc_uninit_platform_driver(); err_dispc: @@ -300,7 +285,7 @@ static int omap_dss_remove(struct platform_device *pdev) dss_uninitialize_debugfs(); - venc_exit(); + venc_uninit_platform_driver(); dispc_uninit_platform_driver(); dpi_exit(); rfbi_uninit_platform_driver(); @@ -597,11 +582,6 @@ static void __exit omap_dss_exit(void) core.vdds_sdi_reg = NULL; } - if (core.vdda_dac_reg != NULL) { - regulator_put(core.vdda_dac_reg); - core.vdda_dac_reg = NULL; - } - platform_driver_unregister(&omap_dss_driver); omap_dss_bus_unregister(); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index f4835c85db9..931385185dc 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -172,7 +172,6 @@ struct platform_device; struct bus_type *dss_get_bus(void); struct regulator *dss_get_vdds_dsi(void); struct regulator *dss_get_vdds_sdi(void); -struct regulator *dss_get_vdda_dac(void); /* display */ int dss_suspend_all_devices(void); @@ -412,16 +411,16 @@ int dispc_get_clock_div(enum omap_channel channel, /* VENC */ #ifdef CONFIG_OMAP2_DSS_VENC -int venc_init(struct platform_device *pdev); -void venc_exit(void); +int venc_init_platform_driver(void); +void venc_uninit_platform_driver(void); void venc_dump_regs(struct seq_file *s); int venc_init_display(struct omap_dss_device *display); #else -static inline int venc_init(struct platform_device *pdev) +static inline int venc_init_platform_driver(void) { return 0; } -static inline void venc_exit(void) +static inline void venc_uninit_platform_driver(void) { } #endif diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index eff35050e28..765a4ac44ec 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -289,6 +289,7 @@ const struct omap_video_timings omap_dss_ntsc_timings = { EXPORT_SYMBOL(omap_dss_ntsc_timings); static struct { + struct platform_device *pdev; void __iomem *base; struct mutex venc_lock; u32 wss_data; @@ -306,6 +307,17 @@ static inline u32 venc_read_reg(int idx) return l; } +static struct regulator *venc_get_vdda_dac(void) +{ + struct regulator *reg; + + reg = regulator_get(&venc.pdev->dev, "vdda_dac"); + if (!IS_ERR(reg)) + venc.vdda_dac_reg = reg; + + return reg; +} + static void venc_write_config(const struct venc_config *config) { DSSDBG("write venc conf\n"); @@ -641,46 +653,6 @@ static struct omap_dss_driver venc_driver = { }; /* driver end */ - - -int venc_init(struct platform_device *pdev) -{ - u8 rev_id; - - mutex_init(&venc.venc_lock); - - venc.wss_data = 0; - - venc.base = ioremap(VENC_BASE, SZ_1K); - if (!venc.base) { - DSSERR("can't ioremap VENC\n"); - return -ENOMEM; - } - - venc.vdda_dac_reg = dss_get_vdda_dac(); - if (IS_ERR(venc.vdda_dac_reg)) { - iounmap(venc.base); - DSSERR("can't get VDDA_DAC regulator\n"); - return PTR_ERR(venc.vdda_dac_reg); - } - - venc_enable_clocks(1); - - rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff); - printk(KERN_INFO "OMAP VENC rev %d\n", rev_id); - - venc_enable_clocks(0); - - return omap_dss_register_driver(&venc_driver); -} - -void venc_exit(void) -{ - omap_dss_unregister_driver(&venc_driver); - - iounmap(venc.base); -} - int venc_init_display(struct omap_dss_device *dssdev) { DSSDBG("init_display\n"); @@ -740,3 +712,67 @@ void venc_dump_regs(struct seq_file *s) #undef DUMPREG } + +/* VENC HW IP initialisation */ +static int omap_venchw_probe(struct platform_device *pdev) +{ + u8 rev_id; + venc.pdev = pdev; + + mutex_init(&venc.venc_lock); + + venc.wss_data = 0; + + venc.base = ioremap(VENC_BASE, SZ_1K); + if (!venc.base) { + DSSERR("can't ioremap VENC\n"); + return -ENOMEM; + } + + venc.vdda_dac_reg = venc_get_vdda_dac(); + if (IS_ERR(venc.vdda_dac_reg)) { + iounmap(venc.base); + DSSERR("can't get VDDA_DAC regulator\n"); + return PTR_ERR(venc.vdda_dac_reg); + } + + venc_enable_clocks(1); + + rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff); + printk(KERN_INFO "OMAP VENC rev %d\n", rev_id); + + venc_enable_clocks(0); + + return omap_dss_register_driver(&venc_driver); +} + +static int omap_venchw_remove(struct platform_device *pdev) +{ + if (venc.vdda_dac_reg != NULL) { + regulator_put(venc.vdda_dac_reg); + venc.vdda_dac_reg = NULL; + } + omap_dss_unregister_driver(&venc_driver); + + iounmap(venc.base); + return 0; +} + +static struct platform_driver omap_venchw_driver = { + .probe = omap_venchw_probe, + .remove = omap_venchw_remove, + .driver = { + .name = "omapdss_venc", + .owner = THIS_MODULE, + }, +}; + +int venc_init_platform_driver(void) +{ + return platform_driver_register(&omap_venchw_driver); +} + +void venc_uninit_platform_driver(void) +{ + return platform_driver_unregister(&omap_venchw_driver); +} -- cgit v1.2.3-70-g09d2 From c8aac01b7bd1109795586db11ea7f12ab1e2d163 Mon Sep 17 00:00:00 2001 From: Senthilvadivu Guruswamy Date: Mon, 24 Jan 2011 06:22:02 +0000 Subject: OMAP2, 3: DSS2: DSI: create platform_driver, move init, exit to driver Hwmod adaptation design requires each of the DSS HW IP to be a platform driver. So a platform_driver for DSI is created and init exit methods are moved from core.c to its driver probe,remove. pdev member has to be maintained by its own drivers. Also, vdds_dsi regulator handling is copied to dsi.c, since vdds_dsi regulator is needed by dpi_init() too. Board files are updated accordingly to add 2 instances of vdds_dsi regulator. DSI platform driver is registered from inside omap_dss_probe, in the order desired. Signed-off-by: Senthilvadivu Guruswamy Signed-off-by: Sumit Semwal Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/board-3430sdp.c | 1 + arch/arm/mach-omap2/board-devkit8000.c | 10 +++-- arch/arm/mach-omap2/board-igep0020.c | 10 +++-- arch/arm/mach-omap2/board-omap3beagle.c | 10 +++-- arch/arm/mach-omap2/board-omap3evm.c | 10 +++-- arch/arm/mach-omap2/board-omap3pandora.c | 1 + arch/arm/mach-omap2/board-omap3stalker.c | 10 +++-- arch/arm/mach-omap2/board-zoom-peripherals.c | 10 +++-- drivers/video/omap2/dss/core.c | 8 ++-- drivers/video/omap2/dss/dsi.c | 64 ++++++++++++++++++++++++++-- drivers/video/omap2/dss/dss.h | 8 ++-- 11 files changed, 107 insertions(+), 35 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 652e7c38c62..75814ae4dd0 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -401,6 +401,7 @@ static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = { /* VPLL2 for digital video outputs */ static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = { REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), }; static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = { diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index b64774b3d82..e102e143afb 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -277,8 +277,10 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = { .setup = devkit8000_twl_gpio_setup, }; -static struct regulator_consumer_supply devkit8000_vpll1_supply = - REGULATOR_SUPPLY("vdds_dsi", "omapdss"); +static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), +}; /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ static struct regulator_init_data devkit8000_vmmc1 = { @@ -319,8 +321,8 @@ static struct regulator_init_data devkit8000_vpll1 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &devkit8000_vpll1_supply, + .num_consumer_supplies = ARRAY_SIZE(devkit8000_vpll1_supplies), + .consumer_supplies = devkit8000_vpll1_supplies, }; /* VAUX4 for ads7846 and nubs */ diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index c4b3c1c47ec..12b3e41b6f7 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -485,8 +485,10 @@ static struct omap_dss_board_info igep2_dss_data = { .default_device = &igep2_dvi_device, }; -static struct regulator_consumer_supply igep2_vpll2_supply = - REGULATOR_SUPPLY("vdds_dsi", "omapdss"); +static struct regulator_consumer_supply igep2_vpll2_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), +}; static struct regulator_init_data igep2_vpll2 = { .constraints = { @@ -499,8 +501,8 @@ static struct regulator_init_data igep2_vpll2 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &igep2_vpll2_supply, + .num_consumer_supplies = ARRAY_SIZE(igep2_vpll2_supplies), + .consumer_supplies = igep2_vpll2_supplies, }; static void __init igep2_display_init(void) diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 2fad38f9e68..e663c43fe03 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -234,8 +234,10 @@ static struct omap_dss_board_info beagle_dss_data = { static struct regulator_consumer_supply beagle_vdac_supply = REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); -static struct regulator_consumer_supply beagle_vdvi_supply = - REGULATOR_SUPPLY("vdds_dsi", "omapdss"); +static struct regulator_consumer_supply beagle_vdvi_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), +}; static void __init beagle_display_init(void) { @@ -422,8 +424,8 @@ static struct regulator_init_data beagle_vpll2 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &beagle_vdvi_supply, + .num_consumer_supplies = ARRAY_SIZE(beagle_vdvi_supplies), + .consumer_supplies = beagle_vdvi_supplies, }; static struct twl4030_usb_data beagle_usb_data = { diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index a6564b41b97..5800db31e56 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -560,8 +560,10 @@ static struct regulator_init_data omap3_evm_vdac = { }; /* VPLL2 for digital video outputs */ -static struct regulator_consumer_supply omap3_evm_vpll2_supply = - REGULATOR_SUPPLY("vdds_dsi", "omapdss"); +static struct regulator_consumer_supply omap3_evm_vpll2_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), +}; static struct regulator_init_data omap3_evm_vpll2 = { .constraints = { @@ -573,8 +575,8 @@ static struct regulator_init_data omap3_evm_vpll2 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &omap3_evm_vpll2_supply, + .num_consumer_supplies = ARRAY_SIZE(omap3_evm_vpll2_supplies), + .consumer_supplies = omap3_evm_vpll2_supplies, }; /* ads7846 on SPI */ diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 37de418edd2..131a58dd3c9 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -347,6 +347,7 @@ static struct regulator_consumer_supply pandora_vdda_dac_supply = static struct regulator_consumer_supply pandora_vdds_supplies[] = { REGULATOR_SUPPLY("vdds_sdi", "omapdss"), REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), }; static struct regulator_consumer_supply pandora_vcc_lcd_supply = diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index bd0eed85807..d1163a80f84 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c @@ -457,8 +457,10 @@ static struct regulator_init_data omap3_stalker_vdac = { }; /* VPLL2 for digital video outputs */ -static struct regulator_consumer_supply omap3_stalker_vpll2_supply = - REGULATOR_SUPPLY("vdds_dsi", "omapdss"); +static struct regulator_consumer_supply omap3_stalker_vpll2_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), +}; static struct regulator_init_data omap3_stalker_vpll2 = { .constraints = { @@ -471,8 +473,8 @@ static struct regulator_init_data omap3_stalker_vpll2 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &omap3_stalker_vpll2_supply, + .num_consumer_supplies = ARRAY_SIZE(omap3_stalker_vpll2_supplies), + .consumer_supplies = omap3_stalker_vpll2_supplies, }; static struct twl4030_platform_data omap3stalker_twldata = { diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 405400c4762..8dee7549fbd 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -226,8 +226,10 @@ static struct omap2_hsmmc_info mmc[] = { {} /* Terminator */ }; -static struct regulator_consumer_supply zoom_vpll2_supply = - REGULATOR_SUPPLY("vdds_dsi", "omapdss"); +static struct regulator_consumer_supply zoom_vpll2_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), +}; static struct regulator_consumer_supply zoom_vdda_dac_supply = REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); @@ -241,8 +243,8 @@ static struct regulator_init_data zoom_vpll2 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &zoom_vpll2_supply, + .num_consumer_supplies = ARRAY_SIZE(zoom_vpll2_supplies), + .consumer_supplies = zoom_vpll2_supplies, }; static struct regulator_init_data zoom_vdac = { diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 57c6303cb1c..3f7a5fcd114 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -222,9 +222,9 @@ static int omap_dss_probe(struct platform_device *pdev) goto err_sdi; } - r = dsi_init(pdev); + r = dsi_init_platform_driver(); if (r) { - DSSERR("Failed to initialize DSI\n"); + DSSERR("Failed to initialize DSI platform driver\n"); goto err_dsi; } } @@ -259,7 +259,7 @@ err_register: dss_uninitialize_debugfs(); err_debugfs: if (cpu_is_omap34xx()) - dsi_exit(); + dsi_uninit_platform_driver(); err_dsi: if (cpu_is_omap34xx()) sdi_exit(); @@ -290,7 +290,7 @@ static int omap_dss_remove(struct platform_device *pdev) dpi_exit(); rfbi_uninit_platform_driver(); if (cpu_is_omap34xx()) { - dsi_exit(); + dsi_uninit_platform_driver(); sdi_exit(); } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index ddf3a056082..fa85f1adba2 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -222,6 +222,7 @@ struct dsi_irq_stats { static struct { + struct platform_device *pdev; void __iomem *base; struct dsi_clock_info current_cinfo; @@ -292,6 +293,20 @@ static inline u32 dsi_read_reg(const struct dsi_reg idx) return __raw_readl(dsi.base + idx.idx); } +static struct regulator *dsi_get_vdds_dsi(void) +{ + struct regulator *reg; + + if (dsi.vdds_dsi_reg != NULL) + return dsi.vdds_dsi_reg; + + reg = regulator_get(&dsi.pdev->dev, "vdds_dsi"); + if (!IS_ERR(reg)) + dsi.vdds_dsi_reg = reg; + + return reg; +} + void dsi_save_context(void) { @@ -3238,7 +3253,7 @@ void dsi_wait_dsi2_pll_active(void) DSSERR("DSI2 PLL clock not active\n"); } -int dsi_init(struct platform_device *pdev) +static int dsi_init(struct platform_device *pdev) { u32 rev; int r; @@ -3275,7 +3290,7 @@ int dsi_init(struct platform_device *pdev) goto err1; } - dsi.vdds_dsi_reg = dss_get_vdds_dsi(); + dsi.vdds_dsi_reg = dsi_get_vdds_dsi(); if (IS_ERR(dsi.vdds_dsi_reg)) { DSSERR("can't get VDDS_DSI regulator\n"); r = PTR_ERR(dsi.vdds_dsi_reg); @@ -3298,8 +3313,13 @@ err1: return r; } -void dsi_exit(void) +static void dsi_exit(void) { + if (dsi.vdds_dsi_reg != NULL) { + regulator_put(dsi.vdds_dsi_reg); + dsi.vdds_dsi_reg = NULL; + } + iounmap(dsi.base); destroy_workqueue(dsi.workqueue); @@ -3307,3 +3327,41 @@ void dsi_exit(void) DSSDBG("omap_dsi_exit\n"); } +/* DSI1 HW IP initialisation */ +static int omap_dsi1hw_probe(struct platform_device *pdev) +{ + int r; + dsi.pdev = pdev; + r = dsi_init(pdev); + if (r) { + DSSERR("Failed to initialize DSI\n"); + goto err_dsi; + } +err_dsi: + return r; +} + +static int omap_dsi1hw_remove(struct platform_device *pdev) +{ + dsi_exit(); + return 0; +} + +static struct platform_driver omap_dsi1hw_driver = { + .probe = omap_dsi1hw_probe, + .remove = omap_dsi1hw_remove, + .driver = { + .name = "omapdss_dsi1", + .owner = THIS_MODULE, + }, +}; + +int dsi_init_platform_driver(void) +{ + return platform_driver_register(&omap_dsi1hw_driver); +} + +void dsi_uninit_platform_driver(void) +{ + return platform_driver_unregister(&omap_dsi1hw_driver); +} diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 931385185dc..981d247c30f 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -261,8 +261,8 @@ static inline void sdi_exit(void) /* DSI */ #ifdef CONFIG_OMAP2_DSS_DSI -int dsi_init(struct platform_device *pdev); -void dsi_exit(void); +int dsi_init_platform_driver(void); +void dsi_uninit_platform_driver(void); void dsi_dump_clocks(struct seq_file *s); void dsi_dump_irqs(struct seq_file *s); @@ -287,11 +287,11 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, void dsi_wait_dsi1_pll_active(void); void dsi_wait_dsi2_pll_active(void); #else -static inline int dsi_init(struct platform_device *pdev) +static inline int dsi_init_platform_driver(void) { return 0; } -static inline void dsi_exit(void) +static inline void dsi_uninit_platform_driver(void) { } static inline void dsi_wait_dsi1_pll_active(void) -- cgit v1.2.3-70-g09d2 From 6af9cd1431db952a7f9f8931497c9989a48b07df Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 31 Jan 2011 16:27:44 +0000 Subject: OMAP2PLUS: DSS2: Generalize naming of PRCM related clock enums in DSS driver enum dss_clock structure is replaced with generic names that could be used across OMAP2420, 2430, 3xxx, 44xx platforms. Signed-off-by: Sumit Semwal Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 4 +-- drivers/video/omap2/dss/dispc.c | 10 +++---- drivers/video/omap2/dss/dpi.c | 16 +++++----- drivers/video/omap2/dss/dsi.c | 18 ++++++------ drivers/video/omap2/dss/dss.c | 62 +++++++++++++++++++-------------------- drivers/video/omap2/dss/dss.h | 10 +++---- drivers/video/omap2/dss/manager.c | 4 +-- drivers/video/omap2/dss/overlay.c | 4 +-- drivers/video/omap2/dss/rfbi.c | 10 +++---- drivers/video/omap2/dss/sdi.c | 8 ++--- drivers/video/omap2/dss/venc.c | 8 ++--- 11 files changed, 77 insertions(+), 77 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 3f7a5fcd114..f56ee64f5b5 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -184,7 +184,7 @@ static int omap_dss_probe(struct platform_device *pdev) } /* keep clocks enabled to prevent context saves/restores during init */ - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); r = rfbi_init_platform_driver(); if (r) { @@ -251,7 +251,7 @@ static int omap_dss_probe(struct platform_device *pdev) pdata->default_device = dssdev; } - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); return 0; diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 96e37f8e75d..dc4518c4b0e 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -551,9 +551,9 @@ void dispc_restore_context(void) static inline void enable_clocks(bool enable) { if (enable) - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); else - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); } bool dispc_go_busy(enum omap_channel channel) @@ -2311,7 +2311,7 @@ unsigned long dispc_fclk_rate(void) unsigned long r = 0; if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) - r = dss_clk_get_rate(DSS_CLK_FCK1); + r = dss_clk_get_rate(DSS_CLK_FCK); else #ifdef CONFIG_OMAP2_DSS_DSI r = dsi_get_dsi1_pll_rate(); @@ -2439,7 +2439,7 @@ void dispc_dump_regs(struct seq_file *s) { #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); DUMPREG(DISPC_REVISION); DUMPREG(DISPC_SYSCONFIG); @@ -2596,7 +2596,7 @@ void dispc_dump_regs(struct seq_file *s) DUMPREG(DISPC_VID_PRELOAD(0)); DUMPREG(DISPC_VID_PRELOAD(1)); - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); #undef DUMPREG } diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 75fb0a51543..746f1b6dd89 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -107,7 +107,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev) bool is_tft; int r = 0; - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, dssdev->panel.acbi, dssdev->panel.acb); @@ -137,7 +137,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev) dispc_set_lcd_timings(dssdev->manager->id, t); err0: - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); return r; } @@ -173,14 +173,14 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) goto err1; } - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); r = dpi_basic_init(dssdev); if (r) goto err2; #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL - dss_clk_enable(DSS_CLK_FCK2); + dss_clk_enable(DSS_CLK_SYSCK); r = dsi_pll_init(dssdev, 0, 1); if (r) goto err3; @@ -199,10 +199,10 @@ err4: #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL dsi_pll_uninit(); err3: - dss_clk_disable(DSS_CLK_FCK2); + dss_clk_disable(DSS_CLK_SYSCK); #endif err2: - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); if (cpu_is_omap34xx()) regulator_disable(dpi.vdds_dsi_reg); err1: @@ -219,10 +219,10 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); dsi_pll_uninit(); - dss_clk_disable(DSS_CLK_FCK2); + dss_clk_disable(DSS_CLK_SYSCK); #endif - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); if (cpu_is_omap34xx()) regulator_disable(dpi.vdds_dsi_reg); diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index c42acae10af..c7b5382e1a6 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -654,18 +654,18 @@ static void dsi_vc_disable_bta_irq(int channel) static inline void enable_clocks(bool enable) { if (enable) - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); else - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); } /* source clock for DSI PLL. this could also be PCLKFREE */ static inline void dsi_enable_pll_clock(bool enable) { if (enable) - dss_clk_enable(DSS_CLK_FCK2); + dss_clk_enable(DSS_CLK_SYSCK); else - dss_clk_disable(DSS_CLK_FCK2); + dss_clk_disable(DSS_CLK_SYSCK); if (enable && dsi.pll_locked) { if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) @@ -741,7 +741,7 @@ static unsigned long dsi_fclk_rate(void) if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) { /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ - r = dss_clk_get_rate(DSS_CLK_FCK1); + r = dss_clk_get_rate(DSS_CLK_FCK); } else { /* DSI FCLK source is DSI2_PLL_FCLK */ r = dsi_get_dsi2_pll_rate(); @@ -821,7 +821,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, return -EINVAL; if (cinfo->use_dss2_fck) { - cinfo->clkin = dss_clk_get_rate(DSS_CLK_FCK2); + cinfo->clkin = dss_clk_get_rate(DSS_CLK_SYSCK); /* XXX it is unclear if highfreq should be used * with DSS2_FCK source also */ cinfo->highfreq = 0; @@ -867,7 +867,7 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, int match = 0; unsigned long dss_clk_fck2; - dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_FCK2); + dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_SYSCK); if (req_pck == dsi.cache_req_pck && dsi.cache_cinfo.clkin == dss_clk_fck2) { @@ -1319,7 +1319,7 @@ void dsi_dump_regs(struct seq_file *s) { #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); DUMPREG(DSI_REVISION); DUMPREG(DSI_SYSCONFIG); @@ -1391,7 +1391,7 @@ void dsi_dump_regs(struct seq_file *s) DUMPREG(DSI_PLL_CONFIGURATION1); DUMPREG(DSI_PLL_CONFIGURATION2); - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); #undef DUMPREG } diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 56d37bfefd4..0372befbb69 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -227,7 +227,7 @@ void dss_dump_clocks(struct seq_file *s) unsigned long dpll4_ck_rate; unsigned long dpll4_m4_ck_rate; - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck); @@ -240,21 +240,21 @@ void dss_dump_clocks(struct seq_file *s) seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n", dpll4_ck_rate, dpll4_ck_rate / dpll4_m4_ck_rate, - dss_clk_get_rate(DSS_CLK_FCK1)); + dss_clk_get_rate(DSS_CLK_FCK)); else seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n", dpll4_ck_rate, dpll4_ck_rate / dpll4_m4_ck_rate, - dss_clk_get_rate(DSS_CLK_FCK1)); + dss_clk_get_rate(DSS_CLK_FCK)); - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); } void dss_dump_regs(struct seq_file *s) { #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); DUMPREG(DSS_REVISION); DUMPREG(DSS_SYSCONFIG); @@ -265,7 +265,7 @@ void dss_dump_regs(struct seq_file *s) DUMPREG(DSS_PLL_CONTROL); DUMPREG(DSS_SDI_STATUS); - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); #undef DUMPREG } @@ -350,7 +350,7 @@ int dss_set_clock_div(struct dss_clock_info *cinfo) int dss_get_clock_div(struct dss_clock_info *cinfo) { - cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK1); + cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK); if (cpu_is_omap34xx()) { unsigned long prate; @@ -391,7 +391,7 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck, prate = dss_get_dpll4_rate(); - fck = dss_clk_get_rate(DSS_CLK_FCK1); + fck = dss_clk_get_rate(DSS_CLK_FCK); if (req_pck == dss.cache_req_pck && ((cpu_is_omap34xx() && prate == dss.cache_prate) || dss.cache_dss_cinfo.fck == fck)) { @@ -418,7 +418,7 @@ retry: if (cpu_is_omap24xx()) { struct dispc_clock_info cur_dispc; /* XXX can we change the clock on omap2? */ - fck = dss_clk_get_rate(DSS_CLK_FCK1); + fck = dss_clk_get_rate(DSS_CLK_FCK); fck_div = 1; dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); @@ -701,7 +701,7 @@ static void save_all_ctx(void) { DSSDBG("save context\n"); - dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK); dss_save_context(); dispc_save_context(); @@ -709,7 +709,7 @@ static void save_all_ctx(void) dsi_save_context(); #endif - dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK); } static void restore_all_ctx(void) @@ -807,13 +807,13 @@ unsigned long dss_clk_get_rate(enum dss_clock clk) switch (clk) { case DSS_CLK_ICK: return clk_get_rate(dss.dss_ick); - case DSS_CLK_FCK1: + case DSS_CLK_FCK: return clk_get_rate(dss.dss1_fck); - case DSS_CLK_FCK2: + case DSS_CLK_SYSCK: return clk_get_rate(dss.dss2_fck); - case DSS_CLK_54M: + case DSS_CLK_TVFCK: return clk_get_rate(dss.dss_54m_fck); - case DSS_CLK_96M: + case DSS_CLK_VIDFCK: return clk_get_rate(dss.dss_96m_fck); } @@ -827,13 +827,13 @@ static unsigned count_clk_bits(enum dss_clock clks) if (clks & DSS_CLK_ICK) ++num_clks; - if (clks & DSS_CLK_FCK1) + if (clks & DSS_CLK_FCK) ++num_clks; - if (clks & DSS_CLK_FCK2) + if (clks & DSS_CLK_SYSCK) ++num_clks; - if (clks & DSS_CLK_54M) + if (clks & DSS_CLK_TVFCK) ++num_clks; - if (clks & DSS_CLK_96M) + if (clks & DSS_CLK_VIDFCK) ++num_clks; return num_clks; @@ -845,13 +845,13 @@ static void dss_clk_enable_no_ctx(enum dss_clock clks) if (clks & DSS_CLK_ICK) clk_enable(dss.dss_ick); - if (clks & DSS_CLK_FCK1) + if (clks & DSS_CLK_FCK) clk_enable(dss.dss1_fck); - if (clks & DSS_CLK_FCK2) + if (clks & DSS_CLK_SYSCK) clk_enable(dss.dss2_fck); - if (clks & DSS_CLK_54M) + if (clks & DSS_CLK_TVFCK) clk_enable(dss.dss_54m_fck); - if (clks & DSS_CLK_96M) + if (clks & DSS_CLK_VIDFCK) clk_enable(dss.dss_96m_fck); dss.num_clks_enabled += num_clks; @@ -873,13 +873,13 @@ static void dss_clk_disable_no_ctx(enum dss_clock clks) if (clks & DSS_CLK_ICK) clk_disable(dss.dss_ick); - if (clks & DSS_CLK_FCK1) + if (clks & DSS_CLK_FCK) clk_disable(dss.dss1_fck); - if (clks & DSS_CLK_FCK2) + if (clks & DSS_CLK_SYSCK) clk_disable(dss.dss2_fck); - if (clks & DSS_CLK_54M) + if (clks & DSS_CLK_TVFCK) clk_disable(dss.dss_54m_fck); - if (clks & DSS_CLK_96M) + if (clks & DSS_CLK_VIDFCK) clk_disable(dss.dss_96m_fck); dss.num_clks_enabled -= num_clks; @@ -903,9 +903,9 @@ static void dss_clk_enable_all_no_ctx(void) { enum dss_clock clks; - clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; + clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK; if (cpu_is_omap34xx()) - clks |= DSS_CLK_96M; + clks |= DSS_CLK_VIDFCK; dss_clk_enable_no_ctx(clks); } @@ -913,9 +913,9 @@ static void dss_clk_disable_all_no_ctx(void) { enum dss_clock clks; - clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; + clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK; if (cpu_is_omap34xx()) - clks |= DSS_CLK_96M; + clks |= DSS_CLK_VIDFCK; dss_clk_disable_no_ctx(clks); } diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 981d247c30f..4b02e079f20 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -112,11 +112,11 @@ enum omap_parallel_interface_mode { }; enum dss_clock { - DSS_CLK_ICK = 1 << 0, - DSS_CLK_FCK1 = 1 << 1, - DSS_CLK_FCK2 = 1 << 2, - DSS_CLK_54M = 1 << 3, - DSS_CLK_96M = 1 << 4, + DSS_CLK_ICK = 1 << 0, /* DSS_L3_ICLK and DSS_L4_ICLK */ + DSS_CLK_FCK = 1 << 1, /* DSS1_ALWON_FCLK */ + DSS_CLK_SYSCK = 1 << 2, /* DSS2_ALWON_FCLK */ + DSS_CLK_TVFCK = 1 << 3, /* DSS_TV_FCLK */ + DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/ }; enum dss_clk_source { diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 172d4e69730..1f53bf20b6c 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -1394,7 +1394,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) } r = 0; - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); if (!dss_cache.irq_enabled) { u32 mask; @@ -1407,7 +1407,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) dss_cache.irq_enabled = true; } configure_dispc(); - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); spin_unlock_irqrestore(&dss_cache.lock, flags); diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index 456efef03c2..996e9a4f677 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -490,7 +490,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl, ovl->manager = mgr; - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); /* XXX: on manual update display, in auto update mode, a bug happens * here. When an overlay is first enabled on LCD, then it's disabled, * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT @@ -499,7 +499,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl, * but I don't understand how or why. */ msleep(40); dispc_set_channel_out(ovl->id, mgr->id); - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); return 0; } diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 6dbb95d557f..5ea17f49c61 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -141,9 +141,9 @@ static inline u32 rfbi_read_reg(const struct rfbi_reg idx) static void rfbi_enable_clocks(bool enable) { if (enable) - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); else - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); } void omap_rfbi_write_command(const void *buf, u32 len) @@ -496,7 +496,7 @@ unsigned long rfbi_get_max_tx_rate(void) }; l4_rate = rfbi.l4_khz / 1000; - dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000; + dss1_rate = dss_clk_get_rate(DSS_CLK_FCK) / 1000000; for (i = 0; i < ARRAY_SIZE(ftab); i++) { /* Use a window instead of an exact match, to account @@ -921,7 +921,7 @@ void rfbi_dump_regs(struct seq_file *s) { #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); DUMPREG(RFBI_REVISION); DUMPREG(RFBI_SYSCONFIG); @@ -952,7 +952,7 @@ void rfbi_dump_regs(struct seq_file *s) DUMPREG(RFBI_VSYNC_WIDTH); DUMPREG(RFBI_HSYNC_WIDTH); - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); #undef DUMPREG } diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index b64adf7dfc8..8272fc1f327 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -70,7 +70,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) /* In case of skip_init sdi_init has already enabled the clocks */ if (!sdi.skip_init) - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); sdi_basic_init(dssdev); @@ -130,7 +130,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) return 0; err2: - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); regulator_disable(sdi.vdds_sdi_reg); err1: omap_dss_stop_device(dssdev); @@ -145,7 +145,7 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) dss_sdi_disable(); - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); regulator_disable(sdi.vdds_sdi_reg); @@ -175,7 +175,7 @@ int sdi_init(bool skip_init) * of them until sdi_display_enable is called. */ if (skip_init) - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); return 0; } diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index ef36811f6ac..1aadceb76e1 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -391,11 +391,11 @@ static void venc_reset(void) static void venc_enable_clocks(int enable) { if (enable) - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | - DSS_CLK_96M); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK | + DSS_CLK_VIDFCK); else - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | - DSS_CLK_96M); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK | + DSS_CLK_VIDFCK); } static const struct venc_config *venc_timings_to_config( -- cgit v1.2.3-70-g09d2 From 819d807c59af10cce1dcbb13539c2fb100953fcd Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Tue, 1 Mar 2011 11:54:00 +0530 Subject: OMAP2PLUS: DSS2: FEATURES: Function to Provide the max fck supported The maximum supported frequency for DSS has increased from 173 to 186 Mhz on OMAP4. Introduce a dss feature function to get the max_fck to replace DISPC_MAX_FCK macro. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 9 ++++++--- drivers/video/omap2/dss/dss.c | 8 +++++--- drivers/video/omap2/dss/dss.h | 2 -- drivers/video/omap2/dss/dss_features.c | 11 +++++++++++ drivers/video/omap2/dss/dss_features.h | 1 + 5 files changed, 23 insertions(+), 8 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index c3019d95618..705599ad316 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -38,6 +38,7 @@ #include #include "dss.h" +#include "dss_features.h" /*#define VERBOSE_IRQ*/ #define DSI_CATCH_MISSING_TE @@ -856,10 +857,12 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, struct dispc_clock_info best_dispc; int min_fck_per_pck; int match = 0; - unsigned long dss_clk_fck2; + unsigned long dss_clk_fck2, max_dss_fck; dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_SYSCK); + max_dss_fck = dss_feat_get_max_dss_fck(); + if (req_pck == dsi.cache_req_pck && dsi.cache_cinfo.clkin == dss_clk_fck2) { DSSDBG("DSI clock info found from cache\n"); @@ -872,7 +875,7 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; if (min_fck_per_pck && - req_pck * min_fck_per_pck > DISPC_MAX_FCK) { + req_pck * min_fck_per_pck > max_dss_fck) { DSSERR("Requested pixel clock not possible with the current " "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " "the constraint off.\n"); @@ -925,7 +928,7 @@ retry: if (cur.dsi1_pll_fclk < req_pck) break; - if (cur.dsi1_pll_fclk > DISPC_MAX_FCK) + if (cur.dsi1_pll_fclk > max_dss_fck) continue; if (min_fck_per_pck && diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 0cf5f8bd1c8..01be82a4f42 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -387,7 +387,7 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck, struct dss_clock_info best_dss; struct dispc_clock_info best_dispc; - unsigned long fck; + unsigned long fck, max_dss_fck; u16 fck_div; @@ -396,6 +396,8 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck, prate = dss_get_dpll4_rate(); + max_dss_fck = dss_feat_get_max_dss_fck(); + fck = dss_clk_get_rate(DSS_CLK_FCK); if (req_pck == dss.cache_req_pck && ((cpu_is_omap34xx() && prate == dss.cache_prate) || @@ -409,7 +411,7 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck, min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; if (min_fck_per_pck && - req_pck * min_fck_per_pck > DISPC_MAX_FCK) { + req_pck * min_fck_per_pck > max_dss_fck) { DSSERR("Requested pixel clock not possible with the current " "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " "the constraint off.\n"); @@ -445,7 +447,7 @@ retry: else fck = prate / fck_div * 2; - if (fck > DISPC_MAX_FCK) + if (fck > max_dss_fck) continue; if (min_fck_per_pck && diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 4b02e079f20..7fe32d1647f 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -97,8 +97,6 @@ extern unsigned int dss_debug; #define FLD_MOD(orig, val, start, end) \ (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) -#define DISPC_MAX_FCK 173000000 - enum omap_burst_size { OMAP_DSS_BURST_4x32 = 0, OMAP_DSS_BURST_8x32 = 1, diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 679be14b73a..3ebe0d91afd 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -41,6 +41,7 @@ struct omap_dss_features { const int num_mgrs; const int num_ovls; + const unsigned long max_dss_fck; const enum omap_display_type *supported_displays; const enum omap_color_mode *supported_color_modes; }; @@ -168,6 +169,7 @@ static struct omap_dss_features omap2_dss_features = { .num_mgrs = 2, .num_ovls = 3, + .max_dss_fck = 173000000, .supported_displays = omap2_dss_supported_displays, .supported_color_modes = omap2_dss_supported_color_modes, }; @@ -185,6 +187,7 @@ static struct omap_dss_features omap3430_dss_features = { .num_mgrs = 2, .num_ovls = 3, + .max_dss_fck = 173000000, .supported_displays = omap3430_dss_supported_displays, .supported_color_modes = omap3_dss_supported_color_modes, }; @@ -202,6 +205,7 @@ static struct omap_dss_features omap3630_dss_features = { .num_mgrs = 2, .num_ovls = 3, + .max_dss_fck = 173000000, .supported_displays = omap3630_dss_supported_displays, .supported_color_modes = omap3_dss_supported_color_modes, }; @@ -217,6 +221,7 @@ static struct omap_dss_features omap4_dss_features = { .num_mgrs = 3, .num_ovls = 3, + .max_dss_fck = 186000000, .supported_displays = omap4_dss_supported_displays, .supported_color_modes = omap3_dss_supported_color_modes, }; @@ -232,6 +237,12 @@ int dss_feat_get_num_ovls(void) return omap_current_dss_features->num_ovls; } +/* Max supported DSS FCK in Hz */ +unsigned long dss_feat_get_max_dss_fck(void) +{ + return omap_current_dss_features->max_dss_fck; +} + enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel) { return omap_current_dss_features->supported_displays[channel]; diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index b3f81415507..18ab1951581 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -52,6 +52,7 @@ enum dss_feat_reg_field { /* DSS Feature Functions */ int dss_feat_get_num_mgrs(void); int dss_feat_get_num_ovls(void); +unsigned long dss_feat_get_max_dss_fck(void); enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); bool dss_feat_color_mode_supported(enum omap_plane plane, -- cgit v1.2.3-70-g09d2 From 88134fa138b90518819b750891ffecc13f5f4886 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Thu, 6 Jan 2011 10:44:10 +0530 Subject: OMAP2PLUS: DSS2: Make members of dss_clk_source generic The enum members of 'dss_clk_source' have clock source names specific to OMAP2/3. Change the names to more generic terms such that they now describe where the clocks come from and what they are used for. Also, change the enum member names to have "DSS_CLK_SRC" instead of "DSS_SRC" for more clarity. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 4 ++-- drivers/video/omap2/dss/dpi.c | 4 ++-- drivers/video/omap2/dss/dsi.c | 20 ++++++++++---------- drivers/video/omap2/dss/dss.c | 20 ++++++++++---------- drivers/video/omap2/dss/dss.h | 6 +++--- 5 files changed, 27 insertions(+), 27 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index aa6479712d4..a06b2ea41e9 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2334,7 +2334,7 @@ unsigned long dispc_fclk_rate(void) { unsigned long r = 0; - if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) + if (dss_get_dispc_clk_source() == DSS_CLK_SRC_FCK) r = dss_clk_get_rate(DSS_CLK_FCK); else #ifdef CONFIG_OMAP2_DSS_DSI @@ -2385,7 +2385,7 @@ void dispc_dump_clocks(struct seq_file *s) seq_printf(s, "- DISPC -\n"); seq_printf(s, "dispc fclk source = %s\n", - dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? + dss_get_dispc_clk_source() == DSS_CLK_SRC_FCK ? "dss1_alwon_fclk" : "dsi1_pll_fclk"); seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 026702b921e..1b2867dfeeb 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -57,7 +57,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft, if (r) return r; - dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); + dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC); r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); if (r) @@ -217,7 +217,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) dssdev->manager->disable(dssdev->manager); #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL - dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); + dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); dsi_pll_uninit(); dss_clk_disable(DSS_CLK_SYSCK); #endif diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 705599ad316..df35aed828d 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -731,7 +731,7 @@ static unsigned long dsi_fclk_rate(void) { unsigned long r; - if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) { + if (dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK) { /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ r = dss_clk_get_rate(DSS_CLK_FCK); } else { @@ -1188,19 +1188,19 @@ void dsi_dump_clocks(struct seq_file *s) seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n", cinfo->dsi1_pll_fclk, cinfo->regm3, - dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? + dss_get_dispc_clk_source() == DSS_CLK_SRC_FCK ? "off" : "on"); seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n", cinfo->dsi2_pll_fclk, cinfo->regm4, - dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? + dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK ? "off" : "on"); seq_printf(s, "- DSI -\n"); seq_printf(s, "dsi fclk source = %s\n", - dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? + dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK ? "dss1_alwon_fclk" : "dsi2_pll_fclk"); seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); @@ -3038,8 +3038,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) if (r) goto err1; - dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); - dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK); + dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC); + dss_select_dsi_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI); DSSDBG("PLL OK\n"); @@ -3075,8 +3075,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) err3: dsi_complexio_uninit(); err2: - dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); - dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); + dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); + dss_select_dsi_clk_source(DSS_CLK_SRC_FCK); err1: dsi_pll_uninit(); err0: @@ -3092,8 +3092,8 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) dsi_vc_enable(2, 0); dsi_vc_enable(3, 0); - dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); - dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); + dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); + dss_select_dsi_clk_source(DSS_CLK_SRC_FCK); dsi_complexio_uninit(); dsi_pll_uninit(); } diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 01be82a4f42..998c188c882 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -278,12 +278,12 @@ void dss_select_dispc_clk_source(enum dss_clk_source clk_src) { int b; - BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK && - clk_src != DSS_SRC_DSS1_ALWON_FCLK); + BUG_ON(clk_src != DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC && + clk_src != DSS_CLK_SRC_FCK); - b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; + b = clk_src == DSS_CLK_SRC_FCK ? 0 : 1; - if (clk_src == DSS_SRC_DSI1_PLL_FCLK) + if (clk_src == DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC) dsi_wait_dsi1_pll_active(); REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ @@ -295,12 +295,12 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src) { int b; - BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK && - clk_src != DSS_SRC_DSS1_ALWON_FCLK); + BUG_ON(clk_src != DSS_CLK_SRC_DSI_PLL_HSDIV_DSI && + clk_src != DSS_CLK_SRC_FCK); - b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; + b = clk_src == DSS_CLK_SRC_FCK ? 0 : 1; - if (clk_src == DSS_SRC_DSI2_PLL_FCLK) + if (clk_src == DSS_CLK_SRC_DSI_PLL_HSDIV_DSI) dsi_wait_dsi2_pll_active(); REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ @@ -601,8 +601,8 @@ static int dss_init(bool skip_init) } } - dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK; - dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK; + dss.dsi_clk_source = DSS_CLK_SRC_FCK; + dss.dispc_clk_source = DSS_CLK_SRC_FCK; dss_save_context(); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 7fe32d1647f..a166ff36ec9 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -118,9 +118,9 @@ enum dss_clock { }; enum dss_clk_source { - DSS_SRC_DSI1_PLL_FCLK, - DSS_SRC_DSI2_PLL_FCLK, - DSS_SRC_DSS1_ALWON_FCLK, + DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* DSI1_PLL_FCLK */ + DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* DSI2_PLL_FCLK */ + DSS_CLK_SRC_FCK, /* DSS1_ALWON_FCLK */ }; struct dss_clock_info { -- cgit v1.2.3-70-g09d2 From 067a57e48e302863eb2d5ac0900ae9ae65dbc8c3 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 2 Mar 2011 11:57:25 +0530 Subject: OMAP2PLUS: DSS2: Use dss features to get clock source names of current OMAP Clock source names vary across OMAP2/3 and OMAP4, the clock source enum names have been made generic in the driver, but for purposes of debugging and dumping clock sources, it is better to preserve the actual TRM name of the clock. Introduce a dss feature function 'dss_feat_get_clk_source_name()' which returns a string with the TRM clock name for the current OMAP in use. The OMAP specific name is printed along the generic name within brackets. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 7 +++--- drivers/video/omap2/dss/dsi.c | 42 +++++++++++++++++++++++----------- drivers/video/omap2/dss/dss.c | 19 +++++++++++++-- drivers/video/omap2/dss/dss.h | 7 ++++++ drivers/video/omap2/dss/dss_features.c | 23 +++++++++++++++++++ drivers/video/omap2/dss/dss_features.h | 1 + 6 files changed, 81 insertions(+), 18 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index a06b2ea41e9..2c82d9a3df4 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2379,14 +2379,15 @@ unsigned long dispc_pclk_rate(enum omap_channel channel) void dispc_dump_clocks(struct seq_file *s) { int lcd, pcd; + enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); enable_clocks(1); seq_printf(s, "- DISPC -\n"); - seq_printf(s, "dispc fclk source = %s\n", - dss_get_dispc_clk_source() == DSS_CLK_SRC_FCK ? - "dss1_alwon_fclk" : "dsi1_pll_fclk"); + seq_printf(s, "dispc fclk source = %s (%s)\n", + dss_get_generic_clk_source_name(dispc_clk_src), + dss_feat_get_clk_source_name(dispc_clk_src)); seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index df35aed828d..3ef94227bbe 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1022,10 +1022,14 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4); - DSSDBG("regm3 = %d, dsi1_pll_fclk = %lu\n", - cinfo->regm3, cinfo->dsi1_pll_fclk); - DSSDBG("regm4 = %d, dsi2_pll_fclk = %lu\n", - cinfo->regm4, cinfo->dsi2_pll_fclk); + DSSDBG("regm3 = %d, %s (%s) = %lu\n", cinfo->regm3, + dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), + dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), + cinfo->dsi1_pll_fclk); + DSSDBG("regm4 = %d, %s (%s) = %lu\n", cinfo->regm4, + dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), + dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), + cinfo->dsi2_pll_fclk); REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ @@ -1169,6 +1173,10 @@ void dsi_dump_clocks(struct seq_file *s) { int clksel; struct dsi_clock_info *cinfo = &dsi.current_cinfo; + enum dss_clk_source dispc_clk_src, dsi_clk_src; + + dispc_clk_src = dss_get_dispc_clk_source(); + dsi_clk_src = dss_get_dsi_clk_source(); enable_clocks(1); @@ -1185,23 +1193,27 @@ void dsi_dump_clocks(struct seq_file *s) seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n", cinfo->clkin4ddr, cinfo->regm); - seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n", + seq_printf(s, "%s (%s)\t%-16luregm3 %u\t(%s)\n", + dss_get_generic_clk_source_name(dispc_clk_src), + dss_feat_get_clk_source_name(dispc_clk_src), cinfo->dsi1_pll_fclk, cinfo->regm3, - dss_get_dispc_clk_source() == DSS_CLK_SRC_FCK ? + dispc_clk_src == DSS_CLK_SRC_FCK ? "off" : "on"); - seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n", + seq_printf(s, "%s (%s)\t%-16luregm4 %u\t(%s)\n", + dss_get_generic_clk_source_name(dsi_clk_src), + dss_feat_get_clk_source_name(dsi_clk_src), cinfo->dsi2_pll_fclk, cinfo->regm4, - dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK ? + dsi_clk_src == DSS_CLK_SRC_FCK ? "off" : "on"); seq_printf(s, "- DSI -\n"); - seq_printf(s, "dsi fclk source = %s\n", - dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK ? - "dss1_alwon_fclk" : "dsi2_pll_fclk"); + seq_printf(s, "dsi fclk source = %s (%s)\n", + dss_get_generic_clk_source_name(dsi_clk_src), + dss_feat_get_clk_source_name(dsi_clk_src)); seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); @@ -3235,13 +3247,17 @@ int dsi_init_display(struct omap_dss_device *dssdev) void dsi_wait_dsi1_pll_active(void) { if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1) - DSSERR("DSI1 PLL clock not active\n"); + DSSERR("%s (%s) not active\n", + dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), + dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC)); } void dsi_wait_dsi2_pll_active(void) { if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1) - DSSERR("DSI2 PLL clock not active\n"); + DSSERR("%s (%s) not active\n", + dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), + dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI)); } static int dsi_init(struct platform_device *pdev) diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 998c188c882..d049598bb41 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -81,6 +81,12 @@ static struct { u32 ctx[DSS_SZ_REGS / sizeof(u32)]; } dss; +static const struct dss_clk_source_name dss_generic_clk_source_names[] = { + { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "DSI_PLL_HSDIV_DISPC" }, + { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "DSI_PLL_HSDIV_DSI" }, + { DSS_CLK_SRC_FCK, "DSS_FCK" }, +}; + static void dss_clk_enable_all_no_ctx(void); static void dss_clk_disable_all_no_ctx(void); static void dss_clk_enable_no_ctx(enum dss_clock clks); @@ -223,6 +229,11 @@ void dss_sdi_disable(void) REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ } +const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src) +{ + return dss_generic_clk_source_names[clk_src].clksrc_name; +} + void dss_dump_clocks(struct seq_file *s) { unsigned long dpll4_ck_rate; @@ -238,12 +249,16 @@ void dss_dump_clocks(struct seq_file *s) seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); if (cpu_is_omap3630()) - seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n", + seq_printf(s, "%s (%s) = %lu / %lu = %lu\n", + dss_get_generic_clk_source_name(DSS_CLK_SRC_FCK), + dss_feat_get_clk_source_name(DSS_CLK_SRC_FCK), dpll4_ck_rate, dpll4_ck_rate / dpll4_m4_ck_rate, dss_clk_get_rate(DSS_CLK_FCK)); else - seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n", + seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n", + dss_get_generic_clk_source_name(DSS_CLK_SRC_FCK), + dss_feat_get_clk_source_name(DSS_CLK_SRC_FCK), dpll4_ck_rate, dpll4_ck_rate / dpll4_m4_ck_rate, dss_clk_get_rate(DSS_CLK_FCK)); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index a166ff36ec9..42ca70f2bfd 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -123,6 +123,12 @@ enum dss_clk_source { DSS_CLK_SRC_FCK, /* DSS1_ALWON_FCLK */ }; +/* Correlates clock source name and dss_clk_source member */ +struct dss_clk_source_name { + enum dss_clk_source clksrc; + const char *clksrc_name; +}; + struct dss_clock_info { /* rates that we get with dividers below */ unsigned long fck; @@ -215,6 +221,7 @@ void dss_clk_enable(enum dss_clock clks); void dss_clk_disable(enum dss_clock clks); unsigned long dss_clk_get_rate(enum dss_clock clk); int dss_need_ctx_restore(void); +const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src); void dss_dump_clocks(struct seq_file *s); void dss_dump_regs(struct seq_file *s); diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 3ebe0d91afd..ccae57b34f5 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -25,6 +25,7 @@ #include #include +#include "dss.h" #include "dss_features.h" /* Defines a generic omap register field */ @@ -44,6 +45,7 @@ struct omap_dss_features { const unsigned long max_dss_fck; const enum omap_display_type *supported_displays; const enum omap_color_mode *supported_color_modes; + const struct dss_clk_source_name *clksrc_names; }; /* This struct is assigned to one of the below during initialization */ @@ -157,6 +159,18 @@ static const enum omap_color_mode omap3_dss_supported_color_modes[] = { OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32, }; +static const struct dss_clk_source_name omap2_dss_clk_source_names[] = { + { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "N/A" }, + { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "N/A" }, + { DSS_CLK_SRC_FCK, "DSS_FCLK1" }, +}; + +static const struct dss_clk_source_name omap3_dss_clk_source_names[] = { + { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "DSI1_PLL_FCLK" }, + { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "DSI2_PLL_FCLK" }, + { DSS_CLK_SRC_FCK, "DSS1_ALWON_FCLK" }, +}; + /* OMAP2 DSS Features */ static struct omap_dss_features omap2_dss_features = { .reg_fields = omap2_dss_reg_fields, @@ -172,6 +186,7 @@ static struct omap_dss_features omap2_dss_features = { .max_dss_fck = 173000000, .supported_displays = omap2_dss_supported_displays, .supported_color_modes = omap2_dss_supported_color_modes, + .clksrc_names = omap2_dss_clk_source_names, }; /* OMAP3 DSS Features */ @@ -190,6 +205,7 @@ static struct omap_dss_features omap3430_dss_features = { .max_dss_fck = 173000000, .supported_displays = omap3430_dss_supported_displays, .supported_color_modes = omap3_dss_supported_color_modes, + .clksrc_names = omap3_dss_clk_source_names, }; static struct omap_dss_features omap3630_dss_features = { @@ -208,6 +224,7 @@ static struct omap_dss_features omap3630_dss_features = { .max_dss_fck = 173000000, .supported_displays = omap3630_dss_supported_displays, .supported_color_modes = omap3_dss_supported_color_modes, + .clksrc_names = omap3_dss_clk_source_names, }; /* OMAP4 DSS Features */ @@ -224,6 +241,7 @@ static struct omap_dss_features omap4_dss_features = { .max_dss_fck = 186000000, .supported_displays = omap4_dss_supported_displays, .supported_color_modes = omap3_dss_supported_color_modes, + .clksrc_names = omap3_dss_clk_source_names, }; /* Functions returning values related to a DSS feature */ @@ -260,6 +278,11 @@ bool dss_feat_color_mode_supported(enum omap_plane plane, color_mode; } +const char *dss_feat_get_clk_source_name(enum dss_clk_source id) +{ + return omap_current_dss_features->clksrc_names[id].clksrc_name; +} + /* DSS has_feature check */ bool dss_has_feature(enum dss_feat_id id) { diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index 18ab1951581..65d6de7e0fe 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -57,6 +57,7 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); bool dss_feat_color_mode_supported(enum omap_plane plane, enum omap_color_mode color_mode); +const char *dss_feat_get_clk_source_name(enum dss_clk_source id); bool dss_has_feature(enum dss_feat_id id); void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); -- cgit v1.2.3-70-g09d2 From 1bb478350670fadf708d3cbd6137c32dfbe3fd5f Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Thu, 24 Feb 2011 14:17:30 +0530 Subject: OMAP2PLUS: DSS2: DSI: Generalize DSI PLL Clock Naming DSI PLL output clock names have been made more generic. The clock name describes what the source of the clock and what clock is used for. Some of DSI PLL parameters like dividers and DSI PLL source have also been made more generic. dsi1_pll_fclk and dsi2_pll_fclk have been changed as dsi_pll_hsdiv_dispc_clk and dsi_pll_hsdiv_dsi_clk respectively. Also, the hsdividers are now named regm_dispc and regm_dsi instead of regm3 and regm4. Functions and macros named on the basis of these clock names have also been made generic. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- arch/arm/plat-omap/include/plat/display.h | 4 +- drivers/video/omap2/dss/dispc.c | 2 +- drivers/video/omap2/dss/dpi.c | 4 +- drivers/video/omap2/dss/dsi.c | 134 ++++++++++++++++-------------- drivers/video/omap2/dss/dss.c | 4 +- drivers/video/omap2/dss/dss.h | 20 ++--- 6 files changed, 87 insertions(+), 81 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h index 4101bcd2133..37658249e48 100644 --- a/arch/arm/plat-omap/include/plat/display.h +++ b/arch/arm/plat-omap/include/plat/display.h @@ -403,8 +403,8 @@ struct omap_dss_device { struct { u16 regn; u16 regm; - u16 regm3; - u16 regm4; + u16 regm_dispc; + u16 regm_dsi; u16 lp_clk_div; diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 2c82d9a3df4..9fb11c17623 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2338,7 +2338,7 @@ unsigned long dispc_fclk_rate(void) r = dss_clk_get_rate(DSS_CLK_FCK); else #ifdef CONFIG_OMAP2_DSS_DSI - r = dsi_get_dsi1_pll_rate(); + r = dsi_get_pll_hsdiv_dispc_rate(); #else BUG(); #endif diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 1b2867dfeeb..08fed3080c0 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -63,7 +63,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft, if (r) return r; - *fck = dsi_cinfo.dsi1_pll_fclk; + *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; *lck_div = dispc_cinfo.lck_div; *pck_div = dispc_cinfo.pck_div; @@ -271,7 +271,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev, if (r) return r; - fck = dsi_cinfo.dsi1_pll_fclk; + fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; lck_div = dispc_cinfo.lck_div; pck_div = dispc_cinfo.pck_div; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 3ef94227bbe..37ffbb6ecf6 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -189,8 +189,8 @@ struct dsi_reg { u16 idx; }; #define FINT_MIN 750000 #define REGN_MAX (1 << 7) #define REGM_MAX ((1 << 11) - 1) -#define REGM3_MAX (1 << 4) -#define REGM4_MAX (1 << 4) +#define REGM_DISPC_MAX (1 << 4) +#define REGM_DSI_MAX (1 << 4) #define LP_DIV_MAX ((1 << 13) - 1) enum fifo_size { @@ -642,7 +642,7 @@ static void dsi_vc_disable_bta_irq(int channel) dsi_write_reg(DSI_VC_IRQENABLE(channel), l); } -/* DSI func clock. this could also be DSI2_PLL_FCLK */ +/* DSI func clock. this could also be dsi_pll_hsdiv_dsi_clk */ static inline void enable_clocks(bool enable) { if (enable) @@ -712,14 +712,14 @@ static inline int dsi_if_enable(bool enable) return 0; } -unsigned long dsi_get_dsi1_pll_rate(void) +unsigned long dsi_get_pll_hsdiv_dispc_rate(void) { - return dsi.current_cinfo.dsi1_pll_fclk; + return dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk; } -static unsigned long dsi_get_dsi2_pll_rate(void) +static unsigned long dsi_get_pll_hsdiv_dsi_rate(void) { - return dsi.current_cinfo.dsi2_pll_fclk; + return dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk; } static unsigned long dsi_get_txbyteclkhs(void) @@ -732,11 +732,11 @@ static unsigned long dsi_fclk_rate(void) unsigned long r; if (dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK) { - /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ + /* DSI FCLK source is DSS_CLK_FCK */ r = dss_clk_get_rate(DSS_CLK_FCK); } else { - /* DSI FCLK source is DSI2_PLL_FCLK */ - r = dsi_get_dsi2_pll_rate(); + /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */ + r = dsi_get_pll_hsdiv_dsi_rate(); } return r; @@ -806,16 +806,16 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, if (cinfo->regm == 0 || cinfo->regm > REGM_MAX) return -EINVAL; - if (cinfo->regm3 > REGM3_MAX) + if (cinfo->regm_dispc > REGM_DISPC_MAX) return -EINVAL; - if (cinfo->regm4 > REGM4_MAX) + if (cinfo->regm_dsi > REGM_DSI_MAX) return -EINVAL; - if (cinfo->use_dss2_fck) { + if (cinfo->use_sys_clk) { cinfo->clkin = dss_clk_get_rate(DSS_CLK_SYSCK); /* XXX it is unclear if highfreq should be used - * with DSS2_FCK source also */ + * with DSS_SYS_CLK source also */ cinfo->highfreq = 0; } else { cinfo->clkin = dispc_pclk_rate(dssdev->manager->id); @@ -836,15 +836,17 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, if (cinfo->clkin4ddr > 1800 * 1000 * 1000) return -EINVAL; - if (cinfo->regm3 > 0) - cinfo->dsi1_pll_fclk = cinfo->clkin4ddr / cinfo->regm3; + if (cinfo->regm_dispc > 0) + cinfo->dsi_pll_hsdiv_dispc_clk = + cinfo->clkin4ddr / cinfo->regm_dispc; else - cinfo->dsi1_pll_fclk = 0; + cinfo->dsi_pll_hsdiv_dispc_clk = 0; - if (cinfo->regm4 > 0) - cinfo->dsi2_pll_fclk = cinfo->clkin4ddr / cinfo->regm4; + if (cinfo->regm_dsi > 0) + cinfo->dsi_pll_hsdiv_dsi_clk = + cinfo->clkin4ddr / cinfo->regm_dsi; else - cinfo->dsi2_pll_fclk = 0; + cinfo->dsi_pll_hsdiv_dsi_clk = 0; return 0; } @@ -857,18 +859,18 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, struct dispc_clock_info best_dispc; int min_fck_per_pck; int match = 0; - unsigned long dss_clk_fck2, max_dss_fck; + unsigned long dss_sys_clk, max_dss_fck; - dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_SYSCK); + dss_sys_clk = dss_clk_get_rate(DSS_CLK_SYSCK); max_dss_fck = dss_feat_get_max_dss_fck(); if (req_pck == dsi.cache_req_pck && - dsi.cache_cinfo.clkin == dss_clk_fck2) { + dsi.cache_cinfo.clkin == dss_sys_clk) { DSSDBG("DSI clock info found from cache\n"); *dsi_cinfo = dsi.cache_cinfo; - dispc_find_clk_divs(is_tft, req_pck, dsi_cinfo->dsi1_pll_fclk, - dispc_cinfo); + dispc_find_clk_divs(is_tft, req_pck, + dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo); return 0; } @@ -889,8 +891,8 @@ retry: memset(&best_dispc, 0, sizeof(best_dispc)); memset(&cur, 0, sizeof(cur)); - cur.clkin = dss_clk_fck2; - cur.use_dss2_fck = 1; + cur.clkin = dss_sys_clk; + cur.use_sys_clk = 1; cur.highfreq = 0; /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ @@ -916,30 +918,32 @@ retry: if (cur.clkin4ddr > 1800 * 1000 * 1000) break; - /* DSI1_PLL_FCLK(MHz) = DSIPHY(MHz) / regm3 < 173MHz */ - for (cur.regm3 = 1; cur.regm3 < REGM3_MAX; - ++cur.regm3) { + /* dsi_pll_hsdiv_dispc_clk(MHz) = + * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */ + for (cur.regm_dispc = 1; cur.regm_dispc < REGM_DISPC_MAX; + ++cur.regm_dispc) { struct dispc_clock_info cur_dispc; - cur.dsi1_pll_fclk = cur.clkin4ddr / cur.regm3; + cur.dsi_pll_hsdiv_dispc_clk = + cur.clkin4ddr / cur.regm_dispc; /* this will narrow down the search a bit, * but still give pixclocks below what was * requested */ - if (cur.dsi1_pll_fclk < req_pck) + if (cur.dsi_pll_hsdiv_dispc_clk < req_pck) break; - if (cur.dsi1_pll_fclk > max_dss_fck) + if (cur.dsi_pll_hsdiv_dispc_clk > max_dss_fck) continue; if (min_fck_per_pck && - cur.dsi1_pll_fclk < + cur.dsi_pll_hsdiv_dispc_clk < req_pck * min_fck_per_pck) continue; match = 1; dispc_find_clk_divs(is_tft, req_pck, - cur.dsi1_pll_fclk, + cur.dsi_pll_hsdiv_dispc_clk, &cur_dispc); if (abs(cur_dispc.pck - req_pck) < @@ -968,9 +972,9 @@ found: return -EINVAL; } - /* DSI2_PLL_FCLK (regm4) is not used */ - best.regm4 = 0; - best.dsi2_pll_fclk = 0; + /* dsi_pll_hsdiv_dsi_clk (regm_dsi) is not used */ + best.regm_dsi = 0; + best.dsi_pll_hsdiv_dsi_clk = 0; if (dsi_cinfo) *dsi_cinfo = best; @@ -994,18 +998,20 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) dsi.current_cinfo.fint = cinfo->fint; dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr; - dsi.current_cinfo.dsi1_pll_fclk = cinfo->dsi1_pll_fclk; - dsi.current_cinfo.dsi2_pll_fclk = cinfo->dsi2_pll_fclk; + 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.regm3 = cinfo->regm3; - dsi.current_cinfo.regm4 = cinfo->regm4; + dsi.current_cinfo.regm_dispc = cinfo->regm_dispc; + dsi.current_cinfo.regm_dsi = cinfo->regm_dsi; DSSDBG("DSI Fint %ld\n", cinfo->fint); DSSDBG("clkin (%s) rate %ld, highfreq %d\n", - cinfo->use_dss2_fck ? "dss2_fck" : "pclkfree", + cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree", cinfo->clkin, cinfo->highfreq); @@ -1022,14 +1028,14 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4); - DSSDBG("regm3 = %d, %s (%s) = %lu\n", cinfo->regm3, + DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc, dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), - cinfo->dsi1_pll_fclk); - DSSDBG("regm4 = %d, %s (%s) = %lu\n", cinfo->regm4, + cinfo->dsi_pll_hsdiv_dispc_clk); + DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi, dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), - cinfo->dsi2_pll_fclk); + cinfo->dsi_pll_hsdiv_dsi_clk); REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ @@ -1037,9 +1043,9 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ l = FLD_MOD(l, cinfo->regn - 1, 7, 1); /* DSI_PLL_REGN */ l = FLD_MOD(l, cinfo->regm, 18, 8); /* DSI_PLL_REGM */ - l = FLD_MOD(l, cinfo->regm3 > 0 ? cinfo->regm3 - 1 : 0, + l = FLD_MOD(l, cinfo->regm_dispc > 0 ? cinfo->regm_dispc - 1 : 0, 22, 19); /* DSI_CLOCK_DIV */ - l = FLD_MOD(l, cinfo->regm4 > 0 ? cinfo->regm4 - 1 : 0, + l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0, 26, 23); /* DSIPROTO_CLOCK_DIV */ dsi_write_reg(DSI_PLL_CONFIGURATION1, l); @@ -1057,7 +1063,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) l = dsi_read_reg(DSI_PLL_CONFIGURATION2); l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ - l = FLD_MOD(l, cinfo->use_dss2_fck ? 0 : 1, + l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1, 11, 11); /* DSI_PLL_CLKSEL */ l = FLD_MOD(l, cinfo->highfreq, 12, 12); /* DSI_PLL_HIGHFREQ */ @@ -1186,26 +1192,26 @@ void dsi_dump_clocks(struct seq_file *s) seq_printf(s, "dsi pll source = %s\n", clksel == 0 ? - "dss2_alwon_fclk" : "pclkfree"); + "dss_sys_clk" : "pclkfree"); 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); - seq_printf(s, "%s (%s)\t%-16luregm3 %u\t(%s)\n", + seq_printf(s, "%s (%s)\t%-16luregm_dispc %u\t(%s)\n", dss_get_generic_clk_source_name(dispc_clk_src), dss_feat_get_clk_source_name(dispc_clk_src), - cinfo->dsi1_pll_fclk, - cinfo->regm3, + cinfo->dsi_pll_hsdiv_dispc_clk, + cinfo->regm_dispc, dispc_clk_src == DSS_CLK_SRC_FCK ? "off" : "on"); - seq_printf(s, "%s (%s)\t%-16luregm4 %u\t(%s)\n", + seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n", dss_get_generic_clk_source_name(dsi_clk_src), dss_feat_get_clk_source_name(dsi_clk_src), - cinfo->dsi2_pll_fclk, - cinfo->regm4, + cinfo->dsi_pll_hsdiv_dsi_clk, + cinfo->regm_dsi, dsi_clk_src == DSS_CLK_SRC_FCK ? "off" : "on"); @@ -2989,12 +2995,12 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) struct dsi_clock_info cinfo; int r; - /* we always use DSS2_FCK as input clock */ - cinfo.use_dss2_fck = true; + /* we always use DSS_CLK_SYSCK as input clock */ + cinfo.use_sys_clk = true; cinfo.regn = dssdev->phy.dsi.div.regn; cinfo.regm = dssdev->phy.dsi.div.regm; - cinfo.regm3 = dssdev->phy.dsi.div.regm3; - cinfo.regm4 = dssdev->phy.dsi.div.regm4; + cinfo.regm_dispc = dssdev->phy.dsi.div.regm_dispc; + cinfo.regm_dsi = dssdev->phy.dsi.div.regm_dsi; r = dsi_calc_clock_rates(dssdev, &cinfo); if (r) { DSSERR("Failed to calc dsi clocks\n"); @@ -3016,7 +3022,7 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev) int r; unsigned long long fck; - fck = dsi_get_dsi1_pll_rate(); + fck = dsi_get_pll_hsdiv_dispc_rate(); dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div; dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div; @@ -3244,7 +3250,7 @@ int dsi_init_display(struct omap_dss_device *dssdev) return 0; } -void dsi_wait_dsi1_pll_active(void) +void dsi_wait_pll_hsdiv_dispc_active(void) { if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1) DSSERR("%s (%s) not active\n", @@ -3252,7 +3258,7 @@ void dsi_wait_dsi1_pll_active(void) dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC)); } -void dsi_wait_dsi2_pll_active(void) +void dsi_wait_pll_hsdiv_dsi_active(void) { if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1) DSSERR("%s (%s) not active\n", diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index d049598bb41..5c6805b3362 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -299,7 +299,7 @@ void dss_select_dispc_clk_source(enum dss_clk_source clk_src) b = clk_src == DSS_CLK_SRC_FCK ? 0 : 1; if (clk_src == DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC) - dsi_wait_dsi1_pll_active(); + dsi_wait_pll_hsdiv_dispc_active(); REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ @@ -316,7 +316,7 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src) b = clk_src == DSS_CLK_SRC_FCK ? 0 : 1; if (clk_src == DSS_CLK_SRC_DSI_PLL_HSDIV_DSI) - dsi_wait_dsi2_pll_active(); + dsi_wait_pll_hsdiv_dsi_active(); REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 42ca70f2bfd..20590fb53c9 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -152,21 +152,21 @@ struct dsi_clock_info { unsigned long fint; unsigned long clkin4ddr; unsigned long clkin; - unsigned long dsi1_pll_fclk; - unsigned long dsi2_pll_fclk; + unsigned long dsi_pll_hsdiv_dispc_clk; /* DSI1_PLL_CLK */ + unsigned long dsi_pll_hsdiv_dsi_clk; /* DSI2_PLL_CLK */ unsigned long lp_clk; /* dividers */ u16 regn; u16 regm; - u16 regm3; - u16 regm4; + u16 regm_dispc; /* REGM3 */ + u16 regm_dsi; /* REGM4 */ u16 lp_clk_div; u8 highfreq; - bool use_dss2_fck; + bool use_sys_clk; }; struct seq_file; @@ -278,7 +278,7 @@ void dsi_restore_context(void); int dsi_init_display(struct omap_dss_device *display); void dsi_irq_handler(void); -unsigned long dsi_get_dsi1_pll_rate(void); +unsigned long dsi_get_pll_hsdiv_dispc_rate(void); int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo); int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, struct dsi_clock_info *cinfo, @@ -289,8 +289,8 @@ void dsi_pll_uninit(void); void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, enum omap_burst_size *burst_size, u32 *fifo_low, u32 *fifo_high); -void dsi_wait_dsi1_pll_active(void); -void dsi_wait_dsi2_pll_active(void); +void dsi_wait_pll_hsdiv_dispc_active(void); +void dsi_wait_pll_hsdiv_dsi_active(void); #else static inline int dsi_init_platform_driver(void) { @@ -299,10 +299,10 @@ static inline int dsi_init_platform_driver(void) static inline void dsi_uninit_platform_driver(void) { } -static inline void dsi_wait_dsi1_pll_active(void) +static inline void dsi_wait_pll_hsdiv_dispc_active(void) { } -static inline void dsi_wait_dsi2_pll_active(void) +static inline void dsi_wait_pll_hsdiv_dsi_active(void) { } #endif -- cgit v1.2.3-70-g09d2 From 42c9dee82129d965bc8ca02170150817317c0135 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 2 Mar 2011 12:29:27 +0200 Subject: OMAP: DSS2: Remove FB_OMAP_BOOTLOADER_INIT support FB_OMAP_BOOTLOADER_INIT does not work, and it was only partially implemented for SDI. This patch removes support for FB_OMAP_BOOTLOADER_INIT to clean up the code and to remove any assumptions that FB_OMAP_BOOTLOADER_INIT would work. Proper implementation is much more complex, requiring early boot time register and clock handling to keep the DSS running. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 8 +------- drivers/video/omap2/dss/dss.c | 41 ++++++++++++++++------------------------- drivers/video/omap2/dss/dss.h | 4 ++-- drivers/video/omap2/dss/sdi.c | 40 +++++++++------------------------------- 4 files changed, 28 insertions(+), 65 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index bcf69a462b5..02db5f1269e 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -166,7 +166,6 @@ static inline void dss_uninitialize_debugfs(void) static int omap_dss_probe(struct platform_device *pdev) { struct omap_dss_board_info *pdata = pdev->dev.platform_data; - int skip_init = 0; int r; int i; @@ -210,13 +209,8 @@ static int omap_dss_probe(struct platform_device *pdev) goto err_venc; } -#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT - /* DISPC_CONTROL */ - if (omap_readl(0x48050440) & 1) /* LCD enabled? */ - skip_init = 1; -#endif if (cpu_is_omap34xx()) { - r = sdi_init(skip_init); + r = sdi_init(); if (r) { DSSERR("Failed to initialize SDI\n"); goto err_sdi; diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 5c6805b3362..4025a14c5bc 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -559,7 +559,7 @@ void dss_set_dac_pwrdn_bgz(bool enable) REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ } -static int dss_init(bool skip_init) +static int dss_init(void) { int r; u32 rev; @@ -578,22 +578,20 @@ static int dss_init(bool skip_init) goto fail0; } - if (!skip_init) { - /* disable LCD and DIGIT output. This seems to fix the synclost - * problem that we get, if the bootloader starts the DSS and - * the kernel resets it */ - omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440); - - /* We need to wait here a bit, otherwise we sometimes start to - * get synclost errors, and after that only power cycle will - * restore DSS functionality. I have no idea why this happens. - * And we have to wait _before_ resetting the DSS, but after - * enabling clocks. - */ - msleep(50); - - _omap_dss_reset(); - } + /* disable LCD and DIGIT output. This seems to fix the synclost + * problem that we get, if the bootloader starts the DSS and + * the kernel resets it */ + omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440); + + /* We need to wait here a bit, otherwise we sometimes start to + * get synclost errors, and after that only power cycle will + * restore DSS functionality. I have no idea why this happens. + * And we have to wait _before_ resetting the DSS, but after + * enabling clocks. + */ + msleep(50); + + _omap_dss_reset(); /* autoidle */ REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); @@ -954,7 +952,6 @@ void dss_debug_dump_clocks(struct seq_file *s) static int omap_dsshw_probe(struct platform_device *pdev) { int r; - int skip_init = 0; dss.pdev = pdev; @@ -967,13 +964,7 @@ static int omap_dsshw_probe(struct platform_device *pdev) dss.ctx_id = dss_get_ctx_id(); DSSDBG("initial ctx id %u\n", dss.ctx_id); -#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT - /* DISPC_CONTROL */ - if (omap_readl(0x48050440) & 1) /* LCD enabled? */ - skip_init = 1; -#endif - - r = dss_init(skip_init); + r = dss_init(); if (r) { DSSERR("Failed to initialize DSS\n"); goto err_dss; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 20590fb53c9..069fcc72331 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -251,11 +251,11 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck, /* SDI */ #ifdef CONFIG_OMAP2_DSS_SDI -int sdi_init(bool skip_init); +int sdi_init(void); void sdi_exit(void); int sdi_init_display(struct omap_dss_device *display); #else -static inline int sdi_init(bool skip_init) +static inline int sdi_init(void) { return 0; } diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 9f10a0d9e76..54a53e64818 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -30,7 +30,6 @@ #include "dss.h" static struct { - bool skip_init; bool update_enabled; struct regulator *vdds_sdi_reg; } sdi; @@ -68,9 +67,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) if (r) goto err1; - /* In case of skip_init sdi_init has already enabled the clocks */ - if (!sdi.skip_init) - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); sdi_basic_init(dssdev); @@ -80,14 +77,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, dssdev->panel.acbi, dssdev->panel.acb); - if (!sdi.skip_init) { - r = dss_calc_clock_div(1, t->pixel_clock * 1000, - &dss_cinfo, &dispc_cinfo); - } else { - r = dss_get_clock_div(&dss_cinfo); - r = dispc_get_clock_div(dssdev->manager->id, &dispc_cinfo); - } - + r = dss_calc_clock_div(1, t->pixel_clock * 1000, + &dss_cinfo, &dispc_cinfo); if (r) goto err2; @@ -116,18 +107,14 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) if (r) goto err2; - if (!sdi.skip_init) { - dss_sdi_init(dssdev->phy.sdi.datapairs); - r = dss_sdi_enable(); - if (r) - goto err1; - mdelay(2); - } + dss_sdi_init(dssdev->phy.sdi.datapairs); + r = dss_sdi_enable(); + if (r) + goto err1; + mdelay(2); dssdev->manager->enable(dssdev->manager); - sdi.skip_init = 0; - return 0; err2: dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); @@ -173,17 +160,8 @@ int sdi_init_display(struct omap_dss_device *dssdev) return 0; } -int sdi_init(bool skip_init) +int sdi_init(void) { - /* we store this for first display enable, then clear it */ - sdi.skip_init = skip_init; - - /* - * Enable clocks already here, otherwise there would be a toggle - * of them until sdi_display_enable is called. - */ - if (skip_init) - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); return 0; } -- cgit v1.2.3-70-g09d2 From 277b2881c3c0d97e214487fbd677b0590fb4acf3 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 2 Mar 2011 12:32:48 +0200 Subject: OMAP: DSS2: Remove pdev argument from dpi_init dpi_init() does not use the pdev argument for anything. Remove it. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 2 +- drivers/video/omap2/dss/dpi.c | 2 +- drivers/video/omap2/dss/dss.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 02db5f1269e..acefe50209f 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -191,7 +191,7 @@ static int omap_dss_probe(struct platform_device *pdev) goto err_rfbi; } - r = dpi_init(pdev); + r = dpi_init(); if (r) { DSSERR("Failed to initialize dpi\n"); goto err_dpi; diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 08fed3080c0..2d3ca4ca4a0 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -319,7 +319,7 @@ int dpi_init_display(struct omap_dss_device *dssdev) return 0; } -int dpi_init(struct platform_device *pdev) +int dpi_init(void) { return 0; } diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 069fcc72331..85d4141689c 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -309,11 +309,11 @@ static inline void dsi_wait_pll_hsdiv_dsi_active(void) /* DPI */ #ifdef CONFIG_OMAP2_DSS_DPI -int dpi_init(struct platform_device *pdev); +int dpi_init(void); void dpi_exit(void); int dpi_init_display(struct omap_dss_device *dssdev); #else -static inline int dpi_init(struct platform_device *pdev) +static inline int dpi_init(void) { return 0; } -- cgit v1.2.3-70-g09d2 From 66534e8e936a0b926863df90054dc59826d70528 Mon Sep 17 00:00:00 2001 From: "Taneja, Archit" Date: Tue, 8 Mar 2011 05:50:34 -0600 Subject: OMAP2PLUS: DSS2: Cleanup clock source related code Clean up some of the DSS functions which select/get clock sources, use switch to select the clock source members since more clock sources will be introduced later on. Remove the use of macro CONFIG_OMAP2_DSS_DSI in dispc_fclk_rate, use a dummy inline for function for dsi_get_pll_hsdiv_dispc_rate() instead for code clarity. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 15 +++++++++------ drivers/video/omap2/dss/dss.c | 32 ++++++++++++++++++++------------ drivers/video/omap2/dss/dss.h | 5 +++++ 3 files changed, 34 insertions(+), 18 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 4a368c47700..28b690f2447 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2341,14 +2341,17 @@ unsigned long dispc_fclk_rate(void) { unsigned long r = 0; - if (dss_get_dispc_clk_source() == DSS_CLK_SRC_FCK) + switch (dss_get_dispc_clk_source()) { + case DSS_CLK_SRC_FCK: r = dss_clk_get_rate(DSS_CLK_FCK); - else -#ifdef CONFIG_OMAP2_DSS_DSI + break; + case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: r = dsi_get_pll_hsdiv_dispc_rate(); -#else - BUG(); -#endif + break; + default: + BUG(); + } + return r; } diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 2be4d03ece4..93813fd626b 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -293,13 +293,17 @@ void dss_select_dispc_clk_source(enum dss_clk_source clk_src) { int b; - BUG_ON(clk_src != DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC && - clk_src != DSS_CLK_SRC_FCK); - - b = clk_src == DSS_CLK_SRC_FCK ? 0 : 1; - - if (clk_src == DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC) + switch (clk_src) { + case DSS_CLK_SRC_FCK: + b = 0; + break; + case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: + b = 1; dsi_wait_pll_hsdiv_dispc_active(); + break; + default: + BUG(); + } REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ @@ -310,13 +314,17 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src) { int b; - BUG_ON(clk_src != DSS_CLK_SRC_DSI_PLL_HSDIV_DSI && - clk_src != DSS_CLK_SRC_FCK); - - b = clk_src == DSS_CLK_SRC_FCK ? 0 : 1; - - if (clk_src == DSS_CLK_SRC_DSI_PLL_HSDIV_DSI) + switch (clk_src) { + case DSS_CLK_SRC_FCK: + b = 0; + break; + case DSS_CLK_SRC_DSI_PLL_HSDIV_DSI: + b = 1; dsi_wait_pll_hsdiv_dsi_active(); + break; + default: + BUG(); + } REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 85d4141689c..fc41b3f0c27 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -299,6 +299,11 @@ static inline int dsi_init_platform_driver(void) static inline void dsi_uninit_platform_driver(void) { } +static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(void) +{ + WARN("%s: DSI not compiled in, returning rate as 0\n", __func__); + return 0; +} static inline void dsi_wait_pll_hsdiv_dispc_active(void) { } -- cgit v1.2.3-70-g09d2 From ea75159ee6f00bd809f57a58e5505dc362382cc8 Mon Sep 17 00:00:00 2001 From: "Taneja, Archit" Date: Tue, 8 Mar 2011 05:50:35 -0600 Subject: OMAP4: DSS2: Clock source changes for OMAP4 On OMAP3, the pixel clock for the LCD manager was derived through DISPC_FCLK as: Lcd Pixel clock = DISPC_FCLK / lcd / pcd Where lcd and pcd are divisors in the DISPC_DIVISOR register. On OMAP4, the pixel clocks for LCD1 and LCD2 managers are derived from 2 new clocks named LCD1_CLK and LCD2_CLK. The pixel clocks are calculated as: Lcd_o Pixel clock = LCDo_CLK / lcdo /pcdo, o = 1, 2 Where lcdo and pcdo registers are divisors in DISPC_DIVISORo registers. LCD1_CLK and LCD2_CLK can have DSS_FCLK, and the M4 divider clocks of DSI1 PLL and DSI2 PLL as clock sources respectively. Introduce functions to select and get the clock source for these new clocks. Modify DISPC functions get the correct lck and pck rates based on the clock source of these clocks. Since OMAP2/3 don't have these clocks, force OMAP2/3 to always have the LCD_CLK source as DSS_CLK_SRC_FCK by introducing a dss feature. Introduce clock source names for OMAP4 and some register field changes in DSS_CTRL on OMAP4. Currently, LCD2_CLK can only have DSS_FCLK as its clock source as DSI2 PLL functionality hasn't been introduced yet. BUG for now if DSI2 PLL is selected as clock. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 31 +++++++++++++++++++++---- drivers/video/omap2/dss/dss.c | 42 +++++++++++++++++++++++++++++++++- drivers/video/omap2/dss/dss.h | 26 +++++++++++++-------- drivers/video/omap2/dss/dss_features.c | 13 +++++++++-- drivers/video/omap2/dss/dss_features.h | 3 +++ 5 files changed, 98 insertions(+), 17 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 28b690f2447..b8c576a0bc0 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2365,25 +2365,33 @@ unsigned long dispc_lclk_rate(enum omap_channel channel) lcd = FLD_GET(l, 23, 16); - r = dispc_fclk_rate(); + switch (dss_get_lcd_clk_source(channel)) { + case DSS_CLK_SRC_FCK: + r = dss_clk_get_rate(DSS_CLK_FCK); + break; + case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: + r = dsi_get_pll_hsdiv_dispc_rate(); + break; + default: + BUG(); + } return r / lcd; } unsigned long dispc_pclk_rate(enum omap_channel channel) { - int lcd, pcd; + int pcd; unsigned long r; u32 l; l = dispc_read_reg(DISPC_DIVISORo(channel)); - lcd = FLD_GET(l, 23, 16); pcd = FLD_GET(l, 7, 0); - r = dispc_fclk_rate(); + r = dispc_lclk_rate(channel); - return r / lcd / pcd; + return r / pcd; } void dispc_dump_clocks(struct seq_file *s) @@ -2391,6 +2399,7 @@ void dispc_dump_clocks(struct seq_file *s) int lcd, pcd; u32 l; enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); + enum dss_clk_source lcd_clk_src; enable_clocks(1); @@ -2412,6 +2421,12 @@ void dispc_dump_clocks(struct seq_file *s) } seq_printf(s, "- LCD1 -\n"); + lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD); + + seq_printf(s, "lcd1_clk source = %s (%s)\n", + dss_get_generic_clk_source_name(lcd_clk_src), + dss_feat_get_clk_source_name(lcd_clk_src)); + dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd); seq_printf(s, "lck\t\t%-16lulck div\t%u\n", @@ -2421,6 +2436,12 @@ void dispc_dump_clocks(struct seq_file *s) if (dss_has_feature(FEAT_MGR_LCD2)) { seq_printf(s, "- LCD2 -\n"); + lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD2); + + seq_printf(s, "lcd2_clk source = %s (%s)\n", + dss_get_generic_clk_source_name(lcd_clk_src), + dss_feat_get_clk_source_name(lcd_clk_src)); + dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd); seq_printf(s, "lck\t\t%-16lulck div\t%u\n", diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 93813fd626b..aed9345e8ad 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -77,6 +77,7 @@ static struct { enum dss_clk_source dsi_clk_source; enum dss_clk_source dispc_clk_source; + enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS]; u32 ctx[DSS_SZ_REGS / sizeof(u32)]; } dss; @@ -292,6 +293,7 @@ void dss_dump_regs(struct seq_file *s) void dss_select_dispc_clk_source(enum dss_clk_source clk_src) { int b; + u8 start, end; switch (clk_src) { case DSS_CLK_SRC_FCK: @@ -305,7 +307,9 @@ void dss_select_dispc_clk_source(enum dss_clk_source clk_src) BUG(); } - REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ + dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end); + + REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */ dss.dispc_clk_source = clk_src; } @@ -331,6 +335,34 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src) dss.dsi_clk_source = clk_src; } +void dss_select_lcd_clk_source(enum omap_channel channel, + enum dss_clk_source clk_src) +{ + int b, ix, pos; + + if (!dss_has_feature(FEAT_LCD_CLK_SRC)) + return; + + switch (clk_src) { + case DSS_CLK_SRC_FCK: + b = 0; + break; + case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: + BUG_ON(channel != OMAP_DSS_CHANNEL_LCD); + b = 1; + dsi_wait_pll_hsdiv_dispc_active(); + break; + default: + BUG(); + } + + pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12; + REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */ + + ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; + dss.lcd_clk_source[ix] = clk_src; +} + enum dss_clk_source dss_get_dispc_clk_source(void) { return dss.dispc_clk_source; @@ -341,6 +373,12 @@ enum dss_clk_source dss_get_dsi_clk_source(void) return dss.dsi_clk_source; } +enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) +{ + int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; + return dss.lcd_clk_source[ix]; +} + /* calculate clock rates using dividers in cinfo */ int dss_calc_clock_rates(struct dss_clock_info *cinfo) { @@ -624,6 +662,8 @@ static int dss_init(void) dss.dsi_clk_source = DSS_CLK_SRC_FCK; dss.dispc_clk_source = DSS_CLK_SRC_FCK; + dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK; + dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK; dss_save_context(); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index fc41b3f0c27..b845468d970 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -118,9 +118,12 @@ enum dss_clock { }; enum dss_clk_source { - DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* DSI1_PLL_FCLK */ - DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* DSI2_PLL_FCLK */ - DSS_CLK_SRC_FCK, /* DSS1_ALWON_FCLK */ + DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK + * OMAP4: PLL1_CLK1 */ + DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK + * OMAP4: PLL1_CLK2 */ + DSS_CLK_SRC_FCK, /* OMAP2/3: DSS1_ALWON_FCLK + * OMAP4: DSS_FCLK */ }; /* Correlates clock source name and dss_clk_source member */ @@ -152,17 +155,19 @@ struct dsi_clock_info { unsigned long fint; unsigned long clkin4ddr; unsigned long clkin; - unsigned long dsi_pll_hsdiv_dispc_clk; /* DSI1_PLL_CLK */ - unsigned long dsi_pll_hsdiv_dsi_clk; /* DSI2_PLL_CLK */ - + 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 lp_clk; /* dividers */ u16 regn; u16 regm; - u16 regm_dispc; /* REGM3 */ - u16 regm_dsi; /* REGM4 */ - + u16 regm_dispc; /* OMAP3: REGM3 + * OMAP4: REGM4 */ + u16 regm_dsi; /* OMAP3: REGM4 + * OMAP4: REGM5 */ u16 lp_clk_div; u8 highfreq; @@ -235,8 +240,11 @@ void dss_sdi_disable(void); void dss_select_dispc_clk_source(enum dss_clk_source clk_src); void dss_select_dsi_clk_source(enum dss_clk_source clk_src); +void dss_select_lcd_clk_source(enum omap_channel channel, + enum dss_clk_source clk_src); enum dss_clk_source dss_get_dispc_clk_source(void); enum dss_clk_source dss_get_dsi_clk_source(void); +enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel); void dss_set_venc_output(enum omap_dss_venc_type type); void dss_set_dac_pwrdn_bgz(bool enable); diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index dc170ad079f..6eb6ec62a00 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -59,6 +59,7 @@ static const struct dss_reg_field omap2_dss_reg_fields[] = { { FEAT_REG_FIFOSIZE, 8, 0 }, { FEAT_REG_HORIZONTALACCU, 9, 0 }, { FEAT_REG_VERTICALACCU, 25, 16 }, + { FEAT_REG_DISPC_CLK_SWITCH, 0, 0 }, }; static const struct dss_reg_field omap3_dss_reg_fields[] = { @@ -69,6 +70,7 @@ static const struct dss_reg_field omap3_dss_reg_fields[] = { { FEAT_REG_FIFOSIZE, 10, 0 }, { FEAT_REG_HORIZONTALACCU, 9, 0 }, { FEAT_REG_VERTICALACCU, 25, 16 }, + { FEAT_REG_DISPC_CLK_SWITCH, 0, 0 }, }; static const struct dss_reg_field omap4_dss_reg_fields[] = { @@ -79,6 +81,7 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = { { FEAT_REG_FIFOSIZE, 15, 0 }, { FEAT_REG_HORIZONTALACCU, 10, 0 }, { FEAT_REG_VERTICALACCU, 26, 16 }, + { FEAT_REG_DISPC_CLK_SWITCH, 9, 8 }, }; static const enum omap_display_type omap2_dss_supported_displays[] = { @@ -171,6 +174,12 @@ static const struct dss_clk_source_name omap3_dss_clk_source_names[] = { { DSS_CLK_SRC_FCK, "DSS1_ALWON_FCLK" }, }; +static const struct dss_clk_source_name omap4_dss_clk_source_names[] = { + { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "PLL1_CLK1" }, + { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "PLL1_CLK2" }, + { DSS_CLK_SRC_FCK, "DSS_FCLK" }, +}; + /* OMAP2 DSS Features */ static struct omap_dss_features omap2_dss_features = { .reg_fields = omap2_dss_reg_fields, @@ -235,14 +244,14 @@ static struct omap_dss_features omap4_dss_features = { .has_feature = FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA | FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 | - FEAT_CORE_CLK_DIV, + FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC, .num_mgrs = 3, .num_ovls = 3, .max_dss_fck = 186000000, .supported_displays = omap4_dss_supported_displays, .supported_color_modes = omap3_dss_supported_color_modes, - .clksrc_names = omap3_dss_clk_source_names, + .clksrc_names = omap4_dss_clk_source_names, }; /* Functions returning values related to a DSS feature */ diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index 569d1b295ed..729b5f19fa2 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -22,6 +22,7 @@ #define MAX_DSS_MANAGERS 3 #define MAX_DSS_OVERLAYS 3 +#define MAX_DSS_LCD_MANAGERS 2 /* DSS has feature id */ enum dss_feat_id { @@ -38,6 +39,7 @@ enum dss_feat_id { FEAT_RESIZECONF = 1 << 10, /* Independent core clk divider */ FEAT_CORE_CLK_DIV = 1 << 11, + FEAT_LCD_CLK_SRC = 1 << 12, }; /* DSS register field id */ @@ -49,6 +51,7 @@ enum dss_feat_reg_field { FEAT_REG_FIFOSIZE, FEAT_REG_HORIZONTALACCU, FEAT_REG_VERTICALACCU, + FEAT_REG_DISPC_CLK_SWITCH, }; /* DSS Feature Functions */ -- cgit v1.2.3-70-g09d2 From 235e7dba0264d4c6e56ee217fc7ef6d80da5eb67 Mon Sep 17 00:00:00 2001 From: "Taneja, Archit" Date: Mon, 14 Mar 2011 23:28:21 -0500 Subject: OMAP2PLUS: DSS2: FEATURES: Fix usage of dss_reg_field and dss_clk_source_name The structures dss_reg_field and dss_clk_source_name have enum members which specify the register field and the clock source respectively. These members are not used to choose the correct result in the corresponding feature functions. Remove these members and change the features array declaration to incorporate these enums. The structure dss_clk_source_name without the enum member is just a pointer to an string. Remove the structure and use a character pointer directly. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 10 ++--- drivers/video/omap2/dss/dss.h | 6 --- drivers/video/omap2/dss/dss_features.c | 77 +++++++++++++++++----------------- 3 files changed, 43 insertions(+), 50 deletions(-) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index aed9345e8ad..06ad3129085 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -82,10 +82,10 @@ static struct { u32 ctx[DSS_SZ_REGS / sizeof(u32)]; } dss; -static const struct dss_clk_source_name dss_generic_clk_source_names[] = { - { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "DSI_PLL_HSDIV_DISPC" }, - { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "DSI_PLL_HSDIV_DSI" }, - { DSS_CLK_SRC_FCK, "DSS_FCK" }, +static const char * const dss_generic_clk_source_names[] = { + [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC", + [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI", + [DSS_CLK_SRC_FCK] = "DSS_FCK", }; static void dss_clk_enable_all_no_ctx(void); @@ -232,7 +232,7 @@ void dss_sdi_disable(void) const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src) { - return dss_generic_clk_source_names[clk_src].clksrc_name; + return dss_generic_clk_source_names[clk_src]; } void dss_dump_clocks(struct seq_file *s) diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index b845468d970..26a43c93e48 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -126,12 +126,6 @@ enum dss_clk_source { * OMAP4: DSS_FCLK */ }; -/* Correlates clock source name and dss_clk_source member */ -struct dss_clk_source_name { - enum dss_clk_source clksrc; - const char *clksrc_name; -}; - struct dss_clock_info { /* rates that we get with dividers below */ unsigned long fck; diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 6eb6ec62a00..8de3344842d 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -30,7 +30,6 @@ /* Defines a generic omap register field */ struct dss_reg_field { - enum dss_feat_reg_field id; u8 start, end; }; @@ -45,43 +44,43 @@ struct omap_dss_features { const unsigned long max_dss_fck; const enum omap_display_type *supported_displays; const enum omap_color_mode *supported_color_modes; - const struct dss_clk_source_name *clksrc_names; + const char * const *clksrc_names; }; /* This struct is assigned to one of the below during initialization */ static struct omap_dss_features *omap_current_dss_features; static const struct dss_reg_field omap2_dss_reg_fields[] = { - { FEAT_REG_FIRHINC, 11, 0 }, - { FEAT_REG_FIRVINC, 27, 16 }, - { FEAT_REG_FIFOLOWTHRESHOLD, 8, 0 }, - { FEAT_REG_FIFOHIGHTHRESHOLD, 24, 16 }, - { FEAT_REG_FIFOSIZE, 8, 0 }, - { FEAT_REG_HORIZONTALACCU, 9, 0 }, - { FEAT_REG_VERTICALACCU, 25, 16 }, - { FEAT_REG_DISPC_CLK_SWITCH, 0, 0 }, + [FEAT_REG_FIRHINC] = { 11, 0 }, + [FEAT_REG_FIRVINC] = { 27, 16 }, + [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 }, + [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 }, + [FEAT_REG_FIFOSIZE] = { 8, 0 }, + [FEAT_REG_HORIZONTALACCU] = { 9, 0 }, + [FEAT_REG_VERTICALACCU] = { 25, 16 }, + [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 }, }; static const struct dss_reg_field omap3_dss_reg_fields[] = { - { FEAT_REG_FIRHINC, 12, 0 }, - { FEAT_REG_FIRVINC, 28, 16 }, - { FEAT_REG_FIFOLOWTHRESHOLD, 11, 0 }, - { FEAT_REG_FIFOHIGHTHRESHOLD, 27, 16 }, - { FEAT_REG_FIFOSIZE, 10, 0 }, - { FEAT_REG_HORIZONTALACCU, 9, 0 }, - { FEAT_REG_VERTICALACCU, 25, 16 }, - { FEAT_REG_DISPC_CLK_SWITCH, 0, 0 }, + [FEAT_REG_FIRHINC] = { 12, 0 }, + [FEAT_REG_FIRVINC] = { 28, 16 }, + [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 }, + [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 }, + [FEAT_REG_FIFOSIZE] = { 10, 0 }, + [FEAT_REG_HORIZONTALACCU] = { 9, 0 }, + [FEAT_REG_VERTICALACCU] = { 25, 16 }, + [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 }, }; static const struct dss_reg_field omap4_dss_reg_fields[] = { - { FEAT_REG_FIRHINC, 12, 0 }, - { FEAT_REG_FIRVINC, 28, 16 }, - { FEAT_REG_FIFOLOWTHRESHOLD, 15, 0 }, - { FEAT_REG_FIFOHIGHTHRESHOLD, 31, 16 }, - { FEAT_REG_FIFOSIZE, 15, 0 }, - { FEAT_REG_HORIZONTALACCU, 10, 0 }, - { FEAT_REG_VERTICALACCU, 26, 16 }, - { FEAT_REG_DISPC_CLK_SWITCH, 9, 8 }, + [FEAT_REG_FIRHINC] = { 12, 0 }, + [FEAT_REG_FIRVINC] = { 28, 16 }, + [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 }, + [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 }, + [FEAT_REG_FIFOSIZE] = { 15, 0 }, + [FEAT_REG_HORIZONTALACCU] = { 10, 0 }, + [FEAT_REG_VERTICALACCU] = { 26, 16 }, + [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 }, }; static const enum omap_display_type omap2_dss_supported_displays[] = { @@ -162,22 +161,22 @@ static const enum omap_color_mode omap3_dss_supported_color_modes[] = { OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32, }; -static const struct dss_clk_source_name omap2_dss_clk_source_names[] = { - { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "N/A" }, - { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "N/A" }, - { DSS_CLK_SRC_FCK, "DSS_FCLK1" }, +static const char * const omap2_dss_clk_source_names[] = { + [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A", + [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A", + [DSS_CLK_SRC_FCK] = "DSS_FCLK1", }; -static const struct dss_clk_source_name omap3_dss_clk_source_names[] = { - { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "DSI1_PLL_FCLK" }, - { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "DSI2_PLL_FCLK" }, - { DSS_CLK_SRC_FCK, "DSS1_ALWON_FCLK" }, +static const char * const omap3_dss_clk_source_names[] = { + [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK", + [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK", + [DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK", }; -static const struct dss_clk_source_name omap4_dss_clk_source_names[] = { - { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "PLL1_CLK1" }, - { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "PLL1_CLK2" }, - { DSS_CLK_SRC_FCK, "DSS_FCLK" }, +static const char * const omap4_dss_clk_source_names[] = { + [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1", + [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2", + [DSS_CLK_SRC_FCK] = "DSS_FCLK", }; /* OMAP2 DSS Features */ @@ -290,7 +289,7 @@ bool dss_feat_color_mode_supported(enum omap_plane plane, const char *dss_feat_get_clk_source_name(enum dss_clk_source id) { - return omap_current_dss_features->clksrc_names[id].clksrc_name; + return omap_current_dss_features->clksrc_names[id]; } /* DSS has_feature check */ -- cgit v1.2.3-70-g09d2 From 7ed024aa280cb38c8aa5c188d2d2c98f5daede10 Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Wed, 9 Mar 2011 16:31:38 +0530 Subject: OMAP4: DSS2: HDMI: Select between HDMI VENC clock source. Adding function to select between HDMI or VENC clock source. Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 5 +++++ drivers/video/omap2/dss/dss.h | 6 ++++++ 2 files changed, 11 insertions(+) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 562d8d28d4f..f1628bd850d 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -605,6 +605,11 @@ void dss_set_dac_pwrdn_bgz(bool enable) REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ } +void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi) +{ + REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */ +} + static int dss_init(void) { int r; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 26a43c93e48..eb05d39ef17 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -126,6 +126,11 @@ enum dss_clk_source { * OMAP4: DSS_FCLK */ }; +enum dss_hdmi_venc_clk_source_select { + DSS_VENC_TV_CLK = 0, + DSS_HDMI_M_PCLK = 1, +}; + struct dss_clock_info { /* rates that we get with dividers below */ unsigned long fck; @@ -214,6 +219,7 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); int dss_init_platform_driver(void); void dss_uninit_platform_driver(void); +void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); void dss_save_context(void); void dss_restore_context(void); void dss_clk_enable(enum dss_clock clks); -- cgit v1.2.3-70-g09d2 From d3862610c95564a586951d5be291b9b0200d39fe Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Fri, 11 Mar 2011 18:02:49 +0530 Subject: OMAP4: DSS2: HDMI: Dispc gamma enable set/reset function for TV. Adding function to reset/set gamma table bit for TV interface, currently only support for disabled is added. Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 14 ++++++++++++++ drivers/video/omap2/dss/dss.h | 1 + 2 files changed, 15 insertions(+) (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index b8c576a0bc0..7804779c9da 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1008,6 +1008,20 @@ void dispc_set_burst_size(enum omap_plane plane, enable_clocks(0); } +void dispc_enable_gamma_table(bool enable) +{ + /* + * This is partially implemented to support only disabling of + * the gamma table. + */ + if (enable) { + DSSWARN("Gamma table enabling for TV not yet supported"); + return; + } + + REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9); +} + static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) { u32 val; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index eb05d39ef17..ab20270d761 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -370,6 +370,7 @@ void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height); void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out); +void dispc_enable_gamma_table(bool enable); int dispc_setup_plane(enum omap_plane plane, u32 paddr, u16 screen_width, u16 pos_x, u16 pos_y, -- cgit v1.2.3-70-g09d2 From c3198a5e83121d6e3d01816f15164f158f4301d8 Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Sat, 12 Mar 2011 12:04:27 +0530 Subject: OMAP4: DSS2: HDMI: HDMI driver addition in the DSS Adding the hdmi interface driver(hdmi.c) to the dss driver. It configures the audio and video portion of HDMI based on functionality called by the panel driver. Signed-off-by: Mythri P K Signed-off-by: Yong Zhi Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/display.c | 3 + drivers/video/omap2/dss/dss.h | 34 + drivers/video/omap2/dss/hdmi.c | 1332 +++++++++++++++++++++++++++++++++++++ 3 files changed, 1369 insertions(+) create mode 100644 drivers/video/omap2/dss/hdmi.c (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index c40bcbd2e14..a85a6f38b40 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -418,6 +418,9 @@ void dss_init_device(struct platform_device *pdev, r = dsi_init_display(dssdev); break; #endif + case OMAP_DISPLAY_TYPE_HDMI: + r = hdmi_init_display(dssdev); + break; default: DSSERR("Support for display '%s' not compiled in.\n", dssdev->name); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index ab20270d761..91ed3fa8e60 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -173,6 +173,16 @@ struct dsi_clock_info { bool use_sys_clk; }; +/* HDMI PLL structure */ +struct hdmi_pll_info { + u16 regn; + u16 regm; + u32 regmf; + u16 regm2; + u16 regsd; + u16 dcofreq; +}; + struct seq_file; struct platform_device; @@ -444,6 +454,30 @@ static inline void venc_uninit_platform_driver(void) } #endif +/* HDMI */ +#ifdef CONFIG_OMAP4_DSS_HDMI +int hdmi_init_platform_driver(void); +void hdmi_uninit_platform_driver(void); +int hdmi_init_display(struct omap_dss_device *dssdev); +#else +static inline int hdmi_init_display(struct omap_dss_device *dssdev) +{ + return 0; +} +static inline int hdmi_init_platform_driver(void) +{ + return 0; +} +static inline void hdmi_uninit_platform_driver(void) +{ +} +#endif +int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); +void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); +void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev); +int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, + struct omap_video_timings *timings); + /* RFBI */ #ifdef CONFIG_OMAP2_DSS_RFBI int rfbi_init_platform_driver(void); diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c new file mode 100644 index 00000000000..0d44f070ef3 --- /dev/null +++ b/drivers/video/omap2/dss/hdmi.c @@ -0,0 +1,1332 @@ +/* + * hdmi.c + * + * HDMI interface DSS driver setting for TI's OMAP4 family of processor. + * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ + * Authors: Yong Zhi + * Mythri pk + * + * 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 . + */ + +#define DSS_SUBSYS_NAME "HDMI" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dss.h" +#include "hdmi.h" + +static struct { + struct mutex lock; + struct omap_display_platform_data *pdata; + struct platform_device *pdev; + void __iomem *base_wp; /* HDMI wrapper */ + int code; + int mode; + u8 edid[HDMI_EDID_MAX_LENGTH]; + u8 edid_set; + bool custom_set; + struct hdmi_config cfg; +} hdmi; + +/* + * Logic for the below structure : + * user enters the CEA or VESA timings by specifying the HDMI/DVI code. + * There is a correspondence between CEA/VESA timing and code, please + * refer to section 6.3 in HDMI 1.3 specification for timing code. + * + * In the below structure, cea_vesa_timings corresponds to all OMAP4 + * supported CEA and VESA timing values.code_cea corresponds to the CEA + * code, It is used to get the timing from cea_vesa_timing array.Similarly + * with code_vesa. Code_index is used for back mapping, that is once EDID + * is read from the TV, EDID is parsed to find the timing values and then + * map it to corresponding CEA or VESA index. + */ + +static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { + { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0}, + { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1}, + { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}, + { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0}, + { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0}, + { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0}, + { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0}, + { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1}, + { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1}, + { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1}, + { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0}, + { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0}, + { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1}, + { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0}, + { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1}, + /* VESA From Here */ + { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0}, + { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1}, + { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1}, + { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0}, + { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0}, + { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1}, + { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1}, + { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1}, + { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0}, + { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0}, + { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0}, + { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0}, + { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1}, + { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1}, + { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1}, + { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1}, + { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1}, + { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1}, + { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1} +}; + +/* + * This is a static mapping array which maps the timing values + * with corresponding CEA / VESA code + */ +static const int code_index[OMAP_HDMI_TIMINGS_NB] = { + 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32, + /* <--15 CEA 17--> vesa*/ + 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A, + 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B +}; + +/* + * This is reverse static mapping which maps the CEA / VESA code + * to the corresponding timing values + */ +static const int code_cea[39] = { + -1, 0, 3, 3, 2, 8, 5, 5, -1, -1, + -1, -1, -1, -1, -1, -1, 9, 10, 10, 1, + 7, 6, 6, -1, -1, -1, -1, -1, -1, 11, + 11, 12, 14, -1, -1, 13, 13, 4, 4 +}; + +static const int code_vesa[85] = { + -1, -1, -1, -1, 15, -1, -1, -1, -1, 16, + -1, -1, -1, -1, 17, -1, 23, -1, -1, -1, + -1, -1, 29, 18, -1, -1, -1, 32, 19, -1, + -1, -1, 21, -1, -1, 22, -1, -1, -1, 20, + -1, 30, 24, -1, -1, -1, -1, 25, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 31, 26, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 27, 28, -1, 33}; + +static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0}; + +static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val) +{ + __raw_writel(val, hdmi.base_wp + idx.idx); +} + +static inline u32 hdmi_read_reg(const struct hdmi_reg idx) +{ + return __raw_readl(hdmi.base_wp + idx.idx); +} + +static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx, + int b2, int b1, u32 val) +{ + u32 t = 0; + while (val != REG_GET(idx, b2, b1)) { + udelay(1); + if (t++ > 10000) + return !val; + } + return val; +} + +int hdmi_init_display(struct omap_dss_device *dssdev) +{ + DSSDBG("init_display\n"); + + return 0; +} + +static int hdmi_pll_init(enum hdmi_clk_refsel refsel, int dcofreq, + struct hdmi_pll_info *fmt, u16 sd) +{ + u32 r; + + /* PLL start always use manual mode */ + REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0); + + r = hdmi_read_reg(PLLCTRL_CFG1); + r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */ + r = FLD_MOD(r, fmt->regn, 8, 1); /* CFG1_PLL_REGN */ + + hdmi_write_reg(PLLCTRL_CFG1, r); + + r = hdmi_read_reg(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 (dcofreq) { + /* divider programming for frequency beyond 1000Mhz */ + REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10); + r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */ + } else { + r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */ + } + + hdmi_write_reg(PLLCTRL_CFG2, r); + + r = hdmi_read_reg(PLLCTRL_CFG4); + r = FLD_MOD(r, fmt->regm2, 24, 18); + r = FLD_MOD(r, fmt->regmf, 17, 0); + + hdmi_write_reg(PLLCTRL_CFG4, r); + + /* go now */ + REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0); + + /* wait for bit change */ + if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) { + DSSERR("PLL GO bit not set\n"); + return -ETIMEDOUT; + } + + /* Wait till the lock bit is set in PLL status */ + if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) { + DSSWARN("cannot lock PLL\n"); + DSSWARN("CFG1 0x%x\n", + hdmi_read_reg(PLLCTRL_CFG1)); + DSSWARN("CFG2 0x%x\n", + hdmi_read_reg(PLLCTRL_CFG2)); + DSSWARN("CFG4 0x%x\n", + hdmi_read_reg(PLLCTRL_CFG4)); + return -ETIMEDOUT; + } + + DSSDBG("PLL locked!\n"); + + return 0; +} + +/* PHY_PWR_CMD */ +static int hdmi_set_phy_pwr(enum hdmi_phy_pwr val) +{ + /* Command for power control of HDMI PHY */ + REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6); + + /* Status of the power control of HDMI PHY */ + if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) { + DSSERR("Failed to set PHY power mode to %d\n", val); + return -ETIMEDOUT; + } + + return 0; +} + +/* PLL_PWR_CMD */ +static int hdmi_set_pll_pwr(enum hdmi_pll_pwr val) +{ + /* Command for power control of HDMI PLL */ + REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2); + + /* wait till PHY_PWR_STATUS is set */ + if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) { + DSSERR("Failed to set PHY_PWR_STATUS\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static int hdmi_pll_reset(void) +{ + /* SYSRESET controlled by power FSM */ + REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3); + + /* READ 0x0 reset is in progress */ + if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) { + DSSERR("Failed to sysreset PLL\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static int hdmi_phy_init(void) +{ + u16 r = 0; + + r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_LDOON); + if (r) + return r; + + r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_TXON); + if (r) + return r; + + /* + * Read address 0 in order to get the SCP reset done completed + * Dummy access performed to make sure reset is done + */ + hdmi_read_reg(HDMI_TXPHY_TX_CTRL); + + /* + * Write to phy address 0 to configure the clock + * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field + */ + REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30); + + /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */ + hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000); + + /* Setup max LDO voltage */ + REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0); + + /* Write to phy address 3 to change the polarity control */ + REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); + + return 0; +} + +static int hdmi_wait_softreset(void) +{ + /* reset W1 */ + REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0); + + /* wait till SOFTRESET == 0 */ + if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) { + DSSERR("sysconfig reset failed\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static int hdmi_pll_program(struct hdmi_pll_info *fmt) +{ + u16 r = 0; + enum hdmi_clk_refsel refsel; + + /* wait for wrapper reset */ + r = hdmi_wait_softreset(); + if (r) + return r; + + r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF); + if (r) + return r; + + r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS); + if (r) + return r; + + r = hdmi_pll_reset(); + if (r) + return r; + + refsel = HDMI_REFSEL_SYSCLK; + + r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd); + if (r) + return r; + + return 0; +} + +static void hdmi_phy_off(void) +{ + hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF); +} + +static int hdmi_core_ddc_edid(u8 *pedid, int ext) +{ + u32 i, j; + char checksum = 0; + u32 offset = 0; + + /* Turn on CLK for DDC */ + REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0); + + /* + * SW HACK : Without the Delay DDC(i2c bus) reads 0 values / + * right shifted values( The behavior is not consistent and seen only + * with some TV's) + */ + usleep_range(800, 1000); + + if (!ext) { + /* Clk SCL Devices */ + REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0); + + /* HDMI_CORE_DDC_STATUS_IN_PROG */ + if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS, + 4, 4, 0) != 0) { + DSSERR("Failed to program DDC\n"); + return -ETIMEDOUT; + } + + /* Clear FIFO */ + REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0); + + /* HDMI_CORE_DDC_STATUS_IN_PROG */ + if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS, + 4, 4, 0) != 0) { + DSSERR("Failed to program DDC\n"); + return -ETIMEDOUT; + } + + } else { + if (ext % 2 != 0) + offset = 0x80; + } + + /* Load Segment Address Register */ + REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0); + + /* Load Slave Address Register */ + REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1); + + /* Load Offset Address Register */ + REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0); + + /* Load Byte Count */ + REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0); + REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0); + + /* Set DDC_CMD */ + if (ext) + REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0); + else + REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0); + + /* HDMI_CORE_DDC_STATUS_BUS_LOW */ + if (REG_GET(HDMI_CORE_DDC_STATUS, 6, 6) == 1) { + DSSWARN("I2C Bus Low?\n"); + return -EIO; + } + /* HDMI_CORE_DDC_STATUS_NO_ACK */ + if (REG_GET(HDMI_CORE_DDC_STATUS, 5, 5) == 1) { + DSSWARN("I2C No Ack\n"); + return -EIO; + } + + i = ext * 128; + j = 0; + while (((REG_GET(HDMI_CORE_DDC_STATUS, 4, 4) == 1) || + (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0)) && + j < 128) { + + if (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0) { + /* FIFO not empty */ + pedid[i++] = REG_GET(HDMI_CORE_DDC_DATA, 7, 0); + j++; + } + } + + for (j = 0; j < 128; j++) + checksum += pedid[j]; + + if (checksum != 0) { + DSSERR("E-EDID checksum failed!!\n"); + return -EIO; + } + + return 0; +} + +static int read_edid(u8 *pedid, u16 max_length) +{ + int r = 0, n = 0, i = 0; + int max_ext_blocks = (max_length / 128) - 1; + + r = hdmi_core_ddc_edid(pedid, 0); + if (r) { + return r; + } else { + n = pedid[0x7e]; + + /* + * README: need to comply with max_length set by the caller. + * Better implementation should be to allocate necessary + * memory to store EDID according to nb_block field found + * in first block + */ + if (n > max_ext_blocks) + n = max_ext_blocks; + + for (i = 1; i <= n; i++) { + r = hdmi_core_ddc_edid(pedid, i); + if (r) + return r; + } + } + return 0; +} + +static int get_timings_index(void) +{ + int code; + + if (hdmi.mode == 0) + code = code_vesa[hdmi.code]; + else + code = code_cea[hdmi.code]; + + if (code == -1) { + /* HDMI code 4 corresponds to 640 * 480 VGA */ + hdmi.code = 4; + /* DVI mode 1 corresponds to HDMI 0 to DVI */ + hdmi.mode = HDMI_DVI; + + code = code_vesa[hdmi.code]; + } + return code; +} + +static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) +{ + int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0; + int timing_vsync = 0, timing_hsync = 0; + struct omap_video_timings temp; + struct hdmi_cm cm = {-1}; + DSSDBG("hdmi_get_code\n"); + + for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) { + temp = cea_vesa_timings[i].timings; + if ((temp.pixel_clock == timing->pixel_clock) && + (temp.x_res == timing->x_res) && + (temp.y_res == timing->y_res)) { + + temp_hsync = temp.hfp + temp.hsw + temp.hbp; + timing_hsync = timing->hfp + timing->hsw + timing->hbp; + temp_vsync = temp.vfp + temp.vsw + temp.vbp; + timing_vsync = timing->vfp + timing->vsw + timing->vbp; + + DSSDBG("temp_hsync = %d , temp_vsync = %d" + "timing_hsync = %d, timing_vsync = %d\n", + temp_hsync, temp_hsync, + timing_hsync, timing_vsync); + + if ((temp_hsync == timing_hsync) && + (temp_vsync == timing_vsync)) { + code = i; + cm.code = code_index[i]; + if (code < 14) + cm.mode = HDMI_HDMI; + else + cm.mode = HDMI_DVI; + DSSDBG("Hdmi_code = %d mode = %d\n", + cm.code, cm.mode); + break; + } + } + } + + return cm; +} + +static void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid , + struct omap_video_timings *timings) +{ + /* X and Y resolution */ + timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) | + edid[current_descriptor_addrs + 2]); + timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) | + edid[current_descriptor_addrs + 5]); + + timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) | + edid[current_descriptor_addrs]); + + timings->pixel_clock = 10 * timings->pixel_clock; + + /* HORIZONTAL FRONT PORCH */ + timings->hfp = edid[current_descriptor_addrs + 8] | + ((edid[current_descriptor_addrs + 11] & 0xc0) << 2); + /* HORIZONTAL SYNC WIDTH */ + timings->hsw = edid[current_descriptor_addrs + 9] | + ((edid[current_descriptor_addrs + 11] & 0x30) << 4); + /* HORIZONTAL BACK PORCH */ + timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) | + edid[current_descriptor_addrs + 3]) - + (timings->hfp + timings->hsw); + /* VERTICAL FRONT PORCH */ + timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) | + ((edid[current_descriptor_addrs + 11] & 0x0f) << 2); + /* VERTICAL SYNC WIDTH */ + timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) | + ((edid[current_descriptor_addrs + 11] & 0x03) << 4); + /* VERTICAL BACK PORCH */ + timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) | + edid[current_descriptor_addrs + 6]) - + (timings->vfp + timings->vsw); + +} + +/* Description : This function gets the resolution information from EDID */ +static void get_edid_timing_data(u8 *edid) +{ + u8 count; + u16 current_descriptor_addrs; + struct hdmi_cm cm; + struct omap_video_timings edid_timings; + + /* seach block 0, there are 4 DTDs arranged in priority order */ + for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) { + current_descriptor_addrs = + EDID_DESCRIPTOR_BLOCK0_ADDRESS + + count * EDID_TIMING_DESCRIPTOR_SIZE; + get_horz_vert_timing_info(current_descriptor_addrs, + edid, &edid_timings); + cm = hdmi_get_code(&edid_timings); + DSSDBG("Block0[%d] value matches code = %d , mode = %d\n", + count, cm.code, cm.mode); + if (cm.code == -1) { + continue; + } else { + hdmi.code = cm.code; + hdmi.mode = cm.mode; + DSSDBG("code = %d , mode = %d\n", + hdmi.code, hdmi.mode); + return; + } + } + if (edid[0x7e] != 0x00) { + for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR; + count++) { + current_descriptor_addrs = + EDID_DESCRIPTOR_BLOCK1_ADDRESS + + count * EDID_TIMING_DESCRIPTOR_SIZE; + get_horz_vert_timing_info(current_descriptor_addrs, + edid, &edid_timings); + cm = hdmi_get_code(&edid_timings); + DSSDBG("Block1[%d] value matches code = %d, mode = %d", + count, cm.code, cm.mode); + if (cm.code == -1) { + continue; + } else { + hdmi.code = cm.code; + hdmi.mode = cm.mode; + DSSDBG("code = %d , mode = %d\n", + hdmi.code, hdmi.mode); + return; + } + } + } + + DSSINFO("no valid timing found , falling back to VGA\n"); + hdmi.code = 4; /* setting default value of 640 480 VGA */ + hdmi.mode = HDMI_DVI; +} + +static void hdmi_read_edid(struct omap_video_timings *dp) +{ + int ret = 0, code; + + memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH); + + if (!hdmi.edid_set) + ret = read_edid(hdmi.edid, HDMI_EDID_MAX_LENGTH); + + if (!ret) { + if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) { + /* search for timings of default resolution */ + get_edid_timing_data(hdmi.edid); + hdmi.edid_set = true; + } + } else { + DSSWARN("failed to read E-EDID\n"); + } + + if (!hdmi.edid_set) { + DSSINFO("fallback to VGA\n"); + hdmi.code = 4; /* setting default value of 640 480 VGA */ + hdmi.mode = HDMI_DVI; + } + + code = get_timings_index(); + + *dp = cea_vesa_timings[code].timings; +} + +static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, + struct hdmi_core_infoframe_avi *avi_cfg, + struct hdmi_core_packet_enable_repeat *repeat_cfg) +{ + DSSDBG("Enter hdmi_core_init\n"); + + /* video core */ + video_cfg->ip_bus_width = HDMI_INPUT_8BIT; + video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT; + video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE; + video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE; + video_cfg->hdmi_dvi = HDMI_DVI; + video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK; + + /* info frame */ + avi_cfg->db1_format = 0; + avi_cfg->db1_active_info = 0; + avi_cfg->db1_bar_info_dv = 0; + avi_cfg->db1_scan_info = 0; + avi_cfg->db2_colorimetry = 0; + avi_cfg->db2_aspect_ratio = 0; + avi_cfg->db2_active_fmt_ar = 0; + avi_cfg->db3_itc = 0; + avi_cfg->db3_ec = 0; + avi_cfg->db3_q_range = 0; + avi_cfg->db3_nup_scaling = 0; + avi_cfg->db4_videocode = 0; + avi_cfg->db5_pixel_repeat = 0; + avi_cfg->db6_7_line_eoftop = 0 ; + avi_cfg->db8_9_line_sofbottom = 0; + avi_cfg->db10_11_pixel_eofleft = 0; + avi_cfg->db12_13_pixel_sofright = 0; + + /* packet enable and repeat */ + repeat_cfg->audio_pkt = 0; + repeat_cfg->audio_pkt_repeat = 0; + repeat_cfg->avi_infoframe = 0; + repeat_cfg->avi_infoframe_repeat = 0; + repeat_cfg->gen_cntrl_pkt = 0; + repeat_cfg->gen_cntrl_pkt_repeat = 0; + repeat_cfg->generic_pkt = 0; + repeat_cfg->generic_pkt_repeat = 0; +} + +static void hdmi_core_powerdown_disable(void) +{ + DSSDBG("Enter hdmi_core_powerdown_disable\n"); + REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0); +} + +static void hdmi_core_swreset_release(void) +{ + DSSDBG("Enter hdmi_core_swreset_release\n"); + REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0); +} + +static void hdmi_core_swreset_assert(void) +{ + DSSDBG("Enter hdmi_core_swreset_assert\n"); + REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0); +} + +/* DSS_HDMI_CORE_VIDEO_CONFIG */ +static void hdmi_core_video_config(struct hdmi_core_video_config *cfg) +{ + u32 r = 0; + + /* sys_ctrl1 default configuration not tunable */ + r = hdmi_read_reg(HDMI_CORE_CTRL1); + r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5); + r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4); + r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2); + r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1); + hdmi_write_reg(HDMI_CORE_CTRL1, r); + + REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6); + + /* Vid_Mode */ + r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE); + + /* dither truncation configuration */ + if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) { + r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6); + r = FLD_MOD(r, 1, 5, 5); + } else { + r = FLD_MOD(r, cfg->op_dither_truc, 7, 6); + r = FLD_MOD(r, 0, 5, 5); + } + hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r); + + /* HDMI_Ctrl */ + r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL); + r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6); + r = FLD_MOD(r, cfg->pkt_mode, 5, 3); + r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0); + hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r); + + /* TMDS_CTRL */ + REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL, + cfg->tclk_sel_clkmult, 6, 5); +} + +static void hdmi_core_aux_infoframe_avi_config( + struct hdmi_core_infoframe_avi info_avi) +{ + u32 val; + char sum = 0, checksum = 0; + + sum += 0x82 + 0x002 + 0x00D; + hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082); + hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002); + hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D); + + val = (info_avi.db1_format << 5) | + (info_avi.db1_active_info << 4) | + (info_avi.db1_bar_info_dv << 2) | + (info_avi.db1_scan_info); + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val); + sum += val; + + val = (info_avi.db2_colorimetry << 6) | + (info_avi.db2_aspect_ratio << 4) | + (info_avi.db2_active_fmt_ar); + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val); + sum += val; + + val = (info_avi.db3_itc << 7) | + (info_avi.db3_ec << 4) | + (info_avi.db3_q_range << 2) | + (info_avi.db3_nup_scaling); + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val); + sum += val; + + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode); + sum += info_avi.db4_videocode; + + val = info_avi.db5_pixel_repeat; + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val); + sum += val; + + val = info_avi.db6_7_line_eoftop & 0x00FF; + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val); + sum += val; + + val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF); + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val); + sum += val; + + val = info_avi.db8_9_line_sofbottom & 0x00FF; + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val); + sum += val; + + val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF); + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val); + sum += val; + + val = info_avi.db10_11_pixel_eofleft & 0x00FF; + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val); + sum += val; + + val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF); + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val); + sum += val; + + val = info_avi.db12_13_pixel_sofright & 0x00FF; + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val); + sum += val; + + val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF); + hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val); + sum += val; + + checksum = 0x100 - sum; + hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum); +} + +static void hdmi_core_av_packet_config( + struct hdmi_core_packet_enable_repeat repeat_cfg) +{ + /* enable/repeat the infoframe */ + hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1, + (repeat_cfg.audio_pkt << 5) | + (repeat_cfg.audio_pkt_repeat << 4) | + (repeat_cfg.avi_infoframe << 1) | + (repeat_cfg.avi_infoframe_repeat)); + + /* enable/repeat the packet */ + hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2, + (repeat_cfg.gen_cntrl_pkt << 3) | + (repeat_cfg.gen_cntrl_pkt_repeat << 2) | + (repeat_cfg.generic_pkt << 1) | + (repeat_cfg.generic_pkt_repeat)); +} + +static void hdmi_wp_init(struct omap_video_timings *timings, + struct hdmi_video_format *video_fmt, + struct hdmi_video_interface *video_int) +{ + DSSDBG("Enter hdmi_wp_init\n"); + + timings->hbp = 0; + timings->hfp = 0; + timings->hsw = 0; + timings->vbp = 0; + timings->vfp = 0; + timings->vsw = 0; + + video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444; + video_fmt->y_res = 0; + video_fmt->x_res = 0; + + video_int->vsp = 0; + video_int->hsp = 0; + + video_int->interlacing = 0; + video_int->tm = 0; /* HDMI_TIMING_SLAVE */ + +} + +static void hdmi_wp_video_start(bool start) +{ + REG_FLD_MOD(HDMI_WP_VIDEO_CFG, start, 31, 31); +} + +static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt, + struct omap_video_timings *timings, struct hdmi_config *param) +{ + DSSDBG("Enter hdmi_wp_video_init_format\n"); + + video_fmt->y_res = param->timings.timings.y_res; + video_fmt->x_res = param->timings.timings.x_res; + + timings->hbp = param->timings.timings.hbp; + timings->hfp = param->timings.timings.hfp; + timings->hsw = param->timings.timings.hsw; + timings->vbp = param->timings.timings.vbp; + timings->vfp = param->timings.timings.vfp; + timings->vsw = param->timings.timings.vsw; +} + +static void hdmi_wp_video_config_format( + struct hdmi_video_format *video_fmt) +{ + u32 l = 0; + + REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8); + + l |= FLD_VAL(video_fmt->y_res, 31, 16); + l |= FLD_VAL(video_fmt->x_res, 15, 0); + hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l); +} + +static void hdmi_wp_video_config_interface( + struct hdmi_video_interface *video_int) +{ + u32 r; + DSSDBG("Enter hdmi_wp_video_config_interface\n"); + + r = hdmi_read_reg(HDMI_WP_VIDEO_CFG); + r = FLD_MOD(r, video_int->vsp, 7, 7); + r = FLD_MOD(r, video_int->hsp, 6, 6); + r = FLD_MOD(r, video_int->interlacing, 3, 3); + r = FLD_MOD(r, video_int->tm, 1, 0); + hdmi_write_reg(HDMI_WP_VIDEO_CFG, r); +} + +static void hdmi_wp_video_config_timing( + struct omap_video_timings *timings) +{ + u32 timing_h = 0; + u32 timing_v = 0; + + DSSDBG("Enter hdmi_wp_video_config_timing\n"); + + timing_h |= FLD_VAL(timings->hbp, 31, 20); + timing_h |= FLD_VAL(timings->hfp, 19, 8); + timing_h |= FLD_VAL(timings->hsw, 7, 0); + hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h); + + timing_v |= FLD_VAL(timings->vbp, 31, 20); + timing_v |= FLD_VAL(timings->vfp, 19, 8); + timing_v |= FLD_VAL(timings->vsw, 7, 0); + hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v); +} + +static void hdmi_basic_configure(struct hdmi_config *cfg) +{ + /* HDMI */ + struct omap_video_timings video_timing; + struct hdmi_video_format video_format; + struct hdmi_video_interface video_interface; + /* HDMI core */ + struct hdmi_core_infoframe_avi avi_cfg; + struct hdmi_core_video_config v_core_cfg; + struct hdmi_core_packet_enable_repeat repeat_cfg; + + hdmi_wp_init(&video_timing, &video_format, + &video_interface); + + hdmi_core_init(&v_core_cfg, + &avi_cfg, + &repeat_cfg); + + hdmi_wp_video_init_format(&video_format, + &video_timing, cfg); + + hdmi_wp_video_config_timing(&video_timing); + + /* video config */ + video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422; + + hdmi_wp_video_config_format(&video_format); + + video_interface.vsp = cfg->timings.vsync_pol; + video_interface.hsp = cfg->timings.hsync_pol; + video_interface.interlacing = cfg->interlace; + video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */ + + hdmi_wp_video_config_interface(&video_interface); + + /* + * configure core video part + * set software reset in the core + */ + hdmi_core_swreset_assert(); + + /* power down off */ + hdmi_core_powerdown_disable(); + + v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL; + v_core_cfg.hdmi_dvi = cfg->cm.mode; + + hdmi_core_video_config(&v_core_cfg); + + /* release software reset in the core */ + hdmi_core_swreset_release(); + + /* + * configure packet + * info frame video see doc CEA861-D page 65 + */ + avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; + avi_cfg.db1_active_info = + HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; + avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; + avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; + avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; + avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; + avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; + avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; + avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; + avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; + avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; + avi_cfg.db4_videocode = cfg->cm.code; + avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; + avi_cfg.db6_7_line_eoftop = 0; + avi_cfg.db8_9_line_sofbottom = 0; + avi_cfg.db10_11_pixel_eofleft = 0; + avi_cfg.db12_13_pixel_sofright = 0; + + hdmi_core_aux_infoframe_avi_config(avi_cfg); + + /* enable/repeat the infoframe */ + repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; + repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON; + /* wakeup */ + repeat_cfg.audio_pkt = HDMI_PACKETENABLE; + repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON; + hdmi_core_av_packet_config(repeat_cfg); +} + +static void update_hdmi_timings(struct hdmi_config *cfg, + struct omap_video_timings *timings, int code) +{ + cfg->timings.timings.x_res = timings->x_res; + cfg->timings.timings.y_res = timings->y_res; + cfg->timings.timings.hbp = timings->hbp; + cfg->timings.timings.hfp = timings->hfp; + cfg->timings.timings.hsw = timings->hsw; + cfg->timings.timings.vbp = timings->vbp; + cfg->timings.timings.vfp = timings->vfp; + cfg->timings.timings.vsw = timings->vsw; + cfg->timings.timings.pixel_clock = timings->pixel_clock; + cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol; + cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol; +} + +static void hdmi_compute_pll(unsigned long clkin, int phy, + int n, struct hdmi_pll_info *pi) +{ + unsigned long refclk; + u32 mf; + + /* + * Input clock is predivided by N + 1 + * out put of which is reference clk + */ + refclk = clkin / (n + 1); + pi->regn = n; + + /* + * multiplier is pixel_clk/ref_clk + * Multiplying by 100 to avoid fractional part removal + */ + pi->regm = (phy * 100/(refclk))/100; + pi->regm2 = 1; + + /* + * 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 * refclk) * 262144; + pi->regmf = 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) / ((n + 1) * 250) + 5) / 10; + + DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf); + DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); +} + +static void hdmi_enable_clocks(int enable) +{ + if (enable) + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | + DSS_CLK_SYSCK | DSS_CLK_VIDFCK); + else + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | + DSS_CLK_SYSCK | DSS_CLK_VIDFCK); +} + +static int hdmi_power_on(struct omap_dss_device *dssdev) +{ + int r, code = 0; + struct hdmi_pll_info pll_data; + struct omap_video_timings *p; + int clkin, n, phy; + + hdmi_enable_clocks(1); + + dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0); + + p = &dssdev->panel.timings; + + DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", + dssdev->panel.timings.x_res, + dssdev->panel.timings.y_res); + + if (!hdmi.custom_set) { + DSSDBG("Read EDID as no EDID is not set on poweron\n"); + hdmi_read_edid(p); + } + code = get_timings_index(); + dssdev->panel.timings = cea_vesa_timings[code].timings; + update_hdmi_timings(&hdmi.cfg, p, code); + + clkin = 3840; /* 38.4 MHz */ + n = 15; /* this is a constant for our math */ + phy = p->pixel_clock; + + hdmi_compute_pll(clkin, phy, n, &pll_data); + + hdmi_wp_video_start(0); + + /* config the PLL and PHY first */ + r = hdmi_pll_program(&pll_data); + if (r) { + DSSDBG("Failed to lock PLL\n"); + goto err; + } + + r = hdmi_phy_init(); + if (r) { + DSSDBG("Failed to start PHY\n"); + goto err; + } + + hdmi.cfg.cm.mode = hdmi.mode; + hdmi.cfg.cm.code = hdmi.code; + hdmi_basic_configure(&hdmi.cfg); + + /* Make selection of HDMI in DSS */ + dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); + + /* Select the dispc clock source as PRCM clock, to ensure that it is not + * DSI PLL source as the clock selected by DSI PLL might not be + * sufficient for the resolution selected / that can be changed + * dynamically by user. This can be moved to single location , say + * Boardfile. + */ + dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); + + /* bypass TV gamma table */ + dispc_enable_gamma_table(0); + + /* tv size */ + dispc_set_digit_size(dssdev->panel.timings.x_res, + dssdev->panel.timings.y_res); + + dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1); + + hdmi_wp_video_start(1); + + return 0; +err: + hdmi_enable_clocks(0); + return -EIO; +} + +static void hdmi_power_off(struct omap_dss_device *dssdev) +{ + dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0); + + hdmi_wp_video_start(0); + hdmi_phy_off(); + hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF); + hdmi_enable_clocks(0); + + hdmi.edid_set = 0; +} + +int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + struct hdmi_cm cm; + + cm = hdmi_get_code(timings); + if (cm.code == -1) { + DSSERR("Invalid timing entered\n"); + return -EINVAL; + } + + return 0; + +} + +void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev) +{ + struct hdmi_cm cm; + + hdmi.custom_set = 1; + cm = hdmi_get_code(&dssdev->panel.timings); + hdmi.code = cm.code; + hdmi.mode = cm.mode; + omapdss_hdmi_display_enable(dssdev); + hdmi.custom_set = 0; +} + +int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + + DSSDBG("ENTER hdmi_display_enable\n"); + + mutex_lock(&hdmi.lock); + + r = omap_dss_start_device(dssdev); + if (r) { + DSSERR("failed to start device\n"); + goto err0; + } + + if (dssdev->platform_enable) { + r = dssdev->platform_enable(dssdev); + if (r) { + DSSERR("failed to enable GPIO's\n"); + goto err1; + } + } + + r = hdmi_power_on(dssdev); + if (r) { + DSSERR("failed to power on device\n"); + goto err2; + } + + mutex_unlock(&hdmi.lock); + return 0; + +err2: + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); +err1: + omap_dss_stop_device(dssdev); +err0: + mutex_unlock(&hdmi.lock); + return r; +} + +void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) +{ + DSSDBG("Enter hdmi_display_disable\n"); + + mutex_lock(&hdmi.lock); + + hdmi_power_off(dssdev); + + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + omap_dss_stop_device(dssdev); + + mutex_unlock(&hdmi.lock); +} + +/* HDMI HW IP initialisation */ +static int omapdss_hdmihw_probe(struct platform_device *pdev) +{ + struct resource *hdmi_mem; + + hdmi.pdata = pdev->dev.platform_data; + hdmi.pdev = pdev; + + mutex_init(&hdmi.lock); + + hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0); + if (!hdmi_mem) { + DSSERR("can't get IORESOURCE_MEM HDMI\n"); + return -EINVAL; + } + + /* Base address taken from platform */ + hdmi.base_wp = ioremap(hdmi_mem->start, resource_size(hdmi_mem)); + if (!hdmi.base_wp) { + DSSERR("can't ioremap WP\n"); + return -ENOMEM; + } + + hdmi_panel_init(); + + return 0; +} + +static int omapdss_hdmihw_remove(struct platform_device *pdev) +{ + hdmi_panel_exit(); + + iounmap(hdmi.base_wp); + + return 0; +} + +static struct platform_driver omapdss_hdmihw_driver = { + .probe = omapdss_hdmihw_probe, + .remove = omapdss_hdmihw_remove, + .driver = { + .name = "omapdss_hdmi", + .owner = THIS_MODULE, + }, +}; + +int hdmi_init_platform_driver(void) +{ + return platform_driver_register(&omapdss_hdmihw_driver); +} + +void hdmi_uninit_platform_driver(void) +{ + return platform_driver_unregister(&omapdss_hdmihw_driver); +} -- cgit v1.2.3-70-g09d2 From 70be83235ea2815f6c2a5fd45753de406be6c6aa Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Thu, 10 Mar 2011 15:48:48 +0530 Subject: OMAP4: DSS2: HDMI: HDMI panel driver addition in the DSS The panel driver(hdmi_omap4_panel.c) in omap2/dss acts as a controller to manage the enable and disable requests and synchronize audio and video. Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.h | 2 + drivers/video/omap2/dss/hdmi_omap4_panel.c | 222 +++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 drivers/video/omap2/dss/hdmi_omap4_panel.c (limited to 'drivers/video/omap2/dss/dss.h') diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 91ed3fa8e60..c2f582bb19c 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -477,6 +477,8 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev); int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, struct omap_video_timings *timings); +int hdmi_panel_init(void); +void hdmi_panel_exit(void); /* RFBI */ #ifdef CONFIG_OMAP2_DSS_RFBI diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_omap4_panel.c new file mode 100644 index 00000000000..ffb5de94131 --- /dev/null +++ b/drivers/video/omap2/dss/hdmi_omap4_panel.c @@ -0,0 +1,222 @@ +/* + * hdmi_omap4_panel.c + * + * HDMI library support functions for TI OMAP4 processors. + * + * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ + * Authors: Mythri P k + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include "dss.h" + +static struct { + struct mutex hdmi_lock; +} hdmi; + + +static int hdmi_panel_probe(struct omap_dss_device *dssdev) +{ + DSSDBG("ENTER hdmi_panel_probe\n"); + + dssdev->panel.config = OMAP_DSS_LCD_TFT | + OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS; + + /* + * Initialize the timings to 640 * 480 + * This is only for framebuffer update not for TV timing setting + * Setting TV timing will be done only on enable + */ + dssdev->panel.timings.x_res = 640; + dssdev->panel.timings.y_res = 480; + + DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n", + dssdev->panel.timings.x_res, + dssdev->panel.timings.y_res); + return 0; +} + +static void hdmi_panel_remove(struct omap_dss_device *dssdev) +{ + +} + +static int hdmi_panel_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + DSSDBG("ENTER hdmi_panel_enable\n"); + + mutex_lock(&hdmi.hdmi_lock); + + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { + r = -EINVAL; + goto err; + } + + r = omapdss_hdmi_display_enable(dssdev); + if (r) { + DSSERR("failed to power on\n"); + goto err; + } + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + +err: + mutex_unlock(&hdmi.hdmi_lock); + + return r; +} + +static void hdmi_panel_disable(struct omap_dss_device *dssdev) +{ + mutex_lock(&hdmi.hdmi_lock); + + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) + omapdss_hdmi_display_disable(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; + + mutex_unlock(&hdmi.hdmi_lock); +} + +static int hdmi_panel_suspend(struct omap_dss_device *dssdev) +{ + int r = 0; + + mutex_lock(&hdmi.hdmi_lock); + + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { + r = -EINVAL; + goto err; + } + + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; + + omapdss_hdmi_display_disable(dssdev); + +err: + mutex_unlock(&hdmi.hdmi_lock); + + return r; +} + +static int hdmi_panel_resume(struct omap_dss_device *dssdev) +{ + int r = 0; + + mutex_lock(&hdmi.hdmi_lock); + + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { + r = -EINVAL; + goto err; + } + + r = omapdss_hdmi_display_enable(dssdev); + if (r) { + DSSERR("failed to power on\n"); + goto err; + } + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + +err: + mutex_unlock(&hdmi.hdmi_lock); + + return r; +} + +static void hdmi_get_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + mutex_lock(&hdmi.hdmi_lock); + + *timings = dssdev->panel.timings; + + mutex_unlock(&hdmi.hdmi_lock); +} + +static void hdmi_set_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + DSSDBG("hdmi_set_timings\n"); + + mutex_lock(&hdmi.hdmi_lock); + + dssdev->panel.timings = *timings; + + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { + /* turn the hdmi off and on to get new timings to use */ + omapdss_hdmi_display_disable(dssdev); + omapdss_hdmi_display_set_timing(dssdev); + } + + mutex_unlock(&hdmi.hdmi_lock); +} + +static int hdmi_check_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + int r = 0; + + DSSDBG("hdmi_check_timings\n"); + + mutex_lock(&hdmi.hdmi_lock); + + r = omapdss_hdmi_display_check_timing(dssdev, timings); + if (r) { + DSSERR("Timing cannot be applied\n"); + goto err; + } +err: + mutex_unlock(&hdmi.hdmi_lock); + return r; +} + +static struct omap_dss_driver hdmi_driver = { + .probe = hdmi_panel_probe, + .remove = hdmi_panel_remove, + .enable = hdmi_panel_enable, + .disable = hdmi_panel_disable, + .suspend = hdmi_panel_suspend, + .resume = hdmi_panel_resume, + .get_timings = hdmi_get_timings, + .set_timings = hdmi_set_timings, + .check_timings = hdmi_check_timings, + .driver = { + .name = "hdmi_panel", + .owner = THIS_MODULE, + }, +}; + +int hdmi_panel_init(void) +{ + mutex_init(&hdmi.hdmi_lock); + + omap_dss_register_driver(&hdmi_driver); + + return 0; +} + +void hdmi_panel_exit(void) +{ + omap_dss_unregister_driver(&hdmi_driver); + +} -- cgit v1.2.3-70-g09d2