diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2011-05-15 16:53:56 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2011-05-24 16:14:31 -0400 |
commit | 650c2a2145981696c414be1d540a32447d0e353e (patch) | |
tree | f05aadb054bffb88fee3056b78310b148ceed9bf /arch | |
parent | 118718905de6e32c11e09a8f41c7abff6155ba19 (diff) |
mach-ux500: move the DB8500 PRCMU driver to MFD
We have decided that this function arbiter fits better in the MFD
subsystem. Since we need to concatenate the split header files we move
it basically like this:
mv mach-ux500/prcmu-db8500.c drivers/mfd/db8500-prcmu.c
mv mach-ux500/include/mach/prcmu-defs.h include/linux/mfd/db8500-prcmu.h
mv mach-ux500/include/mach/prcmu-regs.h drivers/mfd/db8500-prcmu-regs.h
mach-ux500/include/mach/prcmu.h >> include/linux/mfd/db8500-prcmu.h
rm arch/arm/mach-ux500/include/mach/prcmu.h
Then we update different #include statements and Makefile orders etc
to make the PRCMU driver compile, link and boot in the new place
without really changing any code.
Acked-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-ux500/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-ux500/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-ux500/cpu.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-ux500/cpufreq.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/prcmu-defs.h | 30 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/prcmu-regs.h | 94 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/prcmu.h | 28 | ||||
-rw-r--r-- | arch/arm/mach-ux500/prcmu-db8500.c | 394 |
8 files changed, 4 insertions, 550 deletions
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 58626013aa32..8071d2746f70 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig | |||
@@ -15,6 +15,7 @@ config UX500_SOC_DB5500 | |||
15 | 15 | ||
16 | config UX500_SOC_DB8500 | 16 | config UX500_SOC_DB8500 |
17 | bool "DB8500" | 17 | bool "DB8500" |
18 | select MFD_DB8500_PRCMU | ||
18 | 19 | ||
19 | endmenu | 20 | endmenu |
20 | 21 | ||
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 2a08a10e09da..7a1d43e04f97 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | obj-y := clock.o cpu.o devices.o devices-common.o \ | 5 | obj-y := clock.o cpu.o devices.o devices-common.o \ |
6 | id.o usb.o | 6 | id.o usb.o |
7 | obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o | 7 | obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o |
8 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu-db8500.o | 8 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o |
9 | obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ | 9 | obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ |
10 | board-mop500-regulators.o \ | 10 | board-mop500-regulators.o \ |
11 | board-mop500-uib.o board-mop500-stuib.o \ | 11 | board-mop500-uib.o board-mop500-stuib.o \ |
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 0190e0e68b4d..11360f734cec 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/platform_device.h> | 8 | #include <linux/platform_device.h> |
9 | #include <linux/io.h> | 9 | #include <linux/io.h> |
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/mfd/db8500-prcmu.h> | ||
11 | 12 | ||
12 | #include <asm/cacheflush.h> | 13 | #include <asm/cacheflush.h> |
13 | #include <asm/hardware/cache-l2x0.h> | 14 | #include <asm/hardware/cache-l2x0.h> |
@@ -19,7 +20,6 @@ | |||
19 | #include <mach/hardware.h> | 20 | #include <mach/hardware.h> |
20 | #include <mach/setup.h> | 21 | #include <mach/setup.h> |
21 | #include <mach/devices.h> | 22 | #include <mach/devices.h> |
22 | #include <mach/prcmu.h> | ||
23 | 23 | ||
24 | #include "clock.h" | 24 | #include "clock.h" |
25 | 25 | ||
diff --git a/arch/arm/mach-ux500/cpufreq.c b/arch/arm/mach-ux500/cpufreq.c index 5c5b747f134d..d196939fcdb9 100644 --- a/arch/arm/mach-ux500/cpufreq.c +++ b/arch/arm/mach-ux500/cpufreq.c | |||
@@ -17,10 +17,9 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/cpufreq.h> | 18 | #include <linux/cpufreq.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/mfd/db8500-prcmu.h> | ||
20 | 21 | ||
21 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
22 | #include <mach/prcmu.h> | ||
23 | #include <mach/prcmu-defs.h> | ||
24 | 23 | ||
25 | #define DRIVER_NAME "cpufreq-u8500" | 24 | #define DRIVER_NAME "cpufreq-u8500" |
26 | #define CPUFREQ_NAME "u8500" | 25 | #define CPUFREQ_NAME "u8500" |
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-defs.h b/arch/arm/mach-ux500/include/mach/prcmu-defs.h deleted file mode 100644 index 848ba64b561f..000000000000 --- a/arch/arm/mach-ux500/include/mach/prcmu-defs.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) STMicroelectronics 2009 | ||
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
4 | * | ||
5 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
6 | * Author: Martin Persson <martin.persson@stericsson.com> | ||
7 | * | ||
8 | * License Terms: GNU General Public License v2 | ||
9 | * | ||
10 | * PRCM Unit definitions | ||
11 | */ | ||
12 | |||
13 | #ifndef __MACH_PRCMU_DEFS_H | ||
14 | #define __MACH_PRCMU_DEFS_H | ||
15 | |||
16 | enum prcmu_cpu_opp { | ||
17 | CPU_OPP_INIT = 0x00, | ||
18 | CPU_OPP_NO_CHANGE = 0x01, | ||
19 | CPU_OPP_100 = 0x02, | ||
20 | CPU_OPP_50 = 0x03, | ||
21 | CPU_OPP_MAX = 0x04, | ||
22 | CPU_OPP_EXT_CLK = 0x07 | ||
23 | }; | ||
24 | enum prcmu_ape_opp { | ||
25 | APE_OPP_NO_CHANGE = 0x00, | ||
26 | APE_OPP_100 = 0x02, | ||
27 | APE_OPP_50 = 0x03, | ||
28 | }; | ||
29 | |||
30 | #endif /* __MACH_PRCMU_DEFS_H */ | ||
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-regs.h b/arch/arm/mach-ux500/include/mach/prcmu-regs.h deleted file mode 100644 index c1226da19bfb..000000000000 --- a/arch/arm/mach-ux500/include/mach/prcmu-regs.h +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) STMicroelectronics 2009 | ||
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
4 | * | ||
5 | * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> | ||
6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
7 | * | ||
8 | * License Terms: GNU General Public License v2 | ||
9 | * | ||
10 | * PRCM Unit registers | ||
11 | */ | ||
12 | |||
13 | #ifndef __MACH_PRCMU_REGS_H | ||
14 | #define __MACH_PRCMU_REGS_H | ||
15 | |||
16 | #include <mach/hardware.h> | ||
17 | |||
18 | #define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118) | ||
19 | #define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) | ||
20 | #define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) | ||
21 | #define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0) | ||
22 | #define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4) | ||
23 | #define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0) | ||
24 | #define PRCM_ARM_LS_CLAMP (_PRCMU_BASE + 0x30c) | ||
25 | #define PRCM_SRAM_A9 (_PRCMU_BASE + 0x308) | ||
26 | |||
27 | /* ARM WFI Standby signal register */ | ||
28 | #define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130) | ||
29 | #define PRCMU_IOCR (_PRCMU_BASE + 0x310) | ||
30 | |||
31 | /* CPU mailbox registers */ | ||
32 | #define PRCM_MBOX_CPU_VAL (_PRCMU_BASE + 0x0fc) | ||
33 | #define PRCM_MBOX_CPU_SET (_PRCMU_BASE + 0x100) | ||
34 | #define PRCM_MBOX_CPU_CLR (_PRCMU_BASE + 0x104) | ||
35 | |||
36 | /* Dual A9 core interrupt management unit registers */ | ||
37 | #define PRCM_A9_MASK_REQ (_PRCMU_BASE + 0x328) | ||
38 | #define PRCM_A9_MASK_ACK (_PRCMU_BASE + 0x32c) | ||
39 | #define PRCM_ARMITMSK31TO0 (_PRCMU_BASE + 0x11c) | ||
40 | #define PRCM_ARMITMSK63TO32 (_PRCMU_BASE + 0x120) | ||
41 | #define PRCM_ARMITMSK95TO64 (_PRCMU_BASE + 0x124) | ||
42 | #define PRCM_ARMITMSK127TO96 (_PRCMU_BASE + 0x128) | ||
43 | #define PRCM_POWER_STATE_VAL (_PRCMU_BASE + 0x25C) | ||
44 | #define PRCM_ARMITVAL31TO0 (_PRCMU_BASE + 0x260) | ||
45 | #define PRCM_ARMITVAL63TO32 (_PRCMU_BASE + 0x264) | ||
46 | #define PRCM_ARMITVAL95TO64 (_PRCMU_BASE + 0x268) | ||
47 | #define PRCM_ARMITVAL127TO96 (_PRCMU_BASE + 0x26C) | ||
48 | |||
49 | #define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334) | ||
50 | #define ARM_WAKEUP_MODEM 0x1 | ||
51 | |||
52 | #define PRCM_ARM_IT1_CLEAR (_PRCMU_BASE + 0x48C) | ||
53 | #define PRCM_ARM_IT1_VAL (_PRCMU_BASE + 0x494) | ||
54 | #define PRCM_HOLD_EVT (_PRCMU_BASE + 0x174) | ||
55 | |||
56 | #define PRCM_ITSTATUS0 (_PRCMU_BASE + 0x148) | ||
57 | #define PRCM_ITSTATUS1 (_PRCMU_BASE + 0x150) | ||
58 | #define PRCM_ITSTATUS2 (_PRCMU_BASE + 0x158) | ||
59 | #define PRCM_ITSTATUS3 (_PRCMU_BASE + 0x160) | ||
60 | #define PRCM_ITSTATUS4 (_PRCMU_BASE + 0x168) | ||
61 | #define PRCM_ITSTATUS5 (_PRCMU_BASE + 0x484) | ||
62 | #define PRCM_ITCLEAR5 (_PRCMU_BASE + 0x488) | ||
63 | #define PRCM_ARMIT_MASKXP70_IT (_PRCMU_BASE + 0x1018) | ||
64 | |||
65 | /* System reset register */ | ||
66 | #define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228) | ||
67 | |||
68 | /* Level shifter and clamp control registers */ | ||
69 | #define PRCM_MMIP_LS_CLAMP_SET (_PRCMU_BASE + 0x420) | ||
70 | #define PRCM_MMIP_LS_CLAMP_CLR (_PRCMU_BASE + 0x424) | ||
71 | |||
72 | /* PRCMU clock/PLL/reset registers */ | ||
73 | #define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500) | ||
74 | #define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504) | ||
75 | #define PRCM_LCDCLK_MGT (_PRCMU_BASE + 0x044) | ||
76 | #define PRCM_MCDECLK_MGT (_PRCMU_BASE + 0x064) | ||
77 | #define PRCM_HDMICLK_MGT (_PRCMU_BASE + 0x058) | ||
78 | #define PRCM_TVCLK_MGT (_PRCMU_BASE + 0x07c) | ||
79 | #define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530) | ||
80 | #define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C) | ||
81 | #define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4) | ||
82 | #define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8) | ||
83 | |||
84 | /* ePOD and memory power signal control registers */ | ||
85 | #define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410) | ||
86 | #define PRCM_SRAM_LS_SLEEP (_PRCMU_BASE + 0x304) | ||
87 | |||
88 | /* Debug power control unit registers */ | ||
89 | #define PRCM_POWER_STATE_SET (_PRCMU_BASE + 0x254) | ||
90 | |||
91 | /* Miscellaneous unit registers */ | ||
92 | #define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324) | ||
93 | |||
94 | #endif /* __MACH_PRCMU_REGS_H */ | ||
diff --git a/arch/arm/mach-ux500/include/mach/prcmu.h b/arch/arm/mach-ux500/include/mach/prcmu.h deleted file mode 100644 index c49e456162ef..000000000000 --- a/arch/arm/mach-ux500/include/mach/prcmu.h +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) STMicroelectronics 2009 | ||
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
4 | * | ||
5 | * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> | ||
6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
7 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> | ||
8 | * | ||
9 | * License Terms: GNU General Public License v2 | ||
10 | * | ||
11 | * PRCM Unit f/w API | ||
12 | */ | ||
13 | #ifndef __MACH_PRCMU_H | ||
14 | #define __MACH_PRCMU_H | ||
15 | #include <mach/prcmu-defs.h> | ||
16 | |||
17 | void __init prcmu_early_init(void); | ||
18 | int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); | ||
19 | int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); | ||
20 | int prcmu_set_ape_opp(enum prcmu_ape_opp opp); | ||
21 | int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp); | ||
22 | int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, | ||
23 | enum prcmu_cpu_opp cpu_opp); | ||
24 | int prcmu_get_ape_opp(void); | ||
25 | int prcmu_get_cpu_opp(void); | ||
26 | bool prcmu_has_arm_maxopp(void); | ||
27 | |||
28 | #endif /* __MACH_PRCMU_H */ | ||
diff --git a/arch/arm/mach-ux500/prcmu-db8500.c b/arch/arm/mach-ux500/prcmu-db8500.c deleted file mode 100644 index c522d26ef348..000000000000 --- a/arch/arm/mach-ux500/prcmu-db8500.c +++ /dev/null | |||
@@ -1,394 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) STMicroelectronics 2009 | ||
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
4 | * | ||
5 | * License Terms: GNU General Public License v2 | ||
6 | * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> | ||
7 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
8 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> | ||
9 | * | ||
10 | * U8500 PRCM Unit interface driver | ||
11 | * | ||
12 | */ | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/mutex.h> | ||
19 | #include <linux/completion.h> | ||
20 | #include <linux/jiffies.h> | ||
21 | #include <linux/bitops.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | |||
24 | #include <mach/hardware.h> | ||
25 | #include <mach/prcmu-regs.h> | ||
26 | #include <mach/prcmu-defs.h> | ||
27 | |||
28 | /* Global var to runtime determine TCDM base for v2 or v1 */ | ||
29 | static __iomem void *tcdm_base; | ||
30 | |||
31 | #define _MBOX_HEADER (tcdm_base + 0xFE8) | ||
32 | #define MBOX_HEADER_REQ_MB0 (_MBOX_HEADER + 0x0) | ||
33 | |||
34 | #define REQ_MB1 (tcdm_base + 0xFD0) | ||
35 | #define REQ_MB5 (tcdm_base + 0xE44) | ||
36 | |||
37 | #define REQ_MB1_ARMOPP (REQ_MB1 + 0x0) | ||
38 | #define REQ_MB1_APEOPP (REQ_MB1 + 0x1) | ||
39 | #define REQ_MB1_BOOSTOPP (REQ_MB1 + 0x2) | ||
40 | |||
41 | #define ACK_MB1 (tcdm_base + 0xE04) | ||
42 | #define ACK_MB5 (tcdm_base + 0xDF4) | ||
43 | |||
44 | #define ACK_MB1_CURR_ARMOPP (ACK_MB1 + 0x0) | ||
45 | #define ACK_MB1_CURR_APEOPP (ACK_MB1 + 0x1) | ||
46 | |||
47 | #define REQ_MB5_I2C_SLAVE_OP (REQ_MB5) | ||
48 | #define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1) | ||
49 | #define REQ_MB5_I2C_REG (REQ_MB5 + 2) | ||
50 | #define REQ_MB5_I2C_VAL (REQ_MB5 + 3) | ||
51 | |||
52 | #define ACK_MB5_I2C_STATUS (ACK_MB5 + 1) | ||
53 | #define ACK_MB5_I2C_VAL (ACK_MB5 + 3) | ||
54 | |||
55 | #define PRCM_AVS_VARM_MAX_OPP (tcdm_base + 0x2E4) | ||
56 | #define PRCM_AVS_ISMODEENABLE 7 | ||
57 | #define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE) | ||
58 | |||
59 | #define I2C_WRITE(slave) \ | ||
60 | (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0)) | ||
61 | #define I2C_READ(slave) \ | ||
62 | (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0) | BIT(0)) | ||
63 | #define I2C_STOP_EN BIT(3) | ||
64 | |||
65 | enum mb1_h { | ||
66 | MB1H_ARM_OPP = 1, | ||
67 | MB1H_APE_OPP, | ||
68 | MB1H_ARM_APE_OPP, | ||
69 | }; | ||
70 | |||
71 | static struct { | ||
72 | struct mutex lock; | ||
73 | struct completion work; | ||
74 | struct { | ||
75 | u8 arm_opp; | ||
76 | u8 ape_opp; | ||
77 | u8 arm_status; | ||
78 | u8 ape_status; | ||
79 | } ack; | ||
80 | } mb1_transfer; | ||
81 | |||
82 | enum ack_mb5_status { | ||
83 | I2C_WR_OK = 0x01, | ||
84 | I2C_RD_OK = 0x02, | ||
85 | }; | ||
86 | |||
87 | #define MBOX_BIT BIT | ||
88 | #define NUM_MBOX 8 | ||
89 | |||
90 | static struct { | ||
91 | struct mutex lock; | ||
92 | struct completion work; | ||
93 | bool failed; | ||
94 | struct { | ||
95 | u8 status; | ||
96 | u8 value; | ||
97 | } ack; | ||
98 | } mb5_transfer; | ||
99 | |||
100 | /** | ||
101 | * prcmu_abb_read() - Read register value(s) from the ABB. | ||
102 | * @slave: The I2C slave address. | ||
103 | * @reg: The (start) register address. | ||
104 | * @value: The read out value(s). | ||
105 | * @size: The number of registers to read. | ||
106 | * | ||
107 | * Reads register value(s) from the ABB. | ||
108 | * @size has to be 1 for the current firmware version. | ||
109 | */ | ||
110 | int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) | ||
111 | { | ||
112 | int r; | ||
113 | |||
114 | if (size != 1) | ||
115 | return -EINVAL; | ||
116 | |||
117 | r = mutex_lock_interruptible(&mb5_transfer.lock); | ||
118 | if (r) | ||
119 | return r; | ||
120 | |||
121 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) | ||
122 | cpu_relax(); | ||
123 | |||
124 | writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP); | ||
125 | writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS); | ||
126 | writeb(reg, REQ_MB5_I2C_REG); | ||
127 | |||
128 | writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); | ||
129 | if (!wait_for_completion_timeout(&mb5_transfer.work, | ||
130 | msecs_to_jiffies(500))) { | ||
131 | pr_err("prcmu: prcmu_abb_read timed out.\n"); | ||
132 | r = -EIO; | ||
133 | goto unlock_and_return; | ||
134 | } | ||
135 | r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO); | ||
136 | if (!r) | ||
137 | *value = mb5_transfer.ack.value; | ||
138 | |||
139 | unlock_and_return: | ||
140 | mutex_unlock(&mb5_transfer.lock); | ||
141 | return r; | ||
142 | } | ||
143 | EXPORT_SYMBOL(prcmu_abb_read); | ||
144 | |||
145 | /** | ||
146 | * prcmu_abb_write() - Write register value(s) to the ABB. | ||
147 | * @slave: The I2C slave address. | ||
148 | * @reg: The (start) register address. | ||
149 | * @value: The value(s) to write. | ||
150 | * @size: The number of registers to write. | ||
151 | * | ||
152 | * Reads register value(s) from the ABB. | ||
153 | * @size has to be 1 for the current firmware version. | ||
154 | */ | ||
155 | int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) | ||
156 | { | ||
157 | int r; | ||
158 | |||
159 | if (size != 1) | ||
160 | return -EINVAL; | ||
161 | |||
162 | r = mutex_lock_interruptible(&mb5_transfer.lock); | ||
163 | if (r) | ||
164 | return r; | ||
165 | |||
166 | |||
167 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) | ||
168 | cpu_relax(); | ||
169 | |||
170 | writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP); | ||
171 | writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS); | ||
172 | writeb(reg, REQ_MB5_I2C_REG); | ||
173 | writeb(*value, REQ_MB5_I2C_VAL); | ||
174 | |||
175 | writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); | ||
176 | if (!wait_for_completion_timeout(&mb5_transfer.work, | ||
177 | msecs_to_jiffies(500))) { | ||
178 | pr_err("prcmu: prcmu_abb_write timed out.\n"); | ||
179 | r = -EIO; | ||
180 | goto unlock_and_return; | ||
181 | } | ||
182 | r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO); | ||
183 | |||
184 | unlock_and_return: | ||
185 | mutex_unlock(&mb5_transfer.lock); | ||
186 | return r; | ||
187 | } | ||
188 | EXPORT_SYMBOL(prcmu_abb_write); | ||
189 | |||
190 | static int set_ape_cpu_opps(u8 header, enum prcmu_ape_opp ape_opp, | ||
191 | enum prcmu_cpu_opp cpu_opp) | ||
192 | { | ||
193 | bool do_ape; | ||
194 | bool do_arm; | ||
195 | int err = 0; | ||
196 | |||
197 | do_ape = ((header == MB1H_APE_OPP) || (header == MB1H_ARM_APE_OPP)); | ||
198 | do_arm = ((header == MB1H_ARM_OPP) || (header == MB1H_ARM_APE_OPP)); | ||
199 | |||
200 | mutex_lock(&mb1_transfer.lock); | ||
201 | |||
202 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) | ||
203 | cpu_relax(); | ||
204 | |||
205 | writeb(0, MBOX_HEADER_REQ_MB0); | ||
206 | writeb(cpu_opp, REQ_MB1_ARMOPP); | ||
207 | writeb(ape_opp, REQ_MB1_APEOPP); | ||
208 | writeb(0, REQ_MB1_BOOSTOPP); | ||
209 | writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); | ||
210 | wait_for_completion(&mb1_transfer.work); | ||
211 | if ((do_ape) && (mb1_transfer.ack.ape_status != 0)) | ||
212 | err = -EIO; | ||
213 | if ((do_arm) && (mb1_transfer.ack.arm_status != 0)) | ||
214 | err = -EIO; | ||
215 | |||
216 | mutex_unlock(&mb1_transfer.lock); | ||
217 | |||
218 | return err; | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * prcmu_set_ape_opp() - Set the OPP of the APE. | ||
223 | * @opp: The OPP to set. | ||
224 | * | ||
225 | * This function sets the OPP of the APE. | ||
226 | */ | ||
227 | int prcmu_set_ape_opp(enum prcmu_ape_opp opp) | ||
228 | { | ||
229 | return set_ape_cpu_opps(MB1H_APE_OPP, opp, APE_OPP_NO_CHANGE); | ||
230 | } | ||
231 | EXPORT_SYMBOL(prcmu_set_ape_opp); | ||
232 | |||
233 | /** | ||
234 | * prcmu_set_cpu_opp() - Set the OPP of the CPU. | ||
235 | * @opp: The OPP to set. | ||
236 | * | ||
237 | * This function sets the OPP of the CPU. | ||
238 | */ | ||
239 | int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp) | ||
240 | { | ||
241 | return set_ape_cpu_opps(MB1H_ARM_OPP, CPU_OPP_NO_CHANGE, opp); | ||
242 | } | ||
243 | EXPORT_SYMBOL(prcmu_set_cpu_opp); | ||
244 | |||
245 | /** | ||
246 | * prcmu_set_ape_cpu_opps() - Set the OPPs of the APE and the CPU. | ||
247 | * @ape_opp: The APE OPP to set. | ||
248 | * @cpu_opp: The CPU OPP to set. | ||
249 | * | ||
250 | * This function sets the OPPs of the APE and the CPU. | ||
251 | */ | ||
252 | int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, | ||
253 | enum prcmu_cpu_opp cpu_opp) | ||
254 | { | ||
255 | return set_ape_cpu_opps(MB1H_ARM_APE_OPP, ape_opp, cpu_opp); | ||
256 | } | ||
257 | EXPORT_SYMBOL(prcmu_set_ape_cpu_opps); | ||
258 | |||
259 | /** | ||
260 | * prcmu_get_ape_opp() - Get the OPP of the APE. | ||
261 | * | ||
262 | * This function gets the OPP of the APE. | ||
263 | */ | ||
264 | enum prcmu_ape_opp prcmu_get_ape_opp(void) | ||
265 | { | ||
266 | return readb(ACK_MB1_CURR_APEOPP); | ||
267 | } | ||
268 | EXPORT_SYMBOL(prcmu_get_ape_opp); | ||
269 | |||
270 | /** | ||
271 | * prcmu_get_cpu_opp() - Get the OPP of the CPU. | ||
272 | * | ||
273 | * This function gets the OPP of the CPU. The OPP is specified in %%. | ||
274 | * PRCMU_OPP_EXT is a special OPP value, not specified in %%. | ||
275 | */ | ||
276 | int prcmu_get_cpu_opp(void) | ||
277 | { | ||
278 | return readb(ACK_MB1_CURR_ARMOPP); | ||
279 | } | ||
280 | EXPORT_SYMBOL(prcmu_get_cpu_opp); | ||
281 | |||
282 | bool prcmu_has_arm_maxopp(void) | ||
283 | { | ||
284 | return (readb(PRCM_AVS_VARM_MAX_OPP) & PRCM_AVS_ISMODEENABLE_MASK) | ||
285 | == PRCM_AVS_ISMODEENABLE_MASK; | ||
286 | } | ||
287 | |||
288 | static void read_mailbox_0(void) | ||
289 | { | ||
290 | writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); | ||
291 | } | ||
292 | |||
293 | static void read_mailbox_1(void) | ||
294 | { | ||
295 | mb1_transfer.ack.arm_opp = readb(ACK_MB1_CURR_ARMOPP); | ||
296 | mb1_transfer.ack.ape_opp = readb(ACK_MB1_CURR_APEOPP); | ||
297 | complete(&mb1_transfer.work); | ||
298 | writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); | ||
299 | } | ||
300 | |||
301 | static void read_mailbox_2(void) | ||
302 | { | ||
303 | writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR); | ||
304 | } | ||
305 | |||
306 | static void read_mailbox_3(void) | ||
307 | { | ||
308 | writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR); | ||
309 | } | ||
310 | |||
311 | static void read_mailbox_4(void) | ||
312 | { | ||
313 | writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR); | ||
314 | } | ||
315 | |||
316 | static void read_mailbox_5(void) | ||
317 | { | ||
318 | mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS); | ||
319 | mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL); | ||
320 | complete(&mb5_transfer.work); | ||
321 | writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR); | ||
322 | } | ||
323 | |||
324 | static void read_mailbox_6(void) | ||
325 | { | ||
326 | writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR); | ||
327 | } | ||
328 | |||
329 | static void read_mailbox_7(void) | ||
330 | { | ||
331 | writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR); | ||
332 | } | ||
333 | |||
334 | static void (* const read_mailbox[NUM_MBOX])(void) = { | ||
335 | read_mailbox_0, | ||
336 | read_mailbox_1, | ||
337 | read_mailbox_2, | ||
338 | read_mailbox_3, | ||
339 | read_mailbox_4, | ||
340 | read_mailbox_5, | ||
341 | read_mailbox_6, | ||
342 | read_mailbox_7 | ||
343 | }; | ||
344 | |||
345 | static irqreturn_t prcmu_irq_handler(int irq, void *data) | ||
346 | { | ||
347 | u32 bits; | ||
348 | u8 n; | ||
349 | |||
350 | bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1)); | ||
351 | if (unlikely(!bits)) | ||
352 | return IRQ_NONE; | ||
353 | |||
354 | for (n = 0; bits; n++) { | ||
355 | if (bits & MBOX_BIT(n)) { | ||
356 | bits -= MBOX_BIT(n); | ||
357 | read_mailbox[n](); | ||
358 | } | ||
359 | } | ||
360 | return IRQ_HANDLED; | ||
361 | } | ||
362 | |||
363 | void __init prcmu_early_init(void) | ||
364 | { | ||
365 | if (cpu_is_u8500v11() || cpu_is_u8500ed()) { | ||
366 | tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1); | ||
367 | } else if (cpu_is_u8500v2()) { | ||
368 | tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); | ||
369 | } else { | ||
370 | pr_err("prcmu: Unsupported chip version\n"); | ||
371 | BUG(); | ||
372 | } | ||
373 | } | ||
374 | |||
375 | static int __init prcmu_init(void) | ||
376 | { | ||
377 | if (cpu_is_u8500ed()) { | ||
378 | pr_err("prcmu: Unsupported chip version\n"); | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | mutex_init(&mb1_transfer.lock); | ||
383 | init_completion(&mb1_transfer.work); | ||
384 | mutex_init(&mb5_transfer.lock); | ||
385 | init_completion(&mb5_transfer.work); | ||
386 | |||
387 | /* Clean up the mailbox interrupts after pre-kernel code. */ | ||
388 | writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR); | ||
389 | |||
390 | return request_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, 0, | ||
391 | "prcmu", NULL); | ||
392 | } | ||
393 | |||
394 | arch_initcall(prcmu_init); | ||