Commit e2e0136476397be4fccd16569bbe0695d591c979
1 parent
f0b5a75f1f
Exists in
master
arm:omap:am33xx: Cleanup and fix PRM code
There were some custom API's being introduced for GFX and PRUSS module clk_enable/disable, in order to bring the module out-of-reset. Although there are HWMOD hooks available for doing same thing, so now using generic omap2 clock API's, replacing these custom API's. This will mean, deleting prcm33xx.h and clock33xx.c
Showing 8 changed files with 127 additions and 168 deletions Side-by-side Diff
arch/arm/mach-omap2/Makefile
... | ... | @@ -147,7 +147,7 @@ |
147 | 147 | clock3517.o clock36xx.o \ |
148 | 148 | dpll3xxx.o clock3xxx_data.o \ |
149 | 149 | clkt_iclk.o |
150 | -obj-$(CONFIG_SOC_OMAPAM33XX) += clock33xx_data.o clock33xx.o | |
150 | +obj-$(CONFIG_SOC_OMAPAM33XX) += clock33xx_data.o | |
151 | 151 | obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o \ |
152 | 152 | dpll3xxx.o dpll44xx.o |
153 | 153 |
arch/arm/mach-omap2/clock33xx.c
1 | -/* | |
2 | - * AM33XX specific clock ops. | |
3 | - * | |
4 | - * Copyright (C) 2011 Texas Instruments, Inc. - http://www.ti.com/ | |
5 | - * | |
6 | - * This program is free software; you can redistribute it and/or | |
7 | - * modify it under the terms of the GNU General Public License as | |
8 | - * published by the Free Software Foundation version 2. | |
9 | - * | |
10 | - * This program is distributed "as is" WITHOUT ANY WARRANTY of any | |
11 | - * kind, whether express or implied; without even the implied warranty | |
12 | - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | - * GNU General Public License for more details. | |
14 | - * | |
15 | - * Part of this code are based on code by Hemant Padenkar. | |
16 | - */ | |
17 | - | |
18 | -#include <linux/kernel.h> | |
19 | -#include <linux/clk.h> | |
20 | -#include <linux/io.h> | |
21 | - | |
22 | -#include <plat/clock.h> | |
23 | -#include <plat/prcm.h> | |
24 | - | |
25 | -#include "clock.h" | |
26 | -#include "cm-regbits-33xx.h" | |
27 | - | |
28 | -#include "prm33xx.h" | |
29 | -#include "prm-regbits-33xx.h" | |
30 | - | |
31 | -#include "prm2xxx_3xxx.h" | |
32 | - | |
33 | -/** | |
34 | - * am33xx_dflt_wait_clk_enable() - Enable a am33xx module clock | |
35 | - * @clk: Pointer to the clock to be enabled | |
36 | - * | |
37 | - * This function just wraps omap2_dflt_clk_enable with a check for module idle | |
38 | - * status. We loop till module goes to funcitonal state as the immediate access | |
39 | - * to module space will not work otherwise. | |
40 | - */ | |
41 | -int am33xx_dflt_wait_clk_enable(struct clk *clk) | |
42 | -{ | |
43 | - omap2_dflt_clk_enable(clk); | |
44 | - | |
45 | - omap2_cm_wait_idlest(clk->enable_reg, AM33XX_IDLEST_MASK, | |
46 | - AM33XX_IDLEST_VAL, clk->name); | |
47 | - | |
48 | - return 0; | |
49 | -} | |
50 | - | |
51 | -int am33xx_sgx_clk_enable(struct clk *clk) | |
52 | -{ | |
53 | - omap2_dflt_clk_enable(clk); | |
54 | - | |
55 | - /* De-assert local reset after module enable */ | |
56 | - omap2_prm_clear_mod_reg_bits(AM33XX_GFX_RST_MASK, | |
57 | - AM33XX_PRM_GFX_MOD, | |
58 | - AM33XX_RM_GFX_RSTCTRL_OFFSET); | |
59 | - | |
60 | - omap2_cm_wait_idlest(clk->enable_reg, AM33XX_IDLEST_MASK, | |
61 | - AM33XX_IDLEST_VAL, clk->name); | |
62 | - | |
63 | - return 0; | |
64 | -} | |
65 | - | |
66 | -void am33xx_sgx_clk_disable(struct clk *clk) | |
67 | -{ | |
68 | - /* Assert local reset */ | |
69 | - omap2_prm_set_mod_reg_bits(AM33XX_GFX_RST_MASK, | |
70 | - AM33XX_PRM_GFX_MOD, | |
71 | - AM33XX_RM_GFX_RSTCTRL_OFFSET); | |
72 | - | |
73 | - omap2_dflt_clk_disable(clk); | |
74 | -} | |
75 | - | |
76 | -int am33xx_icss_clk_enable(struct clk *clk) | |
77 | -{ | |
78 | - omap2_dflt_clk_enable(clk); | |
79 | - | |
80 | - /* De-assert local reset after module enable */ | |
81 | - omap2_prm_clear_mod_reg_bits(AM33XX_ICSS_LRST_MASK, | |
82 | - AM33XX_PRM_PER_MOD, | |
83 | - AM33XX_RM_PER_RSTCTRL_OFFSET); | |
84 | - | |
85 | - omap2_cm_wait_idlest(clk->enable_reg, AM33XX_IDLEST_MASK, | |
86 | - AM33XX_IDLEST_VAL, clk->name); | |
87 | - | |
88 | - return 0; | |
89 | -} | |
90 | - | |
91 | -void am33xx_icss_clk_disable(struct clk *clk) | |
92 | -{ | |
93 | - /* Assert local reset */ | |
94 | - omap2_prm_set_mod_reg_bits(AM33XX_ICSS_LRST_MASK, | |
95 | - AM33XX_PRM_PER_MOD, | |
96 | - AM33XX_RM_PER_RSTCTRL_OFFSET); | |
97 | - | |
98 | - omap2_dflt_clk_disable(clk); | |
99 | -} | |
100 | - | |
101 | -const struct clkops clkops_am33xx_dflt_wait = { | |
102 | - .enable = am33xx_dflt_wait_clk_enable, | |
103 | - .disable = omap2_dflt_clk_disable, | |
104 | -}; | |
105 | - | |
106 | -const struct clkops clkops_am33xx_sgx = { | |
107 | - .enable = am33xx_sgx_clk_enable, | |
108 | - .disable = am33xx_sgx_clk_disable, | |
109 | -}; | |
110 | - | |
111 | -const struct clkops clkops_am33xx_icss = { | |
112 | - .enable = am33xx_icss_clk_enable, | |
113 | - .disable = am33xx_icss_clk_disable, | |
114 | -}; |
arch/arm/mach-omap2/cminst33xx.c
arch/arm/mach-omap2/omap_hwmod.c
... | ... | @@ -150,7 +150,9 @@ |
150 | 150 | #include "cminst33xx.h" |
151 | 151 | #include "prm2xxx_3xxx.h" |
152 | 152 | #include "prm44xx.h" |
153 | +#include "prm33xx.h" | |
153 | 154 | #include "prminst44xx.h" |
155 | +#include "prminst33xx.h" | |
154 | 156 | #include "mux.h" |
155 | 157 | |
156 | 158 | /* Maximum microseconds to wait for OMAP module to softreset */ |
... | ... | @@ -1256,7 +1258,11 @@ |
1256 | 1258 | if (IS_ERR_VALUE(ret)) |
1257 | 1259 | return ret; |
1258 | 1260 | |
1259 | - if (cpu_is_omap24xx() || cpu_is_omap34xx()) | |
1261 | + if (cpu_is_am33xx()) { | |
1262 | + return am33xx_prminst_assert_hardreset( | |
1263 | + oh->clkdm->pwrdm.ptr->prcm_offs, | |
1264 | + ohri.rst_shift); | |
1265 | + } else if (cpu_is_omap24xx() || cpu_is_omap34xx()) | |
1260 | 1266 | return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, |
1261 | 1267 | ohri.rst_shift); |
1262 | 1268 | else if (cpu_is_omap44xx()) |
... | ... | @@ -1290,7 +1296,11 @@ |
1290 | 1296 | if (IS_ERR_VALUE(ret)) |
1291 | 1297 | return ret; |
1292 | 1298 | |
1293 | - if (cpu_is_omap24xx() || cpu_is_omap34xx()) { | |
1299 | + if (cpu_is_am33xx()) { | |
1300 | + ret = am33xx_prminst_deassert_hardreset( | |
1301 | + oh->clkdm->pwrdm.ptr->prcm_offs, | |
1302 | + ohri.rst_shift, ohri.st_shift); | |
1303 | + } else if (cpu_is_omap24xx() || cpu_is_omap34xx()) { | |
1294 | 1304 | ret = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs, |
1295 | 1305 | ohri.rst_shift, |
1296 | 1306 | ohri.st_shift); |
... | ... | @@ -1332,7 +1342,11 @@ |
1332 | 1342 | if (IS_ERR_VALUE(ret)) |
1333 | 1343 | return ret; |
1334 | 1344 | |
1335 | - if (cpu_is_omap24xx() || cpu_is_omap34xx()) { | |
1345 | + if (cpu_is_am33xx()) { | |
1346 | + return am33xx_prminst_is_hardreset_asserted( | |
1347 | + oh->clkdm->pwrdm.ptr->prcm_offs, | |
1348 | + AM33XX_PM_RSTST, ohri.st_shift); | |
1349 | + } else if (cpu_is_omap24xx() || cpu_is_omap34xx()) { | |
1336 | 1350 | return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, |
1337 | 1351 | ohri.st_shift); |
1338 | 1352 | } else if (cpu_is_omap44xx()) { |
arch/arm/mach-omap2/prcm33xx.h
1 | -/* | |
2 | - * AM33XX PRCM definitions | |
3 | - * | |
4 | - * Copyright (C) 2010 Texas Instruments, Inc. | |
5 | - * | |
6 | - * Vaibhav Hiremath <hvaibhav@ti.com> | |
7 | - * | |
8 | - * This program is free software; you can redistribute it and/or modify | |
9 | - * it under the terms of the GNU General Public License version 2 as | |
10 | - * published by the Free Software Foundation. | |
11 | - * | |
12 | - * This file contains macros and functions that are common to all of | |
13 | - * the PRM/CM/PRCM blocks on the OMAP4 devices: PRM and CM | |
14 | - */ | |
15 | - | |
16 | -#ifndef __ARCH_ARM_MACH_OMAP2_PRCM33XX_H | |
17 | -#define __ARCH_ARM_MACH_OMAP2_PRCM33XX_H | |
18 | - | |
19 | -/* | |
20 | - * AM33XX PRCM partition IDs | |
21 | - * | |
22 | - * The numbers and order are arbitrary, but 0 is reserved for the | |
23 | - * 'invalid' partition in case someone forgets to add a | |
24 | - * .prcm_partition field. | |
25 | - */ | |
26 | -#define AM33XX_INVALID_PRCM_PARTITION 0 | |
27 | -#define AM33XX_PRM_PARTITION 1 | |
28 | -#define AM33XX_CM_PARTITION 2 | |
29 | - | |
30 | -/* | |
31 | - * AM33XX_MAX_PRCM_PARTITIONS: set to the highest value of the PRCM partition | |
32 | - * IDs, plus one | |
33 | - */ | |
34 | -#define AM33XX_MAX_PRCM_PARTITIONS 3 | |
35 | - | |
36 | -#endif |
arch/arm/mach-omap2/prm33xx.h
... | ... | @@ -37,10 +37,11 @@ |
37 | 37 | #define AM33XX_PRM_GFX_MOD 0x1100 |
38 | 38 | #define AM33XX_PRM_CEFUSE_MOD 0x1200 |
39 | 39 | |
40 | -/* OMAP4 specific register offsets */ | |
40 | +/* Register offsets (used from OMAP4) */ | |
41 | 41 | #define AM33XX_PM_PWSTCTRL 0x0000 |
42 | 42 | #define AM33XX_PM_PWSTST 0x0004 |
43 | - | |
43 | +#define AM33XX_PM_RSTCTRL 0x0008 | |
44 | +#define AM33XX_PM_RSTST 0x000C | |
44 | 45 | |
45 | 46 | /* PRM */ |
46 | 47 |
arch/arm/mach-omap2/prminst33xx.c
... | ... | @@ -27,17 +27,23 @@ |
27 | 27 | |
28 | 28 | #define AM33XX_PRM_MOD_SIZE 0x100 |
29 | 29 | #define AM33XX_PRM_MOD_START AM33XX_PRM_PER_MOD |
30 | -#define PRM_REG_SZ 0x4 | |
30 | +#define PRM_REG_SZ 0x4 | |
31 | 31 | |
32 | -static u16 off_fixup[][2] = { | |
33 | - { 0xC, 0x8 }, /* AM33XX_PRM_PER_MOD */ | |
34 | - { 0x4, 0x8 }, /* AM33XX_PRM_WKUP_MOD */ | |
35 | - { 0x0, 0x4 }, /* AM33XX_PRM_MPU_MOD */ | |
32 | +/* | |
33 | + * PRM Offsets are screwed up, and they are not consistent across modules. | |
34 | + * Below are the offsets for PWRSTCTRL and PWRSTST for respective modules. | |
35 | + * Fields are - | |
36 | + * PWRSTST, PWRSTCTRL, RSTCTRL, RSTST | |
37 | + */ | |
38 | +static u16 off_fixup[][4] = { | |
39 | + { 0x0C, 0x08, 0x00, 0x04 }, /* AM33XX_PRM_PER_MOD */ | |
40 | + { 0x04, 0x08, 0x00, 0x0C }, /* AM33XX_PRM_WKUP_MOD */ | |
41 | + { 0x00, 0x04, 0x08, 0x08 }, /* AM33XX_PRM_MPU_MOD */ | |
36 | 42 | /* XXX: PRM_DEVICE: offsets are invalid for powerdomain*/ |
37 | - { 0x0, 0x0 }, /* AM33XX_PRM_DEVICE_MOD */ | |
38 | - { 0x0, 0x4 }, /* AM33XX_PRM_RTC_MOD */ | |
39 | - { 0x0, 0x10 }, /* AM33XX_PRM_GFX_MOD */ | |
40 | - { 0x0, 0x4 }, /* AM33XX_PRM_CEFUSE_MOD */ | |
43 | + { 0x00, 0x00, 0x00, 0x08 }, /* AM33XX_PRM_DEVICE_MOD */ | |
44 | + { 0x00, 0x04, 0x00, 0x00 }, /* AM33XX_PRM_RTC_MOD */ | |
45 | + { 0x00, 0x10, 0x04, 0x14 }, /* AM33XX_PRM_GFX_MOD */ | |
46 | + { 0x00, 0x04, 0x00, 0x00 }, /* AM33XX_PRM_CEFUSE_MOD */ | |
41 | 47 | }; |
42 | 48 | |
43 | 49 | /* Read a register in a PRM instance */ |
... | ... | @@ -57,8 +63,7 @@ |
57 | 63 | } |
58 | 64 | |
59 | 65 | /* Read-modify-write a register in PRM. Caller must lock */ |
60 | -u32 am33xx_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, | |
61 | - s16 idx) | |
66 | +u32 am33xx_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) | |
62 | 67 | { |
63 | 68 | u32 v; |
64 | 69 | |
... | ... | @@ -68,5 +73,91 @@ |
68 | 73 | am33xx_prminst_write_inst_reg(v, inst, idx); |
69 | 74 | |
70 | 75 | return v; |
76 | +} | |
77 | + | |
78 | +/** | |
79 | + * am33xx_prminst_is_hardreset_asserted - read the HW reset line state of | |
80 | + * submodules contained in the hwmod module | |
81 | + * @prm_mod: PRM submodule base (e.g. CORE_MOD) | |
82 | + * @idx: register bit offset for calculating correct offset | |
83 | + * @mask: register bit mask | |
84 | + * | |
85 | + * Returns 1 if the (sub)module hardreset line is currently asserted, | |
86 | + * 0 if the (sub)module hardreset line is not currently asserted, or | |
87 | + * -EINVAL if called while running on a non-OMAP2/3 chip. | |
88 | + */ | |
89 | + | |
90 | +u32 am33xx_prminst_is_hardreset_asserted(s16 prm_mod, s16 idx, u32 mask) | |
91 | +{ | |
92 | + u32 v; | |
93 | + | |
94 | + v = am33xx_prminst_read_inst_reg(prm_mod, idx); | |
95 | + v &= mask; | |
96 | + v >>= __ffs(mask); | |
97 | + | |
98 | + return v; | |
99 | +} | |
100 | + | |
101 | +/** | |
102 | + * am33xx_prminst_assert_hardreset - assert the HW reset line of a submodule | |
103 | + * @prm_mod: PRM submodule base (e.g. GFX_MOD) | |
104 | + * @shift: register bit shift corresponding to the reset line to assert | |
105 | + * | |
106 | + * Some IPs like iva or PRUSS contain processors that require an HW | |
107 | + * reset line to be asserted / deasserted in order to fully enable the | |
108 | + * IP. These modules may have multiple hard-reset lines that reset | |
109 | + * different 'submodules' inside the IP block. This function will | |
110 | + * place the submodule into reset. Returns 0 upon success or -EINVAL | |
111 | + * upon an argument error. | |
112 | + */ | |
113 | + | |
114 | +int am33xx_prminst_assert_hardreset(s16 prm_mod, u8 shift) | |
115 | +{ | |
116 | + u32 mask; | |
117 | + | |
118 | + if (!cpu_is_am33xx()) | |
119 | + return -EINVAL; | |
120 | + | |
121 | + mask = 1 << shift; | |
122 | + /* assert the reset control line */ | |
123 | + am33xx_prminst_rmw_inst_reg_bits(mask, mask, prm_mod, AM33XX_PM_RSTCTRL); | |
124 | + | |
125 | + return 0; | |
126 | +} | |
127 | + | |
128 | +/** | |
129 | + * am33xx_prminst_deassert_hardreset - deassert a submodule hardreset line and | |
130 | + * wait | |
131 | + * @prm_mod: PRM submodule base (e.g. CORE_MOD) | |
132 | + * @rst_shift: register bit shift corresponding to the reset line to deassert | |
133 | + * @st_shift: register bit shift for the status of the deasserted submodule | |
134 | + * | |
135 | + * Some IPs like SGX, PRUSS and M3 contain processors that require an HW | |
136 | + * reset line to be asserted / deasserted in order to fully enable the | |
137 | + * IP. | |
138 | + * This function will take the submodule out of reset and wait until the | |
139 | + * PRCM indicates that the reset has completed before returning. | |
140 | + * Returns 0 upon success or -EINVAL upon an argument error, | |
141 | + * -EEXIST if the submodule was already out of reset, or -EBUSY if the | |
142 | + * submodule did not exit reset promptly. | |
143 | + */ | |
144 | +int am33xx_prminst_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift) | |
145 | +{ | |
146 | + u32 rst, st; | |
147 | + | |
148 | + if (!cpu_is_am33xx()) | |
149 | + return -EINVAL; | |
150 | + | |
151 | + rst = 1 << rst_shift; | |
152 | + st = 1 << st_shift; | |
153 | + | |
154 | + /* Clear the reset status by writing 1 to the status bit */ | |
155 | + am33xx_prminst_rmw_inst_reg_bits(0xffffffff, st, prm_mod, | |
156 | + AM33XX_PM_RSTST); | |
157 | + /* de-assert the reset control line */ | |
158 | + am33xx_prminst_rmw_inst_reg_bits(rst, 0, prm_mod, AM33XX_PM_RSTCTRL); | |
159 | + /* TODO: wait the status to be set */ | |
160 | + | |
161 | + return 0; | |
71 | 162 | } |
arch/arm/mach-omap2/prminst33xx.h
... | ... | @@ -24,6 +24,10 @@ |
24 | 24 | extern void am33xx_prminst_write_inst_reg(u32 val, s16 inst, u16 idx); |
25 | 25 | extern u32 am33xx_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, |
26 | 26 | s16 inst, s16 idx); |
27 | +extern u32 am33xx_prminst_is_hardreset_asserted(s16 domain, s16 idx, u32 mask); | |
28 | +extern int am33xx_prminst_assert_hardreset(s16 prm_mod, u8 shift); | |
29 | +extern int am33xx_prminst_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 | |
30 | + st_shift); | |
27 | 31 | |
28 | 32 | extern void am33xx_prm_global_warm_sw_reset(void); |
29 | 33 |