tangled
alpha
login
or
join now
jcs.org
/
openbsd-src
0
fork
atom
jcs's openbsd hax
openbsd
0
fork
atom
overview
issues
pulls
pipelines
rkvop: add rk3126 support
jcs.org
1 week ago
bf506c76
7f4c7fda
+329
-102
1 changed file
expand all
collapse all
unified
split
sys
dev
fdt
rkvop.c
+329
-102
sys/dev/fdt/rkvop.c
reviewed
···
37
37
#include <dev/ofw/ofw_clock.h>
38
38
#include <dev/ofw/ofw_gpio.h>
39
39
#include <dev/ofw/ofw_misc.h>
40
40
+
#include <dev/ofw/ofw_power.h>
40
41
#include <dev/ofw/fdt.h>
41
42
42
43
#include <drm/drm_atomic.h>
···
48
49
49
50
#include <dev/fdt/rkdrm.h>
50
51
52
52
+
/* RK3399 VOP registers */
51
53
#define VOP_REG_CFG_DONE 0x0000
52
54
#define REG_LOAD_EN (1 << 0)
53
55
#define VOP_SYS_CTRL 0x0008
···
105
107
#define DSP_VACT_ST(x) (((x) & 0x1fff) << 16)
106
108
#define DSP_VACT_END(x) (((x) & 0x1fff) << 0)
107
109
110
110
+
/* RK3036/RK3126 VOP registers */
111
111
+
#define RK3036_SYS_CTRL 0x00
112
112
+
#define RK3036_STANDBY_EN (1 << 30)
113
113
+
#define RK3036_DSP_CTRL0 0x04
114
114
+
#define RK3036_DSP_CTRL1 0x08
115
115
+
#define RK3036_DSP_BLANK_EN (1 << 24)
116
116
+
#define RK3036_DSP_BLACK_EN (1 << 25)
117
117
+
#define RK3036_DSP_OUT_ZERO (1 << 31)
118
118
+
#define RK3036_DSP_BG 0x0c
119
119
+
#define RK3036_INT_STATUS 0x10
120
120
+
#define RK3036_ALPHA_CTRL 0x14
121
121
+
#define RK3036_WIN0_COLOR_KEY 0x18
122
122
+
#define RK3036_WIN0_YRGB_MST 0x20
123
123
+
#define RK3036_AXI_BUS_CTRL 0x2c
124
124
+
#define RK3036_HDMI_DCLK_EN (1 << 22)
125
125
+
#define RK3036_RGB_DCLK_EN (1 << 24)
126
126
+
#define RK3036_LVDS_DCLK_EN (1 << 26) /* rk312x */
127
127
+
#define RK3036_LVDS_DCLK_INVERT (1 << 27) /* rk312x */
128
128
+
#define RK3036_MIPI_DCLK_EN (1 << 28)
129
129
+
#define RK3036_HDMI_OUT_EN RK3036_HDMI_DCLK_EN
130
130
+
#define RK3036_RGB_OUT_EN RK3036_RGB_DCLK_EN
131
131
+
#define RK3036_MIPI_OUT_EN RK3036_MIPI_DCLK_EN
132
132
+
#define RK3036_WIN0_VIR 0x30
133
133
+
#define RK3036_WIN0_ACT_INFO 0x34
134
134
+
#define RK3036_WIN0_DSP_INFO 0x38
135
135
+
#define RK3036_WIN0_DSP_ST 0x3c
136
136
+
#define RK3036_DSP_HTOTAL_HS_END 0x6c
137
137
+
#define RK3036_DSP_HACT_ST_END 0x70
138
138
+
#define RK3036_DSP_VTOTAL_VS_END 0x74
139
139
+
#define RK3036_DSP_VACT_ST_END 0x78
140
140
+
#define RK3036_REG_CFG_DONE 0x90
141
141
+
108
142
/*
109
143
* Polarity fields are in different locations depending on SoC and output type,
110
144
* but always in the same order.
···
120
154
VOP_EP_HDMI,
121
155
VOP_EP_MIPI1,
122
156
VOP_EP_DP,
157
157
+
VOP_EP_LVDS,
158
158
+
VOP_EP_RGB,
123
159
VOP_NEP
160
160
+
};
161
161
+
162
162
+
enum rkvop_type {
163
163
+
VOP_RK3399,
164
164
+
VOP_RK3126,
124
165
};
125
166
126
167
struct rkvop_softc;
···
152
193
153
194
struct rkvop_config {
154
195
char *descr;
196
196
+
enum rkvop_type type;
155
197
u_int out_mode;
156
198
void (*init)(struct rkvop_softc *);
157
199
void (*set_polarity)(struct rkvop_softc *,
···
167
209
168
210
void rk3399_vop_init(struct rkvop_softc *);
169
211
void rk3399_vop_set_polarity(struct rkvop_softc *, enum vop_ep_type, uint32_t);
212
212
+
void rk3126_vop_init(struct rkvop_softc *);
213
213
+
void rk3126_vop_set_polarity(struct rkvop_softc *, enum vop_ep_type, uint32_t);
170
214
171
215
int rkvop_ep_activate(void *, struct endpoint *, void *);
172
216
void *rkvop_ep_get_cookie(void *, struct endpoint *);
173
217
174
218
struct rkvop_config rk3399_vop_big_config = {
175
219
.descr = "RK3399 VOPB",
220
220
+
.type = VOP_RK3399,
176
221
.out_mode = DSP_OUT_MODE_RGBaaa,
177
222
.init = rk3399_vop_init,
178
223
.set_polarity = rk3399_vop_set_polarity,
···
180
225
181
226
struct rkvop_config rk3399_vop_lit_config = {
182
227
.descr = "RK3399 VOPL",
228
228
+
.type = VOP_RK3399,
183
229
.out_mode = DSP_OUT_MODE_RGB888,
184
230
.init = rk3399_vop_init,
185
231
.set_polarity = rk3399_vop_set_polarity,
232
232
+
};
233
233
+
234
234
+
struct rkvop_config rk3126_vop_config = {
235
235
+
.descr = "RK3126 VOP",
236
236
+
.type = VOP_RK3126,
237
237
+
.out_mode = DSP_OUT_MODE_RGB888,
238
238
+
.init = rk3126_vop_init,
239
239
+
.set_polarity = rk3126_vop_set_polarity,
186
240
};
187
241
188
242
const struct cfattach rkvop_ca = {
···
199
253
struct fdt_attach_args *faa = aux;
200
254
201
255
return (OF_is_compatible(faa->fa_node, "rockchip,rk3399-vop-big") ||
202
202
-
OF_is_compatible(faa->fa_node, "rockchip,rk3399-vop-lit"));
256
256
+
OF_is_compatible(faa->fa_node, "rockchip,rk3399-vop-lit") ||
257
257
+
OF_is_compatible(faa->fa_node, "rockchip,rk3126-vop"));
203
258
}
204
259
205
260
void
···
212
267
if (faa->fa_nreg < 1)
213
268
return;
214
269
270
270
+
power_domain_enable(faa->fa_node);
215
271
clock_set_assigned(faa->fa_node);
216
272
217
273
reset_deassert(faa->fa_node, "axi");
···
232
288
233
289
if (OF_is_compatible(faa->fa_node, "rockchip,rk3399-vop-big"))
234
290
sc->sc_conf = &rk3399_vop_big_config;
235
235
-
if (OF_is_compatible(faa->fa_node, "rockchip,rk3399-vop-lit"))
291
291
+
else if (OF_is_compatible(faa->fa_node, "rockchip,rk3399-vop-lit"))
236
292
sc->sc_conf = &rk3399_vop_lit_config;
293
293
+
else if (OF_is_compatible(faa->fa_node, "rockchip,rk3126-vop"))
294
294
+
sc->sc_conf = &rk3126_vop_config;
237
295
238
296
printf(": %s\n", sc->sc_conf->descr);
239
297
···
246
304
sc->sc_ports.dp_ep_get_cookie = rkvop_ep_get_cookie;
247
305
device_ports_register(&sc->sc_ports, EP_DRM_CRTC);
248
306
249
249
-
paddr = HREAD4(sc, VOP_WIN0_YRGB_MST);
250
250
-
if (paddr != 0) {
251
251
-
uint32_t stride, height;
307
307
+
switch (sc->sc_conf->type) {
308
308
+
case VOP_RK3126:
309
309
+
paddr = HREAD4(sc, RK3036_WIN0_YRGB_MST);
310
310
+
if (paddr != 0) {
311
311
+
uint32_t stride, height;
252
312
253
253
-
stride = HREAD4(sc, VOP_WIN0_VIR) & 0xffff;
254
254
-
height = (HREAD4(sc, VOP_WIN0_DSP_INFO) >> 16) + 1;
255
255
-
rasops_claim_framebuffer(paddr, height * stride * 4, self);
313
313
+
stride = HREAD4(sc, RK3036_WIN0_VIR) & 0xffff;
314
314
+
height = (HREAD4(sc, RK3036_WIN0_DSP_INFO) >> 16) + 1;
315
315
+
rasops_claim_framebuffer(paddr, height * stride * 4,
316
316
+
self);
317
317
+
}
318
318
+
break;
319
319
+
case VOP_RK3399:
320
320
+
paddr = HREAD4(sc, VOP_WIN0_YRGB_MST);
321
321
+
if (paddr != 0) {
322
322
+
uint32_t stride, height;
323
323
+
324
324
+
stride = HREAD4(sc, VOP_WIN0_VIR) & 0xffff;
325
325
+
height = (HREAD4(sc, VOP_WIN0_DSP_INFO) >> 16) + 1;
326
326
+
rasops_claim_framebuffer(paddr, height * stride * 4,
327
327
+
self);
328
328
+
}
329
329
+
break;
256
330
}
257
331
}
258
332
···
296
370
u_int lb_mode;
297
371
uint32_t val;
298
372
299
299
-
val = WIN0_ACT_WIDTH(act_width - 1) |
300
300
-
WIN0_ACT_HEIGHT(act_height - 1);
301
301
-
HWRITE4(sc, VOP_WIN0_ACT_INFO, val);
373
373
+
switch (sc->sc_conf->type) {
374
374
+
case VOP_RK3126:
375
375
+
val = WIN0_ACT_WIDTH(act_width - 1) |
376
376
+
WIN0_ACT_HEIGHT(act_height - 1);
377
377
+
HWRITE4(sc, RK3036_WIN0_ACT_INFO, val);
302
378
303
303
-
val = WIN0_DSP_WIDTH(drm_rect_width(dst) - 1) |
304
304
-
WIN0_DSP_HEIGHT(drm_rect_height(dst) - 1);
305
305
-
HWRITE4(sc, VOP_WIN0_DSP_INFO, val);
379
379
+
val = WIN0_DSP_WIDTH(drm_rect_width(dst) - 1) |
380
380
+
WIN0_DSP_HEIGHT(drm_rect_height(dst) - 1);
381
381
+
HWRITE4(sc, RK3036_WIN0_DSP_INFO, val);
306
382
307
307
-
val = WIN0_DSP_XST(dst->x1 + htotal - hsync_start) |
308
308
-
WIN0_DSP_YST(dst->y1 + vtotal - vsync_start);
309
309
-
HWRITE4(sc, VOP_WIN0_DSP_ST, val);
383
383
+
val = WIN0_DSP_XST(dst->x1 + htotal - hsync_start) |
384
384
+
WIN0_DSP_YST(dst->y1 + vtotal - vsync_start);
385
385
+
HWRITE4(sc, RK3036_WIN0_DSP_ST, val);
310
386
311
311
-
HWRITE4(sc, VOP_WIN0_COLOR_KEY, 0);
387
387
+
HWRITE4(sc, RK3036_WIN0_COLOR_KEY, 0);
312
388
313
313
-
if (act_width > 2560)
314
314
-
lb_mode = WIN0_LB_MODE_RGB_3840X2;
315
315
-
else if (act_width > 1920)
316
316
-
lb_mode = WIN0_LB_MODE_RGB_2560X4;
317
317
-
else if (act_width > 1280)
318
318
-
lb_mode = WIN0_LB_MODE_RGB_1920X5;
319
319
-
else
320
320
-
lb_mode = WIN0_LB_MODE_RGB_1280X8;
389
389
+
HWRITE4(sc, RK3036_SYS_CTRL,
390
390
+
(1 << 0) | /* win0 enable */
391
391
+
(WIN0_DATA_FMT_ARGB888 << 3)); /* win0 format */
321
392
322
322
-
val = WIN0_LB_MODE(lb_mode) |
323
323
-
WIN0_DATA_FMT(WIN0_DATA_FMT_ARGB888) |
324
324
-
WIN0_EN;
325
325
-
HWRITE4(sc, VOP_WIN0_CTRL, val);
393
393
+
val = WIN0_VIR_STRIDE(fb->pitches[0] / 4);
394
394
+
HWRITE4(sc, RK3036_WIN0_VIR, val);
326
395
327
327
-
val = WIN0_VIR_STRIDE(fb->pitches[0] / 4);
328
328
-
HWRITE4(sc, VOP_WIN0_VIR, val);
396
396
+
/* Framebuffer start address */
397
397
+
paddr = (uint64_t)rkfb->obj->dmamap->dm_segs[0].ds_addr;
398
398
+
paddr += (src->y1 >> 16) * fb->pitches[0];
399
399
+
paddr += (src->x1 >> 16) * fb->format->cpp[0];
400
400
+
KASSERT((paddr & ~0xffffffff) == 0);
401
401
+
HWRITE4(sc, RK3036_WIN0_YRGB_MST, (uint32_t)paddr);
402
402
+
break;
403
403
+
case VOP_RK3399:
404
404
+
val = WIN0_ACT_WIDTH(act_width - 1) |
405
405
+
WIN0_ACT_HEIGHT(act_height - 1);
406
406
+
HWRITE4(sc, VOP_WIN0_ACT_INFO, val);
329
407
330
330
-
/* Framebuffer start address */
331
331
-
paddr = (uint64_t)rkfb->obj->dmamap->dm_segs[0].ds_addr;
332
332
-
paddr += (src->y1 >> 16) * fb->pitches[0];
333
333
-
paddr += (src->x1 >> 16) * fb->format->cpp[0];
334
334
-
KASSERT((paddr & ~0xffffffff) == 0);
335
335
-
HWRITE4(sc, VOP_WIN0_YRGB_MST, (uint32_t)paddr);
408
408
+
val = WIN0_DSP_WIDTH(drm_rect_width(dst) - 1) |
409
409
+
WIN0_DSP_HEIGHT(drm_rect_height(dst) - 1);
410
410
+
HWRITE4(sc, VOP_WIN0_DSP_INFO, val);
411
411
+
412
412
+
val = WIN0_DSP_XST(dst->x1 + htotal - hsync_start) |
413
413
+
WIN0_DSP_YST(dst->y1 + vtotal - vsync_start);
414
414
+
HWRITE4(sc, VOP_WIN0_DSP_ST, val);
415
415
+
416
416
+
HWRITE4(sc, VOP_WIN0_COLOR_KEY, 0);
417
417
+
418
418
+
if (act_width > 2560)
419
419
+
lb_mode = WIN0_LB_MODE_RGB_3840X2;
420
420
+
else if (act_width > 1920)
421
421
+
lb_mode = WIN0_LB_MODE_RGB_2560X4;
422
422
+
else if (act_width > 1280)
423
423
+
lb_mode = WIN0_LB_MODE_RGB_1920X5;
424
424
+
else
425
425
+
lb_mode = WIN0_LB_MODE_RGB_1280X8;
426
426
+
427
427
+
val = WIN0_LB_MODE(lb_mode) |
428
428
+
WIN0_DATA_FMT(WIN0_DATA_FMT_ARGB888) |
429
429
+
WIN0_EN;
430
430
+
HWRITE4(sc, VOP_WIN0_CTRL, val);
431
431
+
432
432
+
val = WIN0_VIR_STRIDE(fb->pitches[0] / 4);
433
433
+
HWRITE4(sc, VOP_WIN0_VIR, val);
434
434
+
435
435
+
/* Framebuffer start address */
436
436
+
paddr = (uint64_t)rkfb->obj->dmamap->dm_segs[0].ds_addr;
437
437
+
paddr += (src->y1 >> 16) * fb->pitches[0];
438
438
+
paddr += (src->x1 >> 16) * fb->format->cpp[0];
439
439
+
KASSERT((paddr & ~0xffffffff) == 0);
440
440
+
HWRITE4(sc, VOP_WIN0_YRGB_MST, (uint32_t)paddr);
441
441
+
break;
442
442
+
}
336
443
}
337
444
338
445
struct drm_plane_helper_funcs rkvop_plane_helper_funcs = {
···
356
463
struct rkvop_softc *sc = rkcrtc->sc;
357
464
uint32_t val;
358
465
359
359
-
val = HREAD4(sc, VOP_SYS_CTRL);
360
360
-
361
361
-
switch (mode) {
362
362
-
case DRM_MODE_DPMS_ON:
363
363
-
val &= ~VOP_STANDBY_EN;
466
466
+
switch (sc->sc_conf->type) {
467
467
+
case VOP_RK3126:
468
468
+
/*
469
469
+
* Shadow register - can't use read-modify-write.
470
470
+
* Standby ON clears everything, standby OFF restores
471
471
+
* win0 enable which will be re-set by plane_update.
472
472
+
*/
473
473
+
switch (mode) {
474
474
+
case DRM_MODE_DPMS_ON:
475
475
+
HWRITE4(sc, RK3036_SYS_CTRL, 0);
476
476
+
break;
477
477
+
case DRM_MODE_DPMS_STANDBY:
478
478
+
case DRM_MODE_DPMS_SUSPEND:
479
479
+
case DRM_MODE_DPMS_OFF:
480
480
+
HWRITE4(sc, RK3036_SYS_CTRL, RK3036_STANDBY_EN);
481
481
+
break;
482
482
+
}
483
483
+
HWRITE4(sc, RK3036_REG_CFG_DONE, REG_LOAD_EN);
364
484
break;
365
365
-
case DRM_MODE_DPMS_STANDBY:
366
366
-
case DRM_MODE_DPMS_SUSPEND:
367
367
-
case DRM_MODE_DPMS_OFF:
368
368
-
val |= VOP_STANDBY_EN;
485
485
+
case VOP_RK3399:
486
486
+
val = HREAD4(sc, VOP_SYS_CTRL);
487
487
+
switch (mode) {
488
488
+
case DRM_MODE_DPMS_ON:
489
489
+
val &= ~VOP_STANDBY_EN;
490
490
+
break;
491
491
+
case DRM_MODE_DPMS_STANDBY:
492
492
+
case DRM_MODE_DPMS_SUSPEND:
493
493
+
case DRM_MODE_DPMS_OFF:
494
494
+
val |= VOP_STANDBY_EN;
495
495
+
break;
496
496
+
}
497
497
+
HWRITE4(sc, VOP_SYS_CTRL, val);
498
498
+
HWRITE4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN);
369
499
break;
370
500
}
371
371
-
372
372
-
HWRITE4(sc, VOP_SYS_CTRL, val);
373
373
-
374
374
-
/* Commit settings */
375
375
-
HWRITE4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN);
376
501
}
377
502
378
503
bool
···
410
535
u_int hactive = adjusted_mode->hdisplay;
411
536
u_int hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
412
537
u_int hback_porch = adjusted_mode->htotal - adjusted_mode->hsync_end;
413
413
-
u_int hfront_porch = adjusted_mode->hsync_start - adjusted_mode->hdisplay;
538
538
+
u_int hfront_porch = adjusted_mode->hsync_start -
539
539
+
adjusted_mode->hdisplay;
414
540
415
541
u_int vactive = adjusted_mode->vdisplay;
416
542
u_int vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
417
543
u_int vback_porch = adjusted_mode->vtotal - adjusted_mode->vsync_end;
418
418
-
u_int vfront_porch = adjusted_mode->vsync_start - adjusted_mode->vdisplay;
544
544
+
u_int vfront_porch = adjusted_mode->vsync_start -
545
545
+
adjusted_mode->vdisplay;
419
546
420
420
-
clock_set_frequency(sc->sc_node, "dclk_vop", adjusted_mode->clock * 1000);
547
547
+
clock_set_frequency(sc->sc_node, "dclk_vop",
548
548
+
adjusted_mode->clock * 1000);
421
549
422
550
pol = DSP_DCLK_POL;
423
551
if ((adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) != 0)
···
435
563
}
436
564
}
437
565
438
438
-
switch (connector_type) {
439
439
-
case DRM_MODE_CONNECTOR_HDMIA:
440
440
-
sc->sc_conf->set_polarity(sc, VOP_EP_HDMI, pol);
441
441
-
break;
442
442
-
case DRM_MODE_CONNECTOR_eDP:
443
443
-
sc->sc_conf->set_polarity(sc, VOP_EP_EDP, pol);
566
566
+
switch (sc->sc_conf->type) {
567
567
+
case VOP_RK3126:
568
568
+
/* RK3126 VOP uses shadow registers so use full writes */
569
569
+
570
570
+
/* SYS_CTRL: clear standby */
571
571
+
HWRITE4(sc, RK3036_SYS_CTRL, 0);
572
572
+
HWRITE4(sc, RK3036_REG_CFG_DONE, REG_LOAD_EN);
573
573
+
delay(1000);
574
574
+
575
575
+
/*
576
576
+
* DSP_CTRL0: output mode, no polarity bits.
577
577
+
* RK code sets DSP_CTRL0=0 for LVDS (no DCLK invert).
578
578
+
*/
579
579
+
HWRITE4(sc, RK3036_DSP_CTRL0,
580
580
+
DSP_OUT_MODE(sc->sc_conf->out_mode));
581
581
+
582
582
+
/* DSP_CTRL1: clear BLANK_EN (set by default after reset) */
583
583
+
HWRITE4(sc, RK3036_DSP_CTRL1, 0);
584
584
+
585
585
+
/*
586
586
+
* AXI_BUS_CTRL: enable display clock for the output type.
587
587
+
* RK code writes 0x0c000000 for LVDS (DCLK_EN+INVERT).
588
588
+
*/
589
589
+
switch (connector_type) {
590
590
+
case DRM_MODE_CONNECTOR_HDMIA:
591
591
+
HWRITE4(sc, RK3036_AXI_BUS_CTRL, RK3036_HDMI_DCLK_EN);
592
592
+
break;
593
593
+
case DRM_MODE_CONNECTOR_LVDS:
594
594
+
HWRITE4(sc, RK3036_AXI_BUS_CTRL,
595
595
+
RK3036_LVDS_DCLK_EN | RK3036_LVDS_DCLK_INVERT);
596
596
+
break;
597
597
+
}
598
598
+
599
599
+
/*
600
600
+
* RK3036/RK3126 timing registers have fields swapped compared
601
601
+
* to RK3399: total/period in upper 16 bits, sync width in
602
602
+
* lower 16 bits.
603
603
+
*/
604
604
+
val = DSP_HS_END(hsync_len + hback_porch + hactive +
605
605
+
hfront_porch) | DSP_HTOTAL(hsync_len);
606
606
+
HWRITE4(sc, RK3036_DSP_HTOTAL_HS_END, val);
607
607
+
608
608
+
val = DSP_HACT_ST(hsync_len + hback_porch) |
609
609
+
DSP_HACT_END(hsync_len + hback_porch + hactive);
610
610
+
HWRITE4(sc, RK3036_DSP_HACT_ST_END, val);
611
611
+
612
612
+
val = DSP_VS_END(vsync_len + vback_porch + vactive +
613
613
+
vfront_porch) | DSP_VTOTAL(vsync_len);
614
614
+
HWRITE4(sc, RK3036_DSP_VTOTAL_VS_END, val);
615
615
+
616
616
+
val = DSP_VACT_ST(vsync_len + vback_porch) |
617
617
+
DSP_VACT_END(vsync_len + vback_porch + vactive);
618
618
+
HWRITE4(sc, RK3036_DSP_VACT_ST_END, val);
619
619
+
620
620
+
HWRITE4(sc, RK3036_REG_CFG_DONE, REG_LOAD_EN);
444
621
break;
445
445
-
}
622
622
+
case VOP_RK3399:
623
623
+
switch (connector_type) {
624
624
+
case DRM_MODE_CONNECTOR_HDMIA:
625
625
+
sc->sc_conf->set_polarity(sc, VOP_EP_HDMI, pol);
626
626
+
break;
627
627
+
case DRM_MODE_CONNECTOR_eDP:
628
628
+
sc->sc_conf->set_polarity(sc, VOP_EP_EDP, pol);
629
629
+
break;
630
630
+
}
446
631
447
447
-
val = HREAD4(sc, VOP_SYS_CTRL);
448
448
-
val &= ~VOP_STANDBY_EN;
449
449
-
val &= ~(MIPI_OUT_EN|EDP_OUT_EN|HDMI_OUT_EN|RGB_OUT_EN);
632
632
+
val = HREAD4(sc, VOP_SYS_CTRL);
633
633
+
val &= ~VOP_STANDBY_EN;
634
634
+
val &= ~(MIPI_OUT_EN|EDP_OUT_EN|HDMI_OUT_EN|RGB_OUT_EN);
450
635
451
451
-
switch (connector_type) {
452
452
-
case DRM_MODE_CONNECTOR_HDMIA:
453
453
-
val |= HDMI_OUT_EN;
454
454
-
break;
455
455
-
case DRM_MODE_CONNECTOR_eDP:
456
456
-
val |= EDP_OUT_EN;
457
457
-
break;
458
458
-
}
459
459
-
HWRITE4(sc, VOP_SYS_CTRL, val);
636
636
+
switch (connector_type) {
637
637
+
case DRM_MODE_CONNECTOR_HDMIA:
638
638
+
val |= HDMI_OUT_EN;
639
639
+
break;
640
640
+
case DRM_MODE_CONNECTOR_eDP:
641
641
+
val |= EDP_OUT_EN;
642
642
+
break;
643
643
+
}
644
644
+
HWRITE4(sc, VOP_SYS_CTRL, val);
460
645
461
461
-
val = HREAD4(sc, VOP_DSP_CTRL0);
462
462
-
val &= ~DSP_OUT_MODE(DSP_OUT_MODE_MASK);
463
463
-
val |= DSP_OUT_MODE(sc->sc_conf->out_mode);
464
464
-
HWRITE4(sc, VOP_DSP_CTRL0, val);
646
646
+
val = HREAD4(sc, VOP_DSP_CTRL0);
647
647
+
val &= ~DSP_OUT_MODE(DSP_OUT_MODE_MASK);
648
648
+
val |= DSP_OUT_MODE(sc->sc_conf->out_mode);
649
649
+
HWRITE4(sc, VOP_DSP_CTRL0, val);
465
650
466
466
-
val = DSP_HACT_ST_POST(hsync_len + hback_porch) |
467
467
-
DSP_HACT_END_POST(hsync_len + hback_porch + hactive);
468
468
-
HWRITE4(sc, VOP_POST_DSP_HACT_INFO, val);
651
651
+
val = DSP_HACT_ST_POST(hsync_len + hback_porch) |
652
652
+
DSP_HACT_END_POST(hsync_len + hback_porch + hactive);
653
653
+
HWRITE4(sc, VOP_POST_DSP_HACT_INFO, val);
469
654
470
470
-
val = DSP_HACT_ST(hsync_len + hback_porch) |
471
471
-
DSP_HACT_END(hsync_len + hback_porch + hactive);
472
472
-
HWRITE4(sc, VOP_DSP_HACT_ST_END, val);
655
655
+
val = DSP_HACT_ST(hsync_len + hback_porch) |
656
656
+
DSP_HACT_END(hsync_len + hback_porch + hactive);
657
657
+
HWRITE4(sc, VOP_DSP_HACT_ST_END, val);
473
658
474
474
-
val = DSP_HTOTAL(hsync_len) |
475
475
-
DSP_HS_END(hsync_len + hback_porch + hactive + hfront_porch);
476
476
-
HWRITE4(sc, VOP_DSP_HTOTAL_HS_END, val);
659
659
+
val = DSP_HTOTAL(hsync_len) |
660
660
+
DSP_HS_END(hsync_len + hback_porch + hactive +
661
661
+
hfront_porch);
662
662
+
HWRITE4(sc, VOP_DSP_HTOTAL_HS_END, val);
477
663
478
478
-
val = DSP_VACT_ST_POST(vsync_len + vback_porch) |
479
479
-
DSP_VACT_END_POST(vsync_len + vback_porch + vactive);
480
480
-
HWRITE4(sc, VOP_POST_DSP_VACT_INFO, val);
664
664
+
val = DSP_VACT_ST_POST(vsync_len + vback_porch) |
665
665
+
DSP_VACT_END_POST(vsync_len + vback_porch + vactive);
666
666
+
HWRITE4(sc, VOP_POST_DSP_VACT_INFO, val);
481
667
482
482
-
val = DSP_VACT_ST(vsync_len + vback_porch) |
483
483
-
DSP_VACT_END(vsync_len + vback_porch + vactive);
484
484
-
HWRITE4(sc, VOP_DSP_VACT_ST_END, val);
668
668
+
val = DSP_VACT_ST(vsync_len + vback_porch) |
669
669
+
DSP_VACT_END(vsync_len + vback_porch + vactive);
670
670
+
HWRITE4(sc, VOP_DSP_VACT_ST_END, val);
485
671
486
486
-
val = DSP_VTOTAL(vsync_len) |
487
487
-
DSP_VS_END(vsync_len + vback_porch + vactive + vfront_porch);
488
488
-
HWRITE4(sc, VOP_DSP_VTOTAL_VS_END, val);
672
672
+
val = DSP_VTOTAL(vsync_len) |
673
673
+
DSP_VS_END(vsync_len + vback_porch + vactive +
674
674
+
vfront_porch);
675
675
+
HWRITE4(sc, VOP_DSP_VTOTAL_VS_END, val);
676
676
+
break;
677
677
+
}
489
678
}
490
679
491
680
void
···
495
684
struct rkvop_softc *sc = rkcrtc->sc;
496
685
497
686
/* Commit settings */
498
498
-
HWRITE4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN);
687
687
+
switch (sc->sc_conf->type) {
688
688
+
case VOP_RK3126:
689
689
+
HWRITE4(sc, RK3036_REG_CFG_DONE, REG_LOAD_EN);
690
690
+
break;
691
691
+
case VOP_RK3399:
692
692
+
HWRITE4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN);
693
693
+
break;
694
694
+
}
499
695
}
500
696
501
697
struct drm_crtc_helper_funcs rkvop_crtc_helper_funcs = {
···
522
718
struct drm_device *ddev = arg;
523
719
struct drm_plane *plane = &sc->sc_plane;
524
720
struct drm_crtc *crtc = &sc->sc_crtc.base;
525
525
-
uint32_t formats[] = { DRM_FORMAT_ARGB8888 };
721
721
+
uint32_t formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 };
526
722
int error;
527
723
528
724
if (sc->sc_crtc.sc)
···
540
736
if (error)
541
737
return -error;
542
738
543
543
-
printf("%s: using CRTC %d for %s\n", sc->sc_dev.dv_xname,
544
544
-
drm_crtc_index(&sc->sc_crtc.base), sc->sc_conf->descr);
545
545
-
546
739
sc->sc_crtc.sc = sc;
547
740
return 0;
548
741
}
···
576
769
}
577
770
578
771
void
579
579
-
rk3399_vop_set_polarity(struct rkvop_softc *sc, enum vop_ep_type ep_type, uint32_t pol)
772
772
+
rk3399_vop_set_polarity(struct rkvop_softc *sc, enum vop_ep_type ep_type,
773
773
+
uint32_t pol)
580
774
{
581
775
uint32_t mask, val;
582
776
···
607
801
val |= pol;
608
802
HWRITE4(sc, VOP_DSP_CTRL1, val);
609
803
}
804
804
+
805
805
+
/*
806
806
+
* RK3126 VOP
807
807
+
*/
808
808
+
void
809
809
+
rk3126_vop_init(struct rkvop_softc *sc)
810
810
+
{
811
811
+
/* clear standby (shadow regs) */
812
812
+
HWRITE4(sc, RK3036_SYS_CTRL, 0);
813
813
+
HWRITE4(sc, RK3036_REG_CFG_DONE, REG_LOAD_EN);
814
814
+
}
815
815
+
816
816
+
void
817
817
+
rk3126_vop_set_polarity(struct rkvop_softc *sc, enum vop_ep_type ep_type,
818
818
+
uint32_t pol)
819
819
+
{
820
820
+
uint32_t val;
821
821
+
822
822
+
/*
823
823
+
* Polarity is in DSP_CTRL0 bits 4-7 for RK3036/RK3126.
824
824
+
* RK code does not set any polarity bits for LVDS output
825
825
+
* (DSP_CTRL0 polarity field = 0x00), so clear all polarity bits
826
826
+
* for LVDS. Only apply polarity for non-LVDS outputs.
827
827
+
*/
828
828
+
val = HREAD4(sc, RK3036_DSP_CTRL0);
829
829
+
val &= ~(0xf << 4);
830
830
+
if (ep_type != VOP_EP_LVDS)
831
831
+
val |= (pol << 4);
832
832
+
HWRITE4(sc, RK3036_DSP_CTRL0, val);
833
833
+
834
834
+
/* commit register changes */
835
835
+
HWRITE4(sc, RK3036_REG_CFG_DONE, REG_LOAD_EN);
836
836
+
}