aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c136
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h24
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_calc.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hw.c27
-rw-r--r--drivers/gpu/drm/nouveau/nv04_crtc.c2
6 files changed, 135 insertions, 59 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 974b0f8ae04..2319390b200 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -4675,6 +4675,92 @@ int run_tmds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, i
4675 return 0; 4675 return 0;
4676} 4676}
4677 4677
4678struct pll_mapping {
4679 u8 type;
4680 u32 reg;
4681};
4682
4683static struct pll_mapping nv04_pll_mapping[] = {
4684 { PLL_CORE , NV_PRAMDAC_NVPLL_COEFF },
4685 { PLL_MEMORY, NV_PRAMDAC_MPLL_COEFF },
4686 { PLL_VPLL0 , NV_PRAMDAC_VPLL_COEFF },
4687 { PLL_VPLL1 , NV_RAMDAC_VPLL2 },
4688 {}
4689};
4690
4691static struct pll_mapping nv40_pll_mapping[] = {
4692 { PLL_CORE , 0x004000 },
4693 { PLL_MEMORY, 0x004020 },
4694 { PLL_VPLL0 , NV_PRAMDAC_VPLL_COEFF },
4695 { PLL_VPLL1 , NV_RAMDAC_VPLL2 },
4696 {}
4697};
4698
4699static struct pll_mapping nv50_pll_mapping[] = {
4700 { PLL_CORE , 0x004028 },
4701 { PLL_SHADER, 0x004020 },
4702 { PLL_UNK03 , 0x004000 },
4703 { PLL_MEMORY, 0x004008 },
4704 { PLL_UNK40 , 0x00e810 },
4705 { PLL_UNK41 , 0x00e818 },
4706 { PLL_UNK42 , 0x00e824 },
4707 { PLL_VPLL0 , 0x614100 },
4708 { PLL_VPLL1 , 0x614900 },
4709 {}
4710};
4711
4712static struct pll_mapping nv84_pll_mapping[] = {
4713 { PLL_CORE , 0x004028 },
4714 { PLL_SHADER, 0x004020 },
4715 { PLL_MEMORY, 0x004008 },
4716 { PLL_UNK05 , 0x004030 },
4717 { PLL_UNK41 , 0x00e818 },
4718 { PLL_VPLL0 , 0x614100 },
4719 { PLL_VPLL1 , 0x614900 },
4720 {}
4721};
4722
4723u32
4724get_pll_register(struct drm_device *dev, enum pll_types type)
4725{
4726 struct drm_nouveau_private *dev_priv = dev->dev_private;
4727 struct nvbios *bios = &dev_priv->vbios;
4728 struct pll_mapping *map;
4729 int i;
4730
4731 if (dev_priv->card_type < NV_40)
4732 map = nv04_pll_mapping;
4733 else
4734 if (dev_priv->card_type < NV_50)
4735 map = nv40_pll_mapping;
4736 else {
4737 u8 *plim = &bios->data[bios->pll_limit_tbl_ptr];
4738
4739 if (plim[0] >= 0x40) {
4740 u8 *entry = plim + plim[1];
4741 for (i = 0; i < plim[3]; i++, entry += plim[2]) {
4742 if (entry[0] == type)
4743 return ROM32(entry[3]);
4744 }
4745
4746 return 0;
4747 }
4748
4749 if (dev_priv->chipset == 0x50)
4750 map = nv50_pll_mapping;
4751 else
4752 map = nv84_pll_mapping;
4753 }
4754
4755 while (map->reg) {
4756 if (map->type == type)
4757 return map->reg;
4758 map++;
4759 }
4760
4761 return 0;
4762}
4763
4678int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims *pll_lim) 4764int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims *pll_lim)
4679{ 4765{
4680 /* 4766 /*
@@ -4750,6 +4836,14 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims
4750 /* initialize all members to zero */ 4836 /* initialize all members to zero */
4751 memset(pll_lim, 0, sizeof(struct pll_lims)); 4837 memset(pll_lim, 0, sizeof(struct pll_lims));
4752 4838
4839 /* if we were passed a type rather than a register, figure
4840 * out the register and store it
4841 */
4842 if (limit_match > PLL_MAX)
4843 pll_lim->reg = limit_match;
4844 else
4845 pll_lim->reg = get_pll_register(dev, limit_match);
4846
4753 if (pll_lim_ver == 0x10 || pll_lim_ver == 0x11) { 4847 if (pll_lim_ver == 0x10 || pll_lim_ver == 0x11) {
4754 uint8_t *pll_rec = &bios->data[bios->pll_limit_tbl_ptr + headerlen + recordlen * pllindex]; 4848 uint8_t *pll_rec = &bios->data[bios->pll_limit_tbl_ptr + headerlen + recordlen * pllindex];
4755 4849
@@ -4785,7 +4879,6 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims
4785 pll_lim->max_usable_log2p = 0x6; 4879 pll_lim->max_usable_log2p = 0x6;
4786 } else if (pll_lim_ver == 0x20 || pll_lim_ver == 0x21) { 4880 } else if (pll_lim_ver == 0x20 || pll_lim_ver == 0x21) {
4787 uint16_t plloffs = bios->pll_limit_tbl_ptr + headerlen; 4881 uint16_t plloffs = bios->pll_limit_tbl_ptr + headerlen;
4788 uint32_t reg = 0; /* default match */
4789 uint8_t *pll_rec; 4882 uint8_t *pll_rec;
4790 int i; 4883 int i;
4791 4884
@@ -4797,29 +4890,8 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims
4797 NV_WARN(dev, "Default PLL limit entry has non-zero " 4890 NV_WARN(dev, "Default PLL limit entry has non-zero "
4798 "register field\n"); 4891 "register field\n");
4799 4892
4800 if (limit_match > MAX_PLL_TYPES)
4801 /* we've been passed a reg as the match */
4802 reg = limit_match;
4803 else /* limit match is a pll type */
4804 for (i = 1; i < entries && !reg; i++) {
4805 uint32_t cmpreg = ROM32(bios->data[plloffs + recordlen * i]);
4806
4807 if (limit_match == NVPLL &&
4808 (cmpreg == NV_PRAMDAC_NVPLL_COEFF || cmpreg == 0x4000))
4809 reg = cmpreg;
4810 if (limit_match == MPLL &&
4811 (cmpreg == NV_PRAMDAC_MPLL_COEFF || cmpreg == 0x4020))
4812 reg = cmpreg;
4813 if (limit_match == VPLL1 &&
4814 (cmpreg == NV_PRAMDAC_VPLL_COEFF || cmpreg == 0x4010))
4815 reg = cmpreg;
4816 if (limit_match == VPLL2 &&
4817 (cmpreg == NV_RAMDAC_VPLL2 || cmpreg == 0x4018))
4818 reg = cmpreg;
4819 }
4820
4821 for (i = 1; i < entries; i++) 4893 for (i = 1; i < entries; i++)
4822 if (ROM32(bios->data[plloffs + recordlen * i]) == reg) { 4894 if (ROM32(bios->data[plloffs + recordlen * i]) == pll_lim->reg) {
4823 pllindex = i; 4895 pllindex = i;
4824 break; 4896 break;
4825 } 4897 }
@@ -4827,7 +4899,7 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims
4827 pll_rec = &bios->data[plloffs + recordlen * pllindex]; 4899 pll_rec = &bios->data[plloffs + recordlen * pllindex];
4828 4900
4829 BIOSLOG(bios, "Loading PLL limits for reg 0x%08x\n", 4901 BIOSLOG(bios, "Loading PLL limits for reg 0x%08x\n",
4830 pllindex ? reg : 0); 4902 pllindex ? pll_lim->reg : 0);
4831 4903
4832 /* 4904 /*
4833 * Frequencies are stored in tables in MHz, kHz are more 4905 * Frequencies are stored in tables in MHz, kHz are more
@@ -4877,8 +4949,8 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims
4877 if (cv == 0x51 && !pll_lim->refclk) { 4949 if (cv == 0x51 && !pll_lim->refclk) {
4878 uint32_t sel_clk = bios_rd32(bios, NV_PRAMDAC_SEL_CLK); 4950 uint32_t sel_clk = bios_rd32(bios, NV_PRAMDAC_SEL_CLK);
4879 4951
4880 if (((limit_match == NV_PRAMDAC_VPLL_COEFF || limit_match == VPLL1) && sel_clk & 0x20) || 4952 if ((pll_lim->reg == NV_PRAMDAC_VPLL_COEFF && sel_clk & 0x20) ||
4881 ((limit_match == NV_RAMDAC_VPLL2 || limit_match == VPLL2) && sel_clk & 0x80)) { 4953 (pll_lim->reg == NV_RAMDAC_VPLL2 && sel_clk & 0x80)) {
4882 if (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_CHIP_ID_INDEX) < 0xa3) 4954 if (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_CHIP_ID_INDEX) < 0xa3)
4883 pll_lim->refclk = 200000; 4955 pll_lim->refclk = 200000;
4884 else 4956 else
@@ -4891,10 +4963,10 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims
4891 int i; 4963 int i;
4892 4964
4893 BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n", 4965 BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n",
4894 limit_match); 4966 pll_lim->reg);
4895 4967
4896 for (i = 0; i < entries; i++, entry += recordlen) { 4968 for (i = 0; i < entries; i++, entry += recordlen) {
4897 if (ROM32(entry[3]) == limit_match) { 4969 if (ROM32(entry[3]) == pll_lim->reg) {
4898 record = &bios->data[ROM16(entry[1])]; 4970 record = &bios->data[ROM16(entry[1])];
4899 break; 4971 break;
4900 } 4972 }
@@ -4902,7 +4974,7 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims
4902 4974
4903 if (!record) { 4975 if (!record) {
4904 NV_ERROR(dev, "Register 0x%08x not found in PLL " 4976 NV_ERROR(dev, "Register 0x%08x not found in PLL "
4905 "limits table", limit_match); 4977 "limits table", pll_lim->reg);
4906 return -ENOENT; 4978 return -ENOENT;
4907 } 4979 }
4908 4980
@@ -4931,10 +5003,10 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims
4931 int i; 5003 int i;
4932 5004
4933 BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n", 5005 BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n",
4934 limit_match); 5006 pll_lim->reg);
4935 5007
4936 for (i = 0; i < entries; i++, entry += recordlen) { 5008 for (i = 0; i < entries; i++, entry += recordlen) {
4937 if (ROM32(entry[3]) == limit_match) { 5009 if (ROM32(entry[3]) == pll_lim->reg) {
4938 record = &bios->data[ROM16(entry[1])]; 5010 record = &bios->data[ROM16(entry[1])];
4939 break; 5011 break;
4940 } 5012 }
@@ -4942,7 +5014,7 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims
4942 5014
4943 if (!record) { 5015 if (!record) {
4944 NV_ERROR(dev, "Register 0x%08x not found in PLL " 5016 NV_ERROR(dev, "Register 0x%08x not found in PLL "
4945 "limits table", limit_match); 5017 "limits table", pll_lim->reg);
4946 return -ENOENT; 5018 return -ENOENT;
4947 } 5019 }
4948 5020
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index c1de2f3fcb0..02c5dd09ba7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -170,16 +170,28 @@ enum LVDS_script {
170 LVDS_PANEL_OFF 170 LVDS_PANEL_OFF
171}; 171};
172 172
173/* changing these requires matching changes to reg tables in nv_get_clock */ 173/* these match types in pll limits table version 0x40,
174#define MAX_PLL_TYPES 4 174 * nouveau uses them on all chipsets internally where a
175 * specific pll needs to be referenced, but the exact
176 * register isn't known.
177 */
175enum pll_types { 178enum pll_types {
176 NVPLL, 179 PLL_CORE = 0x01,
177 MPLL, 180 PLL_SHADER = 0x02,
178 VPLL1, 181 PLL_UNK03 = 0x03,
179 VPLL2 182 PLL_MEMORY = 0x04,
183 PLL_UNK05 = 0x05,
184 PLL_UNK40 = 0x40,
185 PLL_UNK41 = 0x41,
186 PLL_UNK42 = 0x42,
187 PLL_VPLL0 = 0x80,
188 PLL_VPLL1 = 0x81,
189 PLL_MAX = 0xff
180}; 190};
181 191
182struct pll_lims { 192struct pll_lims {
193 u32 reg;
194
183 struct { 195 struct {
184 int minfreq; 196 int minfreq;
185 int maxfreq; 197 int maxfreq;
diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/nouveau_calc.c
index 23d9896962f..dad96cce5e3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_calc.c
+++ b/drivers/gpu/drm/nouveau/nouveau_calc.c
@@ -198,8 +198,8 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
198 struct drm_nouveau_private *dev_priv = dev->dev_private; 198 struct drm_nouveau_private *dev_priv = dev->dev_private;
199 struct nv_fifo_info fifo_data; 199 struct nv_fifo_info fifo_data;
200 struct nv_sim_state sim_data; 200 struct nv_sim_state sim_data;
201 int MClk = nouveau_hw_get_clock(dev, MPLL); 201 int MClk = nouveau_hw_get_clock(dev, PLL_MEMORY);
202 int NVClk = nouveau_hw_get_clock(dev, NVPLL); 202 int NVClk = nouveau_hw_get_clock(dev, PLL_CORE);
203 uint32_t cfg1 = nvReadFB(dev, NV04_PFB_CFG1); 203 uint32_t cfg1 = nvReadFB(dev, NV04_PFB_CFG1);
204 204
205 sim_data.pclk_khz = VClk; 205 sim_data.pclk_khz = VClk;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 912b04be0de..d2fecc05eae 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -853,6 +853,7 @@ extern struct dcb_gpio_entry *nouveau_bios_gpio_entry(struct drm_device *,
853 enum dcb_gpio_tag); 853 enum dcb_gpio_tag);
854extern struct dcb_connector_table_entry * 854extern struct dcb_connector_table_entry *
855nouveau_bios_connector_entry(struct drm_device *, int index); 855nouveau_bios_connector_entry(struct drm_device *, int index);
856extern u32 get_pll_register(struct drm_device *, enum pll_types);
856extern int get_pll_limits(struct drm_device *, uint32_t limit_match, 857extern int get_pll_limits(struct drm_device *, uint32_t limit_match,
857 struct pll_lims *); 858 struct pll_lims *);
858extern int nouveau_bios_run_display_table(struct drm_device *, 859extern int nouveau_bios_run_display_table(struct drm_device *,
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c
index f8ec49b5308..e228aafc03e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.c
@@ -427,22 +427,11 @@ nouveau_hw_get_pllvals(struct drm_device *dev, enum pll_types plltype,
427 struct nouveau_pll_vals *pllvals) 427 struct nouveau_pll_vals *pllvals)
428{ 428{
429 struct drm_nouveau_private *dev_priv = dev->dev_private; 429 struct drm_nouveau_private *dev_priv = dev->dev_private;
430 const uint32_t nv04_regs[MAX_PLL_TYPES] = { NV_PRAMDAC_NVPLL_COEFF, 430 uint32_t reg1 = get_pll_register(dev, plltype), pll1, pll2 = 0;
431 NV_PRAMDAC_MPLL_COEFF,
432 NV_PRAMDAC_VPLL_COEFF,
433 NV_RAMDAC_VPLL2 };
434 const uint32_t nv40_regs[MAX_PLL_TYPES] = { 0x4000,
435 0x4020,
436 NV_PRAMDAC_VPLL_COEFF,
437 NV_RAMDAC_VPLL2 };
438 uint32_t reg1, pll1, pll2 = 0;
439 struct pll_lims pll_lim; 431 struct pll_lims pll_lim;
440 int ret; 432 int ret;
441 433
442 if (dev_priv->card_type < NV_40) 434 BUG_ON(reg1 == 0);
443 reg1 = nv04_regs[plltype];
444 else
445 reg1 = nv40_regs[plltype];
446 435
447 pll1 = nvReadMC(dev, reg1); 436 pll1 = nvReadMC(dev, reg1);
448 437
@@ -492,7 +481,8 @@ nouveau_hw_get_clock(struct drm_device *dev, enum pll_types plltype)
492{ 481{
493 struct nouveau_pll_vals pllvals; 482 struct nouveau_pll_vals pllvals;
494 483
495 if (plltype == MPLL && (dev->pci_device & 0x0ff0) == CHIPSET_NFORCE) { 484 if (plltype == PLL_MEMORY &&
485 (dev->pci_device & 0x0ff0) == CHIPSET_NFORCE) {
496 uint32_t mpllP; 486 uint32_t mpllP;
497 487
498 pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP); 488 pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP);
@@ -501,7 +491,8 @@ nouveau_hw_get_clock(struct drm_device *dev, enum pll_types plltype)
501 491
502 return 400000 / mpllP; 492 return 400000 / mpllP;
503 } else 493 } else
504 if (plltype == MPLL && (dev->pci_device & 0xff0) == CHIPSET_NFORCE2) { 494 if (plltype == PLL_MEMORY &&
495 (dev->pci_device & 0xff0) == CHIPSET_NFORCE2) {
505 uint32_t clock; 496 uint32_t clock;
506 497
507 pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock); 498 pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock);
@@ -526,9 +517,9 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
526 struct nouveau_pll_vals pv; 517 struct nouveau_pll_vals pv;
527 uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF; 518 uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF;
528 519
529 if (get_pll_limits(dev, head ? VPLL2 : VPLL1, &pll_lim)) 520 if (get_pll_limits(dev, pllreg, &pll_lim))
530 return; 521 return;
531 nouveau_hw_get_pllvals(dev, head ? VPLL2 : VPLL1, &pv); 522 nouveau_hw_get_pllvals(dev, pllreg, &pv);
532 523
533 if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m && 524 if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m &&
534 pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n && 525 pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n &&
@@ -661,7 +652,7 @@ nv_save_state_ramdac(struct drm_device *dev, int head,
661 if (dev_priv->card_type >= NV_10) 652 if (dev_priv->card_type >= NV_10)
662 regp->nv10_cursync = NVReadRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC); 653 regp->nv10_cursync = NVReadRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC);
663 654
664 nouveau_hw_get_pllvals(dev, head ? VPLL2 : VPLL1, &regp->pllvals); 655 nouveau_hw_get_pllvals(dev, head ? PLL_VPLL1 : PLL_VPLL0, &regp->pllvals);
665 state->pllsel = NVReadRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT); 656 state->pllsel = NVReadRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT);
666 if (nv_two_heads(dev)) 657 if (nv_two_heads(dev))
667 state->sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK); 658 state->sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK);
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
index 1f0f978d8e9..ef480281afe 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -109,7 +109,7 @@ static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mod
109 struct nouveau_pll_vals *pv = &regp->pllvals; 109 struct nouveau_pll_vals *pv = &regp->pllvals;
110 struct pll_lims pll_lim; 110 struct pll_lims pll_lim;
111 111
112 if (get_pll_limits(dev, nv_crtc->index ? VPLL2 : VPLL1, &pll_lim)) 112 if (get_pll_limits(dev, nv_crtc->index ? PLL_VPLL1 : PLL_VPLL0, &pll_lim))
113 return; 113 return;
114 114
115 /* NM2 == 0 is used to determine single stage mode on two stage plls */ 115 /* NM2 == 0 is used to determine single stage mode on two stage plls */