blob: 0a681a02ac7e1e0d1b2f53913aacd9d81b302eca [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.
Channagoud Kadabi672c4c42012-12-20 17:51:45 -08004 * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
Chandan Uddarajufcc15f52009-11-17 21:02:46 -08005 *
6 * Redistribution and use in source and binary forms, with or without
Channagoud Kadabi672c4c42012-12-20 17:51:45 -08007 * modification, are permitted provided that the following conditions are
8 * 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
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
15 * * Neither the name of The Linux Foundation nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080018 *
Channagoud Kadabi672c4c42012-12-20 17:51:45 -080019 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080030 */
31
32#include <stdint.h>
33#include <kernel/thread.h>
34#include <platform/iomap.h>
35#include <reg.h>
Amol Jadi82254562011-06-27 11:25:48 -070036#include <debug.h>
37#include <mmc.h>
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080038
39#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
40
41#define A11S_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100)
42#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104)
43#define VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124)
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070044#define PLL2_L_VAL_ADDR (MSM_CLK_CTL_BASE + 0x33C)
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080045
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080046#define SRC_SEL_PLL1 1 /* PLL1. */
47#define SRC_SEL_PLL2 2 /* PLL2. */
Manas Abichandania3898ff2010-02-10 15:28:31 -080048#define SRC_SEL_PLL3 3 /* PLL3. Used for 7x25. */
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080049#define DIV_4 3
50#define DIV_2 1
51#define WAIT_CNT 100
52#define VDD_LEVEL 7
53#define MIN_AXI_HZ 120000000
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070054#define ACPU_800MHZ 41
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080055
56void pll_request(unsigned pll, unsigned enable);
57void axi_clock_init(unsigned rate);
58
59/* The stepping frequencies have been choosen to make sure the step
60 * is <= 256 MHz for both turbo mode and normal mode targets. The
61 * table also assumes the ACPU is running at TCXO freq and AHB div is
62 * set to DIV_1.
63 *
64 * To use the tables:
65 * - Start at location 0/1 depending on clock source sel bit.
66 * - Set values till end of table skipping every other entry.
67 * - When you reach the end of the table, you are done scaling.
68 *
69 * TODO: Need to fix SRC_SEL_PLL1 for 7x25.
70 */
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070071
72uint32_t const clk_cntl_reg_val_7625[] = {
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080073 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_4,
74 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_4 << 8),
75 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_2 << 8),
Subbaraman Narayanamurthy8282bdc2010-12-17 18:03:57 -080076 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_2,
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070077 (WAIT_CNT << 16) | (SRC_SEL_PLL3 << 4) | DIV_2,
Manas Abichandania3898ff2010-02-10 15:28:31 -080078 (WAIT_CNT << 16) | (SRC_SEL_PLL3 << 12) | (DIV_2 << 8),
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070079};
80
81uint32_t const clk_cntl_reg_val_7627[] = {
82 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_4,
83 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_4 << 8),
84 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_2 << 8),
Subbaraman Narayanamurthy8282bdc2010-12-17 18:03:57 -080085 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_2,
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080086 (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 4) | DIV_2,
87 (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 12) | (DIV_2 << 8),
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070088};
89
Subbaraman Narayanamurthy8282bdc2010-12-17 18:03:57 -080090uint32_t const clk_cntl_reg_val_7627T[] = {
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070091 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_4,
92 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_4 << 8),
93 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_2 << 8),
Subbaraman Narayanamurthy8282bdc2010-12-17 18:03:57 -080094 (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_2,
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -070095 (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 4),
96 (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 12),
Chandan Uddarajufcc15f52009-11-17 21:02:46 -080097};
98
99/* Using DIV_4 for all cases to avoid worrying about turbo vs. normal
100 * mode. Able to use DIV_4 for all steps because it's the largest AND
101 * the final value. */
102uint32_t const clk_sel_reg_val[] = {
103 DIV_4 << 1 | 1,
104 DIV_4 << 1 | 0,
105 DIV_4 << 1 | 0,
106 DIV_4 << 1 | 1,
107 DIV_4 << 1 | 1,
108 DIV_4 << 1 | 0,
109};
110
Amol Jadi82254562011-06-27 11:25:48 -0700111/* enum for SDC CLK IDs */
112enum
113{
114 SDC1_CLK = 19,
115 SDC1_PCLK = 20,
116 SDC2_CLK = 21,
117 SDC2_PCLK = 22,
118 SDC3_CLK = 23,
119 SDC3_PCLK = 24,
120 SDC4_CLK = 25,
121 SDC4_PCLK = 26
122};
123
124/* Zero'th entry is dummy */
125static uint8_t sdc_clk[] = {0, SDC1_CLK, SDC2_CLK, SDC3_CLK, SDC4_CLK};
126static uint8_t sdc_pclk[] = {0, SDC1_PCLK, SDC2_PCLK, SDC3_PCLK, SDC4_PCLK};
127
Chandan Uddaraju852cd2c2009-12-17 14:28:28 -0800128void mdelay(unsigned msecs);
129
130
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800131void acpu_clock_init(void)
132{
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -0700133 unsigned i,clk;
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800134
Chandan Uddaraju96501972009-12-14 23:24:21 -0800135#if (!ENABLE_NANDWRITE)
136 int *modem_stat_check = (MSM_SHARED_BASE + 0x14);
137
138 /* Wait for modem to be ready before clock init */
139 while (readl(modem_stat_check) != 1);
140#endif
141
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800142 /* Increase VDD level to the final value. */
143 writel((1 << 7) | (VDD_LEVEL << 3), VDD_SVS_PLEVEL_ADDR);
Chandan Uddaraju852cd2c2009-12-17 14:28:28 -0800144#if (!ENABLE_NANDWRITE)
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800145 thread_sleep(1);
Chandan Uddaraju852cd2c2009-12-17 14:28:28 -0800146#else
147 mdelay(1);
148#endif
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800149
150 /* Read clock source select bit. */
151 i = readl(A11S_CLK_SEL_ADDR) & 1;
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -0700152 clk = readl(PLL2_L_VAL_ADDR) & 0x3F;
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800153
154 /* Jump into table and set every other entry. */
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -0700155 for(; i < ARRAY_SIZE(clk_cntl_reg_val_7627); i += 2) {
156#ifdef ENABLE_PLL3
157 writel(clk_cntl_reg_val_7625[i], A11S_CLK_CNTL_ADDR);
158#else
159 if(clk == ACPU_800MHZ)
Subbaraman Narayanamurthy8282bdc2010-12-17 18:03:57 -0800160 writel(clk_cntl_reg_val_7627T[i], A11S_CLK_CNTL_ADDR);
Subbaraman Narayanamurthybc089032010-08-27 18:28:28 -0700161 else
162 writel(clk_cntl_reg_val_7627[i], A11S_CLK_CNTL_ADDR);
163#endif
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800164 /* Would need a dmb() here but the whole address space is
165 * strongly ordered, so it should be fine.
166 */
167 writel(clk_sel_reg_val[i], A11S_CLK_SEL_ADDR);
Chandan Uddaraju852cd2c2009-12-17 14:28:28 -0800168#if (!ENABLE_NANDWRITE)
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800169 thread_sleep(1);
Chandan Uddaraju852cd2c2009-12-17 14:28:28 -0800170#else
171 mdelay(1);
172#endif
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800173 }
Chandan Uddarajufcc15f52009-11-17 21:02:46 -0800174}
Amol Jadi82254562011-06-27 11:25:48 -0700175
176/* Configure MMC clock */
177void clock_config_mmc(uint32_t interface, uint32_t freq)
178{
179 uint32_t reg = 0;
180
181 if( mmc_clock_set_rate(sdc_clk[interface], freq) < 0 )
182 {
183 dprintf(CRITICAL, "Failure setting clock rate for MCLK - "
184 "clk_rate: %d\n!", freq);
185 ASSERT(0);
186 }
187
188 /* enable clock */
189 if( mmc_clock_enable_disable(sdc_clk[interface], MMC_CLK_ENABLE) < 0 )
190 {
191 dprintf(CRITICAL, "Failure enabling MMC Clock!\n");
192 ASSERT(0);
193 }
194
195 reg |= MMC_BOOT_MCI_CLK_ENABLE;
196 reg |= MMC_BOOT_MCI_CLK_ENA_FLOW;
197 reg |= MMC_BOOT_MCI_CLK_IN_FEEDBACK;
198 writel( reg, MMC_BOOT_MCI_CLK );
Channagoud Kadabi672c4c42012-12-20 17:51:45 -0800199
200 /* Wait for the MMC_BOOT_MCI_CLK write to go through. */
201 mmc_mclk_reg_wr_delay();
202
203 /* Wait 1 ms to provide the free running SD CLK to the card. */
204 mdelay(1);
Amol Jadi82254562011-06-27 11:25:48 -0700205}
206
207/* Intialize MMC clock */
208void clock_init_mmc(uint32_t interface)
209{
210 if( mmc_clock_enable_disable(sdc_pclk[interface], MMC_CLK_ENABLE) < 0 )
211 {
212 dprintf(CRITICAL, "Failure enabling PCLK!\n");
213 ASSERT(0);
214 }
215}
216