cy22150.c (8490B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * _____ _____________________ 7 * / __\ \ / / _ \ _ \ __/ __/ __| 8 * | (__ \ ^ /| _/ / _|\__ \__ \ 9 * \___| |_| |_| |_|_\___|___/___/ TIMING TECHNOLOGY 10 * ================================================== 11 * Generated by CyClocksRT R1.05.00 12 * 13 * Modification Date: 8/12/02 14 * Comments: 15 * Customer: 16 * FAE: 17 * License #: 18 * Part Number: CY22150 19 * ______________ 20 * _| \__/ |_ 21 * XIN |_| 1 16 |_| XOUT 22 * _| |_ 23 * VDD |_| 2 15 |_| CLK6 24 * _| |_ 25 * AVDD |_| 3 14 |_| CLK5 26 * _| |_ 27 * SDA |_| 4 13 |_| VSS 28 * _| CY22150 |_ 29 * AVSS |_| 5 12 |_| LCLK4 30 * _| |_ 31 * VSSL |_| 6 11 |_| VDDL 32 * _| |_ 33 * LCLK1 |_| 7 10 |_| SCL 34 * _| |_ 35 * LCLK2 |_| 8 9 |_| LCLK3 36 * |______________| 37 * 38 * 39 * Reference Input: 25.000000 MHz External 40 * Target VCO: 314.000000 MHz 41 * Actual VCO: 314.000000 MHz PPM: 0.0 42 * 43 * P value: 314 MSB 0100111010 LSB 44 * Q vaule: 25 MSB 0011001 LSB 45 * Charge Pump Setting: 4 46 * Divider 1-X: 4 VCO 47 * Divider 2-X: 9 VCO 48 * 49 * Clock Output 50 * ==================================================================== 51 * |Output| Source | Desired | Actual | PPM | Voltage | 52 * ==================================================================== 53 * | CLK1 | Pll/2 | 157.000000 | 157.000000 | 0.0 | 2.5V | 54 * | CLK2 | Pll/2 | 157.000000 | 157.000000 | 0.0 | 2.5V | 55 * | CLK3 | Off | Off | Off | - - | 2.5V | 56 * | CLK4 | Off | Off | Off | - - | 2.5V | 57 * | CLK5 | Pll/ 9 | 34.888889 | 34.888889 | 0.0 | 3.3V | 58 * | CLK6 | Pll/ 9 | 34.888889 | 34.888889 | 0.0 | 3.3V | 59 * ==================================================================== 60 * 61 * 62 * 63 * Programming Algorithm 64 * 65 * For Core (Outputs AB, PLL3): NOTE: Q defaults to 25 so no adjustmnt 66 * is necessary. 67 * 68 * 1. Adjust Q to desired value (25). Default so no action necessary!!! 69 * 2. Adjust P to desired value 3. Adjust output divider to desired value 70 * (2) - default is 3 for core and SDRAM 4. Adjust LF 71 * 72 * For SDRAM (Outputs CD, PLL2): 73 * 74 * 1. Adjust Q to desired value (25) 75 * 2. Adjust P to desired value 76 * 3. Adjust output divider to desired value (2) - default is 3 for core and 77 * SDRAM 78 * 4. Adjust LF 79 * 80 * For PCI/CPU clock (OUTPUT E, PLL1) 81 * 82 * 1. Adjust Q to desired value (25). Default so no action necessary!!! 83 * 2. Adjust P to desired value 84 * 3. Adjust output divider to desired value (4) - Default so no action 85 * necessary!!! 86 * 4. Adjust LF. 87 * 5. Compensate as necessary for baud rate or other parameters affected by 88 * changing the PCI or CPU frequency!!!!!! 89 * 90 * 91 * See the Cypress W22393 Clock chip data sheet(s) for more details. 92 * See also: http://www.cypress.com/clock/datasheets.html 93 */ 94 95 #include <sal/types.h> 96 #include <soc/drv.h> 97 #include <soc/error.h> 98 #include <soc/i2c.h> 99 #include <shared/bsl.h> 100 101 #define MHZ(x) ((x)*1000000) 102 103 /* FRef = 25MHz */ 104 #define CY22150_REF_CLK MHZ(25) 105 #define CY22150_DIV_CORE 2 106 #define CY22150_DIV_SDRAM 2 107 #define CY22150_DIV_PCI 4 108 #define CY_DEBUG(x) do { \ 109 LOG_CLI((BSL_META(x); \ 110 sal_usleep(1000); \ 111 } while (0) 112 113 /* 114 * Charge Pump : Computed based on Ptotal 115 * See datasheet for more info. 116 */ 117 STATIC uint8 118 cy22150_charge_pump(int val) 119 { 120 uint8 tmp; 121 122 /* Convert from MHz if required */ 123 if (val > MHZ(1)) { 124 val /= MHZ(1); 125 } 126 if (val >= 16 && val <= 44) { 127 tmp = 0; 128 } else if (val >= 45 && val <= 479) { 129 tmp = 1; 130 } else if (val >= 480 && val <= 639) { 131 tmp = 2; 132 } else if (val >= 640 && val <= 799) { 133 tmp = 3; 134 } else if (val >= 800 && val <= 1023) { 135 tmp = 4; 136 } else { 137 tmp = 0; 138 } 139 return tmp; 140 } 141 142 STATIC int 143 cy22150_ioctl(int unit, int devno, 144 int opcode, void *data, int len) 145 { 146 #ifdef COMPILER_HAS_DOUBLE 147 double clk, qt; 148 #else 149 int qt; 150 #endif 151 int iclk, P0, ip, iq; 152 uint8 tmp, lf, saddr = soc_i2c_addr(unit, devno); 153 154 if ( I2C_XPLL_SET_PCI == opcode ) { 155 /* Not implemented, but report success */ 156 } else if ( I2C_XPLL_GET_PCI == opcode ) { 157 /* Not implemented, but report success */ 158 } else if ( I2C_XPLL_SET_CORE == opcode ) { 159 #ifdef COMPILER_HAS_DOUBLE 160 clk = *((double *)data); 161 162 /* Convert from MHz if required */ 163 if( clk < MHZ(1)) 164 clk *= MHZ(1); 165 166 /* Setup new core clock */ 167 iclk = (int) clk; 168 #else 169 iclk = *((int *)data); 170 #endif 171 /* Compute actual frequency in MHz */ 172 iclk = (CY22150_DIV_CORE * iclk) / MHZ(1); 173 174 /* This is set only on an odd clock freq */ 175 P0 = iclk % 2; 176 177 /* Compute Qt and convert to byte value (in MHz)*/ 178 qt = CY22150_REF_CLK - MHZ(2); 179 qt = qt / MHZ(1); 180 181 /* Compute P/Q (integer format) */ 182 ip = ((iclk - P0) / 2) - 4; 183 iq = (int) qt; 184 185 /* Bit 8 of Q (0x42) is PNot */ 186 iq |= (P0 << 8); 187 188 /* Compute Charge Pump setting */ 189 lf = cy22150_charge_pump(iclk); 190 191 /* Bits 7-5 fixed at 110b */ 192 tmp = 0xC0; 193 194 /* Add upper P bits */ 195 tmp |= (ip >> 8); 196 197 /* Add Charge Pump bits */ 198 tmp |= (lf << 2); 199 200 /* Configure new clock setting */ 201 soc_i2c_write_byte_data(unit, saddr, 0x40, tmp); 202 soc_i2c_write_byte_data(unit, saddr, 0x41, (uint8)ip); 203 soc_i2c_write_byte_data(unit, saddr, 0x42, (uint8)iq); 204 205 } else if ( I2C_XPLL_GET_CORE == opcode) { 206 uint8 p_l, p_h, q, pNot; 207 uint16 p; 208 209 soc_i2c_read_byte_data(unit, saddr, 0x41, &p_l); 210 soc_i2c_read_byte_data(unit, saddr, 0x40, &p_h); 211 soc_i2c_read_byte_data(unit, saddr, 0x42, &q); 212 pNot = ((p_h & 0x04) >> 2); /* Bit 2 of 0x57 */ 213 p_h &= 0x03; /* Clear all bits except bits 0-1 */ 214 p = (p_h << 8) | p_l; /* 10 bits of p value */ 215 #ifdef COMPILER_HAS_DOUBLE 216 clk = 2 * ( p + 4 ) + pNot ; 217 clk *= CY22150_REF_CLK; 218 clk /= (q+2); 219 clk /= 2; 220 clk /= MHZ(1); 221 *((double *)data) = clk; 222 #else 223 iclk = 2 * (p + 4) + pNot; 224 iclk *= CY22150_REF_CLK / (q + 2); 225 iclk /= 2; 226 *((int *)data) = iclk; 227 #endif 228 } else if ( I2C_XPLL_SET_SDRAM == opcode) { 229 /* Not implemented, but report success */ 230 } else if ( I2C_XPLL_GET_SDRAM == opcode) { 231 /* Not implemented, but report success */ 232 } else { 233 return SOC_E_PARAM; 234 } 235 236 return SOC_E_NONE; 237 } 238 239 /* 240 * Function: cy22150_init 241 * 242 * Purpose: 243 * Initialize the CY22150 clock chip 244 * Parameters: 245 * unit - StrataSwitch device number or I2C bus number 246 * devno - chip device id 247 * data - not used 248 * len - not used 249 * Returns: 250 * SOC_E_NONE - no failure 251 */ 252 STATIC int 253 cy22150_init(int unit, int devno, 254 void *data, int len) 255 { 256 #if 0 257 int i; 258 uint8 x; 259 uint8 saddr = soc_i2c_addr(unit, devno); 260 261 /* Dump register values */ 262 for (i = 0x08; i <= 0x17; i++) { 263 soc_i2c_read_byte_data(unit, saddr, (uint8)i, &x); 264 LOG_CLI((BSL_META_U(unit, 265 "pll[%x] = 0x%x\n"), i, x)); 266 } 267 for (i = 0x40; i <= 0x57; i++) { 268 soc_i2c_read_byte_data(unit, saddr, (uint8)i, &x); 269 LOG_CLI((BSL_META_U(unit, 270 "pll[%x] = 0x%x\n"), i, x)); 271 } 272 #endif 273 soc_i2c_devdesc_set(unit, devno, "Cypress W22150 clock Chip"); 274 return SOC_E_NONE; 275 } 276 277 STATIC int 278 cy22150_read(int unit, int devno, 279 uint16 addr, uint8 *data, uint32 *len) 280 { 281 *len = 1; /* Byte-write mode */ 282 return soc_i2c_read_byte_data(unit, 283 soc_i2c_addr(unit, devno), 284 (uint8)addr, data); 285 } 286 287 STATIC int 288 cy22150_write(int unit, int devno, 289 uint16 addr, uint8 *data, uint32 len) 290 { 291 return soc_i2c_write_byte_data(unit, 292 soc_i2c_addr(unit, devno), 293 (uint8)addr, *data); 294 } 295 296 /* CY22150/W311 Clock Chip Driver callout */ 297 i2c_driver_t _soc_i2c_cy22150_driver = { 298 0x0, 0x0, /* System assigned bytes */ 299 CY22150_DEVICE_TYPE, 300 cy22150_read, 301 cy22150_write, 302 cy22150_ioctl, 303 cy22150_init, 304 NULL, 305 };