Skip to content

Commit 3cc4a2f

Browse files
Ranjith LohithakshanPaul Walmsley
authored andcommitted
AM35xx: Add clock support for new modules on AM35xx
This patch adds clock support for the following AM35xx modules - Ethernet MAC - CAN Controller (HECC) - New MUSB OTG Controller with integrated Phy - Video Processing Front End (VPFE) - Additional UART (UART4) Signed-off-by: Ranjith Lohithakshan <[email protected]> Signed-off-by: Paul Walmsley <[email protected]>
1 parent 419cc97 commit 3cc4a2f

File tree

4 files changed

+225
-0
lines changed

4 files changed

+225
-0
lines changed

arch/arm/mach-omap2/clock34xx.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@
3939
*/
4040
#define DPLL5_FREQ_FOR_USBHOST 120000000
4141

42+
/*
43+
* In AM35xx IPSS, the {ICK,FCK} enable bits for modules are exported
44+
* in the same register at a bit offset of 0x8. The EN_ACK for ICK is
45+
* at an offset of 4 from ICK enable bit.
46+
*/
47+
#define AM35XX_IPSS_ICK_MASK 0xF
48+
#define AM35XX_IPSS_ICK_EN_ACK_OFFSET 0x4
49+
#define AM35XX_IPSS_ICK_FCK_OFFSET 0x8
50+
#define AM35XX_IPSS_CLK_IDLEST_VAL 0
51+
4252
/* needed by omap3_core_dpll_m2_set_rate() */
4353
struct clk *sdrc_ick_p, *arm_fck_p;
4454

@@ -144,6 +154,89 @@ const struct clkops omap3_clkops_noncore_dpll_ops = {
144154
.disable = omap3_noncore_dpll_disable,
145155
};
146156

157+
/**
158+
* am35xx_clk_find_idlest - return clock ACK info for AM35XX IPSS
159+
* @clk: struct clk * being enabled
160+
* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
161+
* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
162+
* @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
163+
*
164+
* The interface clocks on AM35xx IPSS reflects the clock idle status
165+
* in the enable register itsel at a bit offset of 4 from the enable
166+
* bit. A value of 1 indicates that clock is enabled.
167+
*/
168+
static void am35xx_clk_find_idlest(struct clk *clk,
169+
void __iomem **idlest_reg,
170+
u8 *idlest_bit,
171+
u8 *idlest_val)
172+
{
173+
*idlest_reg = (__force void __iomem *)(clk->enable_reg);
174+
*idlest_bit = clk->enable_bit + AM35XX_IPSS_ICK_EN_ACK_OFFSET;
175+
*idlest_val = AM35XX_IPSS_CLK_IDLEST_VAL;
176+
}
177+
178+
/**
179+
* am35xx_clk_find_companion - find companion clock to @clk
180+
* @clk: struct clk * to find the companion clock of
181+
* @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
182+
* @other_bit: u8 ** to return the companion clock bit shift in
183+
*
184+
* Some clocks don't have companion clocks. For example, modules with
185+
* only an interface clock (such as HECC) don't have a companion
186+
* clock. Right now, this code relies on the hardware exporting a bit
187+
* in the correct companion register that indicates that the
188+
* nonexistent 'companion clock' is active. Future patches will
189+
* associate this type of code with per-module data structures to
190+
* avoid this issue, and remove the casts. No return value.
191+
*/
192+
static void am35xx_clk_find_companion(struct clk *clk, void __iomem **other_reg,
193+
u8 *other_bit)
194+
{
195+
*other_reg = (__force void __iomem *)(clk->enable_reg);
196+
if (clk->enable_bit & AM35XX_IPSS_ICK_MASK)
197+
*other_bit = clk->enable_bit + AM35XX_IPSS_ICK_FCK_OFFSET;
198+
else
199+
*other_bit = clk->enable_bit - AM35XX_IPSS_ICK_FCK_OFFSET;
200+
}
201+
202+
const struct clkops clkops_am35xx_ipss_module_wait = {
203+
.enable = omap2_dflt_clk_enable,
204+
.disable = omap2_dflt_clk_disable,
205+
.find_idlest = am35xx_clk_find_idlest,
206+
.find_companion = am35xx_clk_find_companion,
207+
};
208+
209+
/**
210+
* am35xx_clk_ipss_find_idlest - return CM_IDLEST info for IPSS
211+
* @clk: struct clk * being enabled
212+
* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
213+
* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
214+
* @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
215+
*
216+
* The IPSS target CM_IDLEST bit is at a different shift from the
217+
* CM_{I,F}CLKEN bit. Pass back the correct info via @idlest_reg
218+
* and @idlest_bit. No return value.
219+
*/
220+
static void am35xx_clk_ipss_find_idlest(struct clk *clk,
221+
void __iomem **idlest_reg,
222+
u8 *idlest_bit,
223+
u8 *idlest_val)
224+
{
225+
u32 r;
226+
227+
r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
228+
*idlest_reg = (__force void __iomem *)r;
229+
*idlest_bit = AM35XX_ST_IPSS_SHIFT;
230+
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
231+
}
232+
233+
const struct clkops clkops_am35xx_ipss_wait = {
234+
.enable = omap2_dflt_clk_enable,
235+
.disable = omap2_dflt_clk_disable,
236+
.find_idlest = am35xx_clk_ipss_find_idlest,
237+
.find_companion = omap2_clk_dflt_find_companion,
238+
};
239+
147240
int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
148241
{
149242
/*

arch/arm/mach-omap2/clock34xx.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,8 @@ extern const struct clkops clkops_omap3430es2_hsotgusb_wait;
2222
extern const struct clkops clkops_omap3430es2_dss_usbhost_wait;
2323
extern const struct clkops omap3_clkops_noncore_dpll_ops;
2424

25+
/* AM35xx-specific clkops */
26+
extern const struct clkops clkops_am35xx_ipss_module_wait;
27+
extern const struct clkops clkops_am35xx_ipss_wait;
28+
2529
#endif

arch/arm/mach-omap2/clock34xx_data.c

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2983,6 +2983,113 @@ static struct clk wdt1_fck = {
29832983
.recalc = &followparent_recalc,
29842984
};
29852985

2986+
/* Clocks for AM35XX */
2987+
static struct clk ipss_ick = {
2988+
.name = "ipss_ick",
2989+
.ops = &clkops_am35xx_ipss_wait,
2990+
.parent = &core_l3_ick,
2991+
.clkdm_name = "core_l3_clkdm",
2992+
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
2993+
.enable_bit = AM35XX_EN_IPSS_SHIFT,
2994+
.recalc = &followparent_recalc,
2995+
};
2996+
2997+
static struct clk emac_ick = {
2998+
.name = "emac_ick",
2999+
.ops = &clkops_am35xx_ipss_module_wait,
3000+
.parent = &ipss_ick,
3001+
.clkdm_name = "core_l3_clkdm",
3002+
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
3003+
.enable_bit = AM35XX_CPGMAC_VBUSP_CLK_SHIFT,
3004+
.recalc = &followparent_recalc,
3005+
};
3006+
3007+
static struct clk rmii_ck = {
3008+
.name = "rmii_ck",
3009+
.ops = &clkops_null,
3010+
.flags = RATE_FIXED,
3011+
.rate = 50000000,
3012+
};
3013+
3014+
static struct clk emac_fck = {
3015+
.name = "emac_fck",
3016+
.ops = &clkops_omap2_dflt,
3017+
.parent = &rmii_ck,
3018+
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
3019+
.enable_bit = AM35XX_CPGMAC_FCLK_SHIFT,
3020+
.recalc = &followparent_recalc,
3021+
};
3022+
3023+
static struct clk hsotgusb_ick_am35xx = {
3024+
.name = "hsotgusb_ick",
3025+
.ops = &clkops_am35xx_ipss_module_wait,
3026+
.parent = &ipss_ick,
3027+
.clkdm_name = "core_l3_clkdm",
3028+
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
3029+
.enable_bit = AM35XX_USBOTG_VBUSP_CLK_SHIFT,
3030+
.recalc = &followparent_recalc,
3031+
};
3032+
3033+
static struct clk hsotgusb_fck_am35xx = {
3034+
.name = "hsotgusb_fck",
3035+
.ops = &clkops_omap2_dflt,
3036+
.parent = &sys_ck,
3037+
.clkdm_name = "core_l3_clkdm",
3038+
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
3039+
.enable_bit = AM35XX_USBOTG_FCLK_SHIFT,
3040+
.recalc = &followparent_recalc,
3041+
};
3042+
3043+
static struct clk hecc_ck = {
3044+
.name = "hecc_ck",
3045+
.ops = &clkops_am35xx_ipss_module_wait,
3046+
.parent = &sys_ck,
3047+
.clkdm_name = "core_l3_clkdm",
3048+
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
3049+
.enable_bit = AM35XX_HECC_VBUSP_CLK_SHIFT,
3050+
.recalc = &followparent_recalc,
3051+
};
3052+
3053+
static struct clk vpfe_ick = {
3054+
.name = "vpfe_ick",
3055+
.ops = &clkops_am35xx_ipss_module_wait,
3056+
.parent = &ipss_ick,
3057+
.clkdm_name = "core_l3_clkdm",
3058+
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
3059+
.enable_bit = AM35XX_VPFE_VBUSP_CLK_SHIFT,
3060+
.recalc = &followparent_recalc,
3061+
};
3062+
3063+
static struct clk pclk_ck = {
3064+
.name = "pclk_ck",
3065+
.ops = &clkops_null,
3066+
.flags = RATE_FIXED,
3067+
.rate = 27000000,
3068+
};
3069+
3070+
static struct clk vpfe_fck = {
3071+
.name = "vpfe_fck",
3072+
.ops = &clkops_omap2_dflt,
3073+
.parent = &pclk_ck,
3074+
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
3075+
.enable_bit = AM35XX_VPFE_FCLK_SHIFT,
3076+
.recalc = &followparent_recalc,
3077+
};
3078+
3079+
/*
3080+
* The UART1/2 functional clock acts as the functional
3081+
* clock for UART4. No separate fclk control available.
3082+
*/
3083+
static struct clk uart4_ick_am35xx = {
3084+
.name = "uart4_ick",
3085+
.ops = &clkops_omap2_dflt_wait,
3086+
.parent = &core_l4_ick,
3087+
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
3088+
.enable_bit = AM35XX_EN_UART4_SHIFT,
3089+
.clkdm_name = "core_l4_clkdm",
3090+
.recalc = &followparent_recalc,
3091+
};
3092+
29863093

29873094
/*
29883095
* clkdev
@@ -3209,6 +3316,17 @@ static struct omap_clk omap3xxx_clks[] = {
32093316
CLK(NULL, "secure_32k_fck", &secure_32k_fck, CK_3XXX),
32103317
CLK(NULL, "gpt12_fck", &gpt12_fck, CK_3XXX),
32113318
CLK(NULL, "wdt1_fck", &wdt1_fck, CK_3XXX),
3319+
CLK(NULL, "ipss_ick", &ipss_ick, CK_AM35XX),
3320+
CLK(NULL, "rmii_ck", &rmii_ck, CK_AM35XX),
3321+
CLK(NULL, "pclk_ck", &pclk_ck, CK_AM35XX),
3322+
CLK("davinci_emac", "ick", &emac_ick, CK_AM35XX),
3323+
CLK("davinci_emac", "fck", &emac_fck, CK_AM35XX),
3324+
CLK("vpfe-capture", "master", &vpfe_ick, CK_AM35XX),
3325+
CLK("vpfe-capture", "slave", &vpfe_fck, CK_AM35XX),
3326+
CLK("musb_hdrc", "ick", &hsotgusb_ick_am35xx, CK_AM35XX),
3327+
CLK("musb_hdrc", "fck", &hsotgusb_fck_am35xx, CK_AM35XX),
3328+
CLK(NULL, "hecc_ck", &hecc_ck, CK_AM35XX),
3329+
CLK(NULL, "uart4_ick", &uart4_ick_am35xx, CK_AM35XX),
32123330
};
32133331

32143332

arch/arm/mach-omap2/cm-regbits-34xx.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,12 @@
168168
#define OMAP3430_EN_SDRC (1 << 1)
169169
#define OMAP3430_EN_SDRC_SHIFT 1
170170

171+
/* AM35XX specific CM_ICLKEN1_CORE bits */
172+
#define AM35XX_EN_IPSS_MASK (1 << 4)
173+
#define AM35XX_EN_IPSS_SHIFT 4
174+
#define AM35XX_EN_UART4_MASK (1 << 23)
175+
#define AM35XX_EN_UART4_SHIFT 23
176+
171177
/* CM_ICLKEN2_CORE */
172178
#define OMAP3430_EN_PKA (1 << 4)
173179
#define OMAP3430_EN_PKA_SHIFT 4
@@ -220,6 +226,10 @@
220226
#define OMAP3430_ST_SSI_STDBY_SHIFT 0
221227
#define OMAP3430_ST_SSI_STDBY_MASK (1 << 0)
222228

229+
/* AM35xx specific CM_IDLEST1_CORE bits */
230+
#define AM35XX_ST_IPSS_SHIFT 5
231+
#define AM35XX_ST_IPSS_MASK (1 << 5)
232+
223233
/* CM_IDLEST2_CORE */
224234
#define OMAP3430_ST_PKA_SHIFT 4
225235
#define OMAP3430_ST_PKA_MASK (1 << 4)

0 commit comments

Comments
 (0)