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