diff options
-rw-r--r-- | arch/arm/mach-msm/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-msm/board-halibut.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-msm/board-trout.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-msm/clock-7x01a.c | 126 | ||||
-rw-r--r-- | arch/arm/mach-msm/clock-pcom.c | 131 | ||||
-rw-r--r-- | arch/arm/mach-msm/clock-pcom.h | 153 | ||||
-rw-r--r-- | arch/arm/mach-msm/clock.c | 257 | ||||
-rw-r--r-- | arch/arm/mach-msm/clock.h | 70 | ||||
-rw-r--r-- | arch/arm/mach-msm/devices-msm7x00.c | 47 | ||||
-rw-r--r-- | arch/arm/mach-msm/devices.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-msm/include/mach/board.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-msm/include/mach/clk.h | 57 |
12 files changed, 651 insertions, 206 deletions
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 435d83cd52c2..70fa9703f437 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile | |||
@@ -2,7 +2,7 @@ obj-y += io.o idle.o irq.o timer.o dma.o | |||
2 | obj-y += proc_comm.o | 2 | obj-y += proc_comm.o |
3 | obj-y += vreg.o | 3 | obj-y += vreg.o |
4 | obj-y += acpuclock-arm11.o | 4 | obj-y += acpuclock-arm11.o |
5 | obj-y += clock.o clock-7x01a.o | 5 | obj-y += clock.o clock-pcom.o |
6 | 6 | ||
7 | obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o | 7 | obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o |
8 | obj-$(CONFIG_MSM_SMD) += last_radio_log.o | 8 | obj-$(CONFIG_MSM_SMD) += last_radio_log.o |
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index acc22886e340..7bd72e8f127e 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c | |||
@@ -90,7 +90,7 @@ static void __init halibut_fixup(struct machine_desc *desc, struct tag *tags, | |||
90 | static void __init halibut_map_io(void) | 90 | static void __init halibut_map_io(void) |
91 | { | 91 | { |
92 | msm_map_common_io(); | 92 | msm_map_common_io(); |
93 | msm_clock_init(); | 93 | msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a); |
94 | } | 94 | } |
95 | 95 | ||
96 | MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") | 96 | MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") |
diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c index b88aec269df5..dca5a5f062dc 100644 --- a/arch/arm/mach-msm/board-trout.c +++ b/arch/arm/mach-msm/board-trout.c | |||
@@ -78,7 +78,7 @@ static void __init trout_map_io(void) | |||
78 | writeb(0x80, TROUT_CPLD_BASE + 0x00); | 78 | writeb(0x80, TROUT_CPLD_BASE + 0x00); |
79 | #endif | 79 | #endif |
80 | 80 | ||
81 | msm_clock_init(); | 81 | msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a); |
82 | } | 82 | } |
83 | 83 | ||
84 | MACHINE_START(TROUT, "HTC Dream") | 84 | MACHINE_START(TROUT, "HTC Dream") |
diff --git a/arch/arm/mach-msm/clock-7x01a.c b/arch/arm/mach-msm/clock-7x01a.c deleted file mode 100644 index 62230a3428ee..000000000000 --- a/arch/arm/mach-msm/clock-7x01a.c +++ /dev/null | |||
@@ -1,126 +0,0 @@ | |||
1 | /* arch/arm/mach-msm/clock-7x01a.c | ||
2 | * | ||
3 | * Clock tables for MSM7X01A | ||
4 | * | ||
5 | * Copyright (C) 2007 Google, Inc. | ||
6 | * Copyright (c) 2007 QUALCOMM Incorporated | ||
7 | * | ||
8 | * This software is licensed under the terms of the GNU General Public | ||
9 | * License version 2, as published by the Free Software Foundation, and | ||
10 | * may be copied, distributed, and modified under those terms. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | |||
22 | #include "clock.h" | ||
23 | #include "devices.h" | ||
24 | |||
25 | /* clock IDs used by the modem processor */ | ||
26 | |||
27 | #define ACPU_CLK 0 /* Applications processor clock */ | ||
28 | #define ADM_CLK 1 /* Applications data mover clock */ | ||
29 | #define ADSP_CLK 2 /* ADSP clock */ | ||
30 | #define EBI1_CLK 3 /* External bus interface 1 clock */ | ||
31 | #define EBI2_CLK 4 /* External bus interface 2 clock */ | ||
32 | #define ECODEC_CLK 5 /* External CODEC clock */ | ||
33 | #define EMDH_CLK 6 /* External MDDI host clock */ | ||
34 | #define GP_CLK 7 /* General purpose clock */ | ||
35 | #define GRP_CLK 8 /* Graphics clock */ | ||
36 | #define I2C_CLK 9 /* I2C clock */ | ||
37 | #define ICODEC_RX_CLK 10 /* Internal CODEX RX clock */ | ||
38 | #define ICODEC_TX_CLK 11 /* Internal CODEX TX clock */ | ||
39 | #define IMEM_CLK 12 /* Internal graphics memory clock */ | ||
40 | #define MDC_CLK 13 /* MDDI client clock */ | ||
41 | #define MDP_CLK 14 /* Mobile display processor clock */ | ||
42 | #define PBUS_CLK 15 /* Peripheral bus clock */ | ||
43 | #define PCM_CLK 16 /* PCM clock */ | ||
44 | #define PMDH_CLK 17 /* Primary MDDI host clock */ | ||
45 | #define SDAC_CLK 18 /* Stereo DAC clock */ | ||
46 | #define SDC1_CLK 19 /* Secure Digital Card clocks */ | ||
47 | #define SDC1_PCLK 20 | ||
48 | #define SDC2_CLK 21 | ||
49 | #define SDC2_PCLK 22 | ||
50 | #define SDC3_CLK 23 | ||
51 | #define SDC3_PCLK 24 | ||
52 | #define SDC4_CLK 25 | ||
53 | #define SDC4_PCLK 26 | ||
54 | #define TSIF_CLK 27 /* Transport Stream Interface clocks */ | ||
55 | #define TSIF_REF_CLK 28 | ||
56 | #define TV_DAC_CLK 29 /* TV clocks */ | ||
57 | #define TV_ENC_CLK 30 | ||
58 | #define UART1_CLK 31 /* UART clocks */ | ||
59 | #define UART2_CLK 32 | ||
60 | #define UART3_CLK 33 | ||
61 | #define UART1DM_CLK 34 | ||
62 | #define UART2DM_CLK 35 | ||
63 | #define USB_HS_CLK 36 /* High speed USB core clock */ | ||
64 | #define USB_HS_PCLK 37 /* High speed USB pbus clock */ | ||
65 | #define USB_OTG_CLK 38 /* Full speed USB clock */ | ||
66 | #define VDC_CLK 39 /* Video controller clock */ | ||
67 | #define VFE_CLK 40 /* Camera / Video Front End clock */ | ||
68 | #define VFE_MDC_CLK 41 /* VFE MDDI client clock */ | ||
69 | |||
70 | #define NR_CLKS 42 | ||
71 | |||
72 | #define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \ | ||
73 | .name = clk_name, \ | ||
74 | .id = clk_id, \ | ||
75 | .flags = clk_flags, \ | ||
76 | .dev = clk_dev, \ | ||
77 | } | ||
78 | |||
79 | #define OFF CLKFLAG_AUTO_OFF | ||
80 | #define MINMAX CLKFLAG_USE_MIN_MAX_TO_SET | ||
81 | |||
82 | struct clk msm_clocks[] = { | ||
83 | CLOCK("adm_clk", ADM_CLK, NULL, 0), | ||
84 | CLOCK("adsp_clk", ADSP_CLK, NULL, 0), | ||
85 | CLOCK("ebi1_clk", EBI1_CLK, NULL, 0), | ||
86 | CLOCK("ebi2_clk", EBI2_CLK, NULL, 0), | ||
87 | CLOCK("ecodec_clk", ECODEC_CLK, NULL, 0), | ||
88 | CLOCK("emdh_clk", EMDH_CLK, NULL, OFF), | ||
89 | CLOCK("gp_clk", GP_CLK, NULL, 0), | ||
90 | CLOCK("grp_clk", GRP_CLK, NULL, OFF), | ||
91 | CLOCK("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0), | ||
92 | CLOCK("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0), | ||
93 | CLOCK("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0), | ||
94 | CLOCK("imem_clk", IMEM_CLK, NULL, OFF), | ||
95 | CLOCK("mdc_clk", MDC_CLK, NULL, 0), | ||
96 | CLOCK("mdp_clk", MDP_CLK, NULL, OFF), | ||
97 | CLOCK("pbus_clk", PBUS_CLK, NULL, 0), | ||
98 | CLOCK("pcm_clk", PCM_CLK, NULL, 0), | ||
99 | CLOCK("pmdh_clk", PMDH_CLK, NULL, OFF | MINMAX), | ||
100 | CLOCK("sdac_clk", SDAC_CLK, NULL, OFF), | ||
101 | CLOCK("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF), | ||
102 | CLOCK("sdc_pclk", SDC1_PCLK, &msm_device_sdc1.dev, OFF), | ||
103 | CLOCK("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF), | ||
104 | CLOCK("sdc_pclk", SDC2_PCLK, &msm_device_sdc2.dev, OFF), | ||
105 | CLOCK("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF), | ||
106 | CLOCK("sdc_pclk", SDC3_PCLK, &msm_device_sdc3.dev, OFF), | ||
107 | CLOCK("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF), | ||
108 | CLOCK("sdc_pclk", SDC4_PCLK, &msm_device_sdc4.dev, OFF), | ||
109 | CLOCK("tsif_clk", TSIF_CLK, NULL, 0), | ||
110 | CLOCK("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), | ||
111 | CLOCK("tv_dac_clk", TV_DAC_CLK, NULL, 0), | ||
112 | CLOCK("tv_enc_clk", TV_ENC_CLK, NULL, 0), | ||
113 | CLOCK("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF), | ||
114 | CLOCK("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0), | ||
115 | CLOCK("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF), | ||
116 | CLOCK("uart1dm_clk", UART1DM_CLK, NULL, OFF), | ||
117 | CLOCK("uart2dm_clk", UART2DM_CLK, NULL, 0), | ||
118 | CLOCK("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF), | ||
119 | CLOCK("usb_hs_pclk", USB_HS_PCLK, &msm_device_hsusb.dev, OFF), | ||
120 | CLOCK("usb_otg_clk", USB_OTG_CLK, NULL, 0), | ||
121 | CLOCK("vdc_clk", VDC_CLK, NULL, OFF | MINMAX), | ||
122 | CLOCK("vfe_clk", VFE_CLK, NULL, OFF), | ||
123 | CLOCK("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF), | ||
124 | }; | ||
125 | |||
126 | unsigned msm_num_clocks = ARRAY_SIZE(msm_clocks); | ||
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c new file mode 100644 index 000000000000..a3b45627eb4a --- /dev/null +++ b/arch/arm/mach-msm/clock-pcom.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 Google, Inc. | ||
3 | * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/err.h> | ||
17 | #include <linux/ctype.h> | ||
18 | #include <linux/stddef.h> | ||
19 | #include <mach/clk.h> | ||
20 | |||
21 | #include "proc_comm.h" | ||
22 | #include "clock.h" | ||
23 | |||
24 | /* | ||
25 | * glue for the proc_comm interface | ||
26 | */ | ||
27 | int pc_clk_enable(unsigned id) | ||
28 | { | ||
29 | int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL); | ||
30 | if (rc < 0) | ||
31 | return rc; | ||
32 | else | ||
33 | return (int)id < 0 ? -EINVAL : 0; | ||
34 | } | ||
35 | |||
36 | void pc_clk_disable(unsigned id) | ||
37 | { | ||
38 | msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL); | ||
39 | } | ||
40 | |||
41 | int pc_clk_reset(unsigned id, enum clk_reset_action action) | ||
42 | { | ||
43 | int rc; | ||
44 | |||
45 | if (action == CLK_RESET_ASSERT) | ||
46 | rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL); | ||
47 | else | ||
48 | rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_DEASSERT, &id, NULL); | ||
49 | |||
50 | if (rc < 0) | ||
51 | return rc; | ||
52 | else | ||
53 | return (int)id < 0 ? -EINVAL : 0; | ||
54 | } | ||
55 | |||
56 | int pc_clk_set_rate(unsigned id, unsigned rate) | ||
57 | { | ||
58 | /* The rate _might_ be rounded off to the nearest KHz value by the | ||
59 | * remote function. So a return value of 0 doesn't necessarily mean | ||
60 | * that the exact rate was set successfully. | ||
61 | */ | ||
62 | int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate); | ||
63 | if (rc < 0) | ||
64 | return rc; | ||
65 | else | ||
66 | return (int)id < 0 ? -EINVAL : 0; | ||
67 | } | ||
68 | |||
69 | int pc_clk_set_min_rate(unsigned id, unsigned rate) | ||
70 | { | ||
71 | int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate); | ||
72 | if (rc < 0) | ||
73 | return rc; | ||
74 | else | ||
75 | return (int)id < 0 ? -EINVAL : 0; | ||
76 | } | ||
77 | |||
78 | int pc_clk_set_max_rate(unsigned id, unsigned rate) | ||
79 | { | ||
80 | int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate); | ||
81 | if (rc < 0) | ||
82 | return rc; | ||
83 | else | ||
84 | return (int)id < 0 ? -EINVAL : 0; | ||
85 | } | ||
86 | |||
87 | int pc_clk_set_flags(unsigned id, unsigned flags) | ||
88 | { | ||
89 | int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags); | ||
90 | if (rc < 0) | ||
91 | return rc; | ||
92 | else | ||
93 | return (int)id < 0 ? -EINVAL : 0; | ||
94 | } | ||
95 | |||
96 | unsigned pc_clk_get_rate(unsigned id) | ||
97 | { | ||
98 | if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL)) | ||
99 | return 0; | ||
100 | else | ||
101 | return id; | ||
102 | } | ||
103 | |||
104 | unsigned pc_clk_is_enabled(unsigned id) | ||
105 | { | ||
106 | if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL)) | ||
107 | return 0; | ||
108 | else | ||
109 | return id; | ||
110 | } | ||
111 | |||
112 | long pc_clk_round_rate(unsigned id, unsigned rate) | ||
113 | { | ||
114 | |||
115 | /* Not really supported; pc_clk_set_rate() does rounding on it's own. */ | ||
116 | return rate; | ||
117 | } | ||
118 | |||
119 | struct clk_ops clk_ops_pcom = { | ||
120 | .enable = pc_clk_enable, | ||
121 | .disable = pc_clk_disable, | ||
122 | .auto_off = pc_clk_disable, | ||
123 | .reset = pc_clk_reset, | ||
124 | .set_rate = pc_clk_set_rate, | ||
125 | .set_min_rate = pc_clk_set_min_rate, | ||
126 | .set_max_rate = pc_clk_set_max_rate, | ||
127 | .set_flags = pc_clk_set_flags, | ||
128 | .get_rate = pc_clk_get_rate, | ||
129 | .is_enabled = pc_clk_is_enabled, | ||
130 | .round_rate = pc_clk_round_rate, | ||
131 | }; | ||
diff --git a/arch/arm/mach-msm/clock-pcom.h b/arch/arm/mach-msm/clock-pcom.h new file mode 100644 index 000000000000..17d027b23501 --- /dev/null +++ b/arch/arm/mach-msm/clock-pcom.h | |||
@@ -0,0 +1,153 @@ | |||
1 | /* Copyright (c) 2009, Code Aurora Forum. All rights reserved. | ||
2 | * | ||
3 | * Redistribution and use in source and binary forms, with or without | ||
4 | * modification, are permitted provided that the following conditions are | ||
5 | * met: | ||
6 | * * Redistributions of source code must retain the above copyright | ||
7 | * notice, this list of conditions and the following disclaimer. | ||
8 | * * Redistributions in binary form must reproduce the above | ||
9 | * copyright notice, this list of conditions and the following | ||
10 | * disclaimer in the documentation and/or other materials provided | ||
11 | * with the distribution. | ||
12 | * * Neither the name of Code Aurora Forum, Inc. nor the names of its | ||
13 | * contributors may be used to endorse or promote products derived | ||
14 | * from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | ||
17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT | ||
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | ||
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #ifndef __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H | ||
31 | #define __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H | ||
32 | |||
33 | /* clock IDs used by the modem processor */ | ||
34 | |||
35 | #define P_ACPU_CLK 0 /* Applications processor clock */ | ||
36 | #define P_ADM_CLK 1 /* Applications data mover clock */ | ||
37 | #define P_ADSP_CLK 2 /* ADSP clock */ | ||
38 | #define P_EBI1_CLK 3 /* External bus interface 1 clock */ | ||
39 | #define P_EBI2_CLK 4 /* External bus interface 2 clock */ | ||
40 | #define P_ECODEC_CLK 5 /* External CODEC clock */ | ||
41 | #define P_EMDH_CLK 6 /* External MDDI host clock */ | ||
42 | #define P_GP_CLK 7 /* General purpose clock */ | ||
43 | #define P_GRP_3D_CLK 8 /* Graphics clock */ | ||
44 | #define P_I2C_CLK 9 /* I2C clock */ | ||
45 | #define P_ICODEC_RX_CLK 10 /* Internal CODEX RX clock */ | ||
46 | #define P_ICODEC_TX_CLK 11 /* Internal CODEX TX clock */ | ||
47 | #define P_IMEM_CLK 12 /* Internal graphics memory clock */ | ||
48 | #define P_MDC_CLK 13 /* MDDI client clock */ | ||
49 | #define P_MDP_CLK 14 /* Mobile display processor clock */ | ||
50 | #define P_PBUS_CLK 15 /* Peripheral bus clock */ | ||
51 | #define P_PCM_CLK 16 /* PCM clock */ | ||
52 | #define P_PMDH_CLK 17 /* Primary MDDI host clock */ | ||
53 | #define P_SDAC_CLK 18 /* Stereo DAC clock */ | ||
54 | #define P_SDC1_CLK 19 /* Secure Digital Card clocks */ | ||
55 | #define P_SDC1_P_CLK 20 | ||
56 | #define P_SDC2_CLK 21 | ||
57 | #define P_SDC2_P_CLK 22 | ||
58 | #define P_SDC3_CLK 23 | ||
59 | #define P_SDC3_P_CLK 24 | ||
60 | #define P_SDC4_CLK 25 | ||
61 | #define P_SDC4_P_CLK 26 | ||
62 | #define P_TSIF_CLK 27 /* Transport Stream Interface clocks */ | ||
63 | #define P_TSIF_REF_CLK 28 | ||
64 | #define P_TV_DAC_CLK 29 /* TV clocks */ | ||
65 | #define P_TV_ENC_CLK 30 | ||
66 | #define P_UART1_CLK 31 /* UART clocks */ | ||
67 | #define P_UART2_CLK 32 | ||
68 | #define P_UART3_CLK 33 | ||
69 | #define P_UART1DM_CLK 34 | ||
70 | #define P_UART2DM_CLK 35 | ||
71 | #define P_USB_HS_CLK 36 /* High speed USB core clock */ | ||
72 | #define P_USB_HS_P_CLK 37 /* High speed USB pbus clock */ | ||
73 | #define P_USB_OTG_CLK 38 /* Full speed USB clock */ | ||
74 | #define P_VDC_CLK 39 /* Video controller clock */ | ||
75 | #define P_VFE_MDC_CLK 40 /* Camera / Video Front End clock */ | ||
76 | #define P_VFE_CLK 41 /* VFE MDDI client clock */ | ||
77 | #define P_MDP_LCDC_PCLK_CLK 42 | ||
78 | #define P_MDP_LCDC_PAD_PCLK_CLK 43 | ||
79 | #define P_MDP_VSYNC_CLK 44 | ||
80 | #define P_SPI_CLK 45 | ||
81 | #define P_VFE_AXI_CLK 46 | ||
82 | #define P_USB_HS2_CLK 47 /* High speed USB 2 core clock */ | ||
83 | #define P_USB_HS2_P_CLK 48 /* High speed USB 2 pbus clock */ | ||
84 | #define P_USB_HS3_CLK 49 /* High speed USB 3 core clock */ | ||
85 | #define P_USB_HS3_P_CLK 50 /* High speed USB 3 pbus clock */ | ||
86 | #define P_GRP_3D_P_CLK 51 /* Graphics pbus clock */ | ||
87 | #define P_USB_PHY_CLK 52 /* USB PHY clock */ | ||
88 | #define P_USB_HS_CORE_CLK 53 /* High speed USB 1 core clock */ | ||
89 | #define P_USB_HS2_CORE_CLK 54 /* High speed USB 2 core clock */ | ||
90 | #define P_USB_HS3_CORE_CLK 55 /* High speed USB 3 core clock */ | ||
91 | #define P_CAM_M_CLK 56 | ||
92 | #define P_CAMIF_PAD_P_CLK 57 | ||
93 | #define P_GRP_2D_CLK 58 | ||
94 | #define P_GRP_2D_P_CLK 59 | ||
95 | #define P_I2S_CLK 60 | ||
96 | #define P_JPEG_CLK 61 | ||
97 | #define P_JPEG_P_CLK 62 | ||
98 | #define P_LPA_CODEC_CLK 63 | ||
99 | #define P_LPA_CORE_CLK 64 | ||
100 | #define P_LPA_P_CLK 65 | ||
101 | #define P_MDC_IO_CLK 66 | ||
102 | #define P_MDC_P_CLK 67 | ||
103 | #define P_MFC_CLK 68 | ||
104 | #define P_MFC_DIV2_CLK 69 | ||
105 | #define P_MFC_P_CLK 70 | ||
106 | #define P_QUP_I2C_CLK 71 | ||
107 | #define P_ROTATOR_IMEM_CLK 72 | ||
108 | #define P_ROTATOR_P_CLK 73 | ||
109 | #define P_VFE_CAMIF_CLK 74 | ||
110 | #define P_VFE_P_CLK 75 | ||
111 | #define P_VPE_CLK 76 | ||
112 | #define P_I2C_2_CLK 77 | ||
113 | #define P_MI2S_CODEC_RX_S_CLK 78 | ||
114 | #define P_MI2S_CODEC_RX_M_CLK 79 | ||
115 | #define P_MI2S_CODEC_TX_S_CLK 80 | ||
116 | #define P_MI2S_CODEC_TX_M_CLK 81 | ||
117 | #define P_PMDH_P_CLK 82 | ||
118 | #define P_EMDH_P_CLK 83 | ||
119 | #define P_SPI_P_CLK 84 | ||
120 | #define P_TSIF_P_CLK 85 | ||
121 | #define P_MDP_P_CLK 86 | ||
122 | #define P_SDAC_M_CLK 87 | ||
123 | #define P_MI2S_S_CLK 88 | ||
124 | #define P_MI2S_M_CLK 89 | ||
125 | #define P_AXI_ROTATOR_CLK 90 | ||
126 | #define P_HDMI_CLK 91 | ||
127 | #define P_CSI0_CLK 92 | ||
128 | #define P_CSI0_VFE_CLK 93 | ||
129 | #define P_CSI0_P_CLK 94 | ||
130 | #define P_CSI1_CLK 95 | ||
131 | #define P_CSI1_VFE_CLK 96 | ||
132 | #define P_CSI1_P_CLK 97 | ||
133 | #define P_GSBI_CLK 98 | ||
134 | #define P_GSBI_P_CLK 99 | ||
135 | |||
136 | #define P_NR_CLKS 100 | ||
137 | |||
138 | struct clk_ops; | ||
139 | extern struct clk_ops clk_ops_pcom; | ||
140 | |||
141 | int pc_clk_reset(unsigned id, enum clk_reset_action action); | ||
142 | |||
143 | #define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) { \ | ||
144 | .name = clk_name, \ | ||
145 | .id = P_##clk_id, \ | ||
146 | .remote_id = P_##clk_id, \ | ||
147 | .ops = &clk_ops_pcom, \ | ||
148 | .flags = clk_flags, \ | ||
149 | .dev = clk_dev, \ | ||
150 | .dbg_name = #clk_id, \ | ||
151 | } | ||
152 | |||
153 | #endif | ||
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c index 3b1ce36f1032..34c6a52af060 100644 --- a/arch/arm/mach-msm/clock.c +++ b/arch/arm/mach-msm/clock.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* arch/arm/mach-msm/clock.c | 1 | /* arch/arm/mach-msm/clock.c |
2 | * | 2 | * |
3 | * Copyright (C) 2007 Google, Inc. | 3 | * Copyright (C) 2007 Google, Inc. |
4 | * Copyright (c) 2007 QUALCOMM Incorporated | 4 | * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved. |
5 | * | 5 | * |
6 | * This software is licensed under the terms of the GNU General Public | 6 | * This software is licensed under the terms of the GNU General Public |
7 | * License version 2, as published by the Free Software Foundation, and | 7 | * License version 2, as published by the Free Software Foundation, and |
@@ -22,6 +22,10 @@ | |||
22 | #include <linux/err.h> | 22 | #include <linux/err.h> |
23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/debugfs.h> | ||
26 | #include <linux/ctype.h> | ||
27 | #include <linux/pm_qos_params.h> | ||
28 | #include <mach/clk.h> | ||
25 | 29 | ||
26 | #include "clock.h" | 30 | #include "clock.h" |
27 | #include "proc_comm.h" | 31 | #include "proc_comm.h" |
@@ -29,61 +33,15 @@ | |||
29 | static DEFINE_MUTEX(clocks_mutex); | 33 | static DEFINE_MUTEX(clocks_mutex); |
30 | static DEFINE_SPINLOCK(clocks_lock); | 34 | static DEFINE_SPINLOCK(clocks_lock); |
31 | static LIST_HEAD(clocks); | 35 | static LIST_HEAD(clocks); |
36 | struct clk *msm_clocks; | ||
37 | unsigned msm_num_clocks; | ||
32 | 38 | ||
33 | /* | 39 | /* |
34 | * glue for the proc_comm interface | 40 | * Bitmap of enabled clocks, excluding ACPU which is always |
41 | * enabled | ||
35 | */ | 42 | */ |
36 | static inline int pc_clk_enable(unsigned id) | 43 | static DECLARE_BITMAP(clock_map_enabled, NR_CLKS); |
37 | { | 44 | static DEFINE_SPINLOCK(clock_map_lock); |
38 | return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL); | ||
39 | } | ||
40 | |||
41 | static inline void pc_clk_disable(unsigned id) | ||
42 | { | ||
43 | msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL); | ||
44 | } | ||
45 | |||
46 | static inline int pc_clk_set_rate(unsigned id, unsigned rate) | ||
47 | { | ||
48 | return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate); | ||
49 | } | ||
50 | |||
51 | static inline int pc_clk_set_min_rate(unsigned id, unsigned rate) | ||
52 | { | ||
53 | return msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate); | ||
54 | } | ||
55 | |||
56 | static inline int pc_clk_set_max_rate(unsigned id, unsigned rate) | ||
57 | { | ||
58 | return msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate); | ||
59 | } | ||
60 | |||
61 | static inline int pc_clk_set_flags(unsigned id, unsigned flags) | ||
62 | { | ||
63 | return msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags); | ||
64 | } | ||
65 | |||
66 | static inline unsigned pc_clk_get_rate(unsigned id) | ||
67 | { | ||
68 | if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL)) | ||
69 | return 0; | ||
70 | else | ||
71 | return id; | ||
72 | } | ||
73 | |||
74 | static inline unsigned pc_clk_is_enabled(unsigned id) | ||
75 | { | ||
76 | if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL)) | ||
77 | return 0; | ||
78 | else | ||
79 | return id; | ||
80 | } | ||
81 | |||
82 | static inline int pc_pll_request(unsigned id, unsigned on) | ||
83 | { | ||
84 | on = !!on; | ||
85 | return msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on); | ||
86 | } | ||
87 | 45 | ||
88 | /* | 46 | /* |
89 | * Standard clock functions defined in include/linux/clk.h | 47 | * Standard clock functions defined in include/linux/clk.h |
@@ -119,8 +77,12 @@ int clk_enable(struct clk *clk) | |||
119 | unsigned long flags; | 77 | unsigned long flags; |
120 | spin_lock_irqsave(&clocks_lock, flags); | 78 | spin_lock_irqsave(&clocks_lock, flags); |
121 | clk->count++; | 79 | clk->count++; |
122 | if (clk->count == 1) | 80 | if (clk->count == 1) { |
123 | pc_clk_enable(clk->id); | 81 | clk->ops->enable(clk->id); |
82 | spin_lock(&clock_map_lock); | ||
83 | clock_map_enabled[BIT_WORD(clk->id)] |= BIT_MASK(clk->id); | ||
84 | spin_unlock(&clock_map_lock); | ||
85 | } | ||
124 | spin_unlock_irqrestore(&clocks_lock, flags); | 86 | spin_unlock_irqrestore(&clocks_lock, flags); |
125 | return 0; | 87 | return 0; |
126 | } | 88 | } |
@@ -132,31 +94,54 @@ void clk_disable(struct clk *clk) | |||
132 | spin_lock_irqsave(&clocks_lock, flags); | 94 | spin_lock_irqsave(&clocks_lock, flags); |
133 | BUG_ON(clk->count == 0); | 95 | BUG_ON(clk->count == 0); |
134 | clk->count--; | 96 | clk->count--; |
135 | if (clk->count == 0) | 97 | if (clk->count == 0) { |
136 | pc_clk_disable(clk->id); | 98 | clk->ops->disable(clk->id); |
99 | spin_lock(&clock_map_lock); | ||
100 | clock_map_enabled[BIT_WORD(clk->id)] &= ~BIT_MASK(clk->id); | ||
101 | spin_unlock(&clock_map_lock); | ||
102 | } | ||
137 | spin_unlock_irqrestore(&clocks_lock, flags); | 103 | spin_unlock_irqrestore(&clocks_lock, flags); |
138 | } | 104 | } |
139 | EXPORT_SYMBOL(clk_disable); | 105 | EXPORT_SYMBOL(clk_disable); |
140 | 106 | ||
107 | int clk_reset(struct clk *clk, enum clk_reset_action action) | ||
108 | { | ||
109 | if (!clk->ops->reset) | ||
110 | clk->ops->reset = &pc_clk_reset; | ||
111 | return clk->ops->reset(clk->remote_id, action); | ||
112 | } | ||
113 | EXPORT_SYMBOL(clk_reset); | ||
114 | |||
141 | unsigned long clk_get_rate(struct clk *clk) | 115 | unsigned long clk_get_rate(struct clk *clk) |
142 | { | 116 | { |
143 | return pc_clk_get_rate(clk->id); | 117 | return clk->ops->get_rate(clk->id); |
144 | } | 118 | } |
145 | EXPORT_SYMBOL(clk_get_rate); | 119 | EXPORT_SYMBOL(clk_get_rate); |
146 | 120 | ||
147 | int clk_set_rate(struct clk *clk, unsigned long rate) | 121 | int clk_set_rate(struct clk *clk, unsigned long rate) |
148 | { | 122 | { |
149 | int ret; | 123 | return clk->ops->set_rate(clk->id, rate); |
150 | if (clk->flags & CLKFLAG_USE_MIN_MAX_TO_SET) { | ||
151 | ret = pc_clk_set_max_rate(clk->id, rate); | ||
152 | if (ret) | ||
153 | return ret; | ||
154 | return pc_clk_set_min_rate(clk->id, rate); | ||
155 | } | ||
156 | return pc_clk_set_rate(clk->id, rate); | ||
157 | } | 124 | } |
158 | EXPORT_SYMBOL(clk_set_rate); | 125 | EXPORT_SYMBOL(clk_set_rate); |
159 | 126 | ||
127 | long clk_round_rate(struct clk *clk, unsigned long rate) | ||
128 | { | ||
129 | return clk->ops->round_rate(clk->id, rate); | ||
130 | } | ||
131 | EXPORT_SYMBOL(clk_round_rate); | ||
132 | |||
133 | int clk_set_min_rate(struct clk *clk, unsigned long rate) | ||
134 | { | ||
135 | return clk->ops->set_min_rate(clk->id, rate); | ||
136 | } | ||
137 | EXPORT_SYMBOL(clk_set_min_rate); | ||
138 | |||
139 | int clk_set_max_rate(struct clk *clk, unsigned long rate) | ||
140 | { | ||
141 | return clk->ops->set_max_rate(clk->id, rate); | ||
142 | } | ||
143 | EXPORT_SYMBOL(clk_set_max_rate); | ||
144 | |||
160 | int clk_set_parent(struct clk *clk, struct clk *parent) | 145 | int clk_set_parent(struct clk *clk, struct clk *parent) |
161 | { | 146 | { |
162 | return -ENOSYS; | 147 | return -ENOSYS; |
@@ -173,22 +158,153 @@ int clk_set_flags(struct clk *clk, unsigned long flags) | |||
173 | { | 158 | { |
174 | if (clk == NULL || IS_ERR(clk)) | 159 | if (clk == NULL || IS_ERR(clk)) |
175 | return -EINVAL; | 160 | return -EINVAL; |
176 | return pc_clk_set_flags(clk->id, flags); | 161 | return clk->ops->set_flags(clk->id, flags); |
177 | } | 162 | } |
178 | EXPORT_SYMBOL(clk_set_flags); | 163 | EXPORT_SYMBOL(clk_set_flags); |
179 | 164 | ||
165 | /* EBI1 is the only shared clock that several clients want to vote on as of | ||
166 | * this commit. If this changes in the future, then it might be better to | ||
167 | * make clk_min_rate handle the voting or make ebi1_clk_set_min_rate more | ||
168 | * generic to support different clocks. | ||
169 | */ | ||
170 | static struct clk *ebi1_clk; | ||
180 | 171 | ||
181 | void __init msm_clock_init(void) | 172 | static void __init set_clock_ops(struct clk *clk) |
173 | { | ||
174 | if (!clk->ops) { | ||
175 | clk->ops = &clk_ops_pcom; | ||
176 | clk->id = clk->remote_id; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks) | ||
182 | { | 181 | { |
183 | unsigned n; | 182 | unsigned n; |
184 | 183 | ||
185 | spin_lock_init(&clocks_lock); | 184 | spin_lock_init(&clocks_lock); |
186 | mutex_lock(&clocks_mutex); | 185 | mutex_lock(&clocks_mutex); |
187 | for (n = 0; n < msm_num_clocks; n++) | 186 | msm_clocks = clock_tbl; |
187 | msm_num_clocks = num_clocks; | ||
188 | for (n = 0; n < msm_num_clocks; n++) { | ||
189 | set_clock_ops(&msm_clocks[n]); | ||
188 | list_add_tail(&msm_clocks[n].list, &clocks); | 190 | list_add_tail(&msm_clocks[n].list, &clocks); |
191 | } | ||
189 | mutex_unlock(&clocks_mutex); | 192 | mutex_unlock(&clocks_mutex); |
193 | |||
194 | ebi1_clk = clk_get(NULL, "ebi1_clk"); | ||
195 | BUG_ON(ebi1_clk == NULL); | ||
196 | |||
197 | } | ||
198 | |||
199 | #if defined(CONFIG_DEBUG_FS) | ||
200 | static struct clk *msm_clock_get_nth(unsigned index) | ||
201 | { | ||
202 | if (index < msm_num_clocks) | ||
203 | return msm_clocks + index; | ||
204 | else | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static int clock_debug_rate_set(void *data, u64 val) | ||
209 | { | ||
210 | struct clk *clock = data; | ||
211 | int ret; | ||
212 | |||
213 | /* Only increases to max rate will succeed, but that's actually good | ||
214 | * for debugging purposes. So we don't check for error. */ | ||
215 | if (clock->flags & CLK_MAX) | ||
216 | clk_set_max_rate(clock, val); | ||
217 | if (clock->flags & CLK_MIN) | ||
218 | ret = clk_set_min_rate(clock, val); | ||
219 | else | ||
220 | ret = clk_set_rate(clock, val); | ||
221 | if (ret != 0) | ||
222 | printk(KERN_ERR "clk_set%s_rate failed (%d)\n", | ||
223 | (clock->flags & CLK_MIN) ? "_min" : "", ret); | ||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | static int clock_debug_rate_get(void *data, u64 *val) | ||
228 | { | ||
229 | struct clk *clock = data; | ||
230 | *val = clk_get_rate(clock); | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static int clock_debug_enable_set(void *data, u64 val) | ||
235 | { | ||
236 | struct clk *clock = data; | ||
237 | int rc = 0; | ||
238 | |||
239 | if (val) | ||
240 | rc = clock->ops->enable(clock->id); | ||
241 | else | ||
242 | clock->ops->disable(clock->id); | ||
243 | |||
244 | return rc; | ||
190 | } | 245 | } |
191 | 246 | ||
247 | static int clock_debug_enable_get(void *data, u64 *val) | ||
248 | { | ||
249 | struct clk *clock = data; | ||
250 | |||
251 | *val = clock->ops->is_enabled(clock->id); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static int clock_debug_local_get(void *data, u64 *val) | ||
257 | { | ||
258 | struct clk *clock = data; | ||
259 | |||
260 | *val = clock->ops != &clk_ops_pcom; | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get, | ||
266 | clock_debug_rate_set, "%llu\n"); | ||
267 | DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get, | ||
268 | clock_debug_enable_set, "%llu\n"); | ||
269 | DEFINE_SIMPLE_ATTRIBUTE(clock_local_fops, clock_debug_local_get, | ||
270 | NULL, "%llu\n"); | ||
271 | |||
272 | static int __init clock_debug_init(void) | ||
273 | { | ||
274 | struct dentry *dent_rate, *dent_enable, *dent_local; | ||
275 | struct clk *clock; | ||
276 | unsigned n = 0; | ||
277 | char temp[50], *ptr; | ||
278 | |||
279 | dent_rate = debugfs_create_dir("clk_rate", 0); | ||
280 | if (IS_ERR(dent_rate)) | ||
281 | return PTR_ERR(dent_rate); | ||
282 | |||
283 | dent_enable = debugfs_create_dir("clk_enable", 0); | ||
284 | if (IS_ERR(dent_enable)) | ||
285 | return PTR_ERR(dent_enable); | ||
286 | |||
287 | dent_local = debugfs_create_dir("clk_local", NULL); | ||
288 | if (IS_ERR(dent_local)) | ||
289 | return PTR_ERR(dent_local); | ||
290 | |||
291 | while ((clock = msm_clock_get_nth(n++)) != 0) { | ||
292 | strncpy(temp, clock->dbg_name, ARRAY_SIZE(temp)-1); | ||
293 | for (ptr = temp; *ptr; ptr++) | ||
294 | *ptr = tolower(*ptr); | ||
295 | debugfs_create_file(temp, 0644, dent_rate, | ||
296 | clock, &clock_rate_fops); | ||
297 | debugfs_create_file(temp, 0644, dent_enable, | ||
298 | clock, &clock_enable_fops); | ||
299 | debugfs_create_file(temp, S_IRUGO, dent_local, | ||
300 | clock, &clock_local_fops); | ||
301 | } | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | device_initcall(clock_debug_init); | ||
306 | #endif | ||
307 | |||
192 | /* The bootloader and/or AMSS may have left various clocks enabled. | 308 | /* The bootloader and/or AMSS may have left various clocks enabled. |
193 | * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have | 309 | * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have |
194 | * not been explicitly enabled by a clk_enable() call. | 310 | * not been explicitly enabled by a clk_enable() call. |
@@ -205,7 +321,7 @@ static int __init clock_late_init(void) | |||
205 | spin_lock_irqsave(&clocks_lock, flags); | 321 | spin_lock_irqsave(&clocks_lock, flags); |
206 | if (!clk->count) { | 322 | if (!clk->count) { |
207 | count++; | 323 | count++; |
208 | pc_clk_disable(clk->id); | 324 | clk->ops->auto_off(clk->id); |
209 | } | 325 | } |
210 | spin_unlock_irqrestore(&clocks_lock, flags); | 326 | spin_unlock_irqrestore(&clocks_lock, flags); |
211 | } | 327 | } |
@@ -216,3 +332,4 @@ static int __init clock_late_init(void) | |||
216 | } | 332 | } |
217 | 333 | ||
218 | late_initcall(clock_late_init); | 334 | late_initcall(clock_late_init); |
335 | |||
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h index f875e1544e5f..598db9290422 100644 --- a/arch/arm/mach-msm/clock.h +++ b/arch/arm/mach-msm/clock.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* arch/arm/mach-msm/clock.h | 1 | /* arch/arm/mach-msm/clock.h |
2 | * | 2 | * |
3 | * Copyright (C) 2007 Google, Inc. | 3 | * Copyright (C) 2007 Google, Inc. |
4 | * Copyright (c) 2007 QUALCOMM Incorporated | 4 | * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved. |
5 | * | 5 | * |
6 | * This software is licensed under the terms of the GNU General Public | 6 | * This software is licensed under the terms of the GNU General Public |
7 | * License version 2, as published by the Free Software Foundation, and | 7 | * License version 2, as published by the Free Software Foundation, and |
@@ -18,6 +18,9 @@ | |||
18 | #define __ARCH_ARM_MACH_MSM_CLOCK_H | 18 | #define __ARCH_ARM_MACH_MSM_CLOCK_H |
19 | 19 | ||
20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
21 | #include <mach/clk.h> | ||
22 | |||
23 | #include "clock-pcom.h" | ||
21 | 24 | ||
22 | #define CLKFLAG_INVERT 0x00000001 | 25 | #define CLKFLAG_INVERT 0x00000001 |
23 | #define CLKFLAG_NOINVERT 0x00000002 | 26 | #define CLKFLAG_NOINVERT 0x00000002 |
@@ -25,14 +28,32 @@ | |||
25 | #define CLKFLAG_NORESET 0x00000008 | 28 | #define CLKFLAG_NORESET 0x00000008 |
26 | 29 | ||
27 | #define CLK_FIRST_AVAILABLE_FLAG 0x00000100 | 30 | #define CLK_FIRST_AVAILABLE_FLAG 0x00000100 |
28 | #define CLKFLAG_USE_MIN_MAX_TO_SET 0x00000200 | 31 | #define CLKFLAG_AUTO_OFF 0x00000200 |
29 | #define CLKFLAG_AUTO_OFF 0x00000400 | 32 | #define CLKFLAG_MIN 0x00000400 |
33 | #define CLKFLAG_MAX 0x00000800 | ||
34 | |||
35 | struct clk_ops { | ||
36 | int (*enable)(unsigned id); | ||
37 | void (*disable)(unsigned id); | ||
38 | void (*auto_off)(unsigned id); | ||
39 | int (*reset)(unsigned id, enum clk_reset_action action); | ||
40 | int (*set_rate)(unsigned id, unsigned rate); | ||
41 | int (*set_min_rate)(unsigned id, unsigned rate); | ||
42 | int (*set_max_rate)(unsigned id, unsigned rate); | ||
43 | int (*set_flags)(unsigned id, unsigned flags); | ||
44 | unsigned (*get_rate)(unsigned id); | ||
45 | unsigned (*is_enabled)(unsigned id); | ||
46 | long (*round_rate)(unsigned id, unsigned rate); | ||
47 | }; | ||
30 | 48 | ||
31 | struct clk { | 49 | struct clk { |
32 | uint32_t id; | 50 | uint32_t id; |
51 | uint32_t remote_id; | ||
33 | uint32_t count; | 52 | uint32_t count; |
34 | uint32_t flags; | 53 | uint32_t flags; |
35 | const char *name; | 54 | const char *name; |
55 | struct clk_ops *ops; | ||
56 | const char *dbg_name; | ||
36 | struct list_head list; | 57 | struct list_head list; |
37 | struct device *dev; | 58 | struct device *dev; |
38 | }; | 59 | }; |
@@ -41,8 +62,47 @@ struct clk { | |||
41 | #define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104) | 62 | #define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104) |
42 | #define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124) | 63 | #define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124) |
43 | 64 | ||
44 | extern struct clk msm_clocks[]; | 65 | #ifdef CONFIG_DEBUG_FS |
45 | extern unsigned msm_num_clocks; | 66 | #define CLOCK_DBG_NAME(x) .dbg_name = x, |
67 | #else | ||
68 | #define CLOCK_DBG_NAME(x) | ||
69 | #endif | ||
70 | |||
71 | #define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \ | ||
72 | .name = clk_name, \ | ||
73 | .id = clk_id, \ | ||
74 | .flags = clk_flags, \ | ||
75 | .dev = clk_dev, \ | ||
76 | CLOCK_DBG_NAME(#clk_id) \ | ||
77 | } | ||
78 | |||
79 | #define OFF CLKFLAG_AUTO_OFF | ||
80 | #define CLK_MIN CLKFLAG_MIN | ||
81 | #define CLK_MAX CLKFLAG_MAX | ||
82 | #define CLK_MINMAX (CLK_MIN | CLK_MAX) | ||
83 | #define NR_CLKS P_NR_CLKS | ||
84 | |||
85 | enum { | ||
86 | PLL_0 = 0, | ||
87 | PLL_1, | ||
88 | PLL_2, | ||
89 | PLL_3, | ||
90 | PLL_4, | ||
91 | PLL_5, | ||
92 | PLL_6, | ||
93 | NUM_PLL | ||
94 | }; | ||
95 | |||
96 | enum clkvote_client { | ||
97 | CLKVOTE_ACPUCLK = 0, | ||
98 | CLKVOTE_PMQOS, | ||
99 | CLKVOTE_MAX, | ||
100 | }; | ||
101 | |||
102 | int msm_clock_require_tcxo(unsigned long *reason, int nbits); | ||
103 | int msm_clock_get_name(uint32_t id, char *name, uint32_t size); | ||
104 | int ebi1_clk_set_min_rate(enum clkvote_client client, unsigned long rate); | ||
105 | unsigned long clk_get_max_axi_khz(void); | ||
46 | 106 | ||
47 | #endif | 107 | #endif |
48 | 108 | ||
diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c index 982f1da60160..fde9d8f69f10 100644 --- a/arch/arm/mach-msm/devices-msm7x00.c +++ b/arch/arm/mach-msm/devices-msm7x00.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/mtd/nand.h> | 24 | #include <linux/mtd/nand.h> |
25 | #include <linux/mtd/partitions.h> | 25 | #include <linux/mtd/partitions.h> |
26 | 26 | ||
27 | |||
28 | #include "clock.h" | ||
27 | #include <mach/mmc.h> | 29 | #include <mach/mmc.h> |
28 | 30 | ||
29 | static struct resource resources_uart1[] = { | 31 | static struct resource resources_uart1[] = { |
@@ -344,3 +346,48 @@ int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat, | |||
344 | return platform_device_register(pdev); | 346 | return platform_device_register(pdev); |
345 | } | 347 | } |
346 | 348 | ||
349 | struct clk msm_clocks_7x01a[] = { | ||
350 | CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), | ||
351 | CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), | ||
352 | CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, 0), | ||
353 | CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0), | ||
354 | CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0), | ||
355 | CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF), | ||
356 | CLK_PCOM("gp_clk", GP_CLK, NULL, 0), | ||
357 | CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, OFF), | ||
358 | CLK_PCOM("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0), | ||
359 | CLK_PCOM("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0), | ||
360 | CLK_PCOM("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0), | ||
361 | CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF), | ||
362 | CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0), | ||
363 | CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF), | ||
364 | CLK_PCOM("pbus_clk", PBUS_CLK, NULL, 0), | ||
365 | CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0), | ||
366 | CLK_PCOM("pmdh_clk", PMDH_CLK, NULL, OFF ), | ||
367 | CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF), | ||
368 | CLK_PCOM("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF), | ||
369 | CLK_PCOM("sdc_pclk", SDC1_P_CLK, &msm_device_sdc1.dev, OFF), | ||
370 | CLK_PCOM("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF), | ||
371 | CLK_PCOM("sdc_pclk", SDC2_P_CLK, &msm_device_sdc2.dev, OFF), | ||
372 | CLK_PCOM("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF), | ||
373 | CLK_PCOM("sdc_pclk", SDC3_P_CLK, &msm_device_sdc3.dev, OFF), | ||
374 | CLK_PCOM("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF), | ||
375 | CLK_PCOM("sdc_pclk", SDC4_P_CLK, &msm_device_sdc4.dev, OFF), | ||
376 | CLK_PCOM("tsif_clk", TSIF_CLK, NULL, 0), | ||
377 | CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), | ||
378 | CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), | ||
379 | CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), | ||
380 | CLK_PCOM("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF), | ||
381 | CLK_PCOM("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0), | ||
382 | CLK_PCOM("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF), | ||
383 | CLK_PCOM("uart1dm_clk", UART1DM_CLK, NULL, OFF), | ||
384 | CLK_PCOM("uart2dm_clk", UART2DM_CLK, NULL, 0), | ||
385 | CLK_PCOM("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF), | ||
386 | CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, &msm_device_hsusb.dev, OFF), | ||
387 | CLK_PCOM("usb_otg_clk", USB_OTG_CLK, NULL, 0), | ||
388 | CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF ), | ||
389 | CLK_PCOM("vfe_clk", VFE_CLK, NULL, OFF), | ||
390 | CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF), | ||
391 | }; | ||
392 | |||
393 | unsigned msm_num_clocks_7x01a = ARRAY_SIZE(msm_clocks_7x01a); | ||
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h index 0744c4a27d6a..19c5de99e20c 100644 --- a/arch/arm/mach-msm/devices.h +++ b/arch/arm/mach-msm/devices.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #ifndef __ARCH_ARM_MACH_MSM_DEVICES_H | 16 | #ifndef __ARCH_ARM_MACH_MSM_DEVICES_H |
17 | #define __ARCH_ARM_MACH_MSM_DEVICES_H | 17 | #define __ARCH_ARM_MACH_MSM_DEVICES_H |
18 | 18 | ||
19 | #include "clock.h" | ||
20 | |||
19 | extern struct platform_device msm_device_uart1; | 21 | extern struct platform_device msm_device_uart1; |
20 | extern struct platform_device msm_device_uart2; | 22 | extern struct platform_device msm_device_uart2; |
21 | extern struct platform_device msm_device_uart3; | 23 | extern struct platform_device msm_device_uart3; |
@@ -33,4 +35,7 @@ extern struct platform_device msm_device_smd; | |||
33 | 35 | ||
34 | extern struct platform_device msm_device_nand; | 36 | extern struct platform_device msm_device_nand; |
35 | 37 | ||
38 | extern struct clk msm_clocks_7x01a[]; | ||
39 | extern unsigned msm_num_clocks_7x01a; | ||
40 | |||
36 | #endif | 41 | #endif |
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h index 7933641c4761..e302fbdc439b 100644 --- a/arch/arm/mach-msm/include/mach/board.h +++ b/arch/arm/mach-msm/include/mach/board.h | |||
@@ -30,14 +30,15 @@ struct msm_acpu_clock_platform_data | |||
30 | unsigned long wait_for_irq_khz; | 30 | unsigned long wait_for_irq_khz; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | 33 | struct clk; | |
34 | |||
34 | /* common init routines for use by arch/arm/mach-msm/board-*.c */ | 35 | /* common init routines for use by arch/arm/mach-msm/board-*.c */ |
35 | 36 | ||
36 | void __init msm_add_devices(void); | 37 | void __init msm_add_devices(void); |
37 | void __init msm_map_common_io(void); | 38 | void __init msm_map_common_io(void); |
38 | void __init msm_init_irq(void); | 39 | void __init msm_init_irq(void); |
39 | void __init msm_init_gpio(void); | 40 | void __init msm_init_gpio(void); |
40 | void __init msm_clock_init(void); | 41 | void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks); |
41 | void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *); | 42 | void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *); |
42 | 43 | ||
43 | #endif | 44 | #endif |
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h new file mode 100644 index 000000000000..c05ca40478c7 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/clk.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* Copyright (c) 2009, Code Aurora Forum. All rights reserved. | ||
2 | * | ||
3 | * Redistribution and use in source and binary forms, with or without | ||
4 | * modification, are permitted provided that the following conditions are | ||
5 | * met: | ||
6 | * * Redistributions of source code must retain the above copyright | ||
7 | * notice, this list of conditions and the following disclaimer. | ||
8 | * * Redistributions in binary form must reproduce the above | ||
9 | * copyright notice, this list of conditions and the following | ||
10 | * disclaimer in the documentation and/or other materials provided | ||
11 | * with the distribution. | ||
12 | * * Neither the name of Code Aurora Forum, Inc. nor the names of its | ||
13 | * contributors may be used to endorse or promote products derived | ||
14 | * from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | ||
17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT | ||
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | ||
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | * | ||
28 | */ | ||
29 | #ifndef __MACH_CLK_H | ||
30 | #define __MACH_CLK_H | ||
31 | |||
32 | /* Magic rate value for use with PM QOS to request the board's maximum | ||
33 | * supported AXI rate. PM QOS will only pass positive s32 rate values | ||
34 | * through to the clock driver, so INT_MAX is used. | ||
35 | */ | ||
36 | #define MSM_AXI_MAX_FREQ LONG_MAX | ||
37 | |||
38 | enum clk_reset_action { | ||
39 | CLK_RESET_DEASSERT = 0, | ||
40 | CLK_RESET_ASSERT = 1 | ||
41 | }; | ||
42 | |||
43 | struct clk; | ||
44 | |||
45 | /* Rate is minimum clock rate in Hz */ | ||
46 | int clk_set_min_rate(struct clk *clk, unsigned long rate); | ||
47 | |||
48 | /* Rate is maximum clock rate in Hz */ | ||
49 | int clk_set_max_rate(struct clk *clk, unsigned long rate); | ||
50 | |||
51 | /* Assert/Deassert reset to a hardware block associated with a clock */ | ||
52 | int clk_reset(struct clk *clk, enum clk_reset_action action); | ||
53 | |||
54 | /* Set clock-specific configuration parameters */ | ||
55 | int clk_set_flags(struct clk *clk, unsigned long flags); | ||
56 | |||
57 | #endif | ||