1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (C) 2023 Loongson Technology Corporation Limited
4  */
5 
6 #ifndef __LSDC_PIXPLL_H__
7 #define __LSDC_PIXPLL_H__
8 
9 #include <drm/drm_device.h>
10 
11 /*
12  * Loongson Pixel PLL hardware structure
13  *
14  * refclk: reference frequency, 100 MHz from external oscillator
15  * outclk: output frequency desired.
16  *
17  *
18  *               L1       Fref                      Fvco     L2
19  * refclk   +-----------+      +------------------+      +---------+   outclk
20  * ---+---> | Prescaler | ---> | Clock Multiplier | ---> | divider | -------->
21  *    |     +-----------+      +------------------+      +---------+     ^
22  *    |           ^                      ^                    ^          |
23  *    |           |                      |                    |          |
24  *    |           |                      |                    |          |
25  *    |        div_ref                 loopc               div_out       |
26  *    |                                                                  |
27  *    +---- bypass (bypass above software configurable clock if set) ----+
28  *
29  *   outclk = refclk / div_ref * loopc / div_out;
30  *
31  *   sel_out: PLL clock output selector(enable).
32  *
33  *   If sel_out == 1, then enable output clock (turn On);
34  *   If sel_out == 0, then disable output clock (turn Off);
35  *
36  * PLL working requirements:
37  *
38  *  1) 20 MHz <= refclk / div_ref <= 40Mhz
39  *  2) 1.2 GHz <= refclk /div_out * loopc <= 3.2 Ghz
40  */
41 
42 struct lsdc_pixpll_parms {
43 	unsigned int ref_clock;
44 	unsigned int div_ref;
45 	unsigned int loopc;
46 	unsigned int div_out;
47 };
48 
49 struct lsdc_pixpll;
50 
51 struct lsdc_pixpll_funcs {
52 	int (*setup)(struct lsdc_pixpll * const this);
53 
54 	int (*compute)(struct lsdc_pixpll * const this,
55 		       unsigned int clock,
56 		       struct lsdc_pixpll_parms *pout);
57 
58 	int (*update)(struct lsdc_pixpll * const this,
59 		      struct lsdc_pixpll_parms const *pin);
60 
61 	unsigned int (*get_rate)(struct lsdc_pixpll * const this);
62 
63 	void (*print)(struct lsdc_pixpll * const this,
64 		      struct drm_printer *printer);
65 };
66 
67 struct lsdc_pixpll {
68 	const struct lsdc_pixpll_funcs *funcs;
69 
70 	struct drm_device *ddev;
71 
72 	/* PLL register offset */
73 	u32 reg_base;
74 	/* PLL register size in bytes */
75 	u32 reg_size;
76 
77 	void __iomem *mmio;
78 
79 	struct lsdc_pixpll_parms *priv;
80 };
81 
82 int lsdc_pixpll_init(struct lsdc_pixpll * const this,
83 		     struct drm_device *ddev,
84 		     unsigned int index);
85 
86 #endif
87