lsdc_pixpll.c 12 KB

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