1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
|
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2023 Loongson Technology Corporation Limited
*/
#ifndef __LSDC_REGS_H__
#define __LSDC_REGS_H__
#include <linux/bitops.h>
#include <linux/types.h>
/*
* PIXEL PLL Reference clock
*/
#define LSDC_PLL_REF_CLK_KHZ 100000
/*
* Those PLL registers are relative to LSxxxxx_CFG_REG_BASE. xxxxx = 7A1000,
* 7A2000, 2K2000, 2K1000 etc.
*/
/* LS7A1000 */
#define LS7A1000_PIXPLL0_REG 0x04B0
#define LS7A1000_PIXPLL1_REG 0x04C0
/* The DC, GPU, Graphic Memory Controller share the single gfxpll */
#define LS7A1000_PLL_GFX_REG 0x0490
#define LS7A1000_CONF_REG_BASE 0x10010000
/* LS7A2000 */
#define LS7A2000_PIXPLL0_REG 0x04B0
#define LS7A2000_PIXPLL1_REG 0x04C0
/* The DC, GPU, Graphic Memory Controller share the single gfxpll */
#define LS7A2000_PLL_GFX_REG 0x0490
#define LS7A2000_CONF_REG_BASE 0x10010000
/* For LSDC_CRTCx_CFG_REG */
#define CFG_PIX_FMT_MASK GENMASK(2, 0)
enum lsdc_pixel_format {
LSDC_PF_NONE = 0,
LSDC_PF_XRGB444 = 1, /* [12 bits] */
LSDC_PF_XRGB555 = 2, /* [15 bits] */
LSDC_PF_XRGB565 = 3, /* RGB [16 bits] */
LSDC_PF_XRGB8888 = 4, /* XRGB [32 bits] */
};
/*
* Each crtc has two set fb address registers usable, FB_REG_IN_USING bit of
* LSDC_CRTCx_CFG_REG indicate which fb address register is in using by the
* CRTC currently. CFG_PAGE_FLIP is used to trigger the switch, the switching
* will be finished at the very next vblank. Trigger it again if you want to
* switch back.
*
* If FB0_ADDR_REG is in using, we write the address to FB0_ADDR_REG,
* if FB1_ADDR_REG is in using, we write the address to FB1_ADDR_REG.
*/
#define CFG_PAGE_FLIP BIT(7)
#define CFG_OUTPUT_ENABLE BIT(8)
#define CFG_HW_CLONE BIT(9)
/* Indicate witch fb addr reg is in using, currently. read only */
#define FB_REG_IN_USING BIT(11)
#define CFG_GAMMA_EN BIT(12)
/* The DC get soft reset if this bit changed from "1" to "0", active low */
#define CFG_RESET_N BIT(20)
/* If this bit is set, it say that the CRTC stop working anymore, anchored. */
#define CRTC_ANCHORED BIT(24)
/*
* The DMA step of the DC in LS7A2000/LS2K2000 is configurable,
* setting those bits on ls7a1000 platform make no effect.
*/
#define CFG_DMA_STEP_MASK GENMASK(17, 16)
#define CFG_DMA_STEP_SHIFT 16
enum lsdc_dma_steps {
LSDC_DMA_STEP_256_BYTES = 0,
LSDC_DMA_STEP_128_BYTES = 1,
LSDC_DMA_STEP_64_BYTES = 2,
LSDC_DMA_STEP_32_BYTES = 3,
};
#define CFG_VALID_BITS_MASK GENMASK(20, 0)
/* For LSDC_CRTCx_HSYNC_REG */
#define HSYNC_INV BIT(31)
#define HSYNC_EN BIT(30)
#define HSYNC_END_MASK GENMASK(28, 16)
#define HSYNC_END_SHIFT 16
#define HSYNC_START_MASK GENMASK(12, 0)
#define HSYNC_START_SHIFT 0
/* For LSDC_CRTCx_VSYNC_REG */
#define VSYNC_INV BIT(31)
#define VSYNC_EN BIT(30)
#define VSYNC_END_MASK GENMASK(27, 16)
#define VSYNC_END_SHIFT 16
#define VSYNC_START_MASK GENMASK(11, 0)
#define VSYNC_START_SHIFT 0
/*********** CRTC0 ***********/
#define LSDC_CRTC0_CFG_REG 0x1240
#define LSDC_CRTC0_FB0_ADDR_LO_REG 0x1260
#define LSDC_CRTC0_FB0_ADDR_HI_REG 0x15A0
#define LSDC_CRTC0_STRIDE_REG 0x1280
#define LSDC_CRTC0_FB_ORIGIN_REG 0x1300
#define LSDC_CRTC0_HDISPLAY_REG 0x1400
#define LSDC_CRTC0_HSYNC_REG 0x1420
#define LSDC_CRTC0_VDISPLAY_REG 0x1480
#define LSDC_CRTC0_VSYNC_REG 0x14A0
#define LSDC_CRTC0_GAMMA_INDEX_REG 0x14E0
#define LSDC_CRTC0_GAMMA_DATA_REG 0x1500
#define LSDC_CRTC0_FB1_ADDR_LO_REG 0x1580
#define LSDC_CRTC0_FB1_ADDR_HI_REG 0x15C0
/*********** CRTC1 ***********/
#define LSDC_CRTC1_CFG_REG 0x1250
#define LSDC_CRTC1_FB0_ADDR_LO_REG 0x1270
#define LSDC_CRTC1_FB0_ADDR_HI_REG 0x15B0
#define LSDC_CRTC1_STRIDE_REG 0x1290
#define LSDC_CRTC1_FB_ORIGIN_REG 0x1310
#define LSDC_CRTC1_HDISPLAY_REG 0x1410
#define LSDC_CRTC1_HSYNC_REG 0x1430
#define LSDC_CRTC1_VDISPLAY_REG 0x1490
#define LSDC_CRTC1_VSYNC_REG 0x14B0
#define LSDC_CRTC1_GAMMA_INDEX_REG 0x14F0
#define LSDC_CRTC1_GAMMA_DATA_REG 0x1510
#define LSDC_CRTC1_FB1_ADDR_LO_REG 0x1590
#define LSDC_CRTC1_FB1_ADDR_HI_REG 0x15D0
/* For LSDC_CRTCx_DVO_CONF_REG */
#define PHY_CLOCK_POL BIT(9)
#define PHY_CLOCK_EN BIT(8)
#define PHY_DE_POL BIT(1)
#define PHY_DATA_EN BIT(0)
/*********** DVO0 ***********/
#define LSDC_CRTC0_DVO_CONF_REG 0x13C0
/*********** DVO1 ***********/
#define LSDC_CRTC1_DVO_CONF_REG 0x13D0
/*
* All of the DC variants has the hardware which record the scan position
* of the CRTC, [31:16] : current X position, [15:0] : current Y position
*/
#define LSDC_CRTC0_SCAN_POS_REG 0x14C0
#define LSDC_CRTC1_SCAN_POS_REG 0x14D0
/*
* LS7A2000 has Sync Deviation register.
*/
#define SYNC_DEVIATION_EN BIT(31)
#define SYNC_DEVIATION_NUM GENMASK(12, 0)
#define LSDC_CRTC0_SYNC_DEVIATION_REG 0x1B80
#define LSDC_CRTC1_SYNC_DEVIATION_REG 0x1B90
/*
* In gross, LSDC_CRTC1_XXX_REG - LSDC_CRTC0_XXX_REG = 0x10, but not all of
* the registers obey this rule, LSDC_CURSORx_XXX_REG just don't honor this.
* This is the root cause we can't untangle the code by manpulating offset
* of the register access simply. Our hardware engineers are lack experiance
* when they design this...
*/
#define CRTC_PIPE_OFFSET 0x10
/*
* There is only one hardware cursor unit in LS7A1000 and LS2K1000, let
* CFG_HW_CLONE_EN bit be "1" could eliminate this embarrassment, we made
* it on custom clone mode application. While LS7A2000 has two hardware
* cursor unit which is good enough.
*/
#define CURSOR_FORMAT_MASK GENMASK(1, 0)
#define CURSOR_FORMAT_SHIFT 0
enum lsdc_cursor_format {
CURSOR_FORMAT_DISABLE = 0,
CURSOR_FORMAT_MONOCHROME = 1, /* masked */
CURSOR_FORMAT_ARGB8888 = 2, /* A8R8G8B8 */
};
/*
* LS7A1000 and LS2K1000 only support 32x32, LS2K2000 and LS7A2000 support
* 64x64, but it seems that setting this bit make no harms on LS7A1000, it
* just don't take effects.
*/
#define CURSOR_SIZE_SHIFT 2
enum lsdc_cursor_size {
CURSOR_SIZE_32X32 = 0,
CURSOR_SIZE_64X64 = 1,
};
#define CURSOR_LOCATION_SHIFT 4
enum lsdc_cursor_location {
CURSOR_ON_CRTC0 = 0,
CURSOR_ON_CRTC1 = 1,
};
#define LSDC_CURSOR0_CFG_REG 0x1520
#define LSDC_CURSOR0_ADDR_LO_REG 0x1530
#define LSDC_CURSOR0_ADDR_HI_REG 0x15e0
#define LSDC_CURSOR0_POSITION_REG 0x1540 /* [31:16] Y, [15:0] X */
#define LSDC_CURSOR0_BG_COLOR_REG 0x1550 /* background color */
#define LSDC_CURSOR0_FG_COLOR_REG 0x1560 /* foreground color */
#define LSDC_CURSOR1_CFG_REG 0x1670
#define LSDC_CURSOR1_ADDR_LO_REG 0x1680
#define LSDC_CURSOR1_ADDR_HI_REG 0x16e0
#define LSDC_CURSOR1_POSITION_REG 0x1690 /* [31:16] Y, [15:0] X */
#define LSDC_CURSOR1_BG_COLOR_REG 0x16A0 /* background color */
#define LSDC_CURSOR1_FG_COLOR_REG 0x16B0 /* foreground color */
/*
* DC Interrupt Control Register, 32bit, Address Offset: 1570
*
* Bits 15:0 inidicate the interrupt status
* Bits 31:16 control enable interrupts corresponding to bit 15:0 or not
* Write 1 to enable, write 0 to disable
*
* RF: Read Finished
* IDBU: Internal Data Buffer Underflow
* IDBFU: Internal Data Buffer Fatal Underflow
* CBRF: Cursor Buffer Read Finished Flag, no use.
* FBRF0: CRTC-0 reading from its framebuffer finished.
* FBRF1: CRTC-1 reading from its framebuffer finished.
*
* +-------+--------------------------+-------+--------+--------+-------+
* | 31:27 | 26:16 | 15:11 | 10 | 9 | 8 |
* +-------+--------------------------+-------+--------+--------+-------+
* | N/A | Interrupt Enable Control | N/A | IDBFU0 | IDBFU1 | IDBU0 |
* +-------+--------------------------+-------+--------+--------+-------+
*
* +-------+-------+-------+------+--------+--------+--------+--------+
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
* +-------+-------+-------+------+--------+--------+--------+--------+
* | IDBU1 | FBRF0 | FBRF1 | CRRF | HSYNC0 | VSYNC0 | HSYNC1 | VSYNC1 |
* +-------+-------+-------+------+--------+--------+--------+--------+
*
* unfortunately, CRTC0's interrupt is mess with CRTC1's interrupt in one
* register again.
*/
#define LSDC_INT_REG 0x1570
#define INT_CRTC0_VSYNC BIT(2)
#define INT_CRTC0_HSYNC BIT(3)
#define INT_CRTC0_RF BIT(6)
#define INT_CRTC0_IDBU BIT(8)
#define INT_CRTC0_IDBFU BIT(10)
#define INT_CRTC1_VSYNC BIT(0)
#define INT_CRTC1_HSYNC BIT(1)
#define INT_CRTC1_RF BIT(5)
#define INT_CRTC1_IDBU BIT(7)
#define INT_CRTC1_IDBFU BIT(9)
#define INT_CRTC0_VSYNC_EN BIT(18)
#define INT_CRTC0_HSYNC_EN BIT(19)
#define INT_CRTC0_RF_EN BIT(22)
#define INT_CRTC0_IDBU_EN BIT(24)
#define INT_CRTC0_IDBFU_EN BIT(26)
#define INT_CRTC1_VSYNC_EN BIT(16)
#define INT_CRTC1_HSYNC_EN BIT(17)
#define INT_CRTC1_RF_EN BIT(21)
#define INT_CRTC1_IDBU_EN BIT(23)
#define INT_CRTC1_IDBFU_EN BIT(25)
#define INT_STATUS_MASK GENMASK(15, 0)
/*
* LS7A1000/LS7A2000 have 4 gpios which are used to emulated I2C.
* They are under control of the LS7A_DC_GPIO_DAT_REG and LS7A_DC_GPIO_DIR_REG
* register, Those GPIOs has no relationship whth the GPIO hardware on the
* bridge chip itself. Those offsets are relative to DC register base address
*
* LS2k1000 don't have those registers, they use hardware i2c or general GPIO
* emulated i2c from linux i2c subsystem.
*
* GPIO data register, address offset: 0x1650
* +---------------+-----------+-----------+
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
* +---------------+-----------+-----------+
* | | DVO1 | DVO0 |
* + N/A +-----------+-----------+
* | | SCL | SDA | SCL | SDA |
* +---------------+-----------+-----------+
*/
#define LS7A_DC_GPIO_DAT_REG 0x1650
/*
* GPIO Input/Output direction control register, address offset: 0x1660
*/
#define LS7A_DC_GPIO_DIR_REG 0x1660
/*
* LS7A2000 has two built-in HDMI Encoder and one VGA encoder
*/
/*
* Number of continuous packets may be present
* in HDMI hblank and vblank zone, should >= 48
*/
#define LSDC_HDMI0_ZONE_REG 0x1700
#define LSDC_HDMI1_ZONE_REG 0x1710
#define HDMI_H_ZONE_IDLE_SHIFT 0
#define HDMI_V_ZONE_IDLE_SHIFT 16
/* HDMI Iterface Control Reg */
#define HDMI_INTERFACE_EN BIT(0)
#define HDMI_PACKET_EN BIT(1)
#define HDMI_AUDIO_EN BIT(2)
/*
* Preamble:
* Immediately preceding each video data period or data island period is the
* preamble. This is a sequence of eight identical control characters that
* indicate whether the upcoming data period is a video data period or is a
* data island. The values of CTL0, CTL1, CTL2, and CTL3 indicate the type of
* data period that follows.
*/
#define HDMI_VIDEO_PREAMBLE_MASK GENMASK(7, 4)
#define HDMI_VIDEO_PREAMBLE_SHIFT 4
/* 1: hw i2c, 0: gpio emu i2c, shouldn't put in LSDC_HDMIx_INTF_CTRL_REG */
#define HW_I2C_EN BIT(8)
#define HDMI_CTL_PERIOD_MODE BIT(9)
#define LSDC_HDMI0_INTF_CTRL_REG 0x1720
#define LSDC_HDMI1_INTF_CTRL_REG 0x1730
#define HDMI_PHY_EN BIT(0)
#define HDMI_PHY_RESET_N BIT(1)
#define HDMI_PHY_TERM_L_EN BIT(8)
#define HDMI_PHY_TERM_H_EN BIT(9)
#define HDMI_PHY_TERM_DET_EN BIT(10)
#define HDMI_PHY_TERM_STATUS BIT(11)
#define LSDC_HDMI0_PHY_CTRL_REG 0x1800
#define LSDC_HDMI1_PHY_CTRL_REG 0x1810
/* High level duration need > 1us */
#define HDMI_PLL_ENABLE BIT(0)
#define HDMI_PLL_LOCKED BIT(16)
/* Bypass the software configured values, using default source from somewhere */
#define HDMI_PLL_BYPASS BIT(17)
#define HDMI_PLL_IDF_SHIFT 1
#define HDMI_PLL_IDF_MASK GENMASK(5, 1)
#define HDMI_PLL_LF_SHIFT 6
#define HDMI_PLL_LF_MASK GENMASK(12, 6)
#define HDMI_PLL_ODF_SHIFT 13
#define HDMI_PLL_ODF_MASK GENMASK(15, 13)
#define LSDC_HDMI0_PHY_PLL_REG 0x1820
#define LSDC_HDMI1_PHY_PLL_REG 0x1830
/* LS7A2000/LS2K2000 has hpd status reg, while the two hdmi's status
* located at the one register again.
*/
#define LSDC_HDMI_HPD_STATUS_REG 0x1BA0
#define HDMI0_HPD_FLAG BIT(0)
#define HDMI1_HPD_FLAG BIT(1)
#define LSDC_HDMI0_PHY_CAL_REG 0x18C0
#define LSDC_HDMI1_PHY_CAL_REG 0x18D0
/* AVI InfoFrame */
#define LSDC_HDMI0_AVI_CONTENT0 0x18E0
#define LSDC_HDMI1_AVI_CONTENT0 0x18D0
#define LSDC_HDMI0_AVI_CONTENT1 0x1900
#define LSDC_HDMI1_AVI_CONTENT1 0x1910
#define LSDC_HDMI0_AVI_CONTENT2 0x1920
#define LSDC_HDMI1_AVI_CONTENT2 0x1930
#define LSDC_HDMI0_AVI_CONTENT3 0x1940
#define LSDC_HDMI1_AVI_CONTENT3 0x1950
/* 1: enable avi infoframe packet, 0: disable avi infoframe packet */
#define AVI_PKT_ENABLE BIT(0)
/* 1: send one every two frame, 0: send one each frame */
#define AVI_PKT_SEND_FREQ BIT(1)
/*
* 1: write 1 to flush avi reg content0 ~ content3 to the packet to be send,
* The hardware will clear this bit automatically.
*/
#define AVI_PKT_UPDATE BIT(2)
#define LSDC_HDMI0_AVI_INFO_CRTL_REG 0x1960
#define LSDC_HDMI1_AVI_INFO_CRTL_REG 0x1970
/*
* LS7A2000 has the hardware which count the number of vblank generated
*/
#define LSDC_CRTC0_VSYNC_COUNTER_REG 0x1A00
#define LSDC_CRTC1_VSYNC_COUNTER_REG 0x1A10
/*
* LS7A2000 has the audio hardware associate with the HDMI encoder.
*/
#define LSDC_HDMI0_AUDIO_PLL_LO_REG 0x1A20
#define LSDC_HDMI1_AUDIO_PLL_LO_REG 0x1A30
#define LSDC_HDMI0_AUDIO_PLL_HI_REG 0x1A40
#define LSDC_HDMI1_AUDIO_PLL_HI_REG 0x1A50
#endif
|