|
@@ -50,3 +50,64 @@ static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsi
|
|
|
pbca |= PCI_FUNC(devfn) << 8;
|
|
|
pbca |= bus_nr << 16;
|
|
|
|
|
|
+ if (bus_nr == 0) {
|
|
|
+ /* use Type-0 transaction */
|
|
|
+ __raw_writel(pbca, KS8695_PCI_VA + KS8695_PBCA);
|
|
|
+ } else {
|
|
|
+ /* use Type-1 transaction */
|
|
|
+ __raw_writel(pbca | PBCA_TYPE1, KS8695_PCI_VA + KS8695_PBCA);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * The KS8695 datasheet prohibits anything other than 32bit accesses
|
|
|
+ * to the IO registers, so all our configuration must be done with
|
|
|
+ * 32bit operations, and the correct bit masking and shifting.
|
|
|
+ */
|
|
|
+
|
|
|
+static int ks8695_pci_readconfig(struct pci_bus *bus,
|
|
|
+ unsigned int devfn, int where, int size, u32 *value)
|
|
|
+{
|
|
|
+ ks8695_pci_setupconfig(bus->number, devfn, where);
|
|
|
+
|
|
|
+ *value = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
|
|
|
+
|
|
|
+ switch (size) {
|
|
|
+ case 4:
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ *value = *value >> ((where & 2) * 8);
|
|
|
+ *value &= 0xffff;
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ *value = *value >> ((where & 3) * 8);
|
|
|
+ *value &= 0xff;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pci_cfg_dbg) {
|
|
|
+ printk("read: %d,%08x,%02x,%d: %08x (%08x)\n",
|
|
|
+ bus->number, devfn, where, size, *value,
|
|
|
+ __raw_readl(KS8695_PCI_VA + KS8695_PBCD));
|
|
|
+ }
|
|
|
+
|
|
|
+ return PCIBIOS_SUCCESSFUL;
|
|
|
+}
|
|
|
+
|
|
|
+static int ks8695_pci_writeconfig(struct pci_bus *bus,
|
|
|
+ unsigned int devfn, int where, int size, u32 value)
|
|
|
+{
|
|
|
+ unsigned long tmp;
|
|
|
+
|
|
|
+ if (pci_cfg_dbg) {
|
|
|
+ printk("write: %d,%08x,%02x,%d: %08x\n",
|
|
|
+ bus->number, devfn, where, size, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ ks8695_pci_setupconfig(bus->number, devfn, where);
|
|
|
+
|
|
|
+ switch (size) {
|
|
|
+ case 4:
|
|
|
+ __raw_writel(value, KS8695_PCI_VA + KS8695_PBCD);
|
|
|
+ break;
|