1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright 2010 Matt Turner.
4 * Copyright 2012 Red Hat
6 * Authors: Matthew Garrett
11 #include <linux/delay.h>
12 #include <linux/dma-buf-map.h>
14 #include <drm/drm_atomic_helper.h>
15 #include <drm/drm_atomic_state_helper.h>
16 #include <drm/drm_crtc_helper.h>
17 #include <drm/drm_damage_helper.h>
18 #include <drm/drm_format_helper.h>
19 #include <drm/drm_fourcc.h>
20 #include <drm/drm_gem_atomic_helper.h>
21 #include <drm/drm_gem_framebuffer_helper.h>
22 #include <drm/drm_plane_helper.h>
23 #include <drm/drm_print.h>
24 #include <drm/drm_probe_helper.h>
25 #include <drm/drm_simple_kms_helper.h>
27 #include "mgag200_drv.h"
29 #define MGAG200_LUT_SIZE 256
32 * This file contains setup code for the CRTC.
35 static void mga_crtc_load_lut(struct drm_crtc
*crtc
)
37 struct drm_device
*dev
= crtc
->dev
;
38 struct mga_device
*mdev
= to_mga_device(dev
);
39 struct drm_framebuffer
*fb
;
40 u16
*r_ptr
, *g_ptr
, *b_ptr
;
46 if (!mdev
->display_pipe
.plane
.state
)
49 fb
= mdev
->display_pipe
.plane
.state
->fb
;
51 r_ptr
= crtc
->gamma_store
;
52 g_ptr
= r_ptr
+ crtc
->gamma_size
;
53 b_ptr
= g_ptr
+ crtc
->gamma_size
;
55 WREG8(DAC_INDEX
+ MGA1064_INDEX
, 0);
57 if (fb
&& fb
->format
->cpp
[0] * 8 == 16) {
58 int inc
= (fb
->format
->depth
== 15) ? 8 : 4;
60 for (i
= 0; i
< MGAG200_LUT_SIZE
; i
+= inc
) {
61 if (fb
->format
->depth
== 16) {
62 if (i
> (MGAG200_LUT_SIZE
>> 1)) {
75 WREG8(DAC_INDEX
+ MGA1064_COL_PAL
, r
);
76 WREG8(DAC_INDEX
+ MGA1064_COL_PAL
, *g_ptr
++ >> 8);
77 WREG8(DAC_INDEX
+ MGA1064_COL_PAL
, b
);
81 for (i
= 0; i
< MGAG200_LUT_SIZE
; i
++) {
83 WREG8(DAC_INDEX
+ MGA1064_COL_PAL
, *r_ptr
++ >> 8);
84 WREG8(DAC_INDEX
+ MGA1064_COL_PAL
, *g_ptr
++ >> 8);
85 WREG8(DAC_INDEX
+ MGA1064_COL_PAL
, *b_ptr
++ >> 8);
89 static inline void mga_wait_vsync(struct mga_device
*mdev
)
91 unsigned long timeout
= jiffies
+ HZ
/10;
92 unsigned int status
= 0;
95 status
= RREG32(MGAREG_Status
);
96 } while ((status
& 0x08) && time_before(jiffies
, timeout
));
97 timeout
= jiffies
+ HZ
/10;
100 status
= RREG32(MGAREG_Status
);
101 } while (!(status
& 0x08) && time_before(jiffies
, timeout
));
104 static inline void mga_wait_busy(struct mga_device
*mdev
)
106 unsigned long timeout
= jiffies
+ HZ
;
107 unsigned int status
= 0;
109 status
= RREG8(MGAREG_Status
+ 2);
110 } while ((status
& 0x01) && time_before(jiffies
, timeout
));
113 static void mgag200_g200wb_hold_bmc(struct mga_device
*mdev
)
118 /* 1- The first step is to warn the BMC of an upcoming mode change.
119 * We are putting the misc<0> to output.*/
121 WREG8(DAC_INDEX
, MGA1064_GEN_IO_CTL
);
122 tmp
= RREG8(DAC_DATA
);
124 WREG_DAC(MGA1064_GEN_IO_CTL
, tmp
);
126 /* we are putting a 1 on the misc<0> line */
127 WREG8(DAC_INDEX
, MGA1064_GEN_IO_DATA
);
128 tmp
= RREG8(DAC_DATA
);
130 WREG_DAC(MGA1064_GEN_IO_DATA
, tmp
);
132 /* 2- Second step to mask and further scan request
133 * This will be done by asserting the remfreqmsk bit (XSPAREREG<7>)
135 WREG8(DAC_INDEX
, MGA1064_SPAREREG
);
136 tmp
= RREG8(DAC_DATA
);
138 WREG_DAC(MGA1064_SPAREREG
, tmp
);
140 /* 3a- the third step is to verifu if there is an active scan
141 * We are searching for a 0 on remhsyncsts <XSPAREREG<0>)
144 while (!(tmp
& 0x1) && iter_max
) {
145 WREG8(DAC_INDEX
, MGA1064_SPAREREG
);
146 tmp
= RREG8(DAC_DATA
);
151 /* 3b- this step occurs only if the remove is actually scanning
152 * we are waiting for the end of the frame which is a 1 on
153 * remvsyncsts (XSPAREREG<1>)
157 while ((tmp
& 0x2) && iter_max
) {
158 WREG8(DAC_INDEX
, MGA1064_SPAREREG
);
159 tmp
= RREG8(DAC_DATA
);
166 static void mgag200_g200wb_release_bmc(struct mga_device
*mdev
)
170 /* 1- The first step is to ensure that the vrsten and hrsten are set */
171 WREG8(MGAREG_CRTCEXT_INDEX
, 1);
172 tmp
= RREG8(MGAREG_CRTCEXT_DATA
);
173 WREG8(MGAREG_CRTCEXT_DATA
, tmp
| 0x88);
175 /* 2- second step is to assert the rstlvl2 */
176 WREG8(DAC_INDEX
, MGA1064_REMHEADCTL2
);
177 tmp
= RREG8(DAC_DATA
);
179 WREG8(DAC_DATA
, tmp
);
184 /* 3- deassert rstlvl2 */
186 WREG8(DAC_INDEX
, MGA1064_REMHEADCTL2
);
187 WREG8(DAC_DATA
, tmp
);
189 /* 4- remove mask of scan request */
190 WREG8(DAC_INDEX
, MGA1064_SPAREREG
);
191 tmp
= RREG8(DAC_DATA
);
193 WREG8(DAC_DATA
, tmp
);
195 /* 5- put back a 0 on the misc<0> line */
196 WREG8(DAC_INDEX
, MGA1064_GEN_IO_DATA
);
197 tmp
= RREG8(DAC_DATA
);
199 WREG_DAC(MGA1064_GEN_IO_DATA
, tmp
);
203 * This is how the framebuffer base address is stored in g200 cards:
204 * * Assume @offset is the gpu_addr variable of the framebuffer object
205 * * Then addr is the number of _pixels_ (not bytes) from the start of
206 * VRAM to the first pixel we want to display. (divided by 2 for 32bit
208 * * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers
209 * addr<20> -> CRTCEXT0<6>
210 * addr<19-16> -> CRTCEXT0<3-0>
211 * addr<15-8> -> CRTCC<7-0>
212 * addr<7-0> -> CRTCD<7-0>
214 * CRTCEXT0 has to be programmed last to trigger an update and make the
215 * new addr variable take effect.
217 static void mgag200_set_startadd(struct mga_device
*mdev
,
218 unsigned long offset
)
220 struct drm_device
*dev
= &mdev
->base
;
222 u8 crtcc
, crtcd
, crtcext0
;
224 startadd
= offset
/ 8;
227 * Can't store addresses any higher than that, but we also
228 * don't have more than 16 MiB of memory, so it should be fine.
230 drm_WARN_ON(dev
, startadd
> 0x1fffff);
232 RREG_ECRT(0x00, crtcext0
);
234 crtcc
= (startadd
>> 8) & 0xff;
235 crtcd
= startadd
& 0xff;
237 crtcext0
|= ((startadd
>> 14) & BIT(6)) |
238 ((startadd
>> 16) & 0x0f);
240 WREG_CRT(0x0c, crtcc
);
241 WREG_CRT(0x0d, crtcd
);
242 WREG_ECRT(0x00, crtcext0
);
245 static void mgag200_set_dac_regs(struct mga_device
*mdev
)
249 /* 0x00: */ 0, 0, 0, 0, 0, 0, 0x00, 0,
250 /* 0x08: */ 0, 0, 0, 0, 0, 0, 0, 0,
251 /* 0x10: */ 0, 0, 0, 0, 0, 0, 0, 0,
252 /* 0x18: */ 0x00, 0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20,
253 /* 0x20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
254 /* 0x28: */ 0x00, 0x00, 0x00, 0x00, 0, 0, 0, 0x40,
255 /* 0x30: */ 0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83,
256 /* 0x38: */ 0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A,
257 /* 0x40: */ 0, 0, 0, 0, 0, 0, 0, 0,
258 /* 0x48: */ 0, 0, 0, 0, 0, 0, 0, 0
261 switch (mdev
->type
) {
264 dacvalue
[MGA1064_SYS_PLL_M
] = 0x04;
265 dacvalue
[MGA1064_SYS_PLL_N
] = 0x2D;
266 dacvalue
[MGA1064_SYS_PLL_P
] = 0x19;
270 dacvalue
[MGA1064_VREF_CTL
] = 0x03;
271 dacvalue
[MGA1064_PIX_CLK_CTL
] = MGA1064_PIX_CLK_CTL_SEL_PLL
;
272 dacvalue
[MGA1064_MISC_CTL
] = MGA1064_MISC_CTL_DAC_EN
|
273 MGA1064_MISC_CTL_VGA8
|
274 MGA1064_MISC_CTL_DAC_RAM_CS
;
278 dacvalue
[MGA1064_VREF_CTL
] = 0x07;
281 dacvalue
[MGA1064_PIX_CLK_CTL
] = MGA1064_PIX_CLK_CTL_SEL_PLL
;
282 dacvalue
[MGA1064_MISC_CTL
] = MGA1064_MISC_CTL_VGA8
|
283 MGA1064_MISC_CTL_DAC_RAM_CS
;
287 dacvalue
[MGA1064_MISC_CTL
] = MGA1064_MISC_CTL_VGA8
|
288 MGA1064_MISC_CTL_DAC_RAM_CS
;
294 for (i
= 0; i
< ARRAY_SIZE(dacvalue
); i
++) {
298 ((i
>= 0x1f) && (i
<= 0x29)) ||
299 ((i
>= 0x30) && (i
<= 0x37)))
301 if (IS_G200_SE(mdev
) &&
302 ((i
== 0x2c) || (i
== 0x2d) || (i
== 0x2e)))
304 if ((mdev
->type
== G200_EV
||
305 mdev
->type
== G200_WB
||
306 mdev
->type
== G200_EH
||
307 mdev
->type
== G200_EW3
||
308 mdev
->type
== G200_EH3
) &&
309 (i
>= 0x44) && (i
<= 0x4e))
312 WREG_DAC(i
, dacvalue
[i
]);
315 if (mdev
->type
== G200_ER
)
319 static void mgag200_init_regs(struct mga_device
*mdev
)
323 mgag200_set_dac_regs(mdev
);
336 RREG_CRT(0x11, crtc11
);
337 crtc11
&= ~(MGAREG_CRTC11_CRTCPROTECT
|
338 MGAREG_CRTC11_VINTEN
|
339 MGAREG_CRTC11_VINTCLR
);
340 WREG_CRT(0x11, crtc11
);
342 if (mdev
->type
== G200_ER
)
343 WREG_ECRT(0x24, 0x5);
345 if (mdev
->type
== G200_EW3
)
346 WREG_ECRT(0x34, 0x5);
348 misc
= RREG8(MGA_MISC_IN
);
349 misc
|= MGAREG_MISC_IOADSEL
;
350 WREG8(MGA_MISC_OUT
, misc
);
353 static void mgag200_set_mode_regs(struct mga_device
*mdev
,
354 const struct drm_display_mode
*mode
)
356 unsigned int hdisplay
, hsyncstart
, hsyncend
, htotal
;
357 unsigned int vdisplay
, vsyncstart
, vsyncend
, vtotal
;
358 u8 misc
, crtcext1
, crtcext2
, crtcext5
;
360 hdisplay
= mode
->hdisplay
/ 8 - 1;
361 hsyncstart
= mode
->hsync_start
/ 8 - 1;
362 hsyncend
= mode
->hsync_end
/ 8 - 1;
363 htotal
= mode
->htotal
/ 8 - 1;
365 /* Work around hardware quirk */
366 if ((htotal
& 0x07) == 0x06 || (htotal
& 0x07) == 0x04)
369 vdisplay
= mode
->vdisplay
- 1;
370 vsyncstart
= mode
->vsync_start
- 1;
371 vsyncend
= mode
->vsync_end
- 1;
372 vtotal
= mode
->vtotal
- 2;
374 misc
= RREG8(MGA_MISC_IN
);
376 if (mode
->flags
& DRM_MODE_FLAG_NHSYNC
)
377 misc
|= MGAREG_MISC_HSYNCPOL
;
379 misc
&= ~MGAREG_MISC_HSYNCPOL
;
381 if (mode
->flags
& DRM_MODE_FLAG_NVSYNC
)
382 misc
|= MGAREG_MISC_VSYNCPOL
;
384 misc
&= ~MGAREG_MISC_VSYNCPOL
;
386 crtcext1
= (((htotal
- 4) & 0x100) >> 8) |
387 ((hdisplay
& 0x100) >> 7) |
388 ((hsyncstart
& 0x100) >> 6) |
390 if (mdev
->type
== G200_WB
|| mdev
->type
== G200_EW3
)
391 crtcext1
|= BIT(7) | /* vrsten */
394 crtcext2
= ((vtotal
& 0xc00) >> 10) |
395 ((vdisplay
& 0x400) >> 8) |
396 ((vdisplay
& 0xc00) >> 7) |
397 ((vsyncstart
& 0xc00) >> 5) |
398 ((vdisplay
& 0x400) >> 3);
401 WREG_CRT(0, htotal
- 4);
402 WREG_CRT(1, hdisplay
);
403 WREG_CRT(2, hdisplay
);
404 WREG_CRT(3, (htotal
& 0x1F) | 0x80);
405 WREG_CRT(4, hsyncstart
);
406 WREG_CRT(5, ((htotal
& 0x20) << 2) | (hsyncend
& 0x1F));
407 WREG_CRT(6, vtotal
& 0xFF);
408 WREG_CRT(7, ((vtotal
& 0x100) >> 8) |
409 ((vdisplay
& 0x100) >> 7) |
410 ((vsyncstart
& 0x100) >> 6) |
411 ((vdisplay
& 0x100) >> 5) |
412 ((vdisplay
& 0x100) >> 4) | /* linecomp */
413 ((vtotal
& 0x200) >> 4) |
414 ((vdisplay
& 0x200) >> 3) |
415 ((vsyncstart
& 0x200) >> 2));
416 WREG_CRT(9, ((vdisplay
& 0x200) >> 4) |
417 ((vdisplay
& 0x200) >> 3));
418 WREG_CRT(16, vsyncstart
& 0xFF);
419 WREG_CRT(17, (vsyncend
& 0x0F) | 0x20);
420 WREG_CRT(18, vdisplay
& 0xFF);
422 WREG_CRT(21, vdisplay
& 0xFF);
423 WREG_CRT(22, (vtotal
+ 1) & 0xFF);
425 WREG_CRT(24, vdisplay
& 0xFF);
427 WREG_ECRT(0x01, crtcext1
);
428 WREG_ECRT(0x02, crtcext2
);
429 WREG_ECRT(0x05, crtcext5
);
431 WREG8(MGA_MISC_OUT
, misc
);
434 static u8
mgag200_get_bpp_shift(const struct drm_format_info
*format
)
436 static const u8 bpp_shift
[] = {0, 1, 0, 2};
438 return bpp_shift
[format
->cpp
[0] - 1];
442 * Calculates the HW offset value from the framebuffer's pitch. The
443 * offset is a multiple of the pixel size and depends on the display
446 static u32
mgag200_calculate_offset(struct mga_device
*mdev
,
447 const struct drm_framebuffer
*fb
)
449 u32 offset
= fb
->pitches
[0] / fb
->format
->cpp
[0];
450 u8 bppshift
= mgag200_get_bpp_shift(fb
->format
);
452 if (fb
->format
->cpp
[0] * 8 == 24)
453 offset
= (offset
* 3) >> (4 - bppshift
);
455 offset
= offset
>> (4 - bppshift
);
460 static void mgag200_set_offset(struct mga_device
*mdev
,
461 const struct drm_framebuffer
*fb
)
464 u32 offset
= mgag200_calculate_offset(mdev
, fb
);
466 RREG_ECRT(0, crtcext0
);
468 crtc13
= offset
& 0xff;
470 crtcext0
&= ~MGAREG_CRTCEXT0_OFFSET_MASK
;
471 crtcext0
|= (offset
>> 4) & MGAREG_CRTCEXT0_OFFSET_MASK
;
473 WREG_CRT(0x13, crtc13
);
474 WREG_ECRT(0x00, crtcext0
);
477 static void mgag200_set_format_regs(struct mga_device
*mdev
,
478 const struct drm_framebuffer
*fb
)
480 struct drm_device
*dev
= &mdev
->base
;
481 const struct drm_format_info
*format
= fb
->format
;
482 unsigned int bpp
, bppshift
, scale
;
483 u8 crtcext3
, xmulctrl
;
485 bpp
= format
->cpp
[0] * 8;
487 bppshift
= mgag200_get_bpp_shift(format
);
490 scale
= ((1 << bppshift
) * 3) - 1;
493 scale
= (1 << bppshift
) - 1;
497 RREG_ECRT(3, crtcext3
);
501 xmulctrl
= MGA1064_MUL_CTL_8bits
;
504 if (format
->depth
== 15)
505 xmulctrl
= MGA1064_MUL_CTL_15bits
;
507 xmulctrl
= MGA1064_MUL_CTL_16bits
;
510 xmulctrl
= MGA1064_MUL_CTL_24bits
;
513 xmulctrl
= MGA1064_MUL_CTL_32_24bits
;
516 /* BUG: We should have caught this problem already. */
517 drm_WARN_ON(dev
, "invalid format depth\n");
521 crtcext3
&= ~GENMASK(2, 0);
524 WREG_DAC(MGA1064_MUL_CTL
, xmulctrl
);
532 /* GCTL6 should be 0x05, but we configure memmapsl to 0xb8000 (text mode),
533 * so that it doesn't hang when running kexec/kdump on G200_SE rev42.
539 WREG_ECRT(3, crtcext3
);
542 static void mgag200_g200er_reset_tagfifo(struct mga_device
*mdev
)
544 static uint32_t RESET_FLAG
= 0x00200000; /* undocumented magic value */
547 memctl
= RREG32(MGAREG_MEMCTL
);
549 memctl
|= RESET_FLAG
;
550 WREG32(MGAREG_MEMCTL
, memctl
);
554 memctl
&= ~RESET_FLAG
;
555 WREG32(MGAREG_MEMCTL
, memctl
);
558 static void mgag200_g200se_set_hiprilvl(struct mga_device
*mdev
,
559 const struct drm_display_mode
*mode
,
560 const struct drm_framebuffer
*fb
)
562 u32 unique_rev_id
= mdev
->model
.g200se
.unique_rev_id
;
563 unsigned int hiprilvl
;
566 if (unique_rev_id
>= 0x04) {
568 } else if (unique_rev_id
>= 0x02) {
572 if (fb
->format
->cpp
[0] * 8 > 16)
574 else if (fb
->format
->cpp
[0] * 8 > 8)
579 mb
= (mode
->clock
* bpp
) / 1000;
593 } else if (unique_rev_id
>= 0x01) {
599 crtcext6
= hiprilvl
; /* implicitly sets maxhipri to 0 */
601 WREG_ECRT(0x06, crtcext6
);
604 static void mgag200_g200ev_set_hiprilvl(struct mga_device
*mdev
)
606 WREG_ECRT(0x06, 0x00);
609 static void mgag200_enable_display(struct mga_device
*mdev
)
611 u8 seq0
, seq1
, crtcext1
;
613 RREG_SEQ(0x00, seq0
);
614 seq0
|= MGAREG_SEQ0_SYNCRST
|
615 MGAREG_SEQ0_ASYNCRST
;
616 WREG_SEQ(0x00, seq0
);
619 * TODO: replace busy waiting with vblank IRQ; put
620 * msleep(50) before changing SCROFF
622 mga_wait_vsync(mdev
);
625 RREG_SEQ(0x01, seq1
);
626 seq1
&= ~MGAREG_SEQ1_SCROFF
;
627 WREG_SEQ(0x01, seq1
);
631 RREG_ECRT(0x01, crtcext1
);
632 crtcext1
&= ~MGAREG_CRTCEXT1_VSYNCOFF
;
633 crtcext1
&= ~MGAREG_CRTCEXT1_HSYNCOFF
;
634 WREG_ECRT(0x01, crtcext1
);
637 static void mgag200_disable_display(struct mga_device
*mdev
)
639 u8 seq0
, seq1
, crtcext1
;
641 RREG_SEQ(0x00, seq0
);
642 seq0
&= ~MGAREG_SEQ0_SYNCRST
;
643 WREG_SEQ(0x00, seq0
);
646 * TODO: replace busy waiting with vblank IRQ; put
647 * msleep(50) before changing SCROFF
649 mga_wait_vsync(mdev
);
652 RREG_SEQ(0x01, seq1
);
653 seq1
|= MGAREG_SEQ1_SCROFF
;
654 WREG_SEQ(0x01, seq1
);
658 RREG_ECRT(0x01, crtcext1
);
659 crtcext1
|= MGAREG_CRTCEXT1_VSYNCOFF
|
660 MGAREG_CRTCEXT1_HSYNCOFF
;
661 WREG_ECRT(0x01, crtcext1
);
668 static int mga_vga_get_modes(struct drm_connector
*connector
)
670 struct mga_connector
*mga_connector
= to_mga_connector(connector
);
674 edid
= drm_get_edid(connector
, &mga_connector
->i2c
->adapter
);
676 drm_connector_update_edid_property(connector
, edid
);
677 ret
= drm_add_edid_modes(connector
, edid
);
683 static uint32_t mga_vga_calculate_mode_bandwidth(struct drm_display_mode
*mode
,
686 uint32_t total_area
, divisor
;
687 uint64_t active_area
, pixels_per_second
, bandwidth
;
688 uint64_t bytes_per_pixel
= (bits_per_pixel
+ 7) / 8;
692 if (!mode
->htotal
|| !mode
->vtotal
|| !mode
->clock
)
695 active_area
= mode
->hdisplay
* mode
->vdisplay
;
696 total_area
= mode
->htotal
* mode
->vtotal
;
698 pixels_per_second
= active_area
* mode
->clock
* 1000;
699 do_div(pixels_per_second
, total_area
);
701 bandwidth
= pixels_per_second
* bytes_per_pixel
* 100;
702 do_div(bandwidth
, divisor
);
704 return (uint32_t)(bandwidth
);
707 #define MODE_BANDWIDTH MODE_BAD
709 static enum drm_mode_status
mga_vga_mode_valid(struct drm_connector
*connector
,
710 struct drm_display_mode
*mode
)
712 struct drm_device
*dev
= connector
->dev
;
713 struct mga_device
*mdev
= to_mga_device(dev
);
716 if (IS_G200_SE(mdev
)) {
717 u32 unique_rev_id
= mdev
->model
.g200se
.unique_rev_id
;
719 if (unique_rev_id
== 0x01) {
720 if (mode
->hdisplay
> 1600)
721 return MODE_VIRTUAL_X
;
722 if (mode
->vdisplay
> 1200)
723 return MODE_VIRTUAL_Y
;
724 if (mga_vga_calculate_mode_bandwidth(mode
, bpp
)
726 return MODE_BANDWIDTH
;
727 } else if (unique_rev_id
== 0x02) {
728 if (mode
->hdisplay
> 1920)
729 return MODE_VIRTUAL_X
;
730 if (mode
->vdisplay
> 1200)
731 return MODE_VIRTUAL_Y
;
732 if (mga_vga_calculate_mode_bandwidth(mode
, bpp
)
734 return MODE_BANDWIDTH
;
736 if (mga_vga_calculate_mode_bandwidth(mode
, bpp
)
738 return MODE_BANDWIDTH
;
740 } else if (mdev
->type
== G200_WB
) {
741 if (mode
->hdisplay
> 1280)
742 return MODE_VIRTUAL_X
;
743 if (mode
->vdisplay
> 1024)
744 return MODE_VIRTUAL_Y
;
745 if (mga_vga_calculate_mode_bandwidth(mode
, bpp
) >
747 return MODE_BANDWIDTH
;
748 } else if (mdev
->type
== G200_EV
&&
749 (mga_vga_calculate_mode_bandwidth(mode
, bpp
)
751 return MODE_BANDWIDTH
;
752 } else if (mdev
->type
== G200_EH
&&
753 (mga_vga_calculate_mode_bandwidth(mode
, bpp
)
755 return MODE_BANDWIDTH
;
756 } else if (mdev
->type
== G200_ER
&&
757 (mga_vga_calculate_mode_bandwidth(mode
,
758 bpp
) > (55000 * 1024))) {
759 return MODE_BANDWIDTH
;
762 if ((mode
->hdisplay
% 8) != 0 || (mode
->hsync_start
% 8) != 0 ||
763 (mode
->hsync_end
% 8) != 0 || (mode
->htotal
% 8) != 0) {
764 return MODE_H_ILLEGAL
;
767 if (mode
->crtc_hdisplay
> 2048 || mode
->crtc_hsync_start
> 4096 ||
768 mode
->crtc_hsync_end
> 4096 || mode
->crtc_htotal
> 4096 ||
769 mode
->crtc_vdisplay
> 2048 || mode
->crtc_vsync_start
> 4096 ||
770 mode
->crtc_vsync_end
> 4096 || mode
->crtc_vtotal
> 4096) {
774 /* Validate the mode input by the user */
775 if (connector
->cmdline_mode
.specified
) {
776 if (connector
->cmdline_mode
.bpp_specified
)
777 bpp
= connector
->cmdline_mode
.bpp
;
780 if ((mode
->hdisplay
* mode
->vdisplay
* (bpp
/8)) > mdev
->vram_fb_available
) {
781 if (connector
->cmdline_mode
.specified
)
782 connector
->cmdline_mode
.specified
= false;
789 static void mga_connector_destroy(struct drm_connector
*connector
)
791 struct mga_connector
*mga_connector
= to_mga_connector(connector
);
792 mgag200_i2c_destroy(mga_connector
->i2c
);
793 drm_connector_cleanup(connector
);
796 static const struct drm_connector_helper_funcs mga_vga_connector_helper_funcs
= {
797 .get_modes
= mga_vga_get_modes
,
798 .mode_valid
= mga_vga_mode_valid
,
801 static const struct drm_connector_funcs mga_vga_connector_funcs
= {
802 .reset
= drm_atomic_helper_connector_reset
,
803 .fill_modes
= drm_helper_probe_single_connector_modes
,
804 .destroy
= mga_connector_destroy
,
805 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
806 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
809 static int mgag200_vga_connector_init(struct mga_device
*mdev
)
811 struct drm_device
*dev
= &mdev
->base
;
812 struct mga_connector
*mconnector
= &mdev
->connector
;
813 struct drm_connector
*connector
= &mconnector
->base
;
814 struct mga_i2c_chan
*i2c
;
817 i2c
= mgag200_i2c_create(dev
);
819 drm_warn(dev
, "failed to add DDC bus\n");
821 ret
= drm_connector_init_with_ddc(dev
, connector
,
822 &mga_vga_connector_funcs
,
823 DRM_MODE_CONNECTOR_VGA
,
826 goto err_mgag200_i2c_destroy
;
827 drm_connector_helper_add(connector
, &mga_vga_connector_helper_funcs
);
829 mconnector
->i2c
= i2c
;
833 err_mgag200_i2c_destroy
:
834 mgag200_i2c_destroy(i2c
);
839 * Simple Display Pipe
842 static enum drm_mode_status
843 mgag200_simple_display_pipe_mode_valid(struct drm_simple_display_pipe
*pipe
,
844 const struct drm_display_mode
*mode
)
850 mgag200_handle_damage(struct mga_device
*mdev
, struct drm_framebuffer
*fb
,
851 struct drm_rect
*clip
, const struct dma_buf_map
*map
)
853 void *vmap
= map
->vaddr
; /* TODO: Use mapping abstraction properly */
855 drm_fb_memcpy_dstclip(mdev
->vram
, fb
->pitches
[0], vmap
, fb
, clip
);
857 /* Always scanout image at VRAM offset 0 */
858 mgag200_set_startadd(mdev
, (u32
)0);
859 mgag200_set_offset(mdev
, fb
);
863 mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe
*pipe
,
864 struct drm_crtc_state
*crtc_state
,
865 struct drm_plane_state
*plane_state
)
867 struct drm_crtc
*crtc
= &pipe
->crtc
;
868 struct drm_device
*dev
= crtc
->dev
;
869 struct mga_device
*mdev
= to_mga_device(dev
);
870 struct mgag200_pll
*pixpll
= &mdev
->pixpll
;
871 struct drm_display_mode
*adjusted_mode
= &crtc_state
->adjusted_mode
;
872 struct mgag200_crtc_state
*mgag200_crtc_state
= to_mgag200_crtc_state(crtc_state
);
873 struct drm_framebuffer
*fb
= plane_state
->fb
;
874 struct drm_shadow_plane_state
*shadow_plane_state
= to_drm_shadow_plane_state(plane_state
);
875 struct drm_rect fullscreen
= {
882 if (mdev
->type
== G200_WB
|| mdev
->type
== G200_EW3
)
883 mgag200_g200wb_hold_bmc(mdev
);
885 mgag200_set_format_regs(mdev
, fb
);
886 mgag200_set_mode_regs(mdev
, adjusted_mode
);
888 pixpll
->funcs
->update(pixpll
, &mgag200_crtc_state
->pixpllc
);
890 if (mdev
->type
== G200_ER
)
891 mgag200_g200er_reset_tagfifo(mdev
);
893 if (IS_G200_SE(mdev
))
894 mgag200_g200se_set_hiprilvl(mdev
, adjusted_mode
, fb
);
895 else if (mdev
->type
== G200_EV
)
896 mgag200_g200ev_set_hiprilvl(mdev
);
898 if (mdev
->type
== G200_WB
|| mdev
->type
== G200_EW3
)
899 mgag200_g200wb_release_bmc(mdev
);
901 mga_crtc_load_lut(crtc
);
902 mgag200_enable_display(mdev
);
904 mgag200_handle_damage(mdev
, fb
, &fullscreen
, &shadow_plane_state
->data
[0]);
908 mgag200_simple_display_pipe_disable(struct drm_simple_display_pipe
*pipe
)
910 struct drm_crtc
*crtc
= &pipe
->crtc
;
911 struct mga_device
*mdev
= to_mga_device(crtc
->dev
);
913 mgag200_disable_display(mdev
);
917 mgag200_simple_display_pipe_check(struct drm_simple_display_pipe
*pipe
,
918 struct drm_plane_state
*plane_state
,
919 struct drm_crtc_state
*crtc_state
)
921 struct drm_plane
*plane
= plane_state
->plane
;
922 struct drm_device
*dev
= plane
->dev
;
923 struct mga_device
*mdev
= to_mga_device(dev
);
924 struct mgag200_pll
*pixpll
= &mdev
->pixpll
;
925 struct mgag200_crtc_state
*mgag200_crtc_state
= to_mgag200_crtc_state(crtc_state
);
926 struct drm_framebuffer
*new_fb
= plane_state
->fb
;
927 struct drm_framebuffer
*fb
= NULL
;
934 fb
= plane
->state
->fb
;
936 if (!fb
|| (fb
->format
!= new_fb
->format
))
937 crtc_state
->mode_changed
= true; /* update PLL settings */
939 if (crtc_state
->mode_changed
) {
940 ret
= pixpll
->funcs
->compute(pixpll
, crtc_state
->mode
.clock
,
941 &mgag200_crtc_state
->pixpllc
);
950 mgag200_simple_display_pipe_update(struct drm_simple_display_pipe
*pipe
,
951 struct drm_plane_state
*old_state
)
953 struct drm_plane
*plane
= &pipe
->plane
;
954 struct drm_device
*dev
= plane
->dev
;
955 struct mga_device
*mdev
= to_mga_device(dev
);
956 struct drm_plane_state
*state
= plane
->state
;
957 struct drm_shadow_plane_state
*shadow_plane_state
= to_drm_shadow_plane_state(state
);
958 struct drm_framebuffer
*fb
= state
->fb
;
959 struct drm_rect damage
;
964 if (drm_atomic_helper_damage_merged(old_state
, state
, &damage
))
965 mgag200_handle_damage(mdev
, fb
, &damage
, &shadow_plane_state
->data
[0]);
968 static struct drm_crtc_state
*
969 mgag200_simple_display_pipe_duplicate_crtc_state(struct drm_simple_display_pipe
*pipe
)
971 struct drm_crtc
*crtc
= &pipe
->crtc
;
972 struct drm_crtc_state
*crtc_state
= crtc
->state
;
973 struct mgag200_crtc_state
*mgag200_crtc_state
= to_mgag200_crtc_state(crtc_state
);
974 struct mgag200_crtc_state
*new_mgag200_crtc_state
;
979 new_mgag200_crtc_state
= kzalloc(sizeof(*new_mgag200_crtc_state
), GFP_KERNEL
);
980 if (!new_mgag200_crtc_state
)
982 __drm_atomic_helper_crtc_duplicate_state(crtc
, &new_mgag200_crtc_state
->base
);
984 memcpy(&new_mgag200_crtc_state
->pixpllc
, &mgag200_crtc_state
->pixpllc
,
985 sizeof(new_mgag200_crtc_state
->pixpllc
));
987 return &new_mgag200_crtc_state
->base
;
990 static void mgag200_simple_display_pipe_destroy_crtc_state(struct drm_simple_display_pipe
*pipe
,
991 struct drm_crtc_state
*crtc_state
)
993 struct mgag200_crtc_state
*mgag200_crtc_state
= to_mgag200_crtc_state(crtc_state
);
995 __drm_atomic_helper_crtc_destroy_state(&mgag200_crtc_state
->base
);
996 kfree(mgag200_crtc_state
);
999 static void mgag200_simple_display_pipe_reset_crtc(struct drm_simple_display_pipe
*pipe
)
1001 struct drm_crtc
*crtc
= &pipe
->crtc
;
1002 struct mgag200_crtc_state
*mgag200_crtc_state
;
1005 mgag200_simple_display_pipe_destroy_crtc_state(pipe
, crtc
->state
);
1006 crtc
->state
= NULL
; /* must be set to NULL here */
1009 mgag200_crtc_state
= kzalloc(sizeof(*mgag200_crtc_state
), GFP_KERNEL
);
1010 if (!mgag200_crtc_state
)
1012 __drm_atomic_helper_crtc_reset(crtc
, &mgag200_crtc_state
->base
);
1015 static const struct drm_simple_display_pipe_funcs
1016 mgag200_simple_display_pipe_funcs
= {
1017 .mode_valid
= mgag200_simple_display_pipe_mode_valid
,
1018 .enable
= mgag200_simple_display_pipe_enable
,
1019 .disable
= mgag200_simple_display_pipe_disable
,
1020 .check
= mgag200_simple_display_pipe_check
,
1021 .update
= mgag200_simple_display_pipe_update
,
1022 .reset_crtc
= mgag200_simple_display_pipe_reset_crtc
,
1023 .duplicate_crtc_state
= mgag200_simple_display_pipe_duplicate_crtc_state
,
1024 .destroy_crtc_state
= mgag200_simple_display_pipe_destroy_crtc_state
,
1025 DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS
,
1028 static const uint32_t mgag200_simple_display_pipe_formats
[] = {
1029 DRM_FORMAT_XRGB8888
,
1034 static const uint64_t mgag200_simple_display_pipe_fmtmods
[] = {
1035 DRM_FORMAT_MOD_LINEAR
,
1036 DRM_FORMAT_MOD_INVALID
1043 static const struct drm_mode_config_funcs mgag200_mode_config_funcs
= {
1044 .fb_create
= drm_gem_fb_create_with_dirty
,
1045 .atomic_check
= drm_atomic_helper_check
,
1046 .atomic_commit
= drm_atomic_helper_commit
,
1049 static unsigned int mgag200_preferred_depth(struct mga_device
*mdev
)
1051 if (IS_G200_SE(mdev
) && mdev
->vram_fb_available
< (2048*1024))
1057 int mgag200_modeset_init(struct mga_device
*mdev
)
1059 struct drm_device
*dev
= &mdev
->base
;
1060 struct drm_connector
*connector
= &mdev
->connector
.base
;
1061 struct drm_simple_display_pipe
*pipe
= &mdev
->display_pipe
;
1062 size_t format_count
= ARRAY_SIZE(mgag200_simple_display_pipe_formats
);
1065 mgag200_init_regs(mdev
);
1067 ret
= drmm_mode_config_init(dev
);
1069 drm_err(dev
, "drmm_mode_config_init() failed, error %d\n",
1074 dev
->mode_config
.max_width
= MGAG200_MAX_FB_WIDTH
;
1075 dev
->mode_config
.max_height
= MGAG200_MAX_FB_HEIGHT
;
1077 dev
->mode_config
.preferred_depth
= mgag200_preferred_depth(mdev
);
1079 dev
->mode_config
.fb_base
= mdev
->mc
.vram_base
;
1081 dev
->mode_config
.funcs
= &mgag200_mode_config_funcs
;
1083 ret
= mgag200_vga_connector_init(mdev
);
1086 "mgag200_vga_connector_init() failed, error %d\n",
1091 ret
= mgag200_pixpll_init(&mdev
->pixpll
, mdev
);
1095 ret
= drm_simple_display_pipe_init(dev
, pipe
,
1096 &mgag200_simple_display_pipe_funcs
,
1097 mgag200_simple_display_pipe_formats
,
1099 mgag200_simple_display_pipe_fmtmods
,
1103 "drm_simple_display_pipe_init() failed, error %d\n",
1108 /* FIXME: legacy gamma tables; convert to CRTC state */
1109 drm_mode_crtc_set_gamma_size(&pipe
->crtc
, MGAG200_LUT_SIZE
);
1111 drm_mode_config_reset(dev
);