1 #ifndef __LOONGSON_DRV_H__
2 #define __LOONGSON_DRV_H__
3
4 #include <linux/i2c.h>
5 #include <linux/i2c-algo-bit.h>
6 #include <linux/module.h>
7 #include <linux/types.h>
8
9 #include <drm/drm_drv.h>
10 #include <drm/drm_encoder.h>
11 #include <drm/drm_fb_helper.h>
12 #include <drm/drm_gem.h>
13 #include <drm/drm_irq.h>
14 #include <drm/drm_vblank.h>
15
16 #include <loongson.h>
17 #include "loongson_i2c.h"
18 #include "loongson_vbios.h"
19
20 #define to_loongson_crtc(x) container_of(x, struct loongson_crtc, base)
21 #define to_loongson_encoder(x) container_of(x, struct loongson_encoder, base)
22 #define to_loongson_connector(x) container_of(x, struct loongson_connector, base)
23
24 #define LOONGSON_MAX_FB_HEIGHT 4096
25 #define LOONGSON_MAX_FB_WIDTH 4096
26
27 #define CUR_WIDTH_SIZE 32
28 #define CUR_HEIGHT_SIZE 32
29
30 #define LO_OFF 0
31 #define HI_OFF 8
32
33 #define LS7A_PIX0_PLL (void *)TO_UNCACHE(LS7A_CHIPCFG_REG_BASE + 0x04b0)
34 #define LS7A_PIX1_PLL (void *)TO_UNCACHE(LS7A_CHIPCFG_REG_BASE + 0x04c0)
35
36 #define CURIOSET_CORLOR 0x4607
37 #define CURIOSET_POSITION 0x4608
38 #define CURIOLOAD_ARGB 0x4609
39 #define CURIOLOAD_IMAGE 0x460A
40 #define CURIOHIDE_SHOW 0x460B
41 #define FBEDID_GET 0X860C
42
43 #define CRTC_REG_OFFSET 0x10
44
45 #define CFG_FMT GENMASK(2,0)
46 #define CFG_FBSWITCH BIT(7)
47 #define CFG_ENABLE BIT(8)
48 #define CFG_PANELSWITCH BIT(9)
49 #define CFG_FBNUM_BIT 11
50 #define CFG_FBNUM BIT(11)
51 #define CFG_GAMMAR BIT(12)
52 #define CFG_RESET BIT(20)
53
54 #define FB_CFG_DVO_REG (0x1240)
55 #define FB_ADDR0_DVO_REG (0x1260)
56 #define FB_ADDR1_DVO_REG (0x1580)
57 #define FB_STRI_DVO_REG (0x1280)
58 #define FB_DITCFG_DVO_REG (0x1360)
59 #define FB_DITTAB_LO_DVO_REG (0x1380)
60 #define FB_DITTAB_HI_DVO_REG (0x13a0)
61 #define FB_PANCFG_DVO_REG (0x13c0)
62 #define FB_PANTIM_DVO_REG (0x13e0)
63 #define FB_HDISPLAY_DVO_REG (0x1400)
64 #define FB_HSYNC_DVO_REG (0x1420)
65 #define FB_VDISPLAY_DVO_REG (0x1480)
66 #define FB_VSYNC_DVO_REG (0x14a0)
67 #define FB_GAMINDEX_DVO_REG (0x14e0)
68 #define FB_GAMDATA_DVO_REG (0x1500)
69
70 #define HDMI_ZONEIDLE_REG (0x1700)
71 #define HDMI_CTRL_REG (0x1720)
72
73 #define HDMI_AUDIO_BUF_REG (0x1740)
74 #define HDMI_AUDIO_NCFG_REG (0x1760)
75 #define HDMI_AUDIO_CTSCFG_REG (0x1780)
76 #define HDMI_AUDIO_CTSCALCFG_REG (0x17a0)
77 #define HDMI_AUDIO_INFOFRAME_REG (0x17c0)
78 #define HDMI_AUDIO_SAMPLE_REG (0x17e0)
79
80 #define HDMI_PHY_CTRL_REG (0x1800)
81 #define HDMI_PHY_PLLCFG_REG (0x1820)
82
83 #define FB_CUR_CFG_REG (0x1520)
84 #define FB_CUR_ADDR_REG (0x1530)
85 #define FB_CUR_LOC_ADDR_REG (0x1540)
86 #define FB_CUR_BACK_REG (0x1550)
87 #define FB_CUR_FORE_REG (0x1560)
88 #define FB_INT_REG (0x1570)
89
90 #define INT_DVO1_VSYNC 0
91 #define INT_DVO1_HSYNC 1
92 #define INT_DVO0_VSYNC 2
93 #define INT_DVO0_HSYNC 3
94 #define INT_CURSOR_FB_END 4
95 #define INT_DVO1_FB_END 5
96 #define INT_DVO0_FB_END 6
97
98 #define MAX_CRTC 2
99
100 enum loongson_chip {
101 dc_7a1000,
102 dc_7a2000
103 };
104
105 struct pix_pll {
106 unsigned int l2_div;
107 unsigned int l1_loopc;
108 unsigned int l1_frefc;
109 };
110
111 struct config_reg {
112 u8 dev_addr;
113 u8 reg;
114 u8 value;
115 } __packed;
116
117 struct cfg_encoder {
118 u8 reg_num;
119 u32 hdisplay;
120 u32 vdisplay;
121 struct config_reg config_regs[256];
122 };
123
124 struct loongson_crtc {
125 struct drm_crtc base;
126 unsigned int crtc_id;
127 uint32_t cfg_reg;
128 struct drm_plane *primary; /* Primary panel belongs to this crtc */
129 struct drm_pending_vblank_event *event;
130 struct loongson_drm_device *ldev;
131 };
132
133 struct loongson_encoder {
134 struct drm_encoder base;
135 u32 type;
136 u32 i2c_id;
137 int encoder_id;
138 struct loongson_i2c *i2c;
139 struct loongson_crtc *lcrtc; /* Binding crtc, not actual one */
140 };
141
142 struct loongson_connector {
143 struct drm_connector base;
144 u16 id;
145 u32 type;
146 u16 i2c_id;
147 u16 hotplug;
148 u16 edid_method;
149 u8 *vbios_edid;
150 struct loongson_i2c *i2c;
151 struct loongson_drm_device *ldev;
152 };
153
154 struct loongson_mode_info {
155 bool mode_config_initialized;
156 struct loongson_crtc *crtc;
157 struct loongson_encoder *encoder;
158 struct loongson_connector *connector;
159 };
160
161 struct loongson_drm_device {
162 struct drm_device *dev;
163 struct drm_atomic_state *state;
164 struct pci_dev *gpu_pdev; /* LS7A gpu device info */
165
166 resource_size_t mmio_base;
167 resource_size_t mmio_size;
168 void __iomem *mmio;
169 uint32_t int_reg;
170
171 struct drm_display_mode mode;
172 struct loongson_mode_info mode_info[2];
173 struct drm_gem_cma_object *cursor;
174
175 int num_crtc;
176 struct loongson_crtc lcrtc[MAX_CRTC];
177 struct loongson_i2c i2c_bus[DC_I2C_BUS_MAX];
178
179 void *vbios;
180 struct list_head desc_list;
181
182 bool inited;
183 bool suspended;
184 bool cursor_showed;
185 int cursor_crtc_id;
186
187 int connector_active0;
188 int connector_active1;
189
190 enum loongson_chip chip;
191 };
192
193 extern spinlock_t loongson_reglock;
194
195 /* FIXME: LS7A2000's switch_panel is not available, just return false. */
clone_mode(struct loongson_drm_device *ldev)196 static inline bool clone_mode(struct loongson_drm_device *ldev)
197 {
198 return false;
199
200 if (ldev->num_crtc < 2)
201 return true;
202 if (ldev->mode_info[0].connector->base.status != connector_status_connected)
203 return true;
204 if (ldev->mode_info[1].connector->base.status != connector_status_connected)
205 return true;
206 if (ldev->lcrtc[0].base.x || ldev->lcrtc[0].base.y)
207 return false;
208 if (ldev->lcrtc[1].base.x || ldev->lcrtc[1].base.y)
209 return false;
210
211 return true;
212 }
213
214 int loongson_irq_enable_vblank(struct drm_device *dev,unsigned int crtc_id);
215 void loongson_irq_disable_vblank(struct drm_device *dev,unsigned int crtc_id);
216 irqreturn_t loongson_irq_handler(int irq,void *arg);
217 void loongson_irq_preinstall(struct drm_device *dev);
218 int loongson_irq_postinstall(struct drm_device *dev);
219 void loongson_irq_uninstall(struct drm_device *dev);
220
221 u32 crtc_read(struct loongson_crtc *lcrtc, u32 offset);
222 void crtc_write(struct loongson_crtc *lcrtc, u32 offset, u32 val);
223
224 int loongson_gpio_init(struct loongson_drm_device *ldev);
225 int loongson_crtc_init(struct loongson_drm_device *ldev);
226 struct drm_encoder *loongson_encoder_init(struct drm_device *dev, unsigned int index);
227 struct drm_connector *loongson_connector_init(struct drm_device *dev, unsigned int index);
228
229 int loongson_fbdev_init(struct loongson_drm_device *ldev);
230 void loongson_fbdev_fini(struct loongson_drm_device *ldev);
231 void loongson_fbdev_restore_mode(struct loongson_drm_device *ldev);
232
233 int loongson_drm_drm_suspend(struct drm_device *dev, bool suspend,
234 bool fbcon, bool freeze);
235 int loongson_drm_drm_resume(struct drm_device *dev, bool resume, bool fbcon);
236 /* loongson_cursor.c */
237 int loongson_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
238 uint32_t handle, uint32_t width, uint32_t height, int32_t hot_x, int32_t hot_y);
239 int loongson_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
240
241 #endif
242