aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_bios.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-11-10 19:22:19 -0500
committerBen Skeggs <bskeggs@redhat.com>2011-12-21 04:01:40 -0500
commit486a45c2a6c19b159602d044ab601a92cd81f524 (patch)
tree350a368208768873667cd1a659a6d264a76f7c91 /drivers/gpu/drm/nouveau/nouveau_bios.c
parent6b5a81a2e783f26a69fc262b3c393f0b391c8613 (diff)
drm/nouveau/i2c: do parsing of i2c-related vbios info in nouveau_i2c.c
Not much point parsing the vbios data into a struct which is only used once to parse the data into another struct, go directly from vbios to nouveau_i2c_chan. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_bios.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c166
1 files changed, 10 insertions, 156 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index c7723fb54077..7922bb969d25 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -720,116 +720,20 @@ static int dcb_entry_idx_from_crtchead(struct drm_device *dev)
720 return dcb_entry; 720 return dcb_entry;
721} 721}
722 722
723static int
724read_dcb_i2c_entry(struct drm_device *dev, int dcb_version, uint8_t *i2ctable, int index, struct dcb_i2c_entry *i2c)
725{
726 uint8_t dcb_i2c_ver = dcb_version, headerlen = 0, entry_len = 4;
727 int i2c_entries = DCB_MAX_NUM_I2C_ENTRIES;
728 int recordoffset = 0, rdofs = 1, wrofs = 0;
729 uint8_t port_type = 0;
730
731 if (!i2ctable)
732 return -EINVAL;
733
734 if (dcb_version >= 0x30) {
735 if (i2ctable[0] != dcb_version) /* necessary? */
736 NV_WARN(dev,
737 "DCB I2C table version mismatch (%02X vs %02X)\n",
738 i2ctable[0], dcb_version);
739 dcb_i2c_ver = i2ctable[0];
740 headerlen = i2ctable[1];
741 if (i2ctable[2] <= DCB_MAX_NUM_I2C_ENTRIES)
742 i2c_entries = i2ctable[2];
743 else
744 NV_WARN(dev,
745 "DCB I2C table has more entries than indexable "
746 "(%d entries, max %d)\n", i2ctable[2],
747 DCB_MAX_NUM_I2C_ENTRIES);
748 entry_len = i2ctable[3];
749 /* [4] is i2c_default_indices, read in parse_dcb_table() */
750 }
751 /*
752 * It's your own fault if you call this function on a DCB 1.1 BIOS --
753 * the test below is for DCB 1.2
754 */
755 if (dcb_version < 0x14) {
756 recordoffset = 2;
757 rdofs = 0;
758 wrofs = 1;
759 }
760
761 if (index == 0xf)
762 return 0;
763 if (index >= i2c_entries) {
764 NV_ERROR(dev, "DCB I2C index too big (%d >= %d)\n",
765 index, i2ctable[2]);
766 return -ENOENT;
767 }
768 if (i2ctable[headerlen + entry_len * index + 3] == 0xff) {
769 NV_ERROR(dev, "DCB I2C entry invalid\n");
770 return -EINVAL;
771 }
772
773 if (dcb_i2c_ver >= 0x30) {
774 port_type = i2ctable[headerlen + recordoffset + 3 + entry_len * index];
775
776 /*
777 * Fixup for chips using same address offset for read and
778 * write.
779 */
780 if (port_type == 4) /* seen on C51 */
781 rdofs = wrofs = 1;
782 if (port_type >= 5) /* G80+ */
783 rdofs = wrofs = 0;
784 }
785
786 if (dcb_i2c_ver >= 0x40) {
787 if (port_type != 5 && port_type != 6)
788 NV_WARN(dev, "DCB I2C table has port type %d\n", port_type);
789
790 i2c->entry = ROM32(i2ctable[headerlen + recordoffset + entry_len * index]);
791 }
792
793 i2c->port_type = port_type;
794 i2c->read = i2ctable[headerlen + recordoffset + rdofs + entry_len * index];
795 i2c->write = i2ctable[headerlen + recordoffset + wrofs + entry_len * index];
796
797 return 0;
798}
799
800static struct nouveau_i2c_chan * 723static struct nouveau_i2c_chan *
801init_i2c_device_find(struct drm_device *dev, int i2c_index) 724init_i2c_device_find(struct drm_device *dev, int i2c_index)
802{ 725{
803 struct drm_nouveau_private *dev_priv = dev->dev_private;
804 struct dcb_table *dcb = &dev_priv->vbios.dcb;
805
806 if (i2c_index == 0xff) { 726 if (i2c_index == 0xff) {
727 struct drm_nouveau_private *dev_priv = dev->dev_private;
728 struct dcb_table *dcb = &dev_priv->vbios.dcb;
807 /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */ 729 /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */
808 int idx = dcb_entry_idx_from_crtchead(dev), shift = 0; 730 int idx = dcb_entry_idx_from_crtchead(dev);
809 int default_indices = dcb->i2c_default_indices;
810 731
732 i2c_index = NV_I2C_DEFAULT(0);
811 if (idx != 0x7f && dcb->entry[idx].i2c_upper_default) 733 if (idx != 0x7f && dcb->entry[idx].i2c_upper_default)
812 shift = 4; 734 i2c_index = NV_I2C_DEFAULT(1);
813
814 i2c_index = (default_indices >> shift) & 0xf;
815 }
816 if (i2c_index == 0x80) /* g80+ */
817 i2c_index = dcb->i2c_default_indices & 0xf;
818 else
819 if (i2c_index == 0x81)
820 i2c_index = (dcb->i2c_default_indices & 0xf0) >> 4;
821
822 if (i2c_index >= DCB_MAX_NUM_I2C_ENTRIES) {
823 NV_ERROR(dev, "invalid i2c_index 0x%x\n", i2c_index);
824 return NULL;
825 } 735 }
826 736
827 /* Make sure i2c table entry has been parsed, it may not
828 * have been if this is a bus not referenced by a DCB encoder
829 */
830 read_dcb_i2c_entry(dev, dcb->version, dcb->i2c_table,
831 i2c_index, &dcb->i2c[i2c_index]);
832
833 return nouveau_i2c_find(dev, i2c_index); 737 return nouveau_i2c_find(dev, i2c_index);
834} 738}
835 739
@@ -5595,10 +5499,6 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi
5595 uint16_t legacy_scripts_offset, legacy_i2c_offset; 5499 uint16_t legacy_scripts_offset, legacy_i2c_offset;
5596 5500
5597 /* load needed defaults in case we can't parse this info */ 5501 /* load needed defaults in case we can't parse this info */
5598 bios->dcb.i2c[0].write = NV_CIO_CRE_DDC_WR__INDEX;
5599 bios->dcb.i2c[0].read = NV_CIO_CRE_DDC_STATUS__INDEX;
5600 bios->dcb.i2c[1].write = NV_CIO_CRE_DDC0_WR__INDEX;
5601 bios->dcb.i2c[1].read = NV_CIO_CRE_DDC0_STATUS__INDEX;
5602 bios->digital_min_front_porch = 0x4b; 5502 bios->digital_min_front_porch = 0x4b;
5603 bios->fmaxvco = 256000; 5503 bios->fmaxvco = 256000;
5604 bios->fminvco = 128000; 5504 bios->fminvco = 128000;
@@ -5706,14 +5606,6 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi
5706 bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset]; 5606 bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset];
5707 bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1]; 5607 bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1];
5708 bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2]; 5608 bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2];
5709 if (bios->data[legacy_i2c_offset + 4])
5710 bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4];
5711 if (bios->data[legacy_i2c_offset + 5])
5712 bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5];
5713 if (bios->data[legacy_i2c_offset + 6])
5714 bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6];
5715 if (bios->data[legacy_i2c_offset + 7])
5716 bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7];
5717 5609
5718 if (bmplength > 74) { 5610 if (bmplength > 74) {
5719 bios->fmaxvco = ROM32(bmp[67]); 5611 bios->fmaxvco = ROM32(bmp[67]);
@@ -6549,10 +6441,6 @@ parse_dcb_entry(struct drm_device *dev, void *data, int idx, u8 *outp)
6549 ret = parse_dcb15_entry(dev, dcb, conn, conf, entry); 6441 ret = parse_dcb15_entry(dev, dcb, conn, conf, entry);
6550 if (!ret) 6442 if (!ret)
6551 return 1; /* stop parsing */ 6443 return 1; /* stop parsing */
6552
6553 read_dcb_i2c_entry(dev, dcb->version, dcb->i2c_table,
6554 entry->i2c_index,
6555 &dcb->i2c[entry->i2c_index]);
6556 } 6444 }
6557 6445
6558 return 0; 6446 return 0;
@@ -6562,7 +6450,6 @@ static int
6562parse_dcb_table(struct drm_device *dev, struct nvbios *bios) 6450parse_dcb_table(struct drm_device *dev, struct nvbios *bios)
6563{ 6451{
6564 struct dcb_table *dcb = &bios->dcb; 6452 struct dcb_table *dcb = &bios->dcb;
6565 u16 i2ctabptr = 0x0000;
6566 u8 *dcbt; 6453 u8 *dcbt;
6567 6454
6568 dcbt = dcb_table(dev); 6455 dcbt = dcb_table(dev);
@@ -6580,32 +6467,8 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios)
6580 6467
6581 dcb->version = dcbt[0]; 6468 dcb->version = dcbt[0];
6582 if (dcb->version >= 0x30) { 6469 if (dcb->version >= 0x30) {
6583 i2ctabptr = ROM16(dcbt[4]);
6584 dcb->gpio_table_ptr = ROM16(dcbt[10]); 6470 dcb->gpio_table_ptr = ROM16(dcbt[10]);
6585 dcb->connector_table_ptr = ROM16(dcbt[20]); 6471 dcb->connector_table_ptr = ROM16(dcbt[20]);
6586 } else
6587 if (dcb->version >= 0x15) {
6588 i2ctabptr = ROM16(dcbt[2]);
6589 }
6590
6591 if (!i2ctabptr)
6592 NV_WARN(dev, "No pointer to DCB I2C port table\n");
6593 else {
6594 dcb->i2c_table = &bios->data[i2ctabptr];
6595 if (dcb->version >= 0x30)
6596 dcb->i2c_default_indices = dcb->i2c_table[4];
6597
6598 /*
6599 * Parse the "management" I2C bus, used for hardware
6600 * monitoring and some external TMDS transmitters.
6601 */
6602 if (dcb->version >= 0x22) {
6603 int idx = (dcb->version >= 0x40 ?
6604 dcb->i2c_default_indices & 0xf : 2);
6605
6606 read_dcb_i2c_entry(dev, dcb->version, dcb->i2c_table,
6607 idx, &dcb->i2c[idx]);
6608 }
6609 } 6472 }
6610 6473
6611 dcb_outp_foreach(dev, NULL, parse_dcb_entry); 6474 dcb_outp_foreach(dev, NULL, parse_dcb_entry);
@@ -6893,19 +6756,6 @@ nouveau_run_vbios_init(struct drm_device *dev)
6893 return ret; 6756 return ret;
6894} 6757}
6895 6758
6896static void
6897nouveau_bios_i2c_devices_takedown(struct drm_device *dev)
6898{
6899 struct drm_nouveau_private *dev_priv = dev->dev_private;
6900 struct nvbios *bios = &dev_priv->vbios;
6901 struct dcb_i2c_entry *entry;
6902 int i;
6903
6904 entry = &bios->dcb.i2c[0];
6905 for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++, entry++)
6906 nouveau_i2c_fini(dev, entry);
6907}
6908
6909static bool 6759static bool
6910nouveau_bios_posted(struct drm_device *dev) 6760nouveau_bios_posted(struct drm_device *dev)
6911{ 6761{
@@ -6942,6 +6792,10 @@ nouveau_bios_init(struct drm_device *dev)
6942 if (ret) 6792 if (ret)
6943 return ret; 6793 return ret;
6944 6794
6795 ret = nouveau_i2c_init(dev);
6796 if (ret)
6797 return ret;
6798
6945 ret = parse_dcb_table(dev, bios); 6799 ret = parse_dcb_table(dev, bios);
6946 if (ret) 6800 if (ret)
6947 return ret; 6801 return ret;
@@ -6984,5 +6838,5 @@ nouveau_bios_init(struct drm_device *dev)
6984void 6838void
6985nouveau_bios_takedown(struct drm_device *dev) 6839nouveau_bios_takedown(struct drm_device *dev)
6986{ 6840{
6987 nouveau_bios_i2c_devices_takedown(dev); 6841 nouveau_i2c_fini(dev);
6988} 6842}