blob: 839d6730bde967e09070bb58b11a4066c756c79b [file] [log] [blame]
Mike Rapoporte074da32016-02-19 17:56:13 +02001#include <linux/kernel.h>
Mike Rapoport4cf26d82015-09-22 12:01:17 +03002#include <linux/sizes.h>
3
Sudip Mukherjee81dee672015-03-03 16:21:06 +05304#include "ddk750_help.h"
5#include "ddk750_reg.h"
6#include "ddk750_chip.h"
7#include "ddk750_power.h"
Sudip Mukherjee81dee672015-03-03 16:21:06 +05308
Mike Rapoport603dd492016-02-19 17:56:14 +02009#define MHz(x) ((x) * 1000000)
10
Moshe Green06a4f422016-09-25 22:58:35 +030011logical_chip_type_t sm750_get_chip_type(void)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053012{
13 unsigned short physicalID;
14 char physicalRev;
15 logical_chip_type_t chip;
16
Juston Li5ee35ea2015-06-12 03:17:22 -070017 physicalID = devId750; /* either 0x718 or 0x750 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +053018 physicalRev = revId750;
19
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -070020 if (physicalID == 0x718)
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -070021 chip = SM718;
Helen Fornazier9767fc52015-03-26 14:09:14 -030022 else if (physicalID == 0x750) {
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -070023 chip = SM750;
Sudip Mukherjee81dee672015-03-03 16:21:06 +053024 /* SM750 and SM750LE are different in their revision ID only. */
Helen Fornazier9767fc52015-03-26 14:09:14 -030025 if (physicalRev == SM750LE_REVISION_ID)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053026 chip = SM750LE;
Helen Fornazier9767fc52015-03-26 14:09:14 -030027 } else
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -070028 chip = SM_UNKNOWN;
Sudip Mukherjee81dee672015-03-03 16:21:06 +053029
30 return chip;
31}
32
Mike Rapoport7092d762015-10-13 09:26:45 +030033static unsigned int get_mxclk_freq(void)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053034{
Mike Rapoport7751e0e2015-10-13 09:26:44 +030035 unsigned int pll_reg;
36 unsigned int M, N, OD, POD;
37
Moshe Green06a4f422016-09-25 22:58:35 +030038 if (sm750_get_chip_type() == SM750LE)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053039 return MHz(130);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053040
Mike Rapoport7751e0e2015-10-13 09:26:44 +030041 pll_reg = PEEK32(MXCLK_PLL_CTRL);
Mike Rapoportcdd5df62016-02-10 18:33:58 +020042 M = (pll_reg & PLL_CTRL_M_MASK) >> PLL_CTRL_M_SHIFT;
43 N = (pll_reg & PLL_CTRL_N_MASK) >> PLL_CTRL_M_SHIFT;
44 OD = (pll_reg & PLL_CTRL_OD_MASK) >> PLL_CTRL_OD_SHIFT;
45 POD = (pll_reg & PLL_CTRL_POD_MASK) >> PLL_CTRL_POD_SHIFT;
Mike Rapoport7751e0e2015-10-13 09:26:44 +030046
47 return DEFAULT_INPUT_CLOCK * M / N / (1 << OD) / (1 << POD);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053048}
49
Sudip Mukherjee81dee672015-03-03 16:21:06 +053050/*
51 * This function set up the main chip clock.
52 *
53 * Input: Frequency to be set.
54 */
Mike Rapoportfb6f37a2015-09-30 08:24:54 +030055static void setChipClock(unsigned int frequency)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053056{
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -070057 pll_value_t pll;
58 unsigned int ulActualMxClk;
Mike Rapoportcfac7d62015-10-22 09:38:39 +030059
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -070060 /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */
Moshe Green06a4f422016-09-25 22:58:35 +030061 if (sm750_get_chip_type() == SM750LE)
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -070062 return;
Sudip Mukherjee81dee672015-03-03 16:21:06 +053063
Amitoj Kaur Chawla59f08402015-04-02 23:01:04 +053064 if (frequency) {
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -070065 /*
66 * Set up PLL, a structure to hold the value to be set in clocks.
67 */
68 pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */
69 pll.clockType = MXCLK_PLL;
Sudip Mukherjee81dee672015-03-03 16:21:06 +053070
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -070071 /*
Moshe Green46b7dd72016-09-15 23:15:50 +030072 * Call calcPllValue() to fill the other fields of PLL structure.
73 * Sometime, the chip cannot set up the exact clock
74 * required by the User.
75 * Return value of calcPllValue gives the actual possible clock.
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -070076 */
77 ulActualMxClk = calcPllValue(frequency, &pll);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053078
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -070079 /* Master Clock Control: MXCLK_PLL */
80 POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll));
81 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +053082}
83
Mike Rapoportfb6f37a2015-09-30 08:24:54 +030084static void setMemoryClock(unsigned int frequency)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053085{
Mike Rapoport19aa2112016-01-17 20:04:26 +020086 unsigned int reg, divisor;
Mike Rapoportcfac7d62015-10-22 09:38:39 +030087
Moshe Greenf90416d2016-06-05 22:09:24 +030088 /* Cheok_0509: For SM750LE, the memory clock is fixed.
89 * Nothing to set.
90 */
Moshe Green06a4f422016-09-25 22:58:35 +030091 if (sm750_get_chip_type() == SM750LE)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053092 return;
Mike Rapoportcfac7d62015-10-22 09:38:39 +030093
Amitoj Kaur Chawla59f08402015-04-02 23:01:04 +053094 if (frequency) {
Moshe Greend9430052016-06-06 22:04:32 +030095 /*
Moshe Green46b7dd72016-09-15 23:15:50 +030096 * Set the frequency to the maximum frequency
97 * that the DDR Memory can take which is 336MHz.
Moshe Greend9430052016-06-06 22:04:32 +030098 */
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -070099 if (frequency > MHz(336))
100 frequency = MHz(336);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530101
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700102 /* Calculate the divisor */
Moshe Green42f8f212016-10-02 14:04:46 +0300103 divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530104
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700105 /* Set the corresponding divisor in the register. */
Mike Rapoport6e8aa4a2016-01-17 20:04:27 +0200106 reg = PEEK32(CURRENT_GATE) & ~CURRENT_GATE_M2XCLK_MASK;
Helen Fornazierc1072432015-03-26 14:09:17 -0300107 switch (divisor) {
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700108 default:
109 case 1:
Mike Rapoport6e8aa4a2016-01-17 20:04:27 +0200110 reg |= CURRENT_GATE_M2XCLK_DIV_1;
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700111 break;
112 case 2:
Mike Rapoport6e8aa4a2016-01-17 20:04:27 +0200113 reg |= CURRENT_GATE_M2XCLK_DIV_2;
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700114 break;
115 case 3:
Mike Rapoport6e8aa4a2016-01-17 20:04:27 +0200116 reg |= CURRENT_GATE_M2XCLK_DIV_3;
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700117 break;
118 case 4:
Mike Rapoport6e8aa4a2016-01-17 20:04:27 +0200119 reg |= CURRENT_GATE_M2XCLK_DIV_4;
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700120 break;
121 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530122
Mike Rapoport19aa2112016-01-17 20:04:26 +0200123 setCurrentGate(reg);
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700124 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530125}
126
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530127/*
128 * This function set up the master clock (MCLK).
129 *
130 * Input: Frequency to be set.
131 *
132 * NOTE:
133 * The maximum frequency the engine can run is 168MHz.
134 */
Mike Rapoportfb6f37a2015-09-30 08:24:54 +0300135static void setMasterClock(unsigned int frequency)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530136{
Mike Rapoport19aa2112016-01-17 20:04:26 +0200137 unsigned int reg, divisor;
Mike Rapoportcfac7d62015-10-22 09:38:39 +0300138
Moshe Green83d62832016-06-01 23:34:21 +0300139 /* Cheok_0509: For SM750LE, the memory clock is fixed.
140 * Nothing to set.
141 */
Moshe Green06a4f422016-09-25 22:58:35 +0300142 if (sm750_get_chip_type() == SM750LE)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530143 return;
Mike Rapoportcfac7d62015-10-22 09:38:39 +0300144
Amitoj Kaur Chawla59f08402015-04-02 23:01:04 +0530145 if (frequency) {
Moshe Greenb29376c32016-09-15 23:16:11 +0300146 /* Set the frequency to the maximum frequency
147 * that the SM750 engine can run, which is about 190 MHz.
148 */
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700149 if (frequency > MHz(190))
150 frequency = MHz(190);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530151
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700152 /* Calculate the divisor */
Moshe Green42f8f212016-10-02 14:04:46 +0300153 divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530154
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700155 /* Set the corresponding divisor in the register. */
Mike Rapoport6e8aa4a2016-01-17 20:04:27 +0200156 reg = PEEK32(CURRENT_GATE) & ~CURRENT_GATE_MCLK_MASK;
Helen Fornazierc1072432015-03-26 14:09:17 -0300157 switch (divisor) {
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700158 default:
159 case 3:
Mike Rapoport6e8aa4a2016-01-17 20:04:27 +0200160 reg |= CURRENT_GATE_MCLK_DIV_3;
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700161 break;
162 case 4:
Mike Rapoport6e8aa4a2016-01-17 20:04:27 +0200163 reg |= CURRENT_GATE_MCLK_DIV_4;
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700164 break;
165 case 6:
Mike Rapoport6e8aa4a2016-01-17 20:04:27 +0200166 reg |= CURRENT_GATE_MCLK_DIV_6;
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700167 break;
168 case 8:
Mike Rapoport6e8aa4a2016-01-17 20:04:27 +0200169 reg |= CURRENT_GATE_MCLK_DIV_8;
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700170 break;
171 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530172
Mike Rapoport19aa2112016-01-17 20:04:26 +0200173 setCurrentGate(reg);
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700174 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530175}
176
Supriya Karanth6fa7db82015-03-12 01:11:00 +0900177unsigned int ddk750_getVMSize(void)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530178{
179 unsigned int reg;
180 unsigned int data;
181
182 /* sm750le only use 64 mb memory*/
Moshe Green06a4f422016-09-25 22:58:35 +0300183 if (sm750_get_chip_type() == SM750LE)
Mike Rapoport4cf26d82015-09-22 12:01:17 +0300184 return SZ_64M;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530185
186 /* for 750,always use power mode0*/
187 reg = PEEK32(MODE0_GATE);
Mike Rapoport05e9d9e2016-01-17 20:04:28 +0200188 reg |= MODE0_GATE_GPIO;
Helen Fornazierc04051f2015-03-26 14:09:18 -0300189 POKE32(MODE0_GATE, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530190
191 /* get frame buffer size from GPIO */
Mike Rapoport5538d5c2016-01-17 20:04:24 +0200192 reg = PEEK32(MISC_CTRL) & MISC_CTRL_LOCALMEM_SIZE_MASK;
Helen Fornazierc1072432015-03-26 14:09:17 -0300193 switch (reg) {
Helen Fornazierae59c462015-03-26 14:09:19 -0300194 case MISC_CTRL_LOCALMEM_SIZE_8M:
Mike Rapoport4cf26d82015-09-22 12:01:17 +0300195 data = SZ_8M; break; /* 8 Mega byte */
Helen Fornazierae59c462015-03-26 14:09:19 -0300196 case MISC_CTRL_LOCALMEM_SIZE_16M:
Mike Rapoport4cf26d82015-09-22 12:01:17 +0300197 data = SZ_16M; break; /* 16 Mega byte */
Helen Fornazierae59c462015-03-26 14:09:19 -0300198 case MISC_CTRL_LOCALMEM_SIZE_32M:
Mike Rapoport4cf26d82015-09-22 12:01:17 +0300199 data = SZ_32M; break; /* 32 Mega byte */
Helen Fornazierae59c462015-03-26 14:09:19 -0300200 case MISC_CTRL_LOCALMEM_SIZE_64M:
Mike Rapoport4cf26d82015-09-22 12:01:17 +0300201 data = SZ_64M; break; /* 64 Mega byte */
Helen Fornazierae59c462015-03-26 14:09:19 -0300202 default:
Amitoj Kaur Chawlae261e692015-04-02 22:57:55 +0530203 data = 0;
204 break;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530205 }
206 return data;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530207}
208
Helen Fornazierf8da0552015-03-26 14:09:20 -0300209int ddk750_initHw(initchip_param_t *pInitParam)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530210{
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200211 unsigned int reg;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530212
Juston Li8332d942015-07-14 21:14:32 -0700213 if (pInitParam->powerMode != 0)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530214 pInitParam->powerMode = 0;
215 setPowerMode(pInitParam->powerMode);
216
217 /* Enable display power gate & LOCALMEM power gate*/
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200218 reg = PEEK32(CURRENT_GATE);
Mike Rapoport90946e52016-01-17 20:04:25 +0200219 reg |= (CURRENT_GATE_DISPLAY | CURRENT_GATE_LOCALMEM);
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200220 setCurrentGate(reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530221
Moshe Green06a4f422016-09-25 22:58:35 +0300222 if (sm750_get_chip_type() != SM750LE) {
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530223 /* set panel pll and graphic mode via mmio_88 */
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200224 reg = PEEK32(VGA_CONFIGURATION);
Mike Rapoportd9798142016-02-10 18:34:00 +0200225 reg |= (VGA_CONFIGURATION_PLL | VGA_CONFIGURATION_MODE);
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200226 POKE32(VGA_CONFIGURATION, reg);
Helen Fornazier9767fc52015-03-26 14:09:14 -0300227 } else {
Amitoj Kaur Chawla31296ba2015-04-08 22:25:06 +0530228#if defined(__i386__) || defined(__x86_64__)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530229 /* set graphic mode via IO method */
Helen Fornazierc04051f2015-03-26 14:09:18 -0300230 outb_p(0x88, 0x3d4);
231 outb_p(0x06, 0x3d5);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530232#endif
233 }
234
235 /* Set the Main Chip Clock */
236 setChipClock(MHz((unsigned int)pInitParam->chipClock));
237
238 /* Set up memory clock. */
239 setMemoryClock(MHz(pInitParam->memClock));
240
241 /* Set up master clock */
242 setMasterClock(MHz(pInitParam->masterClock));
243
244
Moshe Greenb29376c32016-09-15 23:16:11 +0300245 /* Reset the memory controller.
246 * If the memory controller is not reset in SM750,
247 * the system might hang when sw accesses the memory.
248 * The memory should be resetted after changing the MXCLK.
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530249 */
Helen Fornazier9767fc52015-03-26 14:09:14 -0300250 if (pInitParam->resetMemory == 1) {
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200251 reg = PEEK32(MISC_CTRL);
Mike Rapoport53723502016-01-17 20:04:21 +0200252 reg &= ~MISC_CTRL_LOCALMEM_RESET;
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200253 POKE32(MISC_CTRL, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530254
Mike Rapoport53723502016-01-17 20:04:21 +0200255 reg |= MISC_CTRL_LOCALMEM_RESET;
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200256 POKE32(MISC_CTRL, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530257 }
258
Helen Fornazier9767fc52015-03-26 14:09:14 -0300259 if (pInitParam->setAllEngOff == 1) {
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530260 enable2DEngine(0);
261
262 /* Disable Overlay, if a former application left it on */
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200263 reg = PEEK32(VIDEO_DISPLAY_CTRL);
Mike Rapoport6fba39c2016-02-10 18:34:08 +0200264 reg &= ~DISPLAY_CTRL_PLANE;
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200265 POKE32(VIDEO_DISPLAY_CTRL, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530266
267 /* Disable video alpha, if a former application left it on */
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200268 reg = PEEK32(VIDEO_ALPHA_DISPLAY_CTRL);
Mike Rapoport6fba39c2016-02-10 18:34:08 +0200269 reg &= ~DISPLAY_CTRL_PLANE;
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200270 POKE32(VIDEO_ALPHA_DISPLAY_CTRL, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530271
272 /* Disable alpha plane, if a former application left it on */
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200273 reg = PEEK32(ALPHA_DISPLAY_CTRL);
Mike Rapoport6fba39c2016-02-10 18:34:08 +0200274 reg &= ~DISPLAY_CTRL_PLANE;
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200275 POKE32(ALPHA_DISPLAY_CTRL, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530276
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530277 /* Disable DMA Channel, if a former application left it on */
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200278 reg = PEEK32(DMA_ABORT_INTERRUPT);
Mike Rapoport0f23be72016-02-10 18:34:17 +0200279 reg |= DMA_ABORT_INTERRUPT_ABORT_1;
Mike Rapoport8bc728c2016-01-17 20:04:20 +0200280 POKE32(DMA_ABORT_INTERRUPT, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530281
282 /* Disable DMA Power, if a former application left it on */
283 enableDMA(0);
284 }
285
286 /* We can add more initialization as needed. */
287
288 return 0;
289}
290
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530291/*
Moshe Greenb29376c32016-09-15 23:16:11 +0300292 * monk liu @ 4/6/2011:
293 * re-write the calculatePLL function of ddk750.
294 * the original version function does not use
295 * some mathematics tricks and shortcut
296 * when it doing the calculation of the best N,M,D combination
297 * I think this version gives a little upgrade in speed
298 *
299 * 750 pll clock formular:
300 * Request Clock = (Input Clock * M )/(N * X)
301 *
302 * Input Clock = 14318181 hz
303 * X = 2 power D
304 * D ={0,1,2,3,4,5,6}
305 * M = {1,...,255}
306 * N = {2,...,15}
307 */
Helen Fornazierc04051f2015-03-26 14:09:18 -0300308unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530309{
Moshe Green46b7dd72016-09-15 23:15:50 +0300310 /* as sm750 register definition,
311 * N located in 2,15 and M located in 1,255
312 */
Helen Fornazierc04051f2015-03-26 14:09:18 -0300313 int N, M, X, d;
Amitoj Kaur Chawla43ce0b52015-10-10 02:14:27 +0530314 int mini_diff;
Helen Fornazierc04051f2015-03-26 14:09:18 -0300315 unsigned int RN, quo, rem, fl_quo;
316 unsigned int input, request;
317 unsigned int tmpClock, ret;
Mike Rapoporta61dc132015-10-22 09:38:40 +0300318 const int max_OD = 3;
Colin Ian Kingf0e00da2016-03-29 17:53:23 +0100319 int max_d = 6;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530320
Moshe Green06a4f422016-09-25 22:58:35 +0300321 if (sm750_get_chip_type() == SM750LE) {
Moshe Greenb29376c32016-09-15 23:16:11 +0300322 /* SM750LE don't have
323 * programmable PLL and M/N values to work on.
324 * Just return the requested clock.
325 */
Ragavendra Nagrajde99bef2015-03-18 02:37:42 -0700326 return request_orig;
327 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530328
329 ret = 0;
Amitoj Kaur Chawla43ce0b52015-10-10 02:14:27 +0530330 mini_diff = ~0;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530331 request = request_orig / 1000;
332 input = pll->inputFreq / 1000;
333
Moshe Green46b7dd72016-09-15 23:15:50 +0300334 /* for MXCLK register,
335 * no POD provided, so need be treated differently
336 */
Mike Rapoporta61dc132015-10-22 09:38:40 +0300337 if (pll->clockType == MXCLK_PLL)
338 max_d = 3;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530339
Helen Fornazierce02a16a2015-03-26 14:09:15 -0300340 for (N = 15; N > 1; N--) {
Moshe Green46b7dd72016-09-15 23:15:50 +0300341 /* RN will not exceed maximum long
342 * if @request <= 285 MHZ (for 32bit cpu)
343 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530344 RN = N * request;
345 quo = RN / input;
346 rem = RN % input;/* rem always small than 14318181 */
Juston Li6ab5b6d2015-07-14 21:14:40 -0700347 fl_quo = (rem * 10000 / input);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530348
Mike Rapoporta61dc132015-10-22 09:38:40 +0300349 for (d = max_d; d >= 0; d--) {
Rehas Sachdevaf3151e02016-09-20 17:36:29 +0530350 X = BIT(d);
Amitoj Kaur Chawlaf40917e2015-10-04 20:12:30 +0530351 M = quo * X;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530352 M += fl_quo * X / 10000;
353 /* round step */
Amitoj Kaur Chawla07387cb2015-10-04 20:18:32 +0530354 M += (fl_quo * X % 10000) > 5000 ? 1 : 0;
Helen Fornazier82736d22015-03-26 14:09:16 -0300355 if (M < 256 && M > 0) {
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530356 unsigned int diff;
Juston Li40403c12015-07-14 21:14:48 -0700357
Juston Li6ab5b6d2015-07-14 21:14:40 -0700358 tmpClock = pll->inputFreq * M / N / X;
Mike Rapoporte074da32016-02-19 17:56:13 +0200359 diff = abs(tmpClock - request_orig);
Amitoj Kaur Chawla43ce0b52015-10-10 02:14:27 +0530360 if (diff < mini_diff) {
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530361 pll->M = M;
362 pll->N = N;
Mike Rapoporta61dc132015-10-22 09:38:40 +0300363 pll->POD = 0;
364 if (d > max_OD)
365 pll->POD = d - max_OD;
366 pll->OD = d - pll->POD;
Amitoj Kaur Chawla43ce0b52015-10-10 02:14:27 +0530367 mini_diff = diff;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530368 ret = tmpClock;
369 }
370 }
371 }
372 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530373 return ret;
374}
375
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530376unsigned int formatPllReg(pll_value_t *pPLL)
377{
Mike Rapoportcdd5df62016-02-10 18:33:58 +0200378#ifndef VALIDATION_CHIP
379 unsigned int POD = pPLL->POD;
380#endif
381 unsigned int OD = pPLL->OD;
382 unsigned int M = pPLL->M;
383 unsigned int N = pPLL->N;
Mike Rapoport375b4d42016-02-10 18:33:53 +0200384 unsigned int reg = 0;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530385
Mike Rapoport0c4d85f2016-02-10 18:33:54 +0200386 /*
387 * Note that all PLL's have the same format. Here, we just use
388 * Panel PLL parameter to work out the bit fields in the
389 * register. On returning a 32 bit number, the value can be
390 * applied to any PLL in the calling function.
391 */
Mike Rapoportcdd5df62016-02-10 18:33:58 +0200392 reg = PLL_CTRL_POWER |
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530393#ifndef VALIDATION_CHIP
Mike Rapoportcdd5df62016-02-10 18:33:58 +0200394 ((POD << PLL_CTRL_POD_SHIFT) & PLL_CTRL_POD_MASK) |
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530395#endif
Mike Rapoportcdd5df62016-02-10 18:33:58 +0200396 ((OD << PLL_CTRL_OD_SHIFT) & PLL_CTRL_OD_MASK) |
397 ((N << PLL_CTRL_N_SHIFT) & PLL_CTRL_N_MASK) |
398 ((M << PLL_CTRL_M_SHIFT) & PLL_CTRL_M_MASK);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530399
Mike Rapoport375b4d42016-02-10 18:33:53 +0200400 return reg;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530401}
402
403