From patchwork Fri Mar 4 11:02:44 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: archit taneja X-Patchwork-Id: 608561 X-Patchwork-Delegate: tomi.valkeinen@nokia.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p24AxZkI012294 for ; Fri, 4 Mar 2011 10:59:35 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759447Ab1CDK7e (ORCPT ); Fri, 4 Mar 2011 05:59:34 -0500 Received: from devils.ext.ti.com ([198.47.26.153]:51907 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752084Ab1CDK7d (ORCPT ); Fri, 4 Mar 2011 05:59:33 -0500 Received: from dlep36.itg.ti.com ([157.170.170.91]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id p24AxWpH008157 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 4 Mar 2011 04:59:32 -0600 Received: from legion.dal.design.ti.com (localhost [127.0.0.1]) by dlep36.itg.ti.com (8.13.8/8.13.8) with ESMTP id p24AxUgV013384; Fri, 4 Mar 2011 04:59:30 -0600 (CST) Received: from localhost (a0393947pc.apr.dhcp.ti.com [172.24.137.144]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id p24AxSf19306; Fri, 4 Mar 2011 04:59:28 -0600 (CST) From: Archit Taneja To: tomi.valkeinen@ti.com Cc: linux-omap@vger.kernel.org, Archit Taneja Subject: [PATCH] OMAP4: DSS2: Clock source changes for OMAP4 Date: Fri, 4 Mar 2011 16:32:44 +0530 Message-Id: <1299236564-1021-1-git-send-email-archit@ti.com> X-Mailer: git-send-email 1.7.1 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 04 Mar 2011 10:59:35 +0000 (UTC) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index dae9686..7b4392b 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2341,14 +2341,21 @@ 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 + break; #ifdef CONFIG_OMAP2_DSS_DSI + case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: r = dsi_get_pll_hsdiv_dispc_rate(); + break; #else - BUG(); + case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: + BUG(); #endif + default: + BUG(); + } return r; } @@ -2362,25 +2369,35 @@ unsigned long dispc_lclk_rate(enum omap_channel channel) lcd = FLD_GET(l, 23, 16); - r = dispc_fclk_rate(); + if (dss_has_feature(FEAT_LCD_CLK_SRC)) { + if (dss_get_lcd_clk_source(channel) == DSS_CLK_SRC_FCK) + r = dss_clk_get_rate(DSS_CLK_FCK); + else +#ifdef CONFIG_OMAP2_DSS_DSI + r = dsi_get_pll_hsdiv_dispc_rate(); +#else + BUG(); +#endif + } else { + r = dispc_fclk_rate(); + } 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) @@ -2388,6 +2405,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); @@ -2409,6 +2427,14 @@ void dispc_dump_clocks(struct seq_file *s) } seq_printf(s, "- LCD1 -\n"); + if (dss_has_feature(FEAT_LCD_CLK_SRC)) { + 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", @@ -2418,6 +2444,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 2be4d03..cfffa88 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,16 +293,23 @@ void dss_dump_regs(struct seq_file *s) 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) + u8 start, end; + + 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(); + } + + dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end); - REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ + REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */ dss.dispc_clk_source = clk_src; } @@ -310,19 +318,50 @@ 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 */ 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; + + 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; @@ -333,6 +372,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) { @@ -617,6 +662,11 @@ static int dss_init(void) dss.dsi_clk_source = DSS_CLK_SRC_FCK; dss.dispc_clk_source = DSS_CLK_SRC_FCK; + if (dss_has_feature(FEAT_LCD_CLK_SRC)) { + dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK; + dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK; + } + dss_save_context(); rev = dss_read_reg(DSS_REVISION); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 85d4141..8d5c2a4 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 dc170ad..6eb6ec6 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 569d1b2..3302247 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 (MAX_DSS_MANAGERS - 1) /* 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 */