From 7cb4ced5aa83b681c76b004c8960b4f2a6471fef Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 6 Oct 2010 10:57:50 +0200 Subject: ALSA: oxygen: rewrite PCIe bridge initialization Change the PCIe/PCI bridge initialization code to configure only the bridge that is actually connected to the sound chip, instead of any bridge found in the system. The new code also makes it easier to add other bridges. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen_lib.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) (limited to 'sound/pci/oxygen/oxygen_lib.c') diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 7e93cf884437..d10cc6ee1a68 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -308,25 +308,31 @@ static void oxygen_restore_eeprom(struct oxygen *chip, } } -static void pci_bridge_magic(void) +static void configure_pcie_bridge(struct pci_dev *pci) { - struct pci_dev *pci = NULL; + enum { PI7C9X110 }; + static const struct pci_device_id bridge_ids[] = { + { PCI_DEVICE(0x12d8, 0xe110), .driver_data = PI7C9X110 }, + { } + }; + struct pci_dev *bridge; + const struct pci_device_id *id; u32 tmp; - for (;;) { - /* If there is any Pericom PI7C9X110 PCI-E/PCI bridge ... */ - pci = pci_get_device(0x12d8, 0xe110, pci); - if (!pci) - break; - /* - * ... configure its secondary internal arbiter to park to - * the secondary port, instead of to the last master. - */ - if (!pci_read_config_dword(pci, 0x40, &tmp)) { - tmp |= 1; - pci_write_config_dword(pci, 0x40, tmp); - } - /* Why? Try asking C-Media. */ + if (!pci->bus || !pci->bus->self) + return; + bridge = pci->bus->self; + + id = pci_match_id(bridge_ids, bridge); + if (!id) + return; + + switch (id->driver_data) { + case PI7C9X110: /* Pericom PI7C9X110 PCIe/PCI bridge */ + pci_read_config_dword(bridge, 0x40, &tmp); + tmp |= 1; /* park the PCI arbiter to the sound chip */ + pci_write_config_dword(bridge, 0x40, tmp); + break; } } @@ -613,7 +619,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, snd_card_set_dev(card, &pci->dev); card->private_free = oxygen_card_free; - pci_bridge_magic(); + configure_pcie_bridge(pci); oxygen_init(chip); chip->model.init(chip); -- cgit v1.2.3-70-g09d2 From ebebeece4ba596973c0c181a8cce5fd77bae427c Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 6 Oct 2010 10:58:50 +0200 Subject: ALSA: oxygen: add PEX8111 initialization Configure the PEX8111 bridge on the PCI Express cards so that the audio DMA controller can do proper burst reads and is less likely to lose data. This is usually done automatically, but is required on older cards where the user has not applied the PLX firmware update. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen_lib.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'sound/pci/oxygen/oxygen_lib.c') diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index d10cc6ee1a68..e5ebe56fb0c5 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -310,8 +310,10 @@ static void oxygen_restore_eeprom(struct oxygen *chip, static void configure_pcie_bridge(struct pci_dev *pci) { - enum { PI7C9X110 }; + enum { PEX811X, PI7C9X110 }; static const struct pci_device_id bridge_ids[] = { + { PCI_VDEVICE(PLX, 0x8111), .driver_data = PEX811X }, + { PCI_VDEVICE(PLX, 0x8112), .driver_data = PEX811X }, { PCI_DEVICE(0x12d8, 0xe110), .driver_data = PI7C9X110 }, { } }; @@ -328,6 +330,19 @@ static void configure_pcie_bridge(struct pci_dev *pci) return; switch (id->driver_data) { + case PEX811X: /* PLX PEX8111/PEX8112 PCIe/PCI bridge */ + pci_read_config_dword(bridge, 0x48, &tmp); + tmp |= 1; /* enable blind prefetching */ + tmp |= 1 << 11; /* enable beacon generation */ + pci_write_config_dword(bridge, 0x48, tmp); + + pci_write_config_dword(bridge, 0x84, 0x0c); + pci_read_config_dword(bridge, 0x88, &tmp); + tmp &= ~(7 << 27); + tmp |= 2 << 27; /* set prefetch size to 128 bytes */ + pci_write_config_dword(bridge, 0x88, tmp); + break; + case PI7C9X110: /* Pericom PI7C9X110 PCIe/PCI bridge */ pci_read_config_dword(bridge, 0x40, &tmp); tmp |= 1; /* park the PCI arbiter to the sound chip */ -- cgit v1.2.3-70-g09d2