blob: 4a26a754c962c1350fe499b8c1b4499b0cc75aa0 [file] [log] [blame]
Shashank Mittal246f8d02011-01-21 17:12:27 -08001/*
2 * Copyright (c) 2008, Google Inc.
3 * All rights reserved.
4 * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <stdint.h>
31#include <kernel/thread.h>
32#include <platform/iomap.h>
33#include <reg.h>
34
35#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
36
37#define A11S_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100)
38#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104)
39#define VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124)
40#define PLL2_L_VAL_ADDR (MSM_CLK_CTL_BASE + 0x33C)
41
42#define SRC_SEL_PLL1 1 /* PLL1. */
43#define SRC_SEL_PLL2 2 /* PLL2. */
44#define SRC_SEL_PLL3 3 /* PLL3. Used for 7x25. */
45#define DIV_4 3
46#define DIV_2 1
47#define WAIT_CNT 100
48#define VDD_LEVEL 7
49#define MIN_AXI_HZ 120000000
50#define ACPU_800MHZ 41
51
52void pll_request(unsigned pll, unsigned enable);
53void axi_clock_init(unsigned rate);
54
55/* The stepping frequencies have been choosen to make sure the step
56 * is <= 256 MHz for both turbo mode and normal mode targets. The
57 * table also assumes the ACPU is running at TCXO freq and AHB div is
58 * set to DIV_1.
59 *
60 * To use the tables:
61 * - Start at location 0/1 depending on clock source sel bit.
62 * - Set values till end of table skipping every other entry.
63 * - When you reach the end of the table, you are done scaling.
64 *
65 * TODO: Need to fix SRC_SEL_PLL1 for 7x25.
66 */
67
68uint32_t const clk_cntl_reg_val_7625[] = {
69 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_4,
70 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_4 << 8),
71 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_2 << 8),
72 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_2,
73 (WAIT_CNT << 16) | (SRC_SEL_PLL3 << 4) | DIV_2,
74 (WAIT_CNT << 16) | (SRC_SEL_PLL3 << 12) | (DIV_2 << 8),
75};
76
77uint32_t const clk_cntl_reg_val_7627[] = {
78 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_4,
79 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_4 << 8),
80 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_2 << 8),
81 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_2,
82 (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 4) | DIV_2,
83 (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 12) | (DIV_2 << 8),
84};
85
86uint32_t const clk_cntl_reg_val_7627T[] = {
87 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_4,
88 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_4 << 8),
89 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_2 << 8),
90 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_2,
91 (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 4),
92 (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 12),
93};
94
95/* Using DIV_4 for all cases to avoid worrying about turbo vs. normal
96 * mode. Able to use DIV_4 for all steps because it's the largest AND
97 * the final value. */
98uint32_t const clk_sel_reg_val[] = {
99 DIV_4 << 1 | 1,
100 DIV_4 << 1 | 0,
101 DIV_4 << 1 | 0,
102 DIV_4 << 1 | 1,
103 DIV_4 << 1 | 1,
104 DIV_4 << 1 | 0,
105};
106
107void mdelay(unsigned msecs);
108
109
110void acpu_clock_init(void)
111{
112 unsigned i,clk;
113
114#if (!ENABLE_NANDWRITE)
115 int *modem_stat_check = (MSM_SHARED_BASE + 0x14);
116
117 /* Wait for modem to be ready before clock init */
118 while (readl(modem_stat_check) != 1);
119#endif
120
121 /* Increase VDD level to the final value. */
122 writel((1 << 7) | (VDD_LEVEL << 3), VDD_SVS_PLEVEL_ADDR);
123#if (!ENABLE_NANDWRITE)
124 thread_sleep(1);
125#else
126 mdelay(1);
127#endif
128
129 /* Read clock source select bit. */
130 i = readl(A11S_CLK_SEL_ADDR) & 1;
131 clk = readl(PLL2_L_VAL_ADDR) & 0x3F;
132
133 /* Jump into table and set every other entry. */
134 for(; i < ARRAY_SIZE(clk_cntl_reg_val_7627); i += 2) {
135#ifdef ENABLE_PLL3
136 writel(clk_cntl_reg_val_7625[i], A11S_CLK_CNTL_ADDR);
137#else
138 if(clk == ACPU_800MHZ)
139 writel(clk_cntl_reg_val_7627T[i], A11S_CLK_CNTL_ADDR);
140 else
141 writel(clk_cntl_reg_val_7627[i], A11S_CLK_CNTL_ADDR);
142#endif
143 /* Would need a dmb() here but the whole address space is
144 * strongly ordered, so it should be fine.
145 */
146 writel(clk_sel_reg_val[i], A11S_CLK_SEL_ADDR);
147#if (!ENABLE_NANDWRITE)
148 thread_sleep(1);
149#else
150 mdelay(1);
151#endif
152 }
153}
Shashank Mittalef325412011-04-01 13:48:26 -0700154
155void hsusb_clock_init(void)
156{
157 /* USB local clock control not enabled; use proc comm */
158 usb_clock_init();
159}