aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorDaniel Walker <dwalker@codeaurora.org>2010-05-12 16:43:28 -0400
committerDaniel Walker <dwalker@codeaurora.org>2010-05-13 19:08:20 -0400
commit5e96da5d5074eae3b94d4abadfc114febb6e2a51 (patch)
tree4278052c5aaa63ae7af02fac8635c257139f3d6b /arch/arm
parentec4d79255c684a74ade2f2394b9f9a669cee0036 (diff)
msm: generalize clock support.
The 'PCOM' method of clock control (commands issued to the radio CPU) is shared across several (but not all) Qualcomm SOCs. Generalize this clock mechanism so these other SOCs can be added. Signed-off-by: Gregory Bean <gbean@codeaurora.org> Signed-off-by: David Brown <davidb@codeaurora.org> Signed-off-by: Daniel Walker <dwalker@codeaurora.org> Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org> Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-msm/Makefile2
-rw-r--r--arch/arm/mach-msm/board-halibut.c2
-rw-r--r--arch/arm/mach-msm/board-trout.c2
-rw-r--r--arch/arm/mach-msm/clock-7x01a.c126
-rw-r--r--arch/arm/mach-msm/clock-pcom.c131
-rw-r--r--arch/arm/mach-msm/clock-pcom.h153
-rw-r--r--arch/arm/mach-msm/clock.c257
-rw-r--r--arch/arm/mach-msm/clock.h70
-rw-r--r--arch/arm/mach-msm/devices-msm7x00.c47
-rw-r--r--arch/arm/mach-msm/devices.h5
-rw-r--r--arch/arm/mach-msm/include/mach/board.h5
-rw-r--r--arch/arm/mach-msm/include/mach/clk.h57
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
2obj-y += proc_comm.o 2obj-y += proc_comm.o
3obj-y += vreg.o 3obj-y += vreg.o
4obj-y += acpuclock-arm11.o 4obj-y += acpuclock-arm11.o
5obj-y += clock.o clock-7x01a.o 5obj-y += clock.o clock-pcom.o
6 6
7obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o 7obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
8obj-$(CONFIG_MSM_SMD) += last_radio_log.o 8obj-$(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,
90static void __init halibut_map_io(void) 90static 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
96MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") 96MACHINE_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
84MACHINE_START(TROUT, "HTC Dream") 84MACHINE_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
82struct 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
126unsigned 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 */
27int 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
36void pc_clk_disable(unsigned id)
37{
38 msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
39}
40
41int 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
56int 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
69int 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
78int 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
87int 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
96unsigned 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
104unsigned 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
112long 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
119struct 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
138struct clk_ops;
139extern struct clk_ops clk_ops_pcom;
140
141int 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 @@
29static DEFINE_MUTEX(clocks_mutex); 33static DEFINE_MUTEX(clocks_mutex);
30static DEFINE_SPINLOCK(clocks_lock); 34static DEFINE_SPINLOCK(clocks_lock);
31static LIST_HEAD(clocks); 35static LIST_HEAD(clocks);
36struct clk *msm_clocks;
37unsigned 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 */
36static inline int pc_clk_enable(unsigned id) 43static DECLARE_BITMAP(clock_map_enabled, NR_CLKS);
37{ 44static DEFINE_SPINLOCK(clock_map_lock);
38 return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
39}
40
41static inline void pc_clk_disable(unsigned id)
42{
43 msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
44}
45
46static 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
51static 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
56static 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
61static 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
66static 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
74static 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
82static 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}
139EXPORT_SYMBOL(clk_disable); 105EXPORT_SYMBOL(clk_disable);
140 106
107int 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}
113EXPORT_SYMBOL(clk_reset);
114
141unsigned long clk_get_rate(struct clk *clk) 115unsigned 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}
145EXPORT_SYMBOL(clk_get_rate); 119EXPORT_SYMBOL(clk_get_rate);
146 120
147int clk_set_rate(struct clk *clk, unsigned long rate) 121int 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}
158EXPORT_SYMBOL(clk_set_rate); 125EXPORT_SYMBOL(clk_set_rate);
159 126
127long clk_round_rate(struct clk *clk, unsigned long rate)
128{
129 return clk->ops->round_rate(clk->id, rate);
130}
131EXPORT_SYMBOL(clk_round_rate);
132
133int clk_set_min_rate(struct clk *clk, unsigned long rate)
134{
135 return clk->ops->set_min_rate(clk->id, rate);
136}
137EXPORT_SYMBOL(clk_set_min_rate);
138
139int clk_set_max_rate(struct clk *clk, unsigned long rate)
140{
141 return clk->ops->set_max_rate(clk->id, rate);
142}
143EXPORT_SYMBOL(clk_set_max_rate);
144
160int clk_set_parent(struct clk *clk, struct clk *parent) 145int 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}
178EXPORT_SYMBOL(clk_set_flags); 163EXPORT_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 */
170static struct clk *ebi1_clk;
180 171
181void __init msm_clock_init(void) 172static 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
180void __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)
200static 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
208static 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
227static 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
234static 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
247static 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
256static 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
265DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get,
266 clock_debug_rate_set, "%llu\n");
267DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get,
268 clock_debug_enable_set, "%llu\n");
269DEFINE_SIMPLE_ATTRIBUTE(clock_local_fops, clock_debug_local_get,
270 NULL, "%llu\n");
271
272static 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
305device_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
218late_initcall(clock_late_init); 334late_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
35struct 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
31struct clk { 49struct 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
44extern struct clk msm_clocks[]; 65#ifdef CONFIG_DEBUG_FS
45extern 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
85enum {
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
96enum clkvote_client {
97 CLKVOTE_ACPUCLK = 0,
98 CLKVOTE_PMQOS,
99 CLKVOTE_MAX,
100};
101
102int msm_clock_require_tcxo(unsigned long *reason, int nbits);
103int msm_clock_get_name(uint32_t id, char *name, uint32_t size);
104int ebi1_clk_set_min_rate(enum clkvote_client client, unsigned long rate);
105unsigned 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
29static struct resource resources_uart1[] = { 31static 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
349struct 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
393unsigned 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
19extern struct platform_device msm_device_uart1; 21extern struct platform_device msm_device_uart1;
20extern struct platform_device msm_device_uart2; 22extern struct platform_device msm_device_uart2;
21extern struct platform_device msm_device_uart3; 23extern struct platform_device msm_device_uart3;
@@ -33,4 +35,7 @@ extern struct platform_device msm_device_smd;
33 35
34extern struct platform_device msm_device_nand; 36extern struct platform_device msm_device_nand;
35 37
38extern struct clk msm_clocks_7x01a[];
39extern 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 33struct 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
36void __init msm_add_devices(void); 37void __init msm_add_devices(void);
37void __init msm_map_common_io(void); 38void __init msm_map_common_io(void);
38void __init msm_init_irq(void); 39void __init msm_init_irq(void);
39void __init msm_init_gpio(void); 40void __init msm_init_gpio(void);
40void __init msm_clock_init(void); 41void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks);
41void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *); 42void __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
38enum clk_reset_action {
39 CLK_RESET_DEASSERT = 0,
40 CLK_RESET_ASSERT = 1
41};
42
43struct clk;
44
45/* Rate is minimum clock rate in Hz */
46int clk_set_min_rate(struct clk *clk, unsigned long rate);
47
48/* Rate is maximum clock rate in Hz */
49int clk_set_max_rate(struct clk *clk, unsigned long rate);
50
51/* Assert/Deassert reset to a hardware block associated with a clock */
52int clk_reset(struct clk *clk, enum clk_reset_action action);
53
54/* Set clock-specific configuration parameters */
55int clk_set_flags(struct clk *clk, unsigned long flags);
56
57#endif