1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2023 Loongson Technology Corporation Limited 4 */ 5 6 #include <linux/delay.h> 7 8 #include <drm/drm_managed.h> 9 #include <drm/drm_print.h> 10 11 #include "lsdc_drv.h" 12 13 /* 14 * The structure of the pixel PLL registers is evolved with times, 15 * it can be different across different chip also. 16 */ 17 18 /* size is u64, note that all loongson's cpu is little endian. 19 * This structure is same for ls7a2000, ls7a1000 and ls2k2000. 20 */ 21 struct lsdc_pixpll_reg { 22 /* Byte 0 ~ Byte 3 */ 23 unsigned div_out : 7; /* 6 : 0 Output clock divider */ 24 unsigned _reserved_1_ : 14; /* 20 : 7 */ 25 unsigned loopc : 9; /* 29 : 21 Clock multiplier */ 26 unsigned _reserved_2_ : 2; /* 31 : 30 */ 27 28 /* Byte 4 ~ Byte 7 */ 29 unsigned div_ref : 7; /* 38 : 32 Input clock divider */ 30 unsigned locked : 1; /* 39 PLL locked indicator */ 31 unsigned sel_out : 1; /* 40 output clk selector */ 32 unsigned _reserved_3_ : 2; /* 42 : 41 */ 33 unsigned set_param : 1; /* 43 Trigger the update */ 34 unsigned bypass : 1; /* 44 */ 35 unsigned powerdown : 1; /* 45 */ 36 unsigned _reserved_4_ : 18; /* 46 : 63 no use */ 37 }; 38 39 union lsdc_pixpll_reg_bitmap { 40 struct lsdc_pixpll_reg bitmap; 41 u32 w[2]; 42 u64 d; 43 }; 44 45 struct clk_to_pixpll_parms_lookup_t { 46 unsigned int clock; /* kHz */ 47 48 unsigned short width; 49 unsigned short height; 50 unsigned short vrefresh; 51 52 /* Stores parameters for programming the Hardware PLLs */ 53 unsigned short div_out; 54 unsigned short loopc; 55 unsigned short div_ref; 56 }; 57 58 static const struct clk_to_pixpll_parms_lookup_t pixpll_parms_table[] = { 59 {148500, 1920, 1080, 60, 11, 49, 3}, /* 1920x1080@60Hz */ 60 {141750, 1920, 1080, 60, 11, 78, 5}, /* 1920x1080@60Hz */ 61 /* 1920x1080@50Hz */ 62 {174500, 1920, 1080, 75, 17, 89, 3}, /* 1920x1080@75Hz */ 63 {181250, 2560, 1080, 75, 8, 58, 4}, /* 2560x1080@75Hz */ 64 {297000, 2560, 1080, 30, 8, 95, 4}, /* 3840x2160@30Hz */ 65 {301992, 1920, 1080, 100, 10, 151, 5}, /* 1920x1080@100Hz */ 66 {146250, 1680, 1050, 60, 16, 117, 5}, /* 1680x1050@60Hz */ 67 {135000, 1280, 1024, 75, 10, 54, 4}, /* 1280x1024@75Hz */ 68 {119000, 1680, 1050, 60, 20, 119, 5}, /* 1680x1050@60Hz */ 69 {108000, 1600, 900, 60, 15, 81, 5}, /* 1600x900@60Hz */ 70 /* 1280x1024@60Hz */ 71 /* 1280x960@60Hz */ 72 /* 1152x864@75Hz */ 73 74 {106500, 1440, 900, 60, 19, 81, 4}, /* 1440x900@60Hz */ 75 {88750, 1440, 900, 60, 16, 71, 5}, /* 1440x900@60Hz */ 76 {83500, 1280, 800, 60, 17, 71, 5}, /* 1280x800@60Hz */ 77 {71000, 1280, 800, 60, 20, 71, 5}, /* 1280x800@60Hz */ 78 79 {74250, 1280, 720, 60, 22, 49, 3}, /* 1280x720@60Hz */ 80 /* 1280x720@50Hz */ 81 82 {78750, 1024, 768, 75, 16, 63, 5}, /* 1024x768@75Hz */ 83 {75000, 1024, 768, 70, 29, 87, 4}, /* 1024x768@70Hz */ 84 {65000, 1024, 768, 60, 20, 39, 3}, /* 1024x768@60Hz */ 85 86 {51200, 1024, 600, 60, 25, 64, 5}, /* 1024x600@60Hz */ 87 88 {57284, 832, 624, 75, 24, 55, 4}, /* 832x624@75Hz */ 89 {49500, 800, 600, 75, 40, 99, 5}, /* 800x600@75Hz */ 90 {50000, 800, 600, 72, 44, 88, 4}, /* 800x600@72Hz */ 91 {40000, 800, 600, 60, 30, 36, 3}, /* 800x600@60Hz */ 92 {36000, 800, 600, 56, 50, 72, 4}, /* 800x600@56Hz */ 93 {31500, 640, 480, 75, 40, 63, 5}, /* 640x480@75Hz */ 94 /* 640x480@73Hz */ 95 96 {30240, 640, 480, 67, 62, 75, 4}, /* 640x480@67Hz */ 97 {27000, 720, 576, 50, 50, 54, 4}, /* 720x576@60Hz */ 98 {25175, 640, 480, 60, 85, 107, 5}, /* 640x480@60Hz */ 99 {25200, 640, 480, 60, 50, 63, 5}, /* 640x480@60Hz */ 100 /* 720x480@60Hz */ 101 }; 102 103 static void lsdc_pixel_pll_free(struct drm_device *ddev, void *data) 104 { 105 struct lsdc_pixpll *this = (struct lsdc_pixpll *)data; 106 107 iounmap(this->mmio); 108 109 kfree(this->priv); 110 111 drm_dbg(ddev, "pixpll private data freed\n"); 112 } 113 114 /* 115 * ioremap the device dependent PLL registers 116 * 117 * @this: point to the object where this function is called from 118 */ 119 static int lsdc_pixel_pll_setup(struct lsdc_pixpll * const this) 120 { 121 struct lsdc_pixpll_parms *pparms; 122 123 this->mmio = ioremap(this->reg_base, this->reg_size); 124 if (!this->mmio) 125 return -ENOMEM; 126 127 pparms = kzalloc(sizeof(*pparms), GFP_KERNEL); 128 if (!pparms) { 129 iounmap(this->mmio); 130 return -ENOMEM; 131 } 132 133 pparms->ref_clock = LSDC_PLL_REF_CLK_KHZ; 134 135 this->priv = pparms; 136 137 return drmm_add_action_or_reset(this->ddev, lsdc_pixel_pll_free, this); 138 } 139 140 /* 141 * Find a set of pll parameters from a static local table which avoid 142 * computing the pll parameter eachtime a modeset is triggered. 143 * 144 * @this: point to the object where this function is called from 145 * @clock: the desired output pixel clock, the unit is kHz 146 * @pout: point to where the parameters to store if found 147 * 148 * Return 0 if success, return -1 if not found. 149 */ 150 static int lsdc_pixpll_find(struct lsdc_pixpll * const this, 151 unsigned int clock, 152 struct lsdc_pixpll_parms *pout) 153 { 154 unsigned int num = ARRAY_SIZE(pixpll_parms_table); 155 const struct clk_to_pixpll_parms_lookup_t *pt; 156 unsigned int i; 157 158 for (i = 0; i < num; ++i) { 159 pt = &pixpll_parms_table[i]; 160 161 if (clock == pt->clock) { 162 pout->div_ref = pt->div_ref; 163 pout->loopc = pt->loopc; 164 pout->div_out = pt->div_out; 165 166 return 0; 167 } 168 } 169 170 drm_dbg_kms(this->ddev, "pixel clock %u: miss\n", clock); 171 172 return -1; 173 } 174 175 /* 176 * Find a set of pll parameters which have minimal difference with the 177 * desired pixel clock frequency. It does that by computing all of the 178 * possible combination. Compute the diff and find the combination with 179 * minimal diff. 180 * 181 * clock_out = refclk / div_ref * loopc / div_out 182 * 183 * refclk is determined by the oscillator mounted on motherboard(100MHz 184 * in almost all board) 185 * 186 * @this: point to the object from where this function is called 187 * @clock: the desired output pixel clock, the unit is kHz 188 * @pout: point to the out struct of lsdc_pixpll_parms 189 * 190 * Return 0 if a set of parameter is found, otherwise return the error 191 * between clock_kHz we wanted and the most closest candidate with it. 192 */ 193 static int lsdc_pixel_pll_compute(struct lsdc_pixpll * const this, 194 unsigned int clock, 195 struct lsdc_pixpll_parms *pout) 196 { 197 struct lsdc_pixpll_parms *pparms = this->priv; 198 unsigned int refclk = pparms->ref_clock; 199 const unsigned int tolerance = 1000; 200 unsigned int min = tolerance; 201 unsigned int div_out, loopc, div_ref; 202 unsigned int computed; 203 204 if (!lsdc_pixpll_find(this, clock, pout)) 205 return 0; 206 207 for (div_out = 6; div_out < 64; div_out++) { 208 for (div_ref = 3; div_ref < 6; div_ref++) { 209 for (loopc = 6; loopc < 161; loopc++) { 210 unsigned int diff = 0; 211 212 if (loopc < 12 * div_ref) 213 continue; 214 if (loopc > 32 * div_ref) 215 continue; 216 217 computed = refclk / div_ref * loopc / div_out; 218 219 if (clock >= computed) 220 diff = clock - computed; 221 else 222 diff = computed - clock; 223 224 if (diff < min) { 225 min = diff; 226 pparms->div_ref = div_ref; 227 pparms->div_out = div_out; 228 pparms->loopc = loopc; 229 230 if (diff == 0) { 231 *pout = *pparms; 232 return 0; 233 } 234 } 235 } 236 } 237 } 238 239 /* still acceptable */ 240 if (min < tolerance) { 241 *pout = *pparms; 242 return 0; 243 } 244 245 drm_dbg(this->ddev, "can't find suitable params for %u khz\n", clock); 246 247 return min; 248 } 249 250 /* Pixel pll hardware related ops, per display pipe */ 251 252 static void __pixpll_rreg(struct lsdc_pixpll *this, 253 union lsdc_pixpll_reg_bitmap *dst) 254 { 255 #if defined(CONFIG_64BIT) 256 dst->d = readq(this->mmio); 257 #else 258 dst->w[0] = readl(this->mmio); 259 dst->w[1] = readl(this->mmio + 4); 260 #endif 261 } 262 263 static void __pixpll_wreg(struct lsdc_pixpll *this, 264 union lsdc_pixpll_reg_bitmap *src) 265 { 266 #if defined(CONFIG_64BIT) 267 writeq(src->d, this->mmio); 268 #else 269 writel(src->w[0], this->mmio); 270 writel(src->w[1], this->mmio + 4); 271 #endif 272 } 273 274 static void __pixpll_ops_powerup(struct lsdc_pixpll * const this) 275 { 276 union lsdc_pixpll_reg_bitmap pixpll_reg; 277 278 __pixpll_rreg(this, &pixpll_reg); 279 280 pixpll_reg.bitmap.powerdown = 0; 281 282 __pixpll_wreg(this, &pixpll_reg); 283 } 284 285 static void __pixpll_ops_powerdown(struct lsdc_pixpll * const this) 286 { 287 union lsdc_pixpll_reg_bitmap pixpll_reg; 288 289 __pixpll_rreg(this, &pixpll_reg); 290 291 pixpll_reg.bitmap.powerdown = 1; 292 293 __pixpll_wreg(this, &pixpll_reg); 294 } 295 296 static void __pixpll_ops_on(struct lsdc_pixpll * const this) 297 { 298 union lsdc_pixpll_reg_bitmap pixpll_reg; 299 300 __pixpll_rreg(this, &pixpll_reg); 301 302 pixpll_reg.bitmap.sel_out = 1; 303 304 __pixpll_wreg(this, &pixpll_reg); 305 } 306 307 static void __pixpll_ops_off(struct lsdc_pixpll * const this) 308 { 309 union lsdc_pixpll_reg_bitmap pixpll_reg; 310 311 __pixpll_rreg(this, &pixpll_reg); 312 313 pixpll_reg.bitmap.sel_out = 0; 314 315 __pixpll_wreg(this, &pixpll_reg); 316 } 317 318 static void __pixpll_ops_bypass(struct lsdc_pixpll * const this) 319 { 320 union lsdc_pixpll_reg_bitmap pixpll_reg; 321 322 __pixpll_rreg(this, &pixpll_reg); 323 324 pixpll_reg.bitmap.bypass = 1; 325 326 __pixpll_wreg(this, &pixpll_reg); 327 } 328 329 static void __pixpll_ops_unbypass(struct lsdc_pixpll * const this) 330 { 331 union lsdc_pixpll_reg_bitmap pixpll_reg; 332 333 __pixpll_rreg(this, &pixpll_reg); 334 335 pixpll_reg.bitmap.bypass = 0; 336 337 __pixpll_wreg(this, &pixpll_reg); 338 } 339 340 static void __pixpll_ops_untoggle_param(struct lsdc_pixpll * const this) 341 { 342 union lsdc_pixpll_reg_bitmap pixpll_reg; 343 344 __pixpll_rreg(this, &pixpll_reg); 345 346 pixpll_reg.bitmap.set_param = 0; 347 348 __pixpll_wreg(this, &pixpll_reg); 349 } 350 351 static void __pixpll_ops_set_param(struct lsdc_pixpll * const this, 352 struct lsdc_pixpll_parms const *p) 353 { 354 union lsdc_pixpll_reg_bitmap pixpll_reg; 355 356 __pixpll_rreg(this, &pixpll_reg); 357 358 pixpll_reg.bitmap.div_ref = p->div_ref; 359 pixpll_reg.bitmap.loopc = p->loopc; 360 pixpll_reg.bitmap.div_out = p->div_out; 361 362 __pixpll_wreg(this, &pixpll_reg); 363 } 364 365 static void __pixpll_ops_toggle_param(struct lsdc_pixpll * const this) 366 { 367 union lsdc_pixpll_reg_bitmap pixpll_reg; 368 369 __pixpll_rreg(this, &pixpll_reg); 370 371 pixpll_reg.bitmap.set_param = 1; 372 373 __pixpll_wreg(this, &pixpll_reg); 374 } 375 376 static void __pixpll_ops_wait_locked(struct lsdc_pixpll * const this) 377 { 378 union lsdc_pixpll_reg_bitmap pixpll_reg; 379 unsigned int counter = 0; 380 381 do { 382 __pixpll_rreg(this, &pixpll_reg); 383 384 if (pixpll_reg.bitmap.locked) 385 break; 386 387 ++counter; 388 } while (counter < 2000); 389 390 drm_dbg(this->ddev, "%u loop waited\n", counter); 391 } 392 393 /* 394 * Update the PLL parameters to the PLL hardware 395 * 396 * @this: point to the object from which this function is called 397 * @pin: point to the struct of lsdc_pixpll_parms passed in 398 * 399 * return 0 if successful. 400 */ 401 static int lsdc_pixpll_update(struct lsdc_pixpll * const this, 402 struct lsdc_pixpll_parms const *pin) 403 { 404 __pixpll_ops_bypass(this); 405 406 __pixpll_ops_off(this); 407 408 __pixpll_ops_powerdown(this); 409 410 __pixpll_ops_toggle_param(this); 411 412 __pixpll_ops_set_param(this, pin); 413 414 __pixpll_ops_untoggle_param(this); 415 416 __pixpll_ops_powerup(this); 417 418 udelay(2); 419 420 __pixpll_ops_wait_locked(this); 421 422 __pixpll_ops_on(this); 423 424 __pixpll_ops_unbypass(this); 425 426 return 0; 427 } 428 429 static unsigned int lsdc_pixpll_get_freq(struct lsdc_pixpll * const this) 430 { 431 struct lsdc_pixpll_parms *ppar = this->priv; 432 union lsdc_pixpll_reg_bitmap pix_pll_reg; 433 unsigned int freq; 434 435 __pixpll_rreg(this, &pix_pll_reg); 436 437 ppar->div_ref = pix_pll_reg.bitmap.div_ref; 438 ppar->loopc = pix_pll_reg.bitmap.loopc; 439 ppar->div_out = pix_pll_reg.bitmap.div_out; 440 441 freq = ppar->ref_clock / ppar->div_ref * ppar->loopc / ppar->div_out; 442 443 return freq; 444 } 445 446 static void lsdc_pixpll_print(struct lsdc_pixpll * const this, 447 struct drm_printer *p) 448 { 449 struct lsdc_pixpll_parms *parms = this->priv; 450 451 drm_printf(p, "div_ref: %u, loopc: %u, div_out: %u\n", 452 parms->div_ref, parms->loopc, parms->div_out); 453 } 454 455 /* 456 * LS7A1000, LS7A2000 and ls2k2000's pixel pll setting register is same, 457 * we take this as default, create a new instance if a different model is 458 * introduced. 459 */ 460 static const struct lsdc_pixpll_funcs __pixpll_default_funcs = { 461 .setup = lsdc_pixel_pll_setup, 462 .compute = lsdc_pixel_pll_compute, 463 .update = lsdc_pixpll_update, 464 .get_rate = lsdc_pixpll_get_freq, 465 .print = lsdc_pixpll_print, 466 }; 467 468 /* pixel pll initialization */ 469 470 int lsdc_pixpll_init(struct lsdc_pixpll * const this, 471 struct drm_device *ddev, 472 unsigned int index) 473 { 474 struct lsdc_device *ldev = to_lsdc(ddev); 475 const struct lsdc_desc *descp = ldev->descp; 476 const struct loongson_gfx_desc *gfx = to_loongson_gfx(descp); 477 478 this->ddev = ddev; 479 this->reg_size = 8; 480 this->reg_base = gfx->conf_reg_base + gfx->pixpll[index].reg_offset; 481 this->funcs = &__pixpll_default_funcs; 482 483 return this->funcs->setup(this); 484 } 485