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