| /* SPDX-License-Identifier: GPL-2.0+ */ | 
 | /* | 
 |  * Copyright (C) 2023 Loongson Technology Corporation Limited | 
 |  */ | 
 |  | 
 | #ifndef __LSDC_PIXPLL_H__ | 
 | #define __LSDC_PIXPLL_H__ | 
 |  | 
 | #include <drm/drm_device.h> | 
 |  | 
 | /* | 
 |  * Loongson Pixel PLL hardware structure | 
 |  * | 
 |  * refclk: reference frequency, 100 MHz from external oscillator | 
 |  * outclk: output frequency desired. | 
 |  * | 
 |  * | 
 |  *               L1       Fref                      Fvco     L2 | 
 |  * refclk   +-----------+      +------------------+      +---------+   outclk | 
 |  * ---+---> | Prescaler | ---> | Clock Multiplier | ---> | divider | --------> | 
 |  *    |     +-----------+      +------------------+      +---------+     ^ | 
 |  *    |           ^                      ^                    ^          | | 
 |  *    |           |                      |                    |          | | 
 |  *    |           |                      |                    |          | | 
 |  *    |        div_ref                 loopc               div_out       | | 
 |  *    |                                                                  | | 
 |  *    +---- bypass (bypass above software configurable clock if set) ----+ | 
 |  * | 
 |  *   outclk = refclk / div_ref * loopc / div_out; | 
 |  * | 
 |  *   sel_out: PLL clock output selector(enable). | 
 |  * | 
 |  *   If sel_out == 1, then enable output clock (turn On); | 
 |  *   If sel_out == 0, then disable output clock (turn Off); | 
 |  * | 
 |  * PLL working requirements: | 
 |  * | 
 |  *  1) 20 MHz <= refclk / div_ref <= 40Mhz | 
 |  *  2) 1.2 GHz <= refclk /div_out * loopc <= 3.2 Ghz | 
 |  */ | 
 |  | 
 | struct lsdc_pixpll_parms { | 
 | 	unsigned int ref_clock; | 
 | 	unsigned int div_ref; | 
 | 	unsigned int loopc; | 
 | 	unsigned int div_out; | 
 | }; | 
 |  | 
 | struct lsdc_pixpll; | 
 |  | 
 | struct lsdc_pixpll_funcs { | 
 | 	int (*setup)(struct lsdc_pixpll * const this); | 
 |  | 
 | 	int (*compute)(struct lsdc_pixpll * const this, | 
 | 		       unsigned int clock, | 
 | 		       struct lsdc_pixpll_parms *pout); | 
 |  | 
 | 	int (*update)(struct lsdc_pixpll * const this, | 
 | 		      struct lsdc_pixpll_parms const *pin); | 
 |  | 
 | 	unsigned int (*get_rate)(struct lsdc_pixpll * const this); | 
 |  | 
 | 	void (*print)(struct lsdc_pixpll * const this, | 
 | 		      struct drm_printer *printer); | 
 | }; | 
 |  | 
 | struct lsdc_pixpll { | 
 | 	const struct lsdc_pixpll_funcs *funcs; | 
 |  | 
 | 	struct drm_device *ddev; | 
 |  | 
 | 	/* PLL register offset */ | 
 | 	u32 reg_base; | 
 | 	/* PLL register size in bytes */ | 
 | 	u32 reg_size; | 
 |  | 
 | 	void __iomem *mmio; | 
 |  | 
 | 	struct lsdc_pixpll_parms *priv; | 
 | }; | 
 |  | 
 | int lsdc_pixpll_init(struct lsdc_pixpll * const this, | 
 | 		     struct drm_device *ddev, | 
 | 		     unsigned int index); | 
 |  | 
 | #endif |