1*f39db26cSSui Jingfeng /* SPDX-License-Identifier: GPL-2.0+ */
2*f39db26cSSui Jingfeng /*
3*f39db26cSSui Jingfeng  * Copyright (C) 2023 Loongson Technology Corporation Limited
4*f39db26cSSui Jingfeng  */
5*f39db26cSSui Jingfeng 
6*f39db26cSSui Jingfeng #ifndef __LSDC_DRV_H__
7*f39db26cSSui Jingfeng #define __LSDC_DRV_H__
8*f39db26cSSui Jingfeng 
9*f39db26cSSui Jingfeng #include <linux/pci.h>
10*f39db26cSSui Jingfeng 
11*f39db26cSSui Jingfeng #include <drm/drm_connector.h>
12*f39db26cSSui Jingfeng #include <drm/drm_crtc.h>
13*f39db26cSSui Jingfeng #include <drm/drm_device.h>
14*f39db26cSSui Jingfeng #include <drm/drm_encoder.h>
15*f39db26cSSui Jingfeng #include <drm/drm_file.h>
16*f39db26cSSui Jingfeng #include <drm/drm_plane.h>
17*f39db26cSSui Jingfeng #include <drm/ttm/ttm_device.h>
18*f39db26cSSui Jingfeng 
19*f39db26cSSui Jingfeng #include "lsdc_i2c.h"
20*f39db26cSSui Jingfeng #include "lsdc_irq.h"
21*f39db26cSSui Jingfeng #include "lsdc_gfxpll.h"
22*f39db26cSSui Jingfeng #include "lsdc_output.h"
23*f39db26cSSui Jingfeng #include "lsdc_pixpll.h"
24*f39db26cSSui Jingfeng #include "lsdc_regs.h"
25*f39db26cSSui Jingfeng 
26*f39db26cSSui Jingfeng /* Currently, all Loongson display controllers have two display pipes. */
27*f39db26cSSui Jingfeng #define LSDC_NUM_CRTC           2
28*f39db26cSSui Jingfeng 
29*f39db26cSSui Jingfeng /*
30*f39db26cSSui Jingfeng  * LS7A1000/LS7A2000 chipsets function as the south & north bridges of the
31*f39db26cSSui Jingfeng  * Loongson 3 series processors, they are equipped with on-board video RAM
32*f39db26cSSui Jingfeng  * typically. While Loongson LS2K series are low cost SoCs which share the
33*f39db26cSSui Jingfeng  * system RAM as video RAM, they don't has a dedicated VRAM.
34*f39db26cSSui Jingfeng  *
35*f39db26cSSui Jingfeng  * There is only a 1:1 mapping of crtcs, encoders and connectors for the DC
36*f39db26cSSui Jingfeng  *
37*f39db26cSSui Jingfeng  * display pipe 0 = crtc0 + dvo0 + encoder0 + connector0 + cursor0 + primary0
38*f39db26cSSui Jingfeng  * display pipe 1 = crtc1 + dvo1 + encoder1 + connectro1 + cursor1 + primary1
39*f39db26cSSui Jingfeng  */
40*f39db26cSSui Jingfeng 
41*f39db26cSSui Jingfeng enum loongson_chip_id {
42*f39db26cSSui Jingfeng 	CHIP_LS7A1000 = 0,
43*f39db26cSSui Jingfeng 	CHIP_LS7A2000 = 1,
44*f39db26cSSui Jingfeng 	CHIP_LS_LAST,
45*f39db26cSSui Jingfeng };
46*f39db26cSSui Jingfeng 
47*f39db26cSSui Jingfeng const struct lsdc_desc *
48*f39db26cSSui Jingfeng lsdc_device_probe(struct pci_dev *pdev, enum loongson_chip_id chip);
49*f39db26cSSui Jingfeng 
50*f39db26cSSui Jingfeng struct lsdc_kms_funcs;
51*f39db26cSSui Jingfeng 
52*f39db26cSSui Jingfeng /* DC specific */
53*f39db26cSSui Jingfeng 
54*f39db26cSSui Jingfeng struct lsdc_desc {
55*f39db26cSSui Jingfeng 	u32 num_of_crtc;
56*f39db26cSSui Jingfeng 	u32 max_pixel_clk;
57*f39db26cSSui Jingfeng 	u32 max_width;
58*f39db26cSSui Jingfeng 	u32 max_height;
59*f39db26cSSui Jingfeng 	u32 num_of_hw_cursor;
60*f39db26cSSui Jingfeng 	u32 hw_cursor_w;
61*f39db26cSSui Jingfeng 	u32 hw_cursor_h;
62*f39db26cSSui Jingfeng 	u32 pitch_align;         /* CRTC DMA alignment constraint */
63*f39db26cSSui Jingfeng 	bool has_vblank_counter; /* 32 bit hw vsync counter */
64*f39db26cSSui Jingfeng 
65*f39db26cSSui Jingfeng 	/* device dependent ops, dc side */
66*f39db26cSSui Jingfeng 	const struct lsdc_kms_funcs *funcs;
67*f39db26cSSui Jingfeng };
68*f39db26cSSui Jingfeng 
69*f39db26cSSui Jingfeng /* GFX related resources wrangler */
70*f39db26cSSui Jingfeng 
71*f39db26cSSui Jingfeng struct loongson_gfx_desc {
72*f39db26cSSui Jingfeng 	struct lsdc_desc dc;
73*f39db26cSSui Jingfeng 
74*f39db26cSSui Jingfeng 	u32 conf_reg_base;
75*f39db26cSSui Jingfeng 
76*f39db26cSSui Jingfeng 	/* GFXPLL shared by the DC, GMC and GPU */
77*f39db26cSSui Jingfeng 	struct {
78*f39db26cSSui Jingfeng 		u32 reg_offset;
79*f39db26cSSui Jingfeng 		u32 reg_size;
80*f39db26cSSui Jingfeng 	} gfxpll;
81*f39db26cSSui Jingfeng 
82*f39db26cSSui Jingfeng 	/* Pixel PLL, per display pipe */
83*f39db26cSSui Jingfeng 	struct {
84*f39db26cSSui Jingfeng 		u32 reg_offset;
85*f39db26cSSui Jingfeng 		u32 reg_size;
86*f39db26cSSui Jingfeng 	} pixpll[LSDC_NUM_CRTC];
87*f39db26cSSui Jingfeng 
88*f39db26cSSui Jingfeng 	enum loongson_chip_id chip_id;
89*f39db26cSSui Jingfeng 	char model[64];
90*f39db26cSSui Jingfeng };
91*f39db26cSSui Jingfeng 
92*f39db26cSSui Jingfeng static inline const struct loongson_gfx_desc *
to_loongson_gfx(const struct lsdc_desc * dcp)93*f39db26cSSui Jingfeng to_loongson_gfx(const struct lsdc_desc *dcp)
94*f39db26cSSui Jingfeng {
95*f39db26cSSui Jingfeng 	return container_of_const(dcp, struct loongson_gfx_desc, dc);
96*f39db26cSSui Jingfeng };
97*f39db26cSSui Jingfeng 
98*f39db26cSSui Jingfeng struct lsdc_reg32 {
99*f39db26cSSui Jingfeng 	char *name;
100*f39db26cSSui Jingfeng 	u32 offset;
101*f39db26cSSui Jingfeng };
102*f39db26cSSui Jingfeng 
103*f39db26cSSui Jingfeng /* crtc hardware related ops */
104*f39db26cSSui Jingfeng 
105*f39db26cSSui Jingfeng struct lsdc_crtc;
106*f39db26cSSui Jingfeng 
107*f39db26cSSui Jingfeng struct lsdc_crtc_hw_ops {
108*f39db26cSSui Jingfeng 	void (*enable)(struct lsdc_crtc *lcrtc);
109*f39db26cSSui Jingfeng 	void (*disable)(struct lsdc_crtc *lcrtc);
110*f39db26cSSui Jingfeng 	void (*enable_vblank)(struct lsdc_crtc *lcrtc);
111*f39db26cSSui Jingfeng 	void (*disable_vblank)(struct lsdc_crtc *lcrtc);
112*f39db26cSSui Jingfeng 	void (*flip)(struct lsdc_crtc *lcrtc);
113*f39db26cSSui Jingfeng 	void (*clone)(struct lsdc_crtc *lcrtc);
114*f39db26cSSui Jingfeng 	void (*get_scan_pos)(struct lsdc_crtc *lcrtc, int *hpos, int *vpos);
115*f39db26cSSui Jingfeng 	void (*set_mode)(struct lsdc_crtc *lcrtc, const struct drm_display_mode *mode);
116*f39db26cSSui Jingfeng 	void (*soft_reset)(struct lsdc_crtc *lcrtc);
117*f39db26cSSui Jingfeng 	void (*reset)(struct lsdc_crtc *lcrtc);
118*f39db26cSSui Jingfeng 
119*f39db26cSSui Jingfeng 	u32  (*get_vblank_counter)(struct lsdc_crtc *lcrtc);
120*f39db26cSSui Jingfeng 	void (*set_dma_step)(struct lsdc_crtc *lcrtc, enum lsdc_dma_steps step);
121*f39db26cSSui Jingfeng };
122*f39db26cSSui Jingfeng 
123*f39db26cSSui Jingfeng struct lsdc_crtc {
124*f39db26cSSui Jingfeng 	struct drm_crtc base;
125*f39db26cSSui Jingfeng 	struct lsdc_pixpll pixpll;
126*f39db26cSSui Jingfeng 	struct lsdc_device *ldev;
127*f39db26cSSui Jingfeng 	const struct lsdc_crtc_hw_ops *hw_ops;
128*f39db26cSSui Jingfeng 	const struct lsdc_reg32 *preg;
129*f39db26cSSui Jingfeng 	unsigned int nreg;
130*f39db26cSSui Jingfeng 	struct drm_info_list *p_info_list;
131*f39db26cSSui Jingfeng 	unsigned int n_info_list;
132*f39db26cSSui Jingfeng 	bool has_vblank;
133*f39db26cSSui Jingfeng };
134*f39db26cSSui Jingfeng 
135*f39db26cSSui Jingfeng /* primary plane hardware related ops */
136*f39db26cSSui Jingfeng 
137*f39db26cSSui Jingfeng struct lsdc_primary;
138*f39db26cSSui Jingfeng 
139*f39db26cSSui Jingfeng struct lsdc_primary_plane_ops {
140*f39db26cSSui Jingfeng 	void (*update_fb_addr)(struct lsdc_primary *plane, u64 addr);
141*f39db26cSSui Jingfeng 	void (*update_fb_stride)(struct lsdc_primary *plane, u32 stride);
142*f39db26cSSui Jingfeng 	void (*update_fb_format)(struct lsdc_primary *plane,
143*f39db26cSSui Jingfeng 				 const struct drm_format_info *format);
144*f39db26cSSui Jingfeng };
145*f39db26cSSui Jingfeng 
146*f39db26cSSui Jingfeng struct lsdc_primary {
147*f39db26cSSui Jingfeng 	struct drm_plane base;
148*f39db26cSSui Jingfeng 	const struct lsdc_primary_plane_ops *ops;
149*f39db26cSSui Jingfeng 	struct lsdc_device *ldev;
150*f39db26cSSui Jingfeng };
151*f39db26cSSui Jingfeng 
152*f39db26cSSui Jingfeng /* cursor plane hardware related ops */
153*f39db26cSSui Jingfeng 
154*f39db26cSSui Jingfeng struct lsdc_cursor;
155*f39db26cSSui Jingfeng 
156*f39db26cSSui Jingfeng struct lsdc_cursor_plane_ops {
157*f39db26cSSui Jingfeng 	void (*update_bo_addr)(struct lsdc_cursor *plane, u64 addr);
158*f39db26cSSui Jingfeng 	void (*update_cfg)(struct lsdc_cursor *plane,
159*f39db26cSSui Jingfeng 			   enum lsdc_cursor_size cursor_size,
160*f39db26cSSui Jingfeng 			   enum lsdc_cursor_format);
161*f39db26cSSui Jingfeng 	void (*update_position)(struct lsdc_cursor *plane, int x, int y);
162*f39db26cSSui Jingfeng };
163*f39db26cSSui Jingfeng 
164*f39db26cSSui Jingfeng struct lsdc_cursor {
165*f39db26cSSui Jingfeng 	struct drm_plane base;
166*f39db26cSSui Jingfeng 	const struct lsdc_cursor_plane_ops *ops;
167*f39db26cSSui Jingfeng 	struct lsdc_device *ldev;
168*f39db26cSSui Jingfeng };
169*f39db26cSSui Jingfeng 
170*f39db26cSSui Jingfeng struct lsdc_output {
171*f39db26cSSui Jingfeng 	struct drm_encoder encoder;
172*f39db26cSSui Jingfeng 	struct drm_connector connector;
173*f39db26cSSui Jingfeng };
174*f39db26cSSui Jingfeng 
175*f39db26cSSui Jingfeng static inline struct lsdc_output *
connector_to_lsdc_output(struct drm_connector * connector)176*f39db26cSSui Jingfeng connector_to_lsdc_output(struct drm_connector *connector)
177*f39db26cSSui Jingfeng {
178*f39db26cSSui Jingfeng 	return container_of(connector, struct lsdc_output, connector);
179*f39db26cSSui Jingfeng }
180*f39db26cSSui Jingfeng 
181*f39db26cSSui Jingfeng static inline struct lsdc_output *
encoder_to_lsdc_output(struct drm_encoder * encoder)182*f39db26cSSui Jingfeng encoder_to_lsdc_output(struct drm_encoder *encoder)
183*f39db26cSSui Jingfeng {
184*f39db26cSSui Jingfeng 	return container_of(encoder, struct lsdc_output, encoder);
185*f39db26cSSui Jingfeng }
186*f39db26cSSui Jingfeng 
187*f39db26cSSui Jingfeng struct lsdc_display_pipe {
188*f39db26cSSui Jingfeng 	struct lsdc_crtc crtc;
189*f39db26cSSui Jingfeng 	struct lsdc_primary primary;
190*f39db26cSSui Jingfeng 	struct lsdc_cursor cursor;
191*f39db26cSSui Jingfeng 	struct lsdc_output output;
192*f39db26cSSui Jingfeng 	struct lsdc_i2c *li2c;
193*f39db26cSSui Jingfeng 	unsigned int index;
194*f39db26cSSui Jingfeng };
195*f39db26cSSui Jingfeng 
196*f39db26cSSui Jingfeng static inline struct lsdc_display_pipe *
output_to_display_pipe(struct lsdc_output * output)197*f39db26cSSui Jingfeng output_to_display_pipe(struct lsdc_output *output)
198*f39db26cSSui Jingfeng {
199*f39db26cSSui Jingfeng 	return container_of(output, struct lsdc_display_pipe, output);
200*f39db26cSSui Jingfeng }
201*f39db26cSSui Jingfeng 
202*f39db26cSSui Jingfeng struct lsdc_kms_funcs {
203*f39db26cSSui Jingfeng 	irqreturn_t (*irq_handler)(int irq, void *arg);
204*f39db26cSSui Jingfeng 
205*f39db26cSSui Jingfeng 	int (*create_i2c)(struct drm_device *ddev,
206*f39db26cSSui Jingfeng 			  struct lsdc_display_pipe *dispipe,
207*f39db26cSSui Jingfeng 			  unsigned int index);
208*f39db26cSSui Jingfeng 
209*f39db26cSSui Jingfeng 	int (*output_init)(struct drm_device *ddev,
210*f39db26cSSui Jingfeng 			   struct lsdc_display_pipe *dispipe,
211*f39db26cSSui Jingfeng 			   struct i2c_adapter *ddc,
212*f39db26cSSui Jingfeng 			   unsigned int index);
213*f39db26cSSui Jingfeng 
214*f39db26cSSui Jingfeng 	int (*cursor_plane_init)(struct drm_device *ddev,
215*f39db26cSSui Jingfeng 				 struct drm_plane *plane,
216*f39db26cSSui Jingfeng 				 unsigned int index);
217*f39db26cSSui Jingfeng 
218*f39db26cSSui Jingfeng 	int (*primary_plane_init)(struct drm_device *ddev,
219*f39db26cSSui Jingfeng 				  struct drm_plane *plane,
220*f39db26cSSui Jingfeng 				  unsigned int index);
221*f39db26cSSui Jingfeng 
222*f39db26cSSui Jingfeng 	int (*crtc_init)(struct drm_device *ddev,
223*f39db26cSSui Jingfeng 			 struct drm_crtc *crtc,
224*f39db26cSSui Jingfeng 			 struct drm_plane *primary,
225*f39db26cSSui Jingfeng 			 struct drm_plane *cursor,
226*f39db26cSSui Jingfeng 			 unsigned int index,
227*f39db26cSSui Jingfeng 			 bool has_vblank);
228*f39db26cSSui Jingfeng };
229*f39db26cSSui Jingfeng 
230*f39db26cSSui Jingfeng static inline struct lsdc_crtc *
to_lsdc_crtc(struct drm_crtc * crtc)231*f39db26cSSui Jingfeng to_lsdc_crtc(struct drm_crtc *crtc)
232*f39db26cSSui Jingfeng {
233*f39db26cSSui Jingfeng 	return container_of(crtc, struct lsdc_crtc, base);
234*f39db26cSSui Jingfeng }
235*f39db26cSSui Jingfeng 
236*f39db26cSSui Jingfeng static inline struct lsdc_display_pipe *
crtc_to_display_pipe(struct drm_crtc * crtc)237*f39db26cSSui Jingfeng crtc_to_display_pipe(struct drm_crtc *crtc)
238*f39db26cSSui Jingfeng {
239*f39db26cSSui Jingfeng 	return container_of(crtc, struct lsdc_display_pipe, crtc.base);
240*f39db26cSSui Jingfeng }
241*f39db26cSSui Jingfeng 
242*f39db26cSSui Jingfeng static inline struct lsdc_primary *
to_lsdc_primary(struct drm_plane * plane)243*f39db26cSSui Jingfeng to_lsdc_primary(struct drm_plane *plane)
244*f39db26cSSui Jingfeng {
245*f39db26cSSui Jingfeng 	return container_of(plane, struct lsdc_primary, base);
246*f39db26cSSui Jingfeng }
247*f39db26cSSui Jingfeng 
248*f39db26cSSui Jingfeng static inline struct lsdc_cursor *
to_lsdc_cursor(struct drm_plane * plane)249*f39db26cSSui Jingfeng to_lsdc_cursor(struct drm_plane *plane)
250*f39db26cSSui Jingfeng {
251*f39db26cSSui Jingfeng 	return container_of(plane, struct lsdc_cursor, base);
252*f39db26cSSui Jingfeng }
253*f39db26cSSui Jingfeng 
254*f39db26cSSui Jingfeng struct lsdc_crtc_state {
255*f39db26cSSui Jingfeng 	struct drm_crtc_state base;
256*f39db26cSSui Jingfeng 	struct lsdc_pixpll_parms pparms;
257*f39db26cSSui Jingfeng };
258*f39db26cSSui Jingfeng 
259*f39db26cSSui Jingfeng struct lsdc_gem {
260*f39db26cSSui Jingfeng 	/* @mutex: protect objects list */
261*f39db26cSSui Jingfeng 	struct mutex mutex;
262*f39db26cSSui Jingfeng 	struct list_head objects;
263*f39db26cSSui Jingfeng };
264*f39db26cSSui Jingfeng 
265*f39db26cSSui Jingfeng struct lsdc_device {
266*f39db26cSSui Jingfeng 	struct drm_device base;
267*f39db26cSSui Jingfeng 	struct ttm_device bdev;
268*f39db26cSSui Jingfeng 
269*f39db26cSSui Jingfeng 	/* @descp: features description of the DC variant */
270*f39db26cSSui Jingfeng 	const struct lsdc_desc *descp;
271*f39db26cSSui Jingfeng 	struct pci_dev *dc;
272*f39db26cSSui Jingfeng 	struct pci_dev *gpu;
273*f39db26cSSui Jingfeng 
274*f39db26cSSui Jingfeng 	struct loongson_gfxpll *gfxpll;
275*f39db26cSSui Jingfeng 
276*f39db26cSSui Jingfeng 	/* @reglock: protects concurrent access */
277*f39db26cSSui Jingfeng 	spinlock_t reglock;
278*f39db26cSSui Jingfeng 
279*f39db26cSSui Jingfeng 	void __iomem *reg_base;
280*f39db26cSSui Jingfeng 	resource_size_t vram_base;
281*f39db26cSSui Jingfeng 	resource_size_t vram_size;
282*f39db26cSSui Jingfeng 
283*f39db26cSSui Jingfeng 	resource_size_t gtt_base;
284*f39db26cSSui Jingfeng 	resource_size_t gtt_size;
285*f39db26cSSui Jingfeng 
286*f39db26cSSui Jingfeng 	struct lsdc_display_pipe dispipe[LSDC_NUM_CRTC];
287*f39db26cSSui Jingfeng 
288*f39db26cSSui Jingfeng 	struct lsdc_gem gem;
289*f39db26cSSui Jingfeng 
290*f39db26cSSui Jingfeng 	u32 irq_status;
291*f39db26cSSui Jingfeng 
292*f39db26cSSui Jingfeng 	/* tracking pinned memory */
293*f39db26cSSui Jingfeng 	size_t vram_pinned_size;
294*f39db26cSSui Jingfeng 	size_t gtt_pinned_size;
295*f39db26cSSui Jingfeng 
296*f39db26cSSui Jingfeng 	/* @num_output: count the number of active display pipe */
297*f39db26cSSui Jingfeng 	unsigned int num_output;
298*f39db26cSSui Jingfeng };
299*f39db26cSSui Jingfeng 
tdev_to_ldev(struct ttm_device * bdev)300*f39db26cSSui Jingfeng static inline struct lsdc_device *tdev_to_ldev(struct ttm_device *bdev)
301*f39db26cSSui Jingfeng {
302*f39db26cSSui Jingfeng 	return container_of(bdev, struct lsdc_device, bdev);
303*f39db26cSSui Jingfeng }
304*f39db26cSSui Jingfeng 
to_lsdc(struct drm_device * ddev)305*f39db26cSSui Jingfeng static inline struct lsdc_device *to_lsdc(struct drm_device *ddev)
306*f39db26cSSui Jingfeng {
307*f39db26cSSui Jingfeng 	return container_of(ddev, struct lsdc_device, base);
308*f39db26cSSui Jingfeng }
309*f39db26cSSui Jingfeng 
310*f39db26cSSui Jingfeng static inline struct lsdc_crtc_state *
to_lsdc_crtc_state(struct drm_crtc_state * base)311*f39db26cSSui Jingfeng to_lsdc_crtc_state(struct drm_crtc_state *base)
312*f39db26cSSui Jingfeng {
313*f39db26cSSui Jingfeng 	return container_of(base, struct lsdc_crtc_state, base);
314*f39db26cSSui Jingfeng }
315*f39db26cSSui Jingfeng 
316*f39db26cSSui Jingfeng void lsdc_debugfs_init(struct drm_minor *minor);
317*f39db26cSSui Jingfeng 
318*f39db26cSSui Jingfeng int ls7a1000_crtc_init(struct drm_device *ddev,
319*f39db26cSSui Jingfeng 		       struct drm_crtc *crtc,
320*f39db26cSSui Jingfeng 		       struct drm_plane *primary,
321*f39db26cSSui Jingfeng 		       struct drm_plane *cursor,
322*f39db26cSSui Jingfeng 		       unsigned int index,
323*f39db26cSSui Jingfeng 		       bool no_vblank);
324*f39db26cSSui Jingfeng 
325*f39db26cSSui Jingfeng int ls7a2000_crtc_init(struct drm_device *ddev,
326*f39db26cSSui Jingfeng 		       struct drm_crtc *crtc,
327*f39db26cSSui Jingfeng 		       struct drm_plane *primary,
328*f39db26cSSui Jingfeng 		       struct drm_plane *cursor,
329*f39db26cSSui Jingfeng 		       unsigned int index,
330*f39db26cSSui Jingfeng 		       bool no_vblank);
331*f39db26cSSui Jingfeng 
332*f39db26cSSui Jingfeng int lsdc_primary_plane_init(struct drm_device *ddev,
333*f39db26cSSui Jingfeng 			    struct drm_plane *plane,
334*f39db26cSSui Jingfeng 			    unsigned int index);
335*f39db26cSSui Jingfeng 
336*f39db26cSSui Jingfeng int ls7a1000_cursor_plane_init(struct drm_device *ddev,
337*f39db26cSSui Jingfeng 			       struct drm_plane *plane,
338*f39db26cSSui Jingfeng 			       unsigned int index);
339*f39db26cSSui Jingfeng 
340*f39db26cSSui Jingfeng int ls7a2000_cursor_plane_init(struct drm_device *ddev,
341*f39db26cSSui Jingfeng 			       struct drm_plane *plane,
342*f39db26cSSui Jingfeng 			       unsigned int index);
343*f39db26cSSui Jingfeng 
344*f39db26cSSui Jingfeng /* Registers access helpers */
345*f39db26cSSui Jingfeng 
lsdc_rreg32(struct lsdc_device * ldev,u32 offset)346*f39db26cSSui Jingfeng static inline u32 lsdc_rreg32(struct lsdc_device *ldev, u32 offset)
347*f39db26cSSui Jingfeng {
348*f39db26cSSui Jingfeng 	return readl(ldev->reg_base + offset);
349*f39db26cSSui Jingfeng }
350*f39db26cSSui Jingfeng 
lsdc_wreg32(struct lsdc_device * ldev,u32 offset,u32 val)351*f39db26cSSui Jingfeng static inline void lsdc_wreg32(struct lsdc_device *ldev, u32 offset, u32 val)
352*f39db26cSSui Jingfeng {
353*f39db26cSSui Jingfeng 	writel(val, ldev->reg_base + offset);
354*f39db26cSSui Jingfeng }
355*f39db26cSSui Jingfeng 
lsdc_ureg32_set(struct lsdc_device * ldev,u32 offset,u32 mask)356*f39db26cSSui Jingfeng static inline void lsdc_ureg32_set(struct lsdc_device *ldev,
357*f39db26cSSui Jingfeng 				   u32 offset,
358*f39db26cSSui Jingfeng 				   u32 mask)
359*f39db26cSSui Jingfeng {
360*f39db26cSSui Jingfeng 	void __iomem *addr = ldev->reg_base + offset;
361*f39db26cSSui Jingfeng 	u32 val = readl(addr);
362*f39db26cSSui Jingfeng 
363*f39db26cSSui Jingfeng 	writel(val | mask, addr);
364*f39db26cSSui Jingfeng }
365*f39db26cSSui Jingfeng 
lsdc_ureg32_clr(struct lsdc_device * ldev,u32 offset,u32 mask)366*f39db26cSSui Jingfeng static inline void lsdc_ureg32_clr(struct lsdc_device *ldev,
367*f39db26cSSui Jingfeng 				   u32 offset,
368*f39db26cSSui Jingfeng 				   u32 mask)
369*f39db26cSSui Jingfeng {
370*f39db26cSSui Jingfeng 	void __iomem *addr = ldev->reg_base + offset;
371*f39db26cSSui Jingfeng 	u32 val = readl(addr);
372*f39db26cSSui Jingfeng 
373*f39db26cSSui Jingfeng 	writel(val & ~mask, addr);
374*f39db26cSSui Jingfeng }
375*f39db26cSSui Jingfeng 
lsdc_pipe_rreg32(struct lsdc_device * ldev,u32 offset,u32 pipe)376*f39db26cSSui Jingfeng static inline u32 lsdc_pipe_rreg32(struct lsdc_device *ldev,
377*f39db26cSSui Jingfeng 				   u32 offset, u32 pipe)
378*f39db26cSSui Jingfeng {
379*f39db26cSSui Jingfeng 	return readl(ldev->reg_base + offset + pipe * CRTC_PIPE_OFFSET);
380*f39db26cSSui Jingfeng }
381*f39db26cSSui Jingfeng 
lsdc_pipe_wreg32(struct lsdc_device * ldev,u32 offset,u32 pipe,u32 val)382*f39db26cSSui Jingfeng static inline void lsdc_pipe_wreg32(struct lsdc_device *ldev,
383*f39db26cSSui Jingfeng 				    u32 offset, u32 pipe, u32 val)
384*f39db26cSSui Jingfeng {
385*f39db26cSSui Jingfeng 	writel(val, ldev->reg_base + offset + pipe * CRTC_PIPE_OFFSET);
386*f39db26cSSui Jingfeng }
387*f39db26cSSui Jingfeng 
388*f39db26cSSui Jingfeng #endif
389