hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/gpu/drm/mgag200/mgag200_mode.c
....@@ -1,10 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright 2010 Matt Turner.
34 * Copyright 2012 Red Hat
4
- *
5
- * This file is subject to the terms and conditions of the GNU General
6
- * Public License version 2. See the file COPYING in the main
7
- * directory of this archive for more details.
85 *
96 * Authors: Matthew Garrett
107 * Matt Turner
....@@ -13,9 +10,17 @@
1310
1411 #include <linux/delay.h>
1512
16
-#include <drm/drmP.h>
13
+#include <drm/drm_atomic_helper.h>
14
+#include <drm/drm_atomic_state_helper.h>
1715 #include <drm/drm_crtc_helper.h>
16
+#include <drm/drm_damage_helper.h>
17
+#include <drm/drm_format_helper.h>
18
+#include <drm/drm_fourcc.h>
19
+#include <drm/drm_gem_framebuffer_helper.h>
1820 #include <drm/drm_plane_helper.h>
21
+#include <drm/drm_print.h>
22
+#include <drm/drm_probe_helper.h>
23
+#include <drm/drm_simple_kms_helper.h>
1924
2025 #include "mgag200_drv.h"
2126
....@@ -28,13 +33,18 @@
2833 static void mga_crtc_load_lut(struct drm_crtc *crtc)
2934 {
3035 struct drm_device *dev = crtc->dev;
31
- struct mga_device *mdev = dev->dev_private;
32
- struct drm_framebuffer *fb = crtc->primary->fb;
36
+ struct mga_device *mdev = to_mga_device(dev);
37
+ struct drm_framebuffer *fb;
3338 u16 *r_ptr, *g_ptr, *b_ptr;
3439 int i;
3540
3641 if (!crtc->enabled)
3742 return;
43
+
44
+ if (!mdev->display_pipe.plane.state)
45
+ return;
46
+
47
+ fb = mdev->display_pipe.plane.state->fb;
3848
3949 r_ptr = crtc->gamma_store;
4050 g_ptr = r_ptr + crtc->gamma_size;
....@@ -98,10 +108,84 @@
98108 } while ((status & 0x01) && time_before(jiffies, timeout));
99109 }
100110
111
+/*
112
+ * PLL setup
113
+ */
114
+
115
+static int mgag200_g200_set_plls(struct mga_device *mdev, long clock)
116
+{
117
+ struct drm_device *dev = &mdev->base;
118
+ const int post_div_max = 7;
119
+ const int in_div_min = 1;
120
+ const int in_div_max = 6;
121
+ const int feed_div_min = 7;
122
+ const int feed_div_max = 127;
123
+ u8 testm, testn;
124
+ u8 n = 0, m = 0, p, s;
125
+ long f_vco;
126
+ long computed;
127
+ long delta, tmp_delta;
128
+ long ref_clk = mdev->model.g200.ref_clk;
129
+ long p_clk_min = mdev->model.g200.pclk_min;
130
+ long p_clk_max = mdev->model.g200.pclk_max;
131
+
132
+ if (clock > p_clk_max) {
133
+ drm_err(dev, "Pixel Clock %ld too high\n", clock);
134
+ return 1;
135
+ }
136
+
137
+ if (clock < p_clk_min >> 3)
138
+ clock = p_clk_min >> 3;
139
+
140
+ f_vco = clock;
141
+ for (p = 0;
142
+ p <= post_div_max && f_vco < p_clk_min;
143
+ p = (p << 1) + 1, f_vco <<= 1)
144
+ ;
145
+
146
+ delta = clock;
147
+
148
+ for (testm = in_div_min; testm <= in_div_max; testm++) {
149
+ for (testn = feed_div_min; testn <= feed_div_max; testn++) {
150
+ computed = ref_clk * (testn + 1) / (testm + 1);
151
+ if (computed < f_vco)
152
+ tmp_delta = f_vco - computed;
153
+ else
154
+ tmp_delta = computed - f_vco;
155
+ if (tmp_delta < delta) {
156
+ delta = tmp_delta;
157
+ m = testm;
158
+ n = testn;
159
+ }
160
+ }
161
+ }
162
+ f_vco = ref_clk * (n + 1) / (m + 1);
163
+ if (f_vco < 100000)
164
+ s = 0;
165
+ else if (f_vco < 140000)
166
+ s = 1;
167
+ else if (f_vco < 180000)
168
+ s = 2;
169
+ else
170
+ s = 3;
171
+
172
+ drm_dbg_kms(dev, "clock: %ld vco: %ld m: %d n: %d p: %d s: %d\n",
173
+ clock, f_vco, m, n, p, s);
174
+
175
+ WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);
176
+
177
+ WREG_DAC(MGA1064_PIX_PLLC_M, m);
178
+ WREG_DAC(MGA1064_PIX_PLLC_N, n);
179
+ WREG_DAC(MGA1064_PIX_PLLC_P, (p | (s << 3)));
180
+
181
+ return 0;
182
+}
183
+
101184 #define P_ARRAY_SIZE 9
102185
103186 static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
104187 {
188
+ u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
105189 unsigned int vcomax, vcomin, pllreffreq;
106190 unsigned int delta, tmpdelta, permitteddelta;
107191 unsigned int testp, testm, testn;
....@@ -111,7 +195,7 @@
111195 unsigned int fvv;
112196 unsigned int i;
113197
114
- if (mdev->unique_rev_id <= 0x03) {
198
+ if (unique_rev_id <= 0x03) {
115199
116200 m = n = p = 0;
117201 vcomax = 320000;
....@@ -205,11 +289,13 @@
205289 return 1;
206290 }
207291
292
+ WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);
293
+
208294 WREG_DAC(MGA1064_PIX_PLLC_M, m);
209295 WREG_DAC(MGA1064_PIX_PLLC_N, n);
210296 WREG_DAC(MGA1064_PIX_PLLC_P, p);
211297
212
- if (mdev->unique_rev_id >= 0x04) {
298
+ if (unique_rev_id >= 0x04) {
213299 WREG_DAC(0x1a, 0x09);
214300 msleep(20);
215301 WREG_DAC(0x1a, 0x01);
....@@ -300,6 +386,8 @@
300386 }
301387 }
302388 }
389
+
390
+ WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);
303391
304392 for (i = 0; i <= 32 && pll_locked == false; i++) {
305393 if (i > 0) {
....@@ -438,6 +526,8 @@
438526 }
439527 }
440528
529
+ WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);
530
+
441531 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
442532 tmp = RREG8(DAC_DATA);
443533 tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
....@@ -570,6 +660,9 @@
570660 }
571661 }
572662 }
663
+
664
+ WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);
665
+
573666 for (i = 0; i <= 32 && pll_locked == false; i++) {
574667 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
575668 tmp = RREG8(DAC_DATA);
....@@ -670,6 +763,8 @@
670763 }
671764 }
672765
766
+ WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK);
767
+
673768 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
674769 tmp = RREG8(DAC_DATA);
675770 tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
....@@ -701,9 +796,12 @@
701796 return 0;
702797 }
703798
704
-static int mga_crtc_set_plls(struct mga_device *mdev, long clock)
799
+static int mgag200_crtc_set_plls(struct mga_device *mdev, long clock)
705800 {
706801 switch(mdev->type) {
802
+ case G200_PCI:
803
+ case G200_AGP:
804
+ return mgag200_g200_set_plls(mdev, clock);
707805 case G200_SE_A:
708806 case G200_SE_B:
709807 return mga_g200se_set_plls(mdev, clock);
....@@ -723,12 +821,12 @@
723821 return mga_g200er_set_plls(mdev, clock);
724822 break;
725823 }
824
+
726825 return 0;
727826 }
728827
729
-static void mga_g200wb_prepare(struct drm_crtc *crtc)
828
+static void mgag200_g200wb_hold_bmc(struct mga_device *mdev)
730829 {
731
- struct mga_device *mdev = crtc->dev->dev_private;
732830 u8 tmp;
733831 int iter_max;
734832
....@@ -780,10 +878,9 @@
780878 }
781879 }
782880
783
-static void mga_g200wb_commit(struct drm_crtc *crtc)
881
+static void mgag200_g200wb_release_bmc(struct mga_device *mdev)
784882 {
785883 u8 tmp;
786
- struct mga_device *mdev = crtc->dev->dev_private;
787884
788885 /* 1- The first step is to ensure that the vrsten and hrsten are set */
789886 WREG8(MGAREG_CRTCEXT_INDEX, 1);
....@@ -818,122 +915,52 @@
818915 }
819916
820917 /*
821
- This is how the framebuffer base address is stored in g200 cards:
822
- * Assume @offset is the gpu_addr variable of the framebuffer object
823
- * Then addr is the number of _pixels_ (not bytes) from the start of
824
- VRAM to the first pixel we want to display. (divided by 2 for 32bit
825
- framebuffers)
826
- * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers
827
- addr<20> -> CRTCEXT0<6>
828
- addr<19-16> -> CRTCEXT0<3-0>
829
- addr<15-8> -> CRTCC<7-0>
830
- addr<7-0> -> CRTCD<7-0>
831
- CRTCEXT0 has to be programmed last to trigger an update and make the
832
- new addr variable take effect.
918
+ * This is how the framebuffer base address is stored in g200 cards:
919
+ * * Assume @offset is the gpu_addr variable of the framebuffer object
920
+ * * Then addr is the number of _pixels_ (not bytes) from the start of
921
+ * VRAM to the first pixel we want to display. (divided by 2 for 32bit
922
+ * framebuffers)
923
+ * * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers
924
+ * addr<20> -> CRTCEXT0<6>
925
+ * addr<19-16> -> CRTCEXT0<3-0>
926
+ * addr<15-8> -> CRTCC<7-0>
927
+ * addr<7-0> -> CRTCD<7-0>
928
+ *
929
+ * CRTCEXT0 has to be programmed last to trigger an update and make the
930
+ * new addr variable take effect.
833931 */
834
-static void mga_set_start_address(struct drm_crtc *crtc, unsigned offset)
932
+static void mgag200_set_startadd(struct mga_device *mdev,
933
+ unsigned long offset)
835934 {
836
- struct mga_device *mdev = crtc->dev->dev_private;
837
- u32 addr;
838
- int count;
839
- u8 crtcext0;
935
+ struct drm_device *dev = &mdev->base;
936
+ u32 startadd;
937
+ u8 crtcc, crtcd, crtcext0;
840938
841
- while (RREG8(0x1fda) & 0x08);
842
- while (!(RREG8(0x1fda) & 0x08));
939
+ startadd = offset / 8;
843940
844
- count = RREG8(MGAREG_VCOUNT) + 2;
845
- while (RREG8(MGAREG_VCOUNT) < count);
941
+ /*
942
+ * Can't store addresses any higher than that, but we also
943
+ * don't have more than 16 MiB of memory, so it should be fine.
944
+ */
945
+ drm_WARN_ON(dev, startadd > 0x1fffff);
846946
847
- WREG8(MGAREG_CRTCEXT_INDEX, 0);
848
- crtcext0 = RREG8(MGAREG_CRTCEXT_DATA);
849
- crtcext0 &= 0xB0;
850
- addr = offset / 8;
851
- /* Can't store addresses any higher than that...
852
- but we also don't have more than 16MB of memory, so it should be fine. */
853
- WARN_ON(addr > 0x1fffff);
854
- crtcext0 |= (!!(addr & (1<<20)))<<6;
855
- WREG_CRT(0x0d, (u8)(addr & 0xff));
856
- WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff);
857
- WREG_ECRT(0x0, ((u8)(addr >> 16) & 0xf) | crtcext0);
947
+ RREG_ECRT(0x00, crtcext0);
948
+
949
+ crtcc = (startadd >> 8) & 0xff;
950
+ crtcd = startadd & 0xff;
951
+ crtcext0 &= 0xb0;
952
+ crtcext0 |= ((startadd >> 14) & BIT(6)) |
953
+ ((startadd >> 16) & 0x0f);
954
+
955
+ WREG_CRT(0x0c, crtcc);
956
+ WREG_CRT(0x0d, crtcd);
957
+ WREG_ECRT(0x00, crtcext0);
858958 }
859959
860
-
861
-/* ast is different - we will force move buffers out of VRAM */
862
-static int mga_crtc_do_set_base(struct drm_crtc *crtc,
863
- struct drm_framebuffer *fb,
864
- int x, int y, int atomic)
960
+static void mgag200_set_dac_regs(struct mga_device *mdev)
865961 {
866
- struct mga_device *mdev = crtc->dev->dev_private;
867
- struct drm_gem_object *obj;
868
- struct mga_framebuffer *mga_fb;
869
- struct mgag200_bo *bo;
870
- int ret;
871
- u64 gpu_addr;
872
-
873
- /* push the previous fb to system ram */
874
- if (!atomic && fb) {
875
- mga_fb = to_mga_framebuffer(fb);
876
- obj = mga_fb->obj;
877
- bo = gem_to_mga_bo(obj);
878
- ret = mgag200_bo_reserve(bo, false);
879
- if (ret)
880
- return ret;
881
- mgag200_bo_push_sysram(bo);
882
- mgag200_bo_unreserve(bo);
883
- }
884
-
885
- mga_fb = to_mga_framebuffer(crtc->primary->fb);
886
- obj = mga_fb->obj;
887
- bo = gem_to_mga_bo(obj);
888
-
889
- ret = mgag200_bo_reserve(bo, false);
890
- if (ret)
891
- return ret;
892
-
893
- ret = mgag200_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
894
- if (ret) {
895
- mgag200_bo_unreserve(bo);
896
- return ret;
897
- }
898
-
899
- if (&mdev->mfbdev->mfb == mga_fb) {
900
- /* if pushing console in kmap it */
901
- ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
902
- if (ret)
903
- DRM_ERROR("failed to kmap fbcon\n");
904
-
905
- }
906
- mgag200_bo_unreserve(bo);
907
-
908
- mga_set_start_address(crtc, (u32)gpu_addr);
909
-
910
- return 0;
911
-}
912
-
913
-static int mga_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
914
- struct drm_framebuffer *old_fb)
915
-{
916
- return mga_crtc_do_set_base(crtc, old_fb, x, y, 0);
917
-}
918
-
919
-static int mga_crtc_mode_set(struct drm_crtc *crtc,
920
- struct drm_display_mode *mode,
921
- struct drm_display_mode *adjusted_mode,
922
- int x, int y, struct drm_framebuffer *old_fb)
923
-{
924
- struct drm_device *dev = crtc->dev;
925
- struct mga_device *mdev = dev->dev_private;
926
- const struct drm_framebuffer *fb = crtc->primary->fb;
927
- int hdisplay, hsyncstart, hsyncend, htotal;
928
- int vdisplay, vsyncstart, vsyncend, vtotal;
929
- int pitch;
930
- int option = 0, option2 = 0;
931
- int i;
932
- unsigned char misc = 0;
933
- unsigned char ext_vga[6];
934
- u8 bppshift;
935
-
936
- static unsigned char dacvalue[] = {
962
+ size_t i;
963
+ u8 dacvalue[] = {
937964 /* 0x00: */ 0, 0, 0, 0, 0, 0, 0x00, 0,
938965 /* 0x08: */ 0, 0, 0, 0, 0, 0, 0, 0,
939966 /* 0x10: */ 0, 0, 0, 0, 0, 0, 0, 0,
....@@ -946,9 +973,13 @@
946973 /* 0x48: */ 0, 0, 0, 0, 0, 0, 0, 0
947974 };
948975
949
- bppshift = mdev->bpp_shifts[fb->format->cpp[0] - 1];
950
-
951976 switch (mdev->type) {
977
+ case G200_PCI:
978
+ case G200_AGP:
979
+ dacvalue[MGA1064_SYS_PLL_M] = 0x04;
980
+ dacvalue[MGA1064_SYS_PLL_N] = 0x2D;
981
+ dacvalue[MGA1064_SYS_PLL_P] = 0x19;
982
+ break;
952983 case G200_SE_A:
953984 case G200_SE_B:
954985 dacvalue[MGA1064_VREF_CTL] = 0x03;
....@@ -956,61 +987,26 @@
956987 dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_DAC_EN |
957988 MGA1064_MISC_CTL_VGA8 |
958989 MGA1064_MISC_CTL_DAC_RAM_CS;
959
- if (mdev->has_sdram)
960
- option = 0x40049120;
961
- else
962
- option = 0x4004d120;
963
- option2 = 0x00008000;
964990 break;
965991 case G200_WB:
966992 case G200_EW3:
967993 dacvalue[MGA1064_VREF_CTL] = 0x07;
968
- option = 0x41049120;
969
- option2 = 0x0000b000;
970994 break;
971995 case G200_EV:
972996 dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL;
973997 dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
974998 MGA1064_MISC_CTL_DAC_RAM_CS;
975
- option = 0x00000120;
976
- option2 = 0x0000b000;
977999 break;
9781000 case G200_EH:
9791001 case G200_EH3:
9801002 dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
9811003 MGA1064_MISC_CTL_DAC_RAM_CS;
982
- option = 0x00000120;
983
- option2 = 0x0000b000;
9841004 break;
9851005 case G200_ER:
9861006 break;
9871007 }
9881008
989
- switch (fb->format->cpp[0] * 8) {
990
- case 8:
991
- dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_8bits;
992
- break;
993
- case 16:
994
- if (fb->format->depth == 15)
995
- dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_15bits;
996
- else
997
- dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_16bits;
998
- break;
999
- case 24:
1000
- dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_24bits;
1001
- break;
1002
- case 32:
1003
- dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_32_24bits;
1004
- break;
1005
- }
1006
-
1007
- if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1008
- misc |= 0x40;
1009
- if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1010
- misc |= 0x80;
1011
-
1012
-
1013
- for (i = 0; i < sizeof(dacvalue); i++) {
1009
+ for (i = 0; i < ARRAY_SIZE(dacvalue); i++) {
10141010 if ((i <= 0x17) ||
10151011 (i == 0x1b) ||
10161012 (i == 0x1c) ||
....@@ -1033,21 +1029,48 @@
10331029
10341030 if (mdev->type == G200_ER)
10351031 WREG_DAC(0x90, 0);
1032
+}
10361033
1037
- if (option)
1038
- pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option);
1039
- if (option2)
1040
- pci_write_config_dword(dev->pdev, PCI_MGA_OPTION2, option2);
1034
+static void mgag200_init_regs(struct mga_device *mdev)
1035
+{
1036
+ u8 crtc11, misc;
10411037
1042
- WREG_SEQ(2, 0xf);
1043
- WREG_SEQ(3, 0);
1044
- WREG_SEQ(4, 0xe);
1038
+ mgag200_set_dac_regs(mdev);
10451039
1046
- pitch = fb->pitches[0] / fb->format->cpp[0];
1047
- if (fb->format->cpp[0] * 8 == 24)
1048
- pitch = (pitch * 3) >> (4 - bppshift);
1049
- else
1050
- pitch = pitch >> (4 - bppshift);
1040
+ WREG_SEQ(2, 0x0f);
1041
+ WREG_SEQ(3, 0x00);
1042
+ WREG_SEQ(4, 0x0e);
1043
+
1044
+ WREG_CRT(10, 0);
1045
+ WREG_CRT(11, 0);
1046
+ WREG_CRT(12, 0);
1047
+ WREG_CRT(13, 0);
1048
+ WREG_CRT(14, 0);
1049
+ WREG_CRT(15, 0);
1050
+
1051
+ RREG_CRT(0x11, crtc11);
1052
+ crtc11 &= ~(MGAREG_CRTC11_CRTCPROTECT |
1053
+ MGAREG_CRTC11_VINTEN |
1054
+ MGAREG_CRTC11_VINTCLR);
1055
+ WREG_CRT(0x11, crtc11);
1056
+
1057
+ if (mdev->type == G200_ER)
1058
+ WREG_ECRT(0x24, 0x5);
1059
+
1060
+ if (mdev->type == G200_EW3)
1061
+ WREG_ECRT(0x34, 0x5);
1062
+
1063
+ misc = RREG8(MGA_MISC_IN);
1064
+ misc |= MGAREG_MISC_IOADSEL;
1065
+ WREG8(MGA_MISC_OUT, misc);
1066
+}
1067
+
1068
+static void mgag200_set_mode_regs(struct mga_device *mdev,
1069
+ const struct drm_display_mode *mode)
1070
+{
1071
+ unsigned int hdisplay, hsyncstart, hsyncend, htotal;
1072
+ unsigned int vdisplay, vsyncstart, vsyncend, vtotal;
1073
+ u8 misc, crtcext1, crtcext2, crtcext5;
10511074
10521075 hdisplay = mode->hdisplay / 8 - 1;
10531076 hsyncstart = mode->hsync_start / 8 - 1;
....@@ -1063,15 +1086,32 @@
10631086 vsyncend = mode->vsync_end - 1;
10641087 vtotal = mode->vtotal - 2;
10651088
1066
- WREG_GFX(0, 0);
1067
- WREG_GFX(1, 0);
1068
- WREG_GFX(2, 0);
1069
- WREG_GFX(3, 0);
1070
- WREG_GFX(4, 0);
1071
- WREG_GFX(5, 0x40);
1072
- WREG_GFX(6, 0x5);
1073
- WREG_GFX(7, 0xf);
1074
- WREG_GFX(8, 0xf);
1089
+ misc = RREG8(MGA_MISC_IN);
1090
+
1091
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1092
+ misc |= MGAREG_MISC_HSYNCPOL;
1093
+ else
1094
+ misc &= ~MGAREG_MISC_HSYNCPOL;
1095
+
1096
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1097
+ misc |= MGAREG_MISC_VSYNCPOL;
1098
+ else
1099
+ misc &= ~MGAREG_MISC_VSYNCPOL;
1100
+
1101
+ crtcext1 = (((htotal - 4) & 0x100) >> 8) |
1102
+ ((hdisplay & 0x100) >> 7) |
1103
+ ((hsyncstart & 0x100) >> 6) |
1104
+ (htotal & 0x40);
1105
+ if (mdev->type == G200_WB || mdev->type == G200_EW3)
1106
+ crtcext1 |= BIT(7) | /* vrsten */
1107
+ BIT(3); /* hrsten */
1108
+
1109
+ crtcext2 = ((vtotal & 0xc00) >> 10) |
1110
+ ((vdisplay & 0x400) >> 8) |
1111
+ ((vdisplay & 0xc00) >> 7) |
1112
+ ((vsyncstart & 0xc00) >> 5) |
1113
+ ((vdisplay & 0x400) >> 3);
1114
+ crtcext5 = 0x00;
10751115
10761116 WREG_CRT(0, htotal - 4);
10771117 WREG_CRT(1, hdisplay);
....@@ -1085,465 +1125,259 @@
10851125 ((vsyncstart & 0x100) >> 6) |
10861126 ((vdisplay & 0x100) >> 5) |
10871127 ((vdisplay & 0x100) >> 4) | /* linecomp */
1088
- ((vtotal & 0x200) >> 4)|
1128
+ ((vtotal & 0x200) >> 4) |
10891129 ((vdisplay & 0x200) >> 3) |
10901130 ((vsyncstart & 0x200) >> 2));
10911131 WREG_CRT(9, ((vdisplay & 0x200) >> 4) |
10921132 ((vdisplay & 0x200) >> 3));
1093
- WREG_CRT(10, 0);
1094
- WREG_CRT(11, 0);
1095
- WREG_CRT(12, 0);
1096
- WREG_CRT(13, 0);
1097
- WREG_CRT(14, 0);
1098
- WREG_CRT(15, 0);
10991133 WREG_CRT(16, vsyncstart & 0xFF);
11001134 WREG_CRT(17, (vsyncend & 0x0F) | 0x20);
11011135 WREG_CRT(18, vdisplay & 0xFF);
1102
- WREG_CRT(19, pitch & 0xFF);
11031136 WREG_CRT(20, 0);
11041137 WREG_CRT(21, vdisplay & 0xFF);
11051138 WREG_CRT(22, (vtotal + 1) & 0xFF);
11061139 WREG_CRT(23, 0xc3);
11071140 WREG_CRT(24, vdisplay & 0xFF);
11081141
1109
- ext_vga[0] = 0;
1110
- ext_vga[5] = 0;
1142
+ WREG_ECRT(0x01, crtcext1);
1143
+ WREG_ECRT(0x02, crtcext2);
1144
+ WREG_ECRT(0x05, crtcext5);
11111145
1112
- /* TODO interlace */
1146
+ WREG8(MGA_MISC_OUT, misc);
1147
+}
11131148
1114
- ext_vga[0] |= (pitch & 0x300) >> 4;
1115
- ext_vga[1] = (((htotal - 4) & 0x100) >> 8) |
1116
- ((hdisplay & 0x100) >> 7) |
1117
- ((hsyncstart & 0x100) >> 6) |
1118
- (htotal & 0x40);
1119
- ext_vga[2] = ((vtotal & 0xc00) >> 10) |
1120
- ((vdisplay & 0x400) >> 8) |
1121
- ((vdisplay & 0xc00) >> 7) |
1122
- ((vsyncstart & 0xc00) >> 5) |
1123
- ((vdisplay & 0x400) >> 3);
1149
+static u8 mgag200_get_bpp_shift(struct mga_device *mdev,
1150
+ const struct drm_format_info *format)
1151
+{
1152
+ return mdev->bpp_shifts[format->cpp[0] - 1];
1153
+}
1154
+
1155
+/*
1156
+ * Calculates the HW offset value from the framebuffer's pitch. The
1157
+ * offset is a multiple of the pixel size and depends on the display
1158
+ * format.
1159
+ */
1160
+static u32 mgag200_calculate_offset(struct mga_device *mdev,
1161
+ const struct drm_framebuffer *fb)
1162
+{
1163
+ u32 offset = fb->pitches[0] / fb->format->cpp[0];
1164
+ u8 bppshift = mgag200_get_bpp_shift(mdev, fb->format);
1165
+
11241166 if (fb->format->cpp[0] * 8 == 24)
1125
- ext_vga[3] = (((1 << bppshift) * 3) - 1) | 0x80;
1167
+ offset = (offset * 3) >> (4 - bppshift);
11261168 else
1127
- ext_vga[3] = ((1 << bppshift) - 1) | 0x80;
1128
- ext_vga[4] = 0;
1129
- if (mdev->type == G200_WB || mdev->type == G200_EW3)
1130
- ext_vga[1] |= 0x88;
1169
+ offset = offset >> (4 - bppshift);
11311170
1132
- /* Set pixel clocks */
1133
- misc = 0x2d;
1134
- WREG8(MGA_MISC_OUT, misc);
1135
-
1136
- mga_crtc_set_plls(mdev, mode->clock);
1137
-
1138
- for (i = 0; i < 6; i++) {
1139
- WREG_ECRT(i, ext_vga[i]);
1140
- }
1141
-
1142
- if (mdev->type == G200_ER)
1143
- WREG_ECRT(0x24, 0x5);
1144
-
1145
- if (mdev->type == G200_EW3)
1146
- WREG_ECRT(0x34, 0x5);
1147
-
1148
- if (mdev->type == G200_EV) {
1149
- WREG_ECRT(6, 0);
1150
- }
1151
-
1152
- WREG_ECRT(0, ext_vga[0]);
1153
- /* Enable mga pixel clock */
1154
- misc = 0x2d;
1155
-
1156
- WREG8(MGA_MISC_OUT, misc);
1157
-
1158
- if (adjusted_mode)
1159
- memcpy(&mdev->mode, mode, sizeof(struct drm_display_mode));
1160
-
1161
- mga_crtc_do_set_base(crtc, old_fb, x, y, 0);
1162
-
1163
- /* reset tagfifo */
1164
- if (mdev->type == G200_ER) {
1165
- u32 mem_ctl = RREG32(MGAREG_MEMCTL);
1166
- u8 seq1;
1167
-
1168
- /* screen off */
1169
- WREG8(MGAREG_SEQ_INDEX, 0x01);
1170
- seq1 = RREG8(MGAREG_SEQ_DATA) | 0x20;
1171
- WREG8(MGAREG_SEQ_DATA, seq1);
1172
-
1173
- WREG32(MGAREG_MEMCTL, mem_ctl | 0x00200000);
1174
- udelay(1000);
1175
- WREG32(MGAREG_MEMCTL, mem_ctl & ~0x00200000);
1176
-
1177
- WREG8(MGAREG_SEQ_DATA, seq1 & ~0x20);
1178
- }
1179
-
1180
-
1181
- if (IS_G200_SE(mdev)) {
1182
- if (mdev->unique_rev_id >= 0x04) {
1183
- WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
1184
- WREG8(MGAREG_CRTCEXT_DATA, 0);
1185
- } else if (mdev->unique_rev_id >= 0x02) {
1186
- u8 hi_pri_lvl;
1187
- u32 bpp;
1188
- u32 mb;
1189
-
1190
- if (fb->format->cpp[0] * 8 > 16)
1191
- bpp = 32;
1192
- else if (fb->format->cpp[0] * 8 > 8)
1193
- bpp = 16;
1194
- else
1195
- bpp = 8;
1196
-
1197
- mb = (mode->clock * bpp) / 1000;
1198
- if (mb > 3100)
1199
- hi_pri_lvl = 0;
1200
- else if (mb > 2600)
1201
- hi_pri_lvl = 1;
1202
- else if (mb > 1900)
1203
- hi_pri_lvl = 2;
1204
- else if (mb > 1160)
1205
- hi_pri_lvl = 3;
1206
- else if (mb > 440)
1207
- hi_pri_lvl = 4;
1208
- else
1209
- hi_pri_lvl = 5;
1210
-
1211
- WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
1212
- WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl);
1213
- } else {
1214
- WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
1215
- if (mdev->unique_rev_id >= 0x01)
1216
- WREG8(MGAREG_CRTCEXT_DATA, 0x03);
1217
- else
1218
- WREG8(MGAREG_CRTCEXT_DATA, 0x04);
1219
- }
1220
- }
1221
- return 0;
1171
+ return offset;
12221172 }
12231173
1224
-#if 0 /* code from mjg to attempt D3 on crtc dpms off - revisit later */
1225
-static int mga_suspend(struct drm_crtc *crtc)
1174
+static void mgag200_set_offset(struct mga_device *mdev,
1175
+ const struct drm_framebuffer *fb)
12261176 {
1227
- struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1228
- struct drm_device *dev = crtc->dev;
1229
- struct mga_device *mdev = dev->dev_private;
1230
- struct pci_dev *pdev = dev->pdev;
1231
- int option;
1177
+ u8 crtc13, crtcext0;
1178
+ u32 offset = mgag200_calculate_offset(mdev, fb);
12321179
1233
- if (mdev->suspended)
1234
- return 0;
1180
+ RREG_ECRT(0, crtcext0);
12351181
1236
- WREG_SEQ(1, 0x20);
1237
- WREG_ECRT(1, 0x30);
1238
- /* Disable the pixel clock */
1239
- WREG_DAC(0x1a, 0x05);
1240
- /* Power down the DAC */
1241
- WREG_DAC(0x1e, 0x18);
1242
- /* Power down the pixel PLL */
1243
- WREG_DAC(0x1a, 0x0d);
1182
+ crtc13 = offset & 0xff;
12441183
1245
- /* Disable PLLs and clocks */
1246
- pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
1247
- option &= ~(0x1F8024);
1248
- pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
1249
- pci_set_power_state(pdev, PCI_D3hot);
1250
- pci_disable_device(pdev);
1184
+ crtcext0 &= ~MGAREG_CRTCEXT0_OFFSET_MASK;
1185
+ crtcext0 |= (offset >> 4) & MGAREG_CRTCEXT0_OFFSET_MASK;
12511186
1252
- mdev->suspended = true;
1253
-
1254
- return 0;
1187
+ WREG_CRT(0x13, crtc13);
1188
+ WREG_ECRT(0x00, crtcext0);
12551189 }
12561190
1257
-static int mga_resume(struct drm_crtc *crtc)
1191
+static void mgag200_set_format_regs(struct mga_device *mdev,
1192
+ const struct drm_framebuffer *fb)
12581193 {
1259
- struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1260
- struct drm_device *dev = crtc->dev;
1261
- struct mga_device *mdev = dev->dev_private;
1262
- struct pci_dev *pdev = dev->pdev;
1263
- int option;
1194
+ struct drm_device *dev = &mdev->base;
1195
+ const struct drm_format_info *format = fb->format;
1196
+ unsigned int bpp, bppshift, scale;
1197
+ u8 crtcext3, xmulctrl;
12641198
1265
- if (!mdev->suspended)
1266
- return 0;
1199
+ bpp = format->cpp[0] * 8;
12671200
1268
- pci_set_power_state(pdev, PCI_D0);
1269
- pci_enable_device(pdev);
1270
-
1271
- /* Disable sysclk */
1272
- pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
1273
- option &= ~(0x4);
1274
- pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
1275
-
1276
- mdev->suspended = false;
1277
-
1278
- return 0;
1279
-}
1280
-
1281
-#endif
1282
-
1283
-static void mga_crtc_dpms(struct drm_crtc *crtc, int mode)
1284
-{
1285
- struct drm_device *dev = crtc->dev;
1286
- struct mga_device *mdev = dev->dev_private;
1287
- u8 seq1 = 0, crtcext1 = 0;
1288
-
1289
- switch (mode) {
1290
- case DRM_MODE_DPMS_ON:
1291
- seq1 = 0;
1292
- crtcext1 = 0;
1293
- mga_crtc_load_lut(crtc);
1201
+ bppshift = mgag200_get_bpp_shift(mdev, format);
1202
+ switch (bpp) {
1203
+ case 24:
1204
+ scale = ((1 << bppshift) * 3) - 1;
12941205 break;
1295
- case DRM_MODE_DPMS_STANDBY:
1296
- seq1 = 0x20;
1297
- crtcext1 = 0x10;
1298
- break;
1299
- case DRM_MODE_DPMS_SUSPEND:
1300
- seq1 = 0x20;
1301
- crtcext1 = 0x20;
1302
- break;
1303
- case DRM_MODE_DPMS_OFF:
1304
- seq1 = 0x20;
1305
- crtcext1 = 0x30;
1206
+ default:
1207
+ scale = (1 << bppshift) - 1;
13061208 break;
13071209 }
13081210
1309
-#if 0
1310
- if (mode == DRM_MODE_DPMS_OFF) {
1311
- mga_suspend(crtc);
1211
+ RREG_ECRT(3, crtcext3);
1212
+
1213
+ switch (bpp) {
1214
+ case 8:
1215
+ xmulctrl = MGA1064_MUL_CTL_8bits;
1216
+ break;
1217
+ case 16:
1218
+ if (format->depth == 15)
1219
+ xmulctrl = MGA1064_MUL_CTL_15bits;
1220
+ else
1221
+ xmulctrl = MGA1064_MUL_CTL_16bits;
1222
+ break;
1223
+ case 24:
1224
+ xmulctrl = MGA1064_MUL_CTL_24bits;
1225
+ break;
1226
+ case 32:
1227
+ xmulctrl = MGA1064_MUL_CTL_32_24bits;
1228
+ break;
1229
+ default:
1230
+ /* BUG: We should have caught this problem already. */
1231
+ drm_WARN_ON(dev, "invalid format depth\n");
1232
+ return;
13121233 }
1313
-#endif
1314
- WREG8(MGAREG_SEQ_INDEX, 0x01);
1315
- seq1 |= RREG8(MGAREG_SEQ_DATA) & ~0x20;
1234
+
1235
+ crtcext3 &= ~GENMASK(2, 0);
1236
+ crtcext3 |= scale;
1237
+
1238
+ WREG_DAC(MGA1064_MUL_CTL, xmulctrl);
1239
+
1240
+ WREG_GFX(0, 0x00);
1241
+ WREG_GFX(1, 0x00);
1242
+ WREG_GFX(2, 0x00);
1243
+ WREG_GFX(3, 0x00);
1244
+ WREG_GFX(4, 0x00);
1245
+ WREG_GFX(5, 0x40);
1246
+ /* GCTL6 should be 0x05, but we configure memmapsl to 0xb8000 (text mode),
1247
+ * so that it doesn't hang when running kexec/kdump on G200_SE rev42.
1248
+ */
1249
+ WREG_GFX(6, 0x0d);
1250
+ WREG_GFX(7, 0x0f);
1251
+ WREG_GFX(8, 0x0f);
1252
+
1253
+ WREG_ECRT(3, crtcext3);
1254
+}
1255
+
1256
+static void mgag200_g200er_reset_tagfifo(struct mga_device *mdev)
1257
+{
1258
+ static uint32_t RESET_FLAG = 0x00200000; /* undocumented magic value */
1259
+ u32 memctl;
1260
+
1261
+ memctl = RREG32(MGAREG_MEMCTL);
1262
+
1263
+ memctl |= RESET_FLAG;
1264
+ WREG32(MGAREG_MEMCTL, memctl);
1265
+
1266
+ udelay(1000);
1267
+
1268
+ memctl &= ~RESET_FLAG;
1269
+ WREG32(MGAREG_MEMCTL, memctl);
1270
+}
1271
+
1272
+static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev,
1273
+ const struct drm_display_mode *mode,
1274
+ const struct drm_framebuffer *fb)
1275
+{
1276
+ u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
1277
+ unsigned int hiprilvl;
1278
+ u8 crtcext6;
1279
+
1280
+ if (unique_rev_id >= 0x04) {
1281
+ hiprilvl = 0;
1282
+ } else if (unique_rev_id >= 0x02) {
1283
+ unsigned int bpp;
1284
+ unsigned long mb;
1285
+
1286
+ if (fb->format->cpp[0] * 8 > 16)
1287
+ bpp = 32;
1288
+ else if (fb->format->cpp[0] * 8 > 8)
1289
+ bpp = 16;
1290
+ else
1291
+ bpp = 8;
1292
+
1293
+ mb = (mode->clock * bpp) / 1000;
1294
+ if (mb > 3100)
1295
+ hiprilvl = 0;
1296
+ else if (mb > 2600)
1297
+ hiprilvl = 1;
1298
+ else if (mb > 1900)
1299
+ hiprilvl = 2;
1300
+ else if (mb > 1160)
1301
+ hiprilvl = 3;
1302
+ else if (mb > 440)
1303
+ hiprilvl = 4;
1304
+ else
1305
+ hiprilvl = 5;
1306
+
1307
+ } else if (unique_rev_id >= 0x01) {
1308
+ hiprilvl = 3;
1309
+ } else {
1310
+ hiprilvl = 4;
1311
+ }
1312
+
1313
+ crtcext6 = hiprilvl; /* implicitly sets maxhipri to 0 */
1314
+
1315
+ WREG_ECRT(0x06, crtcext6);
1316
+}
1317
+
1318
+static void mgag200_g200ev_set_hiprilvl(struct mga_device *mdev)
1319
+{
1320
+ WREG_ECRT(0x06, 0x00);
1321
+}
1322
+
1323
+static void mgag200_enable_display(struct mga_device *mdev)
1324
+{
1325
+ u8 seq0, seq1, crtcext1;
1326
+
1327
+ RREG_SEQ(0x00, seq0);
1328
+ seq0 |= MGAREG_SEQ0_SYNCRST |
1329
+ MGAREG_SEQ0_ASYNCRST;
1330
+ WREG_SEQ(0x00, seq0);
1331
+
1332
+ /*
1333
+ * TODO: replace busy waiting with vblank IRQ; put
1334
+ * msleep(50) before changing SCROFF
1335
+ */
13161336 mga_wait_vsync(mdev);
13171337 mga_wait_busy(mdev);
1318
- WREG8(MGAREG_SEQ_DATA, seq1);
1338
+
1339
+ RREG_SEQ(0x01, seq1);
1340
+ seq1 &= ~MGAREG_SEQ1_SCROFF;
1341
+ WREG_SEQ(0x01, seq1);
1342
+
13191343 msleep(20);
1320
- WREG8(MGAREG_CRTCEXT_INDEX, 0x01);
1321
- crtcext1 |= RREG8(MGAREG_CRTCEXT_DATA) & ~0x30;
1322
- WREG8(MGAREG_CRTCEXT_DATA, crtcext1);
13231344
1324
-#if 0
1325
- if (mode == DRM_MODE_DPMS_ON && mdev->suspended == true) {
1326
- mga_resume(crtc);
1327
- drm_helper_resume_force_mode(dev);
1328
- }
1329
-#endif
1345
+ RREG_ECRT(0x01, crtcext1);
1346
+ crtcext1 &= ~MGAREG_CRTCEXT1_VSYNCOFF;
1347
+ crtcext1 &= ~MGAREG_CRTCEXT1_HSYNCOFF;
1348
+ WREG_ECRT(0x01, crtcext1);
1349
+}
1350
+
1351
+static void mgag200_disable_display(struct mga_device *mdev)
1352
+{
1353
+ u8 seq0, seq1, crtcext1;
1354
+
1355
+ RREG_SEQ(0x00, seq0);
1356
+ seq0 &= ~MGAREG_SEQ0_SYNCRST;
1357
+ WREG_SEQ(0x00, seq0);
1358
+
1359
+ /*
1360
+ * TODO: replace busy waiting with vblank IRQ; put
1361
+ * msleep(50) before changing SCROFF
1362
+ */
1363
+ mga_wait_vsync(mdev);
1364
+ mga_wait_busy(mdev);
1365
+
1366
+ RREG_SEQ(0x01, seq1);
1367
+ seq1 |= MGAREG_SEQ1_SCROFF;
1368
+ WREG_SEQ(0x01, seq1);
1369
+
1370
+ msleep(20);
1371
+
1372
+ RREG_ECRT(0x01, crtcext1);
1373
+ crtcext1 |= MGAREG_CRTCEXT1_VSYNCOFF |
1374
+ MGAREG_CRTCEXT1_HSYNCOFF;
1375
+ WREG_ECRT(0x01, crtcext1);
13301376 }
13311377
13321378 /*
1333
- * This is called before a mode is programmed. A typical use might be to
1334
- * enable DPMS during the programming to avoid seeing intermediate stages,
1335
- * but that's not relevant to us
1379
+ * Connector
13361380 */
1337
-static void mga_crtc_prepare(struct drm_crtc *crtc)
1338
-{
1339
- struct drm_device *dev = crtc->dev;
1340
- struct mga_device *mdev = dev->dev_private;
1341
- u8 tmp;
1342
-
1343
- /* mga_resume(crtc);*/
1344
-
1345
- WREG8(MGAREG_CRTC_INDEX, 0x11);
1346
- tmp = RREG8(MGAREG_CRTC_DATA);
1347
- WREG_CRT(0x11, tmp | 0x80);
1348
-
1349
- if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {
1350
- WREG_SEQ(0, 1);
1351
- msleep(50);
1352
- WREG_SEQ(1, 0x20);
1353
- msleep(20);
1354
- } else {
1355
- WREG8(MGAREG_SEQ_INDEX, 0x1);
1356
- tmp = RREG8(MGAREG_SEQ_DATA);
1357
-
1358
- /* start sync reset */
1359
- WREG_SEQ(0, 1);
1360
- WREG_SEQ(1, tmp | 0x20);
1361
- }
1362
-
1363
- if (mdev->type == G200_WB || mdev->type == G200_EW3)
1364
- mga_g200wb_prepare(crtc);
1365
-
1366
- WREG_CRT(17, 0);
1367
-}
1368
-
1369
-/*
1370
- * This is called after a mode is programmed. It should reverse anything done
1371
- * by the prepare function
1372
- */
1373
-static void mga_crtc_commit(struct drm_crtc *crtc)
1374
-{
1375
- struct drm_device *dev = crtc->dev;
1376
- struct mga_device *mdev = dev->dev_private;
1377
- const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1378
- u8 tmp;
1379
-
1380
- if (mdev->type == G200_WB || mdev->type == G200_EW3)
1381
- mga_g200wb_commit(crtc);
1382
-
1383
- if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {
1384
- msleep(50);
1385
- WREG_SEQ(1, 0x0);
1386
- msleep(20);
1387
- WREG_SEQ(0, 0x3);
1388
- } else {
1389
- WREG8(MGAREG_SEQ_INDEX, 0x1);
1390
- tmp = RREG8(MGAREG_SEQ_DATA);
1391
-
1392
- tmp &= ~0x20;
1393
- WREG_SEQ(0x1, tmp);
1394
- WREG_SEQ(0, 3);
1395
- }
1396
- crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1397
-}
1398
-
1399
-/*
1400
- * The core can pass us a set of gamma values to program. We actually only
1401
- * use this for 8-bit mode so can't perform smooth fades on deeper modes,
1402
- * but it's a requirement that we provide the function
1403
- */
1404
-static int mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
1405
- u16 *blue, uint32_t size,
1406
- struct drm_modeset_acquire_ctx *ctx)
1407
-{
1408
- mga_crtc_load_lut(crtc);
1409
-
1410
- return 0;
1411
-}
1412
-
1413
-/* Simple cleanup function */
1414
-static void mga_crtc_destroy(struct drm_crtc *crtc)
1415
-{
1416
- struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1417
-
1418
- drm_crtc_cleanup(crtc);
1419
- kfree(mga_crtc);
1420
-}
1421
-
1422
-static void mga_crtc_disable(struct drm_crtc *crtc)
1423
-{
1424
- int ret;
1425
- DRM_DEBUG_KMS("\n");
1426
- mga_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
1427
- if (crtc->primary->fb) {
1428
- struct mga_framebuffer *mga_fb = to_mga_framebuffer(crtc->primary->fb);
1429
- struct drm_gem_object *obj = mga_fb->obj;
1430
- struct mgag200_bo *bo = gem_to_mga_bo(obj);
1431
- ret = mgag200_bo_reserve(bo, false);
1432
- if (ret)
1433
- return;
1434
- mgag200_bo_push_sysram(bo);
1435
- mgag200_bo_unreserve(bo);
1436
- }
1437
- crtc->primary->fb = NULL;
1438
-}
1439
-
1440
-/* These provide the minimum set of functions required to handle a CRTC */
1441
-static const struct drm_crtc_funcs mga_crtc_funcs = {
1442
- .cursor_set = mga_crtc_cursor_set,
1443
- .cursor_move = mga_crtc_cursor_move,
1444
- .gamma_set = mga_crtc_gamma_set,
1445
- .set_config = drm_crtc_helper_set_config,
1446
- .destroy = mga_crtc_destroy,
1447
-};
1448
-
1449
-static const struct drm_crtc_helper_funcs mga_helper_funcs = {
1450
- .disable = mga_crtc_disable,
1451
- .dpms = mga_crtc_dpms,
1452
- .mode_set = mga_crtc_mode_set,
1453
- .mode_set_base = mga_crtc_mode_set_base,
1454
- .prepare = mga_crtc_prepare,
1455
- .commit = mga_crtc_commit,
1456
-};
1457
-
1458
-/* CRTC setup */
1459
-static void mga_crtc_init(struct mga_device *mdev)
1460
-{
1461
- struct mga_crtc *mga_crtc;
1462
-
1463
- mga_crtc = kzalloc(sizeof(struct mga_crtc) +
1464
- (MGAG200FB_CONN_LIMIT * sizeof(struct drm_connector *)),
1465
- GFP_KERNEL);
1466
-
1467
- if (mga_crtc == NULL)
1468
- return;
1469
-
1470
- drm_crtc_init(mdev->dev, &mga_crtc->base, &mga_crtc_funcs);
1471
-
1472
- drm_mode_crtc_set_gamma_size(&mga_crtc->base, MGAG200_LUT_SIZE);
1473
- mdev->mode_info.crtc = mga_crtc;
1474
-
1475
- drm_crtc_helper_add(&mga_crtc->base, &mga_helper_funcs);
1476
-}
1477
-
1478
-/*
1479
- * The encoder comes after the CRTC in the output pipeline, but before
1480
- * the connector. It's responsible for ensuring that the digital
1481
- * stream is appropriately converted into the output format. Setup is
1482
- * very simple in this case - all we have to do is inform qemu of the
1483
- * colour depth in order to ensure that it displays appropriately
1484
- */
1485
-
1486
-/*
1487
- * These functions are analagous to those in the CRTC code, but are intended
1488
- * to handle any encoder-specific limitations
1489
- */
1490
-static void mga_encoder_mode_set(struct drm_encoder *encoder,
1491
- struct drm_display_mode *mode,
1492
- struct drm_display_mode *adjusted_mode)
1493
-{
1494
-
1495
-}
1496
-
1497
-static void mga_encoder_dpms(struct drm_encoder *encoder, int state)
1498
-{
1499
- return;
1500
-}
1501
-
1502
-static void mga_encoder_prepare(struct drm_encoder *encoder)
1503
-{
1504
-}
1505
-
1506
-static void mga_encoder_commit(struct drm_encoder *encoder)
1507
-{
1508
-}
1509
-
1510
-static void mga_encoder_destroy(struct drm_encoder *encoder)
1511
-{
1512
- struct mga_encoder *mga_encoder = to_mga_encoder(encoder);
1513
- drm_encoder_cleanup(encoder);
1514
- kfree(mga_encoder);
1515
-}
1516
-
1517
-static const struct drm_encoder_helper_funcs mga_encoder_helper_funcs = {
1518
- .dpms = mga_encoder_dpms,
1519
- .mode_set = mga_encoder_mode_set,
1520
- .prepare = mga_encoder_prepare,
1521
- .commit = mga_encoder_commit,
1522
-};
1523
-
1524
-static const struct drm_encoder_funcs mga_encoder_encoder_funcs = {
1525
- .destroy = mga_encoder_destroy,
1526
-};
1527
-
1528
-static struct drm_encoder *mga_encoder_init(struct drm_device *dev)
1529
-{
1530
- struct drm_encoder *encoder;
1531
- struct mga_encoder *mga_encoder;
1532
-
1533
- mga_encoder = kzalloc(sizeof(struct mga_encoder), GFP_KERNEL);
1534
- if (!mga_encoder)
1535
- return NULL;
1536
-
1537
- encoder = &mga_encoder->base;
1538
- encoder->possible_crtcs = 0x1;
1539
-
1540
- drm_encoder_init(dev, encoder, &mga_encoder_encoder_funcs,
1541
- DRM_MODE_ENCODER_DAC, NULL);
1542
- drm_encoder_helper_add(encoder, &mga_encoder_helper_funcs);
1543
-
1544
- return encoder;
1545
-}
1546
-
15471381
15481382 static int mga_vga_get_modes(struct drm_connector *connector)
15491383 {
....@@ -1590,11 +1424,13 @@
15901424 struct drm_display_mode *mode)
15911425 {
15921426 struct drm_device *dev = connector->dev;
1593
- struct mga_device *mdev = (struct mga_device*)dev->dev_private;
1427
+ struct mga_device *mdev = to_mga_device(dev);
15941428 int bpp = 32;
15951429
15961430 if (IS_G200_SE(mdev)) {
1597
- if (mdev->unique_rev_id == 0x01) {
1431
+ u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
1432
+
1433
+ if (unique_rev_id == 0x01) {
15981434 if (mode->hdisplay > 1600)
15991435 return MODE_VIRTUAL_X;
16001436 if (mode->vdisplay > 1200)
....@@ -1602,7 +1438,7 @@
16021438 if (mga_vga_calculate_mode_bandwidth(mode, bpp)
16031439 > (24400 * 1024))
16041440 return MODE_BANDWIDTH;
1605
- } else if (mdev->unique_rev_id == 0x02) {
1441
+ } else if (unique_rev_id == 0x02) {
16061442 if (mode->hdisplay > 1920)
16071443 return MODE_VIRTUAL_X;
16081444 if (mode->vdisplay > 1200)
....@@ -1655,7 +1491,7 @@
16551491 bpp = connector->cmdline_mode.bpp;
16561492 }
16571493
1658
- if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) {
1494
+ if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->vram_fb_available) {
16591495 if (connector->cmdline_mode.specified)
16601496 connector->cmdline_mode.specified = false;
16611497 return MODE_BAD;
....@@ -1664,101 +1500,270 @@
16641500 return MODE_OK;
16651501 }
16661502
1667
-static struct drm_encoder *mga_connector_best_encoder(struct drm_connector
1668
- *connector)
1669
-{
1670
- int enc_id = connector->encoder_ids[0];
1671
- /* pick the encoder ids */
1672
- if (enc_id)
1673
- return drm_encoder_find(connector->dev, NULL, enc_id);
1674
- return NULL;
1675
-}
1676
-
16771503 static void mga_connector_destroy(struct drm_connector *connector)
16781504 {
16791505 struct mga_connector *mga_connector = to_mga_connector(connector);
16801506 mgag200_i2c_destroy(mga_connector->i2c);
16811507 drm_connector_cleanup(connector);
1682
- kfree(connector);
16831508 }
16841509
16851510 static const struct drm_connector_helper_funcs mga_vga_connector_helper_funcs = {
1686
- .get_modes = mga_vga_get_modes,
1511
+ .get_modes = mga_vga_get_modes,
16871512 .mode_valid = mga_vga_mode_valid,
1688
- .best_encoder = mga_connector_best_encoder,
16891513 };
16901514
16911515 static const struct drm_connector_funcs mga_vga_connector_funcs = {
1692
- .dpms = drm_helper_connector_dpms,
1693
- .fill_modes = drm_helper_probe_single_connector_modes,
1694
- .destroy = mga_connector_destroy,
1516
+ .reset = drm_atomic_helper_connector_reset,
1517
+ .fill_modes = drm_helper_probe_single_connector_modes,
1518
+ .destroy = mga_connector_destroy,
1519
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1520
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
16951521 };
16961522
1697
-static struct drm_connector *mga_vga_init(struct drm_device *dev)
1523
+static int mgag200_vga_connector_init(struct mga_device *mdev)
16981524 {
1699
- struct drm_connector *connector;
1700
- struct mga_connector *mga_connector;
1701
-
1702
- mga_connector = kzalloc(sizeof(struct mga_connector), GFP_KERNEL);
1703
- if (!mga_connector)
1704
- return NULL;
1705
-
1706
- connector = &mga_connector->base;
1707
-
1708
- drm_connector_init(dev, connector,
1709
- &mga_vga_connector_funcs, DRM_MODE_CONNECTOR_VGA);
1710
-
1711
- drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs);
1712
-
1713
- drm_connector_register(connector);
1714
-
1715
- mga_connector->i2c = mgag200_i2c_create(dev);
1716
- if (!mga_connector->i2c)
1717
- DRM_ERROR("failed to add ddc bus\n");
1718
-
1719
- return connector;
1720
-}
1721
-
1722
-
1723
-int mgag200_modeset_init(struct mga_device *mdev)
1724
-{
1725
- struct drm_encoder *encoder;
1726
- struct drm_connector *connector;
1525
+ struct drm_device *dev = &mdev->base;
1526
+ struct mga_connector *mconnector = &mdev->connector;
1527
+ struct drm_connector *connector = &mconnector->base;
1528
+ struct mga_i2c_chan *i2c;
17271529 int ret;
17281530
1729
- mdev->mode_info.mode_config_initialized = true;
1531
+ i2c = mgag200_i2c_create(dev);
1532
+ if (!i2c)
1533
+ drm_warn(dev, "failed to add DDC bus\n");
17301534
1731
- mdev->dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH;
1732
- mdev->dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT;
1535
+ ret = drm_connector_init_with_ddc(dev, connector,
1536
+ &mga_vga_connector_funcs,
1537
+ DRM_MODE_CONNECTOR_VGA,
1538
+ &i2c->adapter);
1539
+ if (ret)
1540
+ goto err_mgag200_i2c_destroy;
1541
+ drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs);
17331542
1734
- mdev->dev->mode_config.fb_base = mdev->mc.vram_base;
1543
+ mconnector->i2c = i2c;
17351544
1736
- mga_crtc_init(mdev);
1545
+ return 0;
17371546
1738
- encoder = mga_encoder_init(mdev->dev);
1739
- if (!encoder) {
1740
- DRM_ERROR("mga_encoder_init failed\n");
1741
- return -1;
1742
- }
1547
+err_mgag200_i2c_destroy:
1548
+ mgag200_i2c_destroy(i2c);
1549
+ return ret;
1550
+}
17431551
1744
- connector = mga_vga_init(mdev->dev);
1745
- if (!connector) {
1746
- DRM_ERROR("mga_vga_init failed\n");
1747
- return -1;
1748
- }
1552
+/*
1553
+ * Simple Display Pipe
1554
+ */
17491555
1750
- drm_connector_attach_encoder(connector, encoder);
1556
+static enum drm_mode_status
1557
+mgag200_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
1558
+ const struct drm_display_mode *mode)
1559
+{
1560
+ return MODE_OK;
1561
+}
17511562
1752
- ret = mgag200_fbdev_init(mdev);
1753
- if (ret) {
1754
- DRM_ERROR("mga_fbdev_init failed\n");
1755
- return ret;
1756
- }
1563
+static void
1564
+mgag200_handle_damage(struct mga_device *mdev, struct drm_framebuffer *fb,
1565
+ struct drm_rect *clip)
1566
+{
1567
+ struct drm_device *dev = &mdev->base;
1568
+ void *vmap;
1569
+
1570
+ vmap = drm_gem_shmem_vmap(fb->obj[0]);
1571
+ if (drm_WARN_ON(dev, !vmap))
1572
+ return; /* BUG: SHMEM BO should always be vmapped */
1573
+
1574
+ drm_fb_memcpy_dstclip(mdev->vram, vmap, fb, clip);
1575
+
1576
+ drm_gem_shmem_vunmap(fb->obj[0], vmap);
1577
+
1578
+ /* Always scanout image at VRAM offset 0 */
1579
+ mgag200_set_startadd(mdev, (u32)0);
1580
+ mgag200_set_offset(mdev, fb);
1581
+}
1582
+
1583
+static void
1584
+mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
1585
+ struct drm_crtc_state *crtc_state,
1586
+ struct drm_plane_state *plane_state)
1587
+{
1588
+ struct drm_crtc *crtc = &pipe->crtc;
1589
+ struct drm_device *dev = crtc->dev;
1590
+ struct mga_device *mdev = to_mga_device(dev);
1591
+ struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
1592
+ struct drm_framebuffer *fb = plane_state->fb;
1593
+ struct drm_rect fullscreen = {
1594
+ .x1 = 0,
1595
+ .x2 = fb->width,
1596
+ .y1 = 0,
1597
+ .y2 = fb->height,
1598
+ };
1599
+
1600
+ if (mdev->type == G200_WB || mdev->type == G200_EW3)
1601
+ mgag200_g200wb_hold_bmc(mdev);
1602
+
1603
+ mgag200_set_format_regs(mdev, fb);
1604
+ mgag200_set_mode_regs(mdev, adjusted_mode);
1605
+ mgag200_crtc_set_plls(mdev, adjusted_mode->clock);
1606
+
1607
+ if (mdev->type == G200_ER)
1608
+ mgag200_g200er_reset_tagfifo(mdev);
1609
+
1610
+ if (IS_G200_SE(mdev))
1611
+ mgag200_g200se_set_hiprilvl(mdev, adjusted_mode, fb);
1612
+ else if (mdev->type == G200_EV)
1613
+ mgag200_g200ev_set_hiprilvl(mdev);
1614
+
1615
+ if (mdev->type == G200_WB || mdev->type == G200_EW3)
1616
+ mgag200_g200wb_release_bmc(mdev);
1617
+
1618
+ mga_crtc_load_lut(crtc);
1619
+ mgag200_enable_display(mdev);
1620
+
1621
+ mgag200_handle_damage(mdev, fb, &fullscreen);
1622
+}
1623
+
1624
+static void
1625
+mgag200_simple_display_pipe_disable(struct drm_simple_display_pipe *pipe)
1626
+{
1627
+ struct drm_crtc *crtc = &pipe->crtc;
1628
+ struct mga_device *mdev = to_mga_device(crtc->dev);
1629
+
1630
+ mgag200_disable_display(mdev);
1631
+}
1632
+
1633
+static int
1634
+mgag200_simple_display_pipe_check(struct drm_simple_display_pipe *pipe,
1635
+ struct drm_plane_state *plane_state,
1636
+ struct drm_crtc_state *crtc_state)
1637
+{
1638
+ struct drm_plane *plane = plane_state->plane;
1639
+ struct drm_framebuffer *new_fb = plane_state->fb;
1640
+ struct drm_framebuffer *fb = NULL;
1641
+
1642
+ if (!new_fb)
1643
+ return 0;
1644
+
1645
+ if (plane->state)
1646
+ fb = plane->state->fb;
1647
+
1648
+ if (!fb || (fb->format != new_fb->format))
1649
+ crtc_state->mode_changed = true; /* update PLL settings */
17571650
17581651 return 0;
17591652 }
17601653
1761
-void mgag200_modeset_fini(struct mga_device *mdev)
1654
+static void
1655
+mgag200_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
1656
+ struct drm_plane_state *old_state)
17621657 {
1658
+ struct drm_plane *plane = &pipe->plane;
1659
+ struct drm_device *dev = plane->dev;
1660
+ struct mga_device *mdev = to_mga_device(dev);
1661
+ struct drm_plane_state *state = plane->state;
1662
+ struct drm_framebuffer *fb = state->fb;
1663
+ struct drm_rect damage;
17631664
1665
+ if (!fb)
1666
+ return;
1667
+
1668
+ if (drm_atomic_helper_damage_merged(old_state, state, &damage))
1669
+ mgag200_handle_damage(mdev, fb, &damage);
1670
+}
1671
+
1672
+static const struct drm_simple_display_pipe_funcs
1673
+mgag200_simple_display_pipe_funcs = {
1674
+ .mode_valid = mgag200_simple_display_pipe_mode_valid,
1675
+ .enable = mgag200_simple_display_pipe_enable,
1676
+ .disable = mgag200_simple_display_pipe_disable,
1677
+ .check = mgag200_simple_display_pipe_check,
1678
+ .update = mgag200_simple_display_pipe_update,
1679
+ .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
1680
+};
1681
+
1682
+static const uint32_t mgag200_simple_display_pipe_formats[] = {
1683
+ DRM_FORMAT_XRGB8888,
1684
+ DRM_FORMAT_RGB565,
1685
+ DRM_FORMAT_RGB888,
1686
+};
1687
+
1688
+static const uint64_t mgag200_simple_display_pipe_fmtmods[] = {
1689
+ DRM_FORMAT_MOD_LINEAR,
1690
+ DRM_FORMAT_MOD_INVALID
1691
+};
1692
+
1693
+/*
1694
+ * Mode config
1695
+ */
1696
+
1697
+static const struct drm_mode_config_funcs mgag200_mode_config_funcs = {
1698
+ .fb_create = drm_gem_fb_create_with_dirty,
1699
+ .atomic_check = drm_atomic_helper_check,
1700
+ .atomic_commit = drm_atomic_helper_commit,
1701
+};
1702
+
1703
+static unsigned int mgag200_preferred_depth(struct mga_device *mdev)
1704
+{
1705
+ if (IS_G200_SE(mdev) && mdev->vram_fb_available < (2048*1024))
1706
+ return 16;
1707
+ else
1708
+ return 32;
1709
+}
1710
+
1711
+int mgag200_modeset_init(struct mga_device *mdev)
1712
+{
1713
+ struct drm_device *dev = &mdev->base;
1714
+ struct drm_connector *connector = &mdev->connector.base;
1715
+ struct drm_simple_display_pipe *pipe = &mdev->display_pipe;
1716
+ size_t format_count = ARRAY_SIZE(mgag200_simple_display_pipe_formats);
1717
+ int ret;
1718
+
1719
+ mdev->bpp_shifts[0] = 0;
1720
+ mdev->bpp_shifts[1] = 1;
1721
+ mdev->bpp_shifts[2] = 0;
1722
+ mdev->bpp_shifts[3] = 2;
1723
+
1724
+ mgag200_init_regs(mdev);
1725
+
1726
+ ret = drmm_mode_config_init(dev);
1727
+ if (ret) {
1728
+ drm_err(dev, "drmm_mode_config_init() failed, error %d\n",
1729
+ ret);
1730
+ return ret;
1731
+ }
1732
+
1733
+ dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH;
1734
+ dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT;
1735
+
1736
+ dev->mode_config.preferred_depth = mgag200_preferred_depth(mdev);
1737
+
1738
+ dev->mode_config.fb_base = mdev->mc.vram_base;
1739
+
1740
+ dev->mode_config.funcs = &mgag200_mode_config_funcs;
1741
+
1742
+ ret = mgag200_vga_connector_init(mdev);
1743
+ if (ret) {
1744
+ drm_err(dev,
1745
+ "mgag200_vga_connector_init() failed, error %d\n",
1746
+ ret);
1747
+ return ret;
1748
+ }
1749
+
1750
+ ret = drm_simple_display_pipe_init(dev, pipe,
1751
+ &mgag200_simple_display_pipe_funcs,
1752
+ mgag200_simple_display_pipe_formats,
1753
+ format_count,
1754
+ mgag200_simple_display_pipe_fmtmods,
1755
+ connector);
1756
+ if (ret) {
1757
+ drm_err(dev,
1758
+ "drm_simple_display_pipe_init() failed, error %d\n",
1759
+ ret);
1760
+ return ret;
1761
+ }
1762
+
1763
+ /* FIXME: legacy gamma tables; convert to CRTC state */
1764
+ drm_mode_crtc_set_gamma_size(&pipe->crtc, MGAG200_LUT_SIZE);
1765
+
1766
+ drm_mode_config_reset(dev);
1767
+
1768
+ return 0;
17641769 }