52 #include <linux/pci.h>
141 static void nvGetClocks(
struct nvidia_par *par,
unsigned int *MClk,
148 P = (pll >> 16) & 0x07;
151 N = (pll >> 8) & 0xFF;
152 if (((par->
Chipset & 0xfff0) == 0x0290) ||
153 ((par->
Chipset & 0xfff0) == 0x0390)) {
157 MB = (pll >> 16) & 0xFF;
158 NB = (pll >> 24) & 0xFF;
163 P = (pll >> 16) & 0x07;
166 N = (pll >> 8) & 0xFF;
167 MB = (pll >> 16) & 0xFF;
168 NB = (pll >> 24) & 0xFF;
174 N = (pll >> 8) & 0xFF;
175 P = (pll >> 16) & 0x0F;
177 if (pll & 0x80000000) {
179 NB = (pll >> 8) & 0xFF;
188 N = (pll >> 8) & 0xFF;
189 P = (pll >> 16) & 0x0F;
191 if (pll & 0x80000000) {
193 NB = (pll >> 8) & 0xFF;
200 if (((par->
Chipset & 0x0ff0) == 0x0300) ||
201 ((par->
Chipset & 0x0ff0) == 0x0330)) {
204 N = (pll >> 8) & 0xFF;
205 P = (pll >> 16) & 0x07;
206 if (pll & 0x00000080) {
207 MB = (pll >> 4) & 0x07;
208 NB = (pll >> 19) & 0x1f;
217 N = (pll >> 8) & 0xFF;
218 P = (pll >> 16) & 0x07;
219 if (pll & 0x00000080) {
220 MB = (pll >> 4) & 0x07;
221 NB = (pll >> 19) & 0x1f;
230 N = (pll >> 8) & 0xFF;
231 P = (pll >> 16) & 0x0F;
236 N = (pll >> 8) & 0xFF;
237 P = (pll >> 16) & 0x0F;
245 int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
246 int found, mclk_extra, mclk_loop,
cbs, m1,
p1;
247 int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
248 int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate;
249 int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt, clwm;
290 mclk_loop = mclks + mclk_extra;
291 us_m = mclk_loop * 1000 * 1000 / mclk_freq;
292 us_n = nvclks * 1000 * 1000 / nvclk_freq;
293 us_p = nvclks * 1000 * 1000 / pclk_freq;
295 video_drain_rate = pclk_freq * 2;
296 crtc_drain_rate = pclk_freq * bpp / 8;
301 (vpagemiss * pagemiss) * 1000 * 1000 / mclk_freq;
302 if (nvclk_freq * 2 > mclk_freq * width)
304 cbs * 1000 * 1000 / 16 / nvclk_freq;
307 cbs * 1000 * 1000 / (8 *
width) /
309 us_video = vpm_us + us_m + us_n + us_p + video_fill_us;
310 vlwm = us_video * video_drain_rate / (1000 * 1000);
315 if (vlwm > (256 - 64))
317 if (nvclk_freq * 2 > mclk_freq * width)
319 vbs * 1000 * 1000 / 16 / nvclk_freq;
322 vbs * 1000 * 1000 / (8 *
width) /
325 crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
327 us_video + video_fill_us + cpm_us + us_m + us_n +
329 clwm = us_crt * crtc_drain_rate / (1000 * 1000);
332 crtc_drain_rate = pclk_freq * bpp / 8;
336 crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
337 us_crt = cpm_us + us_m + us_n + us_p;
338 clwm = us_crt * crtc_drain_rate / (1000 * 1000);
341 m1 = clwm + cbs - 512;
342 p1 = m1 * pclk_freq / mclk_freq;
344 if ((p1 < m1) && (m1 > 0)) {
350 }
else if (video_enable) {
351 if ((clwm > 511) || (vlwm > 255)) {
374 data = (
int)((vlwm + 15));
380 static void nv4UpdateArbitrationSettings(
unsigned VClk,
387 unsigned int MClk, NVClk, cfg1;
389 nvGetClocks(par, &MClk, &NVClk);
400 (
char)(((cfg1 >> 4) & 0x0F) + ((cfg1 >> 31) & 0x01));
405 nv4CalcArbitration(&fifo_data, &sim_data);
406 if (fifo_data.
valid) {
418 int nvclks, mclks, pclks, vpagemiss, crtpagemiss;
420 int found, mclk_extra, mclk_loop,
cbs, m1;
421 int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
422 int us_m, us_m_min, us_n, us_p, crtc_drain_rate;
424 int vpm_us, us_video, cpm_us, us_crt, clwm;
426 int m2us, us_pipe_min, p1clk, p2;
428 int us_min_mclk_extra;
468 mclk_extra = (bpp == 32) ? 31 : 42;
471 mclk_extra = (bpp == 32) ? 8 : 4;
492 mclk_loop = mclks + mclk_extra;
494 us_m = mclk_loop * 1000 * 1000 / mclk_freq;
496 us_m_min = mclks * 1000 * 1000 / mclk_freq;
497 us_min_mclk_extra = min_mclk_extra * 1000 * 1000 / mclk_freq;
499 us_n = nvclks * 1000 * 1000 / nvclk_freq;
501 us_p = pclks * 1000 * 1000 / pclk_freq;
502 us_pipe_min = us_m_min + us_n + us_p;
505 vus_m = mclk_loop * 1000 * 1000 / mclk_freq;
508 crtc_drain_rate = pclk_freq * bpp / 8;
518 (vpagemiss * pagemiss) * 1000 * 1000 / mclk_freq;
521 us_video = vpm_us + vus_m;
524 crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
531 clwm = us_crt * crtc_drain_rate / (1000 * 1000);
536 crtc_drain_rate = pclk_freq * bpp / 8;
543 crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
544 us_crt = cpm_us + us_m + us_n + us_p;
545 clwm = us_crt * crtc_drain_rate / (1000 * 1000);
551 nvclk_fill = nvclk_freq * 8;
552 if (crtc_drain_rate * 100 >= nvclk_fill * 102)
556 else if (crtc_drain_rate * 100 >=
568 clwm_rnd_down = ((
int)clwm / 8) * 8;
569 if (clwm_rnd_down < clwm)
572 m1 = clwm + cbs - 1024;
573 m2us = us_pipe_min + us_min_mclk_extra;
576 p1clk = m2us * pclk_freq / (1000 * 1000);
577 p2 = p1clk * bpp / 8;
579 if ((p2 < m1) && (m1 > 0)) {
582 if (min_mclk_extra == 0) {
597 if (min_mclk_extra == 0)
605 if (clwm < (1024 - cbs + 8))
606 clwm = 1024 - cbs + 8;
618 static void nv10UpdateArbitrationSettings(
unsigned VClk,
626 unsigned int MClk, NVClk, cfg1;
628 nvGetClocks(par, &MClk, &NVClk);
640 (
char)(((cfg1 >> 4) & 0x0F) + ((cfg1 >> 31) & 0x01));
645 nv10CalcArbitration(&fifo_data, &sim_data);
646 if (fifo_data.
valid) {
655 static void nv30UpdateArbitrationSettings (
661 unsigned int MClk, NVClk;
662 unsigned int fifo_size, burst_size, graphics_lwm;
666 graphics_lwm = fifo_size - burst_size;
668 nvGetClocks(par, &MClk, &NVClk);
672 while(burst_size >>= 1) (*burst)++;
673 *lwm = graphics_lwm >> 3;
676 static void nForceUpdateArbitrationSettings(
unsigned VClk,
684 unsigned int M,
N,
P,
pll, MClk, NVClk, memctrl;
687 if ((par->
Chipset & 0x0FF0) == 0x01A0) {
688 unsigned int uMClkPostDiv;
690 pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
691 uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
695 MClk = 400000 / uMClkPostDiv;
698 pci_read_config_dword(dev, 0x4c, &MClk);
703 M = (pll >> 0) & 0xFF;
704 N = (pll >> 8) & 0xFF;
705 P = (pll >> 16) & 0x0F;
711 pci_read_config_dword(dev, 0x7C, &sim_data.
memory_type);
717 pci_read_config_dword(dev, 0, &memctrl);
721 if ((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) {
725 pci_read_config_dword(dev, 0x40, &dimm[0]);
726 dimm[0] = (dimm[0] >> 8) & 0x4f;
727 pci_read_config_dword(dev, 0x44, &dimm[1]);
728 dimm[1] = (dimm[1] >> 8) & 0x4f;
729 pci_read_config_dword(dev, 0x48, &dimm[2]);
730 dimm[2] = (dimm[2] >> 8) & 0x4f;
732 if ((dimm[0] + dimm[1]) != dimm[2]) {
733 printk(
"nvidiafb: your nForce DIMMs are not arranged "
734 "in optimal banks!\n");
746 nv10CalcArbitration(&fifo_data, &sim_data);
747 if (fifo_data.
valid) {
765 static void CalcVClock(
int clockIn,
768 unsigned lowM, highM;
769 unsigned DeltaNew, DeltaOld;
773 DeltaOld = 0xFFFFFFFF;
775 VClk = (unsigned)clockIn;
785 for (P = 0; P <= 4; P++) {
787 if ((Freq >= 128000) && (Freq <= 350000)) {
788 for (M = lowM; M <= highM; M++) {
795 DeltaNew = Freq - VClk;
797 DeltaNew = VClk -
Freq;
798 if (DeltaNew < DeltaOld) {
800 (P << 16) | (N << 8) |
M;
810 static void CalcVClock2Stage(
int clockIn,
815 unsigned DeltaNew, DeltaOld;
819 DeltaOld = 0xFFFFFFFF;
821 *pllBOut = 0x80000401;
823 VClk = (unsigned)clockIn;
825 for (P = 0; P <= 6; P++) {
827 if ((Freq >= 400000) && (Freq <= 1000000)) {
828 for (M = 1; M <= 13; M++) {
829 N = ((VClk <<
P) * M) /
831 if ((N >= 5) && (N <= 255)) {
836 DeltaNew = Freq - VClk;
838 DeltaNew = VClk -
Freq;
839 if (DeltaNew < DeltaOld) {
841 (P << 16) | (N << 8) |
M;
859 int hDisplaySize,
int height,
int dotClock,
int flags)
861 int pixelDepth, VClk = 0;
871 pixelDepth = (bpp + 1) / 8;
873 CalcVClock2Stage(dotClock, &VClk, &state->
pll, &state->
pllB,
876 CalcVClock(dotClock, &VClk, &state->
pll, par);
880 nv4UpdateArbitrationSettings(VClk,
889 state->
pllsel = 0x10000700;
890 state->
config = 0x00001114;
891 state->
general = bpp == 16 ? 0x00101100 : 0x00100100;
892 state->
repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
903 if ((par->
Chipset & 0xfff0) == 0x0240 ||
904 (par->
Chipset & 0xfff0) == 0x03d0) {
907 }
else if (((par->
Chipset & 0xffff) == 0x01A0) ||
908 ((par->
Chipset & 0xffff) == 0x01f0)) {
909 nForceUpdateArbitrationSettings(VClk,
915 nv10UpdateArbitrationSettings(VClk,
921 nv30UpdateArbitrationSettings(par,
929 if (flags & FB_VMODE_DOUBLE)
931 state->
pllsel = 0x10000700;
933 state->
general = bpp == 16 ? 0x00101100 : 0x00100100;
934 state->
repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
941 state->
repaint0 = (((width / 8) * pixelDepth) & 0x700) >> 3;
942 state->
pixel = (pixelDepth > 2) ? 3 : pixelDepth;
962 (par->
Chipset & 0xfff0) == 0x0040) {
963 for (i = 0; i < 8; i++) {
971 if (((par->
Chipset & 0xfff0) == 0x0090) ||
972 ((par->
Chipset & 0xfff0) == 0x01D0) ||
973 ((par->
Chipset & 0xfff0) == 0x0290) ||
974 ((par->
Chipset & 0xfff0) == 0x0390) ||
975 ((par->
Chipset & 0xfff0) == 0x03D0))
977 for(i = 0; i < regions; i++) {
1163 if ((par->
Chipset & 0x0fff) == 0x0020) {
1202 for (i = 0; i < 32; i++)
1227 for (i = 0; !(j & 1); j >>= 1, i++);
1231 if ((par->
Chipset & 0xfff0) == 0x0040) {
1243 switch (par->
Chipset & 0xfff0) {
1275 0x0608) | 0x00100000);
1323 if ((par->
Chipset & 0x0ff0) >= 0x0250) {
1359 ((par->
Chipset & 0xfff0) == 0x0040)) {
1360 for (i = 0; i < 32; i++) {
1367 if (((par->
Chipset & 0xfff0) == 0x0090) ||
1368 ((par->
Chipset & 0xfff0) == 0x01D0) ||
1369 ((par->
Chipset & 0xfff0) == 0x0290) ||
1370 ((par->
Chipset & 0xfff0) == 0x0390) ||
1371 ((par->
Chipset & 0xfff0) == 0x03D0)) {
1372 for (i = 0; i < 60; i++) {
1383 for (i = 0; i < 48; i++) {
1403 if ((par->
Chipset & 0xfff0) == 0x0040) {
1420 if ((par->
Chipset & 0xfff0) == 0x0090 ||
1421 (par->
Chipset & 0xfff0) == 0x01D0 ||
1422 (par->
Chipset & 0xfff0) == 0x0290 ||
1423 (par->
Chipset & 0xfff0) == 0x0390) {
1537 if ((par->
Chipset & 0x0ff0) == 0x0110) {
1669 if ((par->
Chipset & 0x0ff0) == 0x0110) {