blob: 89583f3431fe7d305ae1c9b00963e7f7dd4a9777 [file] [log] [blame]
Chandan Uddarajufcc15f52009-11-17 21:02:46 -08001/*
Ajay Dudanib1b7d102009-11-25 14:47:20 -08002 * Copyright (c) 2008, Google Inc.
Chandan Uddarajufcc15f52009-11-17 21:02:46 -08003 * All rights reserved.
4 * Copyright (c) 2009, 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)
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070040#define PLL2_L_VAL_ADDR (MSM_CLK_CTL_BASE + 0x33C)
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080041
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080042#define SRC_SEL_PLL1 1 /* PLL1. */
43#define SRC_SEL_PLL2 2 /* PLL2. */
Manas Abichandania3898ff2010-02-10 15:28:31 -080044#define SRC_SEL_PLL3 3 /* PLL3. Used for 7x25. */
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080045#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
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070050#define ACPU_800MHZ 41
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080051
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 */
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070067
68uint32_t const clk_cntl_reg_val_7625[] = {
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080069 (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 << 12) | DIV_2,
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070073 (WAIT_CNT << 16) | (SRC_SEL_PLL3 << 4) | DIV_2,
Manas Abichandania3898ff2010-02-10 15:28:31 -080074 (WAIT_CNT << 16) | (SRC_SEL_PLL3 << 12) | (DIV_2 << 8),
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070075};
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 << 12) | DIV_2,
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080082 (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 4) | DIV_2,
83 (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 12) | (DIV_2 << 8),
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070084};
85
86uint32_t const clk_cntl_reg_val_7627A[] = {
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 << 12) | DIV_2,
91 (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 4),
92 (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 12),
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080093};
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
Chandan Uddaraju852cd2c2009-12-17 14:28:28 -0800107void mdelay(unsigned msecs);
108
109
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800110void acpu_clock_init(void)
111{
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -0700112 unsigned i,clk;
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800113
Chandan Uddaraju96501972009-12-14 23:24:21 -0800114#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
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800121 /* Increase VDD level to the final value. */
122 writel((1 << 7) | (VDD_LEVEL << 3), VDD_SVS_PLEVEL_ADDR);
Chandan Uddaraju852cd2c2009-12-17 14:28:28 -0800123#if (!ENABLE_NANDWRITE)
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800124 thread_sleep(1);
Chandan Uddaraju852cd2c2009-12-17 14:28:28 -0800125#else
126 mdelay(1);
127#endif
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800128
129 /* Read clock source select bit. */
130 i = readl(A11S_CLK_SEL_ADDR) & 1;
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -0700131 clk = readl(PLL2_L_VAL_ADDR) & 0x3F;
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800132
133 /* Jump into table and set every other entry. */
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -0700134 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_7627A[i], A11S_CLK_CNTL_ADDR);
140 else
141 writel(clk_cntl_reg_val_7627[i], A11S_CLK_CNTL_ADDR);
142#endif
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800143 /* 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);
Chandan Uddaraju852cd2c2009-12-17 14:28:28 -0800147#if (!ENABLE_NANDWRITE)
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800148 thread_sleep(1);
Chandan Uddaraju852cd2c2009-12-17 14:28:28 -0800149#else
150 mdelay(1);
151#endif
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800152 }
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800153}