lsdc_drv.h 9.2 KB

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