ddk750_chip.c (9760B)
1// SPDX-License-Identifier: GPL-2.0 2#include <linux/kernel.h> 3#include <linux/sizes.h> 4 5#include "ddk750_reg.h" 6#include "ddk750_chip.h" 7#include "ddk750_power.h" 8 9#define MHz(x) ((x) * 1000000) 10 11static enum logical_chip_type chip; 12 13enum logical_chip_type sm750_get_chip_type(void) 14{ 15 return chip; 16} 17 18void sm750_set_chip_type(unsigned short dev_id, u8 rev_id) 19{ 20 if (dev_id == 0x718) { 21 chip = SM718; 22 } else if (dev_id == 0x750) { 23 chip = SM750; 24 /* SM750 and SM750LE are different in their revision ID only. */ 25 if (rev_id == SM750LE_REVISION_ID) { 26 chip = SM750LE; 27 pr_info("found sm750le\n"); 28 } 29 } else { 30 chip = SM_UNKNOWN; 31 } 32} 33 34static unsigned int get_mxclk_freq(void) 35{ 36 unsigned int pll_reg; 37 unsigned int M, N, OD, POD; 38 39 if (sm750_get_chip_type() == SM750LE) 40 return MHz(130); 41 42 pll_reg = peek32(MXCLK_PLL_CTRL); 43 M = (pll_reg & PLL_CTRL_M_MASK) >> PLL_CTRL_M_SHIFT; 44 N = (pll_reg & PLL_CTRL_N_MASK) >> PLL_CTRL_N_SHIFT; 45 OD = (pll_reg & PLL_CTRL_OD_MASK) >> PLL_CTRL_OD_SHIFT; 46 POD = (pll_reg & PLL_CTRL_POD_MASK) >> PLL_CTRL_POD_SHIFT; 47 48 return DEFAULT_INPUT_CLOCK * M / N / BIT(OD) / BIT(POD); 49} 50 51/* 52 * This function set up the main chip clock. 53 * 54 * Input: Frequency to be set. 55 */ 56static void set_chip_clock(unsigned int frequency) 57{ 58 struct pll_value pll; 59 60 /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */ 61 if (sm750_get_chip_type() == SM750LE) 62 return; 63 64 if (frequency) { 65 /* 66 * Set up PLL structure to hold the value to be set in clocks. 67 */ 68 pll.input_freq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */ 69 pll.clock_type = MXCLK_PLL; 70 71 /* 72 * Call sm750_calc_pll_value() to fill the other fields 73 * of the PLL structure. Sometimes, the chip cannot set 74 * up the exact clock required by the User. 75 * Return value of sm750_calc_pll_value gives the actual 76 * possible clock. 77 */ 78 sm750_calc_pll_value(frequency, &pll); 79 80 /* Master Clock Control: MXCLK_PLL */ 81 poke32(MXCLK_PLL_CTRL, sm750_format_pll_reg(&pll)); 82 } 83} 84 85static void set_memory_clock(unsigned int frequency) 86{ 87 unsigned int reg, divisor; 88 89 /* 90 * Cheok_0509: For SM750LE, the memory clock is fixed. 91 * Nothing to set. 92 */ 93 if (sm750_get_chip_type() == SM750LE) 94 return; 95 96 if (frequency) { 97 /* 98 * Set the frequency to the maximum frequency 99 * that the DDR Memory can take which is 336MHz. 100 */ 101 if (frequency > MHz(336)) 102 frequency = MHz(336); 103 104 /* Calculate the divisor */ 105 divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency); 106 107 /* Set the corresponding divisor in the register. */ 108 reg = peek32(CURRENT_GATE) & ~CURRENT_GATE_M2XCLK_MASK; 109 switch (divisor) { 110 default: 111 case 1: 112 reg |= CURRENT_GATE_M2XCLK_DIV_1; 113 break; 114 case 2: 115 reg |= CURRENT_GATE_M2XCLK_DIV_2; 116 break; 117 case 3: 118 reg |= CURRENT_GATE_M2XCLK_DIV_3; 119 break; 120 case 4: 121 reg |= CURRENT_GATE_M2XCLK_DIV_4; 122 break; 123 } 124 125 sm750_set_current_gate(reg); 126 } 127} 128 129/* 130 * This function set up the master clock (MCLK). 131 * 132 * Input: Frequency to be set. 133 * 134 * NOTE: 135 * The maximum frequency the engine can run is 168MHz. 136 */ 137static void set_master_clock(unsigned int frequency) 138{ 139 unsigned int reg, divisor; 140 141 /* 142 * Cheok_0509: For SM750LE, the memory clock is fixed. 143 * Nothing to set. 144 */ 145 if (sm750_get_chip_type() == SM750LE) 146 return; 147 148 if (frequency) { 149 /* 150 * Set the frequency to the maximum frequency 151 * that the SM750 engine can run, which is about 190 MHz. 152 */ 153 if (frequency > MHz(190)) 154 frequency = MHz(190); 155 156 /* Calculate the divisor */ 157 divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency); 158 159 /* Set the corresponding divisor in the register. */ 160 reg = peek32(CURRENT_GATE) & ~CURRENT_GATE_MCLK_MASK; 161 switch (divisor) { 162 default: 163 case 3: 164 reg |= CURRENT_GATE_MCLK_DIV_3; 165 break; 166 case 4: 167 reg |= CURRENT_GATE_MCLK_DIV_4; 168 break; 169 case 6: 170 reg |= CURRENT_GATE_MCLK_DIV_6; 171 break; 172 case 8: 173 reg |= CURRENT_GATE_MCLK_DIV_8; 174 break; 175 } 176 177 sm750_set_current_gate(reg); 178 } 179} 180 181unsigned int ddk750_get_vm_size(void) 182{ 183 unsigned int reg; 184 unsigned int data; 185 186 /* sm750le only use 64 mb memory*/ 187 if (sm750_get_chip_type() == SM750LE) 188 return SZ_64M; 189 190 /* for 750,always use power mode0*/ 191 reg = peek32(MODE0_GATE); 192 reg |= MODE0_GATE_GPIO; 193 poke32(MODE0_GATE, reg); 194 195 /* get frame buffer size from GPIO */ 196 reg = peek32(MISC_CTRL) & MISC_CTRL_LOCALMEM_SIZE_MASK; 197 switch (reg) { 198 case MISC_CTRL_LOCALMEM_SIZE_8M: 199 data = SZ_8M; break; /* 8 Mega byte */ 200 case MISC_CTRL_LOCALMEM_SIZE_16M: 201 data = SZ_16M; break; /* 16 Mega byte */ 202 case MISC_CTRL_LOCALMEM_SIZE_32M: 203 data = SZ_32M; break; /* 32 Mega byte */ 204 case MISC_CTRL_LOCALMEM_SIZE_64M: 205 data = SZ_64M; break; /* 64 Mega byte */ 206 default: 207 data = 0; 208 break; 209 } 210 return data; 211} 212 213int ddk750_init_hw(struct initchip_param *p_init_param) 214{ 215 unsigned int reg; 216 217 if (p_init_param->power_mode != 0) 218 p_init_param->power_mode = 0; 219 sm750_set_power_mode(p_init_param->power_mode); 220 221 /* Enable display power gate & LOCALMEM power gate*/ 222 reg = peek32(CURRENT_GATE); 223 reg |= (CURRENT_GATE_DISPLAY | CURRENT_GATE_LOCALMEM); 224 sm750_set_current_gate(reg); 225 226 if (sm750_get_chip_type() != SM750LE) { 227 /* set panel pll and graphic mode via mmio_88 */ 228 reg = peek32(VGA_CONFIGURATION); 229 reg |= (VGA_CONFIGURATION_PLL | VGA_CONFIGURATION_MODE); 230 poke32(VGA_CONFIGURATION, reg); 231 } else { 232#if defined(__i386__) || defined(__x86_64__) 233 /* set graphic mode via IO method */ 234 outb_p(0x88, 0x3d4); 235 outb_p(0x06, 0x3d5); 236#endif 237 } 238 239 /* Set the Main Chip Clock */ 240 set_chip_clock(MHz((unsigned int)p_init_param->chip_clock)); 241 242 /* Set up memory clock. */ 243 set_memory_clock(MHz(p_init_param->mem_clock)); 244 245 /* Set up master clock */ 246 set_master_clock(MHz(p_init_param->master_clock)); 247 248 /* 249 * Reset the memory controller. 250 * If the memory controller is not reset in SM750, 251 * the system might hang when sw accesses the memory. 252 * The memory should be resetted after changing the MXCLK. 253 */ 254 if (p_init_param->reset_memory == 1) { 255 reg = peek32(MISC_CTRL); 256 reg &= ~MISC_CTRL_LOCALMEM_RESET; 257 poke32(MISC_CTRL, reg); 258 259 reg |= MISC_CTRL_LOCALMEM_RESET; 260 poke32(MISC_CTRL, reg); 261 } 262 263 if (p_init_param->set_all_eng_off == 1) { 264 sm750_enable_2d_engine(0); 265 266 /* Disable Overlay, if a former application left it on */ 267 reg = peek32(VIDEO_DISPLAY_CTRL); 268 reg &= ~DISPLAY_CTRL_PLANE; 269 poke32(VIDEO_DISPLAY_CTRL, reg); 270 271 /* Disable video alpha, if a former application left it on */ 272 reg = peek32(VIDEO_ALPHA_DISPLAY_CTRL); 273 reg &= ~DISPLAY_CTRL_PLANE; 274 poke32(VIDEO_ALPHA_DISPLAY_CTRL, reg); 275 276 /* Disable alpha plane, if a former application left it on */ 277 reg = peek32(ALPHA_DISPLAY_CTRL); 278 reg &= ~DISPLAY_CTRL_PLANE; 279 poke32(ALPHA_DISPLAY_CTRL, reg); 280 281 /* Disable DMA Channel, if a former application left it on */ 282 reg = peek32(DMA_ABORT_INTERRUPT); 283 reg |= DMA_ABORT_INTERRUPT_ABORT_1; 284 poke32(DMA_ABORT_INTERRUPT, reg); 285 286 /* Disable DMA Power, if a former application left it on */ 287 sm750_enable_dma(0); 288 } 289 290 /* We can add more initialization as needed. */ 291 292 return 0; 293} 294 295/* 296 * monk liu @ 4/6/2011: 297 * re-write the calculatePLL function of ddk750. 298 * the original version function does not use 299 * some mathematics tricks and shortcut 300 * when it doing the calculation of the best N,M,D combination 301 * I think this version gives a little upgrade in speed 302 * 303 * 750 pll clock formular: 304 * Request Clock = (Input Clock * M )/(N * X) 305 * 306 * Input Clock = 14318181 hz 307 * X = 2 power D 308 * D ={0,1,2,3,4,5,6} 309 * M = {1,...,255} 310 * N = {2,...,15} 311 */ 312unsigned int sm750_calc_pll_value(unsigned int request_orig, 313 struct pll_value *pll) 314{ 315 /* 316 * as sm750 register definition, 317 * N located in 2,15 and M located in 1,255 318 */ 319 int N, M, X, d; 320 int mini_diff; 321 unsigned int RN, quo, rem, fl_quo; 322 unsigned int input, request; 323 unsigned int tmp_clock, ret; 324 const int max_OD = 3; 325 int max_d = 6; 326 327 if (sm750_get_chip_type() == SM750LE) { 328 /* 329 * SM750LE don't have 330 * programmable PLL and M/N values to work on. 331 * Just return the requested clock. 332 */ 333 return request_orig; 334 } 335 336 ret = 0; 337 mini_diff = ~0; 338 request = request_orig / 1000; 339 input = pll->input_freq / 1000; 340 341 /* 342 * for MXCLK register, 343 * no POD provided, so need be treated differently 344 */ 345 if (pll->clock_type == MXCLK_PLL) 346 max_d = 3; 347 348 for (N = 15; N > 1; N--) { 349 /* 350 * RN will not exceed maximum long 351 * if @request <= 285 MHZ (for 32bit cpu) 352 */ 353 RN = N * request; 354 quo = RN / input; 355 rem = RN % input;/* rem always small than 14318181 */ 356 fl_quo = rem * 10000 / input; 357 358 for (d = max_d; d >= 0; d--) { 359 X = BIT(d); 360 M = quo * X; 361 M += fl_quo * X / 10000; 362 /* round step */ 363 M += (fl_quo * X % 10000) > 5000 ? 1 : 0; 364 if (M < 256 && M > 0) { 365 unsigned int diff; 366 367 tmp_clock = pll->input_freq * M / N / X; 368 diff = abs(tmp_clock - request_orig); 369 if (diff < mini_diff) { 370 pll->M = M; 371 pll->N = N; 372 pll->POD = 0; 373 if (d > max_OD) 374 pll->POD = d - max_OD; 375 pll->OD = d - pll->POD; 376 mini_diff = diff; 377 ret = tmp_clock; 378 } 379 } 380 } 381 } 382 return ret; 383} 384 385unsigned int sm750_format_pll_reg(struct pll_value *p_PLL) 386{ 387#ifndef VALIDATION_CHIP 388 unsigned int POD = p_PLL->POD; 389#endif 390 unsigned int OD = p_PLL->OD; 391 unsigned int M = p_PLL->M; 392 unsigned int N = p_PLL->N; 393 394 /* 395 * Note that all PLL's have the same format. Here, we just use 396 * Panel PLL parameter to work out the bit fields in the 397 * register. On returning a 32 bit number, the value can be 398 * applied to any PLL in the calling function. 399 */ 400 return PLL_CTRL_POWER | 401#ifndef VALIDATION_CHIP 402 ((POD << PLL_CTRL_POD_SHIFT) & PLL_CTRL_POD_MASK) | 403#endif 404 ((OD << PLL_CTRL_OD_SHIFT) & PLL_CTRL_OD_MASK) | 405 ((N << PLL_CTRL_N_SHIFT) & PLL_CTRL_N_MASK) | 406 ((M << PLL_CTRL_M_SHIFT) & PLL_CTRL_M_MASK); 407}