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
42struct lsdc_pixpll_parms {
43	unsigned int ref_clock;
44	unsigned int div_ref;
45	unsigned int loopc;
46	unsigned int div_out;
47};
48
49struct lsdc_pixpll;
50
51struct 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
67struct 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
82int lsdc_pixpll_init(struct lsdc_pixpll * const this,
83		     struct drm_device *ddev,
84		     unsigned int index);
85
86#endif
87