]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - sitara-epos/sitara-epos-kernel.git/blob - arch/arm/mach-omap2/prminst33xx.c
am335x-evm: beta evm bringup changes for wlan and bt
[sitara-epos/sitara-epos-kernel.git] / arch / arm / mach-omap2 / prminst33xx.c
1 /*
2  * AM33XX PRM instance functions
3  *
4  * Copyright (C) 2011 Texas Instruments Incorporated - 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  */
16 #include <linux/kernel.h>
17 #include <linux/types.h>
18 #include <linux/errno.h>
19 #include <linux/err.h>
20 #include <linux/io.h>
22 #include "common.h"
24 #include "prm33xx.h"
25 #include "prminst33xx.h"
26 #include "prm-regbits-33xx.h"
28 #define AM33XX_PRM_MOD_SIZE     0x100
29 #define AM33XX_PRM_MOD_START    AM33XX_PRM_PER_MOD
30 #define PRM_REG_SZ              0x4
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  */
36 static u16 off_fixup[][4] = {
37         /* PRM_PER_MOD: 0x0C, 0x08, 0x00, 0x04 */
38         {
39                 AM33XX_PM_PER_PWRSTCTRL_OFFSET,
40                 AM33XX_PM_PER_PWRSTST_OFFSET,
41                 AM33XX_RM_PER_RSTCTRL_OFFSET,
42                 AM33XX_RM_PER_RSTST_OFFSET,
43         },
44         /* PRM_WKUP_MOD: 0x04, 0x08, 0x00, 0x0C */
45         {
46                 AM33XX_PM_WKUP_PWRSTCTRL_OFFSET,
47                 AM33XX_PM_WKUP_PWRSTST_OFFSET,
48                 AM33XX_RM_WKUP_RSTCTRL_OFFSET,
49                 AM33XX_RM_WKUP_RSTST_OFFSET,
50         },
51         /* AM33XX_PRM_MPU_MOD: 0x00, 0x04, 0x08, NA */
52         {
53                 AM33XX_PM_MPU_PWRSTCTRL_OFFSET,
54                 AM33XX_PM_MPU_PWRSTST_OFFSET,
55                 AM33XX_RM_MPU_RSTST_OFFSET,
56                 AM33XX_RM_MPU_RSTST_OFFSET,
57         },
58         /* PRM_DEVICE_MOD: NA, NA, 0x00, 0x08 */
59         {
60                 0x0,
61                 0x0,
62                 AM33XX_PRM_RSTCTRL_OFFSET,
63                 AM33XX_PRM_RSTST_OFFSET,
64         },
65         /* PRM_RTC_MOD: 0x00, 0x04, NA, NA */
66         {
67                 AM33XX_PM_RTC_PWRSTCTRL_OFFSET,
68                 AM33XX_PM_RTC_PWRSTST_OFFSET,
69                 0x0,
70                 0x0,
71         },
72         /* PRM_GFX_MOD: 0x00, 0x10, 0x04, 0x14 */
73         {
74                 AM33XX_PM_GFX_PWRSTCTRL_OFFSET,
75                 AM33XX_PM_GFX_PWRSTST_OFFSET,
76                 AM33XX_RM_GFX_RSTCTRL_OFFSET,
77                 AM33XX_RM_GFX_RSTST_OFFSET,
78         },
79         /* PRM_CEFUSE_MOD: 0x00, 0x04, NA, NA */
80         {
81                 AM33XX_PM_CEFUSE_PWRSTCTRL_OFFSET,
82                 AM33XX_PM_CEFUSE_PWRSTST_OFFSET,
83                 0x0,
84                 0x0,
85         },
86 };
88 /* Read a register in a PRM instance */
89 u32 am33xx_prminst_read_inst_reg(s16 inst, u16 idx)
90 {
91         int i = (inst - AM33XX_PRM_MOD_START) / AM33XX_PRM_MOD_SIZE;
93         return __raw_readl(prm_base + inst + off_fixup[i][idx / PRM_REG_SZ]);
94 }
96 /* Write into a register in a PRM instance */
97 void am33xx_prminst_write_inst_reg(u32 val, s16 inst, u16 idx)
98 {
99         int i = (inst - AM33XX_PRM_MOD_START) / AM33XX_PRM_MOD_SIZE;
101         __raw_writel(val, prm_base + inst + off_fixup[i][idx / PRM_REG_SZ]);
104 /* Read-modify-write a register in PRM. Caller must lock */
105 u32 am33xx_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx)
107         u32 v;
109         v = am33xx_prminst_read_inst_reg(inst, idx);
110         v &= ~mask;
111         v |= bits;
112         am33xx_prminst_write_inst_reg(v, inst, idx);
114         return v;
117 /**
118  * am33xx_prminst_is_hardreset_asserted - read the HW reset line state of
119  * submodules contained in the hwmod module
120  * @prm_mod: PRM submodule base (e.g. CORE_MOD)
121  * @idx: register bit offset for calculating correct offset
122  * @mask: register bit mask
123  *
124  * Returns 1 if the (sub)module hardreset line is currently asserted,
125  * 0 if the (sub)module hardreset line is not currently asserted, or
126  * -EINVAL if called while running on a non-OMAP2/3 chip.
127  */
129 u32 am33xx_prminst_is_hardreset_asserted(s16 prm_mod, s16 idx, u32 mask)
131         u32 v;
133         v = am33xx_prminst_read_inst_reg(prm_mod, idx);
134         v &= mask;
135         v >>= __ffs(mask);
137         return v;
140 /**
141  * am33xx_prminst_assert_hardreset - assert the HW reset line of a submodule
142  * @prm_mod: PRM submodule base (e.g. GFX_MOD)
143  * @shift: register bit shift corresponding to the reset line to assert
144  *
145  * Some IPs like iva or PRUSS contain processors that require an HW
146  * reset line to be asserted / deasserted in order to fully enable the
147  * IP.  These modules may have multiple hard-reset lines that reset
148  * different 'submodules' inside the IP block.  This function will
149  * place the submodule into reset.  Returns 0 upon success or -EINVAL
150  * upon an argument error.
151  */
153 int am33xx_prminst_assert_hardreset(s16 prm_mod, u8 shift)
155         u32 mask;
157         if (!cpu_is_am33xx())
158                 return -EINVAL;
160         mask = 1 << shift;
161         /* assert the reset control line */
162         am33xx_prminst_rmw_inst_reg_bits(mask, mask, prm_mod, AM33XX_PM_RSTCTRL);
164         return 0;
167 /**
168  * am33xx_prminst_deassert_hardreset - deassert a submodule hardreset line and
169  * wait
170  * @prm_mod: PRM submodule base (e.g. CORE_MOD)
171  * @rst_shift: register bit shift corresponding to the reset line to deassert
172  * @st_shift: register bit shift for the status of the deasserted submodule
173  *
174  * Some IPs like SGX, PRUSS and M3 contain processors that require an HW
175  * reset line to be asserted / deasserted in order to fully enable the
176  * IP.
177  * This function will take the submodule out of reset and wait until the
178  * PRCM indicates that the reset has completed before returning.
179  * Returns 0 upon success or -EINVAL upon an argument error,
180  * -EEXIST if the submodule was already out of reset, or -EBUSY if the
181  * submodule did not exit reset promptly.
182  */
183 int am33xx_prminst_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
185         u32 rst, st;
187         if (!cpu_is_am33xx())
188                 return -EINVAL;
190         rst = 1 << rst_shift;
191         st = 1 << st_shift;
193         /* Clear the reset status by writing 1 to the status bit */
194         am33xx_prminst_rmw_inst_reg_bits(0xffffffff, st, prm_mod,
195                                                         AM33XX_PM_RSTST);
196         /* de-assert the reset control line */
197         am33xx_prminst_rmw_inst_reg_bits(rst, 0, prm_mod, AM33XX_PM_RSTCTRL);
198         /* TODO: wait the status to be set */
200         return 0;