49 #include <linux/kernel.h>
50 #include <linux/pci.h>
85 static void vgaLockUnlock
94 if(Lock) cr11 |= 0x80;
98 static void nv3LockUnlock
106 vgaLockUnlock(chip, Lock);
108 static void nv4LockUnlock
116 vgaLockUnlock(chip, Lock);
119 static int ShowHideCursor
131 return (cursor & 0x01);
142 #define DEFAULT_GR_LWM 100
143 #define DEFAULT_VID_LWM 100
144 #define DEFAULT_GR_BURST_SIZE 256
145 #define DEFAULT_VID_BURST_SIZE 128
150 #define GFIFO_SIZE 320
151 #define GFIFO_SIZE_128 256
152 #define MFIFO_SIZE 120
153 #define VFIFO_SIZE 256
163 int wcmocc, wcgocc,
wcvocc, wcvlwm, wcglwm;
204 int graphics_burst_size;
205 int video_burst_size;
224 int graphics_burst_size;
225 int video_burst_size;
246 int vfsize, mfsize, gfsize;
247 int mburst_size = 32;
248 int mmisses, gmisses, vmisses;
250 int vlwm, glwm, mlwm;
293 else if (ainfo->
mocc < 0)
305 else if (ainfo->
mocc<0)
314 else if (ainfo->
mocc<0)
334 if (last==cur) misses = 0;
342 vlwm = ainfo->
vocc - vlwm;
350 if (last==cur) misses = 0;
358 glwm = ainfo->
gocc - glwm;
366 if (last==cur) misses = 0;
395 if (
abs(ainfo->
gocc) > max_gfsize)
415 if (
abs(gfsize) > max_gfsize)
429 long ens, vns, mns, gns;
430 int mmisses, gmisses, vmisses, eburst_size, mburst_size;
460 nv3_iterate(res_info, state,ainfo);
472 nv3_iterate(res_info, state,ainfo);
484 nv3_iterate(res_info, state,ainfo);
496 nv3_iterate(res_info, state, ainfo);
539 for (p=0; p < 2; p++)
541 for (g=128 ; g > 32; g= g>> 1)
543 for (v=128; v >=32; v = v>> 1)
548 done = nv3_arb(res_info, state,ainfo);
549 if (done && (g==128))
561 static void nv3CalcArbitration
569 char res_gr, res_vid;
586 res_vid = nv3_get_param(res_info, state, &ainfo);
595 res_gr = nv3_get_param(res_info, state, &ainfo);
599 res_info->
valid = res_gr & res_vid;
605 res_gr = nv3_get_param(res_info, state, &ainfo);
609 static void nv3UpdateArbitrationSettings
620 unsigned int M,
N,
P,
pll, MClk;
623 M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
639 nv3CalcArbitration(&fifo_data, &sim_data);
654 static void nv4CalcArbitration
661 int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
662 int found, mclk_extra, mclk_loop,
cbs, m1,
p1;
663 int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
664 int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate;
665 int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt,clwm;
710 mclk_loop = mclks+mclk_extra;
711 us_m = mclk_loop *1000*1000 / mclk_freq;
712 us_n = nvclks*1000*1000 / nvclk_freq;
713 us_p = nvclks*1000*1000 / pclk_freq;
716 video_drain_rate = pclk_freq * 2;
717 crtc_drain_rate = pclk_freq * bpp/8;
721 vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
722 if (nvclk_freq * 2 > mclk_freq * width)
723 video_fill_us = cbs*1000*1000 / 16 / nvclk_freq ;
725 video_fill_us = cbs*1000*1000 / (8 *
width) / mclk_freq;
726 us_video = vpm_us + us_m + us_n + us_p + video_fill_us;
727 vlwm = us_video * video_drain_rate/(1000*1000);
730 if (vlwm > 128) vbs = 64;
731 if (vlwm > (256-64)) vbs = 32;
732 if (nvclk_freq * 2 > mclk_freq * width)
733 video_fill_us = vbs *1000*1000/ 16 / nvclk_freq ;
735 video_fill_us = vbs*1000*1000 / (8 *
width) / mclk_freq;
736 cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
743 clwm = us_crt * crtc_drain_rate/(1000*1000);
748 crtc_drain_rate = pclk_freq * bpp/8;
751 cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
752 us_crt = cpm_us + us_m + us_n + us_p ;
753 clwm = us_crt * crtc_drain_rate/(1000*1000);
756 m1 = clwm + cbs - 512;
757 p1 = m1 * pclk_freq / mclk_freq;
759 if ((p1 < m1) && (m1 > 0))
763 if (mclk_extra ==0) found = 1;
766 else if (video_enable)
768 if ((clwm > 511) || (vlwm > 255))
772 if (mclk_extra ==0) found = 1;
782 if (mclk_extra ==0) found = 1;
788 if (clwm < 384) clwm = 384;
789 if (vlwm < 128) vlwm = 128;
793 data = (
int)((vlwm+15));
798 static void nv4UpdateArbitrationSettings
809 unsigned int M,
N,
P,
pll, MClk, NVClk, cfg1;
812 M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
815 M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
830 nv4CalcArbitration(&fifo_data, &sim_data);
840 static void nv10CalcArbitration
847 int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
848 int nvclk_fill, us_extra;
849 int found, mclk_extra, mclk_loop,
cbs, m1;
850 int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
851 int us_m, us_m_min, us_n, us_p, video_drain_rate, crtc_drain_rate;
852 int vus_m, vus_n, vus_p;
853 int vpm_us, us_video, vlwm, cpm_us, us_crt,clwm;
855 int craw, m2us, us_pipe, us_pipe_min, vus_pipe, p1clk, p2;
856 int pclks_2_top_fifo, min_mclk_extra;
857 int us_min_mclk_extra;
905 mclk_extra = (bpp == 32) ? 31 : 42;
910 mclk_extra = (bpp == 32) ? 8 : 4;
930 mclk_loop = mclks+mclk_extra;
931 us_m = mclk_loop *1000*1000 / mclk_freq;
932 us_m_min = mclks * 1000*1000 / mclk_freq;
933 us_min_mclk_extra = min_mclk_extra *1000*1000 / mclk_freq;
934 us_n = nvclks*1000*1000 / nvclk_freq;
935 us_p = pclks*1000*1000 / pclk_freq;
936 us_pipe = us_m + us_n + us_p;
937 us_pipe_min = us_m_min + us_n + us_p;
940 vus_m = mclk_loop *1000*1000 / mclk_freq;
941 vus_n = (4)*1000*1000 / nvclk_freq;
942 vus_p = 0*1000*1000 / pclk_freq;
943 vus_pipe = vus_m + vus_n + vus_p;
946 video_drain_rate = pclk_freq * 4;
947 crtc_drain_rate = pclk_freq * bpp/8;
956 vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
958 us_video = vpm_us + vus_m;
960 cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
967 clwm = us_crt * crtc_drain_rate/(1000*1000);
970 crtc_drain_rate = pclk_freq * bpp/8;
976 cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
977 us_crt = cpm_us + us_m + us_n + us_p ;
978 clwm = us_crt * crtc_drain_rate/(1000*1000);
998 nvclk_fill = nvclk_freq * 8;
999 if(crtc_drain_rate * 100 >= nvclk_fill * 102)
1002 else if(crtc_drain_rate * 100 >= nvclk_fill * 98) {
1005 us_extra = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ;
1016 clwm_rnd_down = ((
int)clwm/8)*8;
1017 if (clwm_rnd_down < clwm)
1020 m1 = clwm + cbs - 1024;
1021 m2us = us_pipe_min + us_min_mclk_extra;
1022 pclks_2_top_fifo = (1024-clwm)/(8*width);
1025 p1clk = m2us * pclk_freq/(1000*1000);
1026 p2 = p1clk * bpp / 8;
1028 if((p2 < m1) && (m1 > 0)) {
1031 if(min_mclk_extra == 0) {
1044 if(min_mclk_extra == 0)
1052 if(clwm < (1024-cbs+8)) clwm = 1024-cbs+8;
1061 static void nv10UpdateArbitrationSettings
1064 unsigned pixelDepth,
1072 unsigned int M,
N,
P,
pll, MClk, NVClk, cfg1;
1075 M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
1078 M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
1095 nv10CalcArbitration(&fifo_data, &sim_data);
1096 if (fifo_data.
valid)
1106 static void nForceUpdateArbitrationSettings
1109 unsigned pixelDepth,
1117 unsigned int M,
N,
P,
pll, MClk, NVClk;
1118 unsigned int uMClkPostDiv;
1122 pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
1124 uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
1126 if(!uMClkPostDiv) uMClkPostDiv = 4;
1127 MClk = 400000 / uMClkPostDiv;
1130 M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
1137 pci_read_config_dword(dev, 0x7C, &sim_data.
memory_type);
1149 nv10CalcArbitration(&fifo_data, &sim_data);
1150 if (fifo_data.
valid)
1169 static int CalcVClock
1179 unsigned lowM, highM, highP;
1180 unsigned DeltaNew, DeltaOld;
1181 unsigned VClk,
Freq;
1184 DeltaOld = 0xFFFFFFFF;
1186 VClk = (unsigned)clockIn;
1200 for (P = 0; P <= highP; P ++)
1205 for (M = lowM; M <= highM; M++)
1211 DeltaNew = Freq - VClk;
1213 DeltaNew = VClk -
Freq;
1214 if (DeltaNew < DeltaOld)
1220 DeltaOld = DeltaNew;
1228 return (DeltaOld != 0xFFFFFFFF);
1258 pixelDepth = (bpp + 1)/8;
1259 if (!CalcVClock(dotClock, &VClk, &
m, &
n, &p, chip))
1265 nv3UpdateArbitrationSettings(VClk,
1273 state->
pllsel = 0x10010100;
1274 state->
config = ((width + 31)/32)
1275 | (((pixelDepth > 2) ? 3 : pixelDepth) << 8)
1278 state->
repaint1 = hDisplaySize < 1280 ? 0x06 : 0x02;
1281 nv4UpdateArbitrationSettings(VClk,
1289 state->
pllsel = 0x10000700;
1290 state->
config = 0x00001114;
1291 state->
general = bpp == 16 ? 0x00101100 : 0x00100100;
1292 state->
repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
1300 nForceUpdateArbitrationSettings(VClk,
1306 nv10UpdateArbitrationSettings(VClk,
1315 state->
pllsel = 0x10000700;
1317 state->
general = bpp == 16 ? 0x00101100 : 0x00100100;
1318 state->
repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
1327 state->
vpll = (p << 16) | (
n << 8) |
m;
1328 state->
repaint0 = (((width/8)*pixelDepth) & 0x700) >> 3;
1329 state->
pixel = pixelDepth > 2 ? 3 : pixelDepth;
1345 #define LOAD_FIXED_STATE(tbl,dev) \
1346 for (i = 0; i < sizeof(tbl##Table##dev)/8; i++) \
1347 chip->dev[tbl##Table##dev[i][0]] = tbl##Table##dev[i][1]
1348 #define LOAD_FIXED_STATE_8BPP(tbl,dev) \
1349 for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++) \
1350 chip->dev[tbl##Table##dev##_8BPP[i][0]] = tbl##Table##dev##_8BPP[i][1]
1351 #define LOAD_FIXED_STATE_15BPP(tbl,dev) \
1352 for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++) \
1353 chip->dev[tbl##Table##dev##_15BPP[i][0]] = tbl##Table##dev##_15BPP[i][1]
1354 #define LOAD_FIXED_STATE_16BPP(tbl,dev) \
1355 for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++) \
1356 chip->dev[tbl##Table##dev##_16BPP[i][0]] = tbl##Table##dev##_16BPP[i][1]
1357 #define LOAD_FIXED_STATE_32BPP(tbl,dev) \
1358 for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++) \
1359 chip->dev[tbl##Table##dev##_32BPP[i][0]] = tbl##Table##dev##_32BPP[i][1]
1362 #define LOAD_FIXED_STATE(tbl,dev) \
1363 for (i = 0; i < sizeof(tbl##Table##dev)/8; i++) \
1364 NV_WR32(&chip->dev[tbl##Table##dev[i][0]], 0, tbl##Table##dev[i][1])
1365 #define LOAD_FIXED_STATE_8BPP(tbl,dev) \
1366 for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++) \
1367 NV_WR32(&chip->dev[tbl##Table##dev##_8BPP[i][0]], 0, tbl##Table##dev##_8BPP[i][1])
1368 #define LOAD_FIXED_STATE_15BPP(tbl,dev) \
1369 for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++) \
1370 NV_WR32(&chip->dev[tbl##Table##dev##_15BPP[i][0]], 0, tbl##Table##dev##_15BPP[i][1])
1371 #define LOAD_FIXED_STATE_16BPP(tbl,dev) \
1372 for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++) \
1373 NV_WR32(&chip->dev[tbl##Table##dev##_16BPP[i][0]], 0, tbl##Table##dev##_16BPP[i][1])
1374 #define LOAD_FIXED_STATE_32BPP(tbl,dev) \
1375 for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++) \
1376 NV_WR32(&chip->dev[tbl##Table##dev##_32BPP[i][0]], 0, tbl##Table##dev##_32BPP[i][1])
1378 static void UpdateFifoState
1405 static void LoadStateExt
1449 for (i = 0x00000; i < 0x00800; i++)
1450 NV_WR32(&chip->
PRAMIN[0x00000502 + i], 0, (i << 12) | 0x03);
1624 for (i = 0; i < (3*16); i++)
1629 for (i = 0; i < (16*16); i++)
1634 for (i = 0; i < (59*4); i++)
1637 for (i = 0; i < (47*4); i++)
1640 for (i = 0; i < (3*4); i++)
1643 for (i = 0; i < (19*4); i++)
1646 for (i = 0; i < (12*4); i++)
1649 for (i = 0; i < (12*4); i++)
1652 for (i = 0; i < (8*4); i++)
1655 for (i = 0; i < 16; i++)
1658 for (i = 0; i < 4; i++)
1664 if((chip->
Chipset & 0x0ff0) == 0x0110) {
1667 if((chip->
Chipset & 0x0ff0) >= 0x0170) {
1683 UpdateFifoState(chip);
1740 static void UnloadStateExt
1820 if((chip->
Chipset & 0x0ff0) == 0x0110) {
1823 if((chip->
Chipset & 0x0ff0) >= 0x0170) {
1829 static void SetStartAddress
1838 static void SetStartAddress3
1845 int pan = (start & 3) << 1;
1860 VGA_WR08(chip->
PCIO, 0x3D5, (offset & 0x01F) | (tmp & ~0x1F));
1862 VGA_WR08(chip->
PCIO, 0x3D5, (offset & 0x60) | (tmp & ~0x60));
1870 static void nv3SetSurfaces2D
1882 NV_WR32(&Surface->Offset, 0, surf0);
1884 NV_WR32(&Surface->Offset, 0, surf1);
1887 static void nv4SetSurfaces2D
1898 NV_WR32(&Surface->Offset, 0, surf0);
1900 NV_WR32(&Surface->Offset, 0, surf1);
1903 static void nv10SetSurfaces2D
1914 NV_WR32(&Surface->Offset, 0, surf0);
1916 NV_WR32(&Surface->Offset, 0, surf1);
1919 static void nv3SetSurfaces3D
1931 NV_WR32(&Surface->Offset, 0, surf0);
1933 NV_WR32(&Surface->Offset, 0, surf1);
1936 static void nv4SetSurfaces3D
1947 NV_WR32(&Surface->Offset, 0, surf0);
1949 NV_WR32(&Surface->Offset, 0, surf1);
1952 static void nv10SetSurfaces3D
1964 NV_WR32(&Surfaces3D->RenderBufferOffset, 0, surf0);
1965 NV_WR32(&Surfaces3D->ZBufferOffset, 0, surf1);
1975 static void nv3GetConfig
1983 if (
NV_RD32(&chip->
PFB[0x00000000/4], 0) & 0x00000020)
1985 if (((
NV_RD32(chip->
PMC, 0x00000000) & 0xF0) == 0x20)
1986 && ((
NV_RD32(chip->
PMC, 0x00000000) & 0x0F) >= 0x02))
1992 switch (
NV_RD32(chip->
PFB, 0x00000000) & 0x03)
2017 switch (
NV_RD32(chip->
PFB, 0x00000000) & 0x00000003)
2031 chip->
CURSOR = &(chip->
PRAMIN[0x00008000/4 - 0x0800/4]);
2037 chip->
Busy = nv3Busy;
2046 static void nv4GetConfig
2054 if (
NV_RD32(chip->
PFB, 0x00000000) & 0x00000100)
2061 switch (
NV_RD32(chip->
PFB, 0x00000000) & 0x00000003)
2078 switch ((
NV_RD32(chip->
PFB, 0x00000000) >> 3) & 0x00000003)
2088 chip->
CURSOR = &(chip->
PRAMIN[0x00010000/4 - 0x0800/4]);
2094 chip->
Busy = nv4Busy;
2103 static void nv10GetConfig
2114 if(!(
NV_RD32(chip->
PMC, 0x00000004) & 0x01000001))
2123 pci_read_config_dword(dev, 0x7C, &amt);
2128 pci_read_config_dword(dev, 0x84, &amt);
2132 switch ((
NV_RD32(chip->
PFB, 0x0000020C) >> 20) & 0x000000FF)
2160 switch ((
NV_RD32(chip->
PFB, 0x00000000) >> 3) & 0x00000003)
2172 switch (chipset & 0x0ff0) {
2197 chip->
Busy = nv10Busy;
2206 switch(chipset & 0x0ff0) {
2228 unsigned int chipset
2249 nv10GetConfig(chip, chipset);