^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Low-level PCI config space access for OLPC systems who lack the VSA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * PCI virtualization software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright © 2006 Advanced Micro Devices, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * The AMD Geode chipset (ie: GX2 processor, cs5536 I/O companion device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * has some I/O functions (display, southbridge, sound, USB HCIs, etc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * that more or less behave like PCI devices, but the hardware doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * directly implement the PCI configuration space headers. AMD provides
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * "VSA" (Virtual System Architecture) software that emulates PCI config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * space for these devices, by trapping I/O accesses to PCI config register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * (CF8/CFC) and running some code in System Management Mode interrupt state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * On the OLPC platform, we don't want to use that VSA code because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * (a) it slows down suspend/resume, and (b) recompiling it requires special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * compilers that are hard to get. So instead of letting the complex VSA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * code simulate the PCI config registers for the on-chip devices, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * just simulate them the easy way, by inserting the code into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * pci_write_config and pci_read_config path. Most of the config registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * are read-only anyway, so the bulk of the simulation is just table lookup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/olpc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/geode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/pci_x86.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * In the tables below, the first two line (8 longwords) are the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * size masks that are used when the higher level PCI code determines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * the size of the region by writing ~0 to a base address register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * and reading back the result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * The following lines are the values that are read during normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * PCI config access cycles, i.e. not after just having written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * ~0 to a base address register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static const uint32_t lxnb_hdr[] = { /* dev 1 function 0 - devfn = 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 0x281022, 0x2200005, 0x6000021, 0x80f808, /* AMD Vendor ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 0x0, 0x0, 0x0, 0x0, /* No virtual registers, hence no BAR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 0x0, 0x0, 0x0, 0x28100b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static const uint32_t gxnb_hdr[] = { /* dev 1 function 0 - devfn = 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 0xfffffffd, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 0x28100b, 0x2200005, 0x6000021, 0x80f808, /* NSC Vendor ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 0xac1d, 0x0, 0x0, 0x0, /* I/O BAR - base of virtual registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 0x0, 0x0, 0x0, 0x28100b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static const uint32_t lxfb_hdr[] = { /* dev 1 function 1 - devfn = 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 0xff000008, 0xffffc000, 0xffffc000, 0xffffc000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 0xffffc000, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 0x20811022, 0x2200003, 0x3000000, 0x0, /* AMD Vendor ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 0xfd000000, 0xfe000000, 0xfe004000, 0xfe008000, /* FB, GP, VG, DF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 0xfe00c000, 0x0, 0x0, 0x30100b, /* VIP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 0x0, 0x0, 0x0, 0x10e, /* INTA, IRQ14 for graphics accel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 0x3d0, 0x3c0, 0xa0000, 0x0, /* VG IO, VG IO, EGA FB, MONO FB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static const uint32_t gxfb_hdr[] = { /* dev 1 function 1 - devfn = 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 0xff800008, 0xffffc000, 0xffffc000, 0xffffc000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 0x30100b, 0x2200003, 0x3000000, 0x0, /* NSC Vendor ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 0xfd000000, 0xfe000000, 0xfe004000, 0xfe008000, /* FB, GP, VG, DF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 0x0, 0x0, 0x0, 0x30100b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 0x3d0, 0x3c0, 0xa0000, 0x0, /* VG IO, VG IO, EGA FB, MONO FB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static const uint32_t aes_hdr[] = { /* dev 1 function 2 - devfn = 0xa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) 0xffffc000, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) 0x20821022, 0x2a00006, 0x10100000, 0x8, /* NSC Vendor ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) 0xfe010000, 0x0, 0x0, 0x0, /* AES registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) 0x0, 0x0, 0x0, 0x20821022,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static const uint32_t isa_hdr[] = { /* dev f function 0 - devfn = 78 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 0xfffffff9, 0xffffff01, 0xffffffc1, 0xffffffe1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 0xffffff81, 0xffffffc1, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 0x20901022, 0x2a00049, 0x6010003, 0x802000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 0x18b1, 0x1001, 0x1801, 0x1881, /* SMB-8 GPIO-256 MFGPT-64 IRQ-32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 0x1401, 0x1841, 0x0, 0x20901022, /* PMS-128 ACPI-64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 0x0, 0x0, 0x0, 0xaa5b, /* IRQ steering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static const uint32_t ac97_hdr[] = { /* dev f function 3 - devfn = 7b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 0xffffff81, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 0x20931022, 0x2a00041, 0x4010001, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 0x1481, 0x0, 0x0, 0x0, /* I/O BAR-128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 0x0, 0x0, 0x0, 0x20931022,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 0x0, 0x0, 0x0, 0x205, /* IntB, IRQ5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static const uint32_t ohci_hdr[] = { /* dev f function 4 - devfn = 7c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 0xfffff000, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 0x20941022, 0x2300006, 0xc031002, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 0xfe01a000, 0x0, 0x0, 0x0, /* MEMBAR-1000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 0x0, 0x0, 0x0, 0x20941022,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 0x0, 0x40, 0x0, 0x40a, /* CapPtr INT-D, IRQA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 0xc8020001, 0x0, 0x0, 0x0, /* Capabilities - 40 is R/O,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 44 is mask 8103 (power control) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static const uint32_t ehci_hdr[] = { /* dev f function 4 - devfn = 7d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 0xfffff000, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 0x0, 0x0, 0x0, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 0x20951022, 0x2300006, 0xc032002, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 0xfe01b000, 0x0, 0x0, 0x0, /* MEMBAR-1000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 0x0, 0x0, 0x0, 0x20951022,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 0x0, 0x40, 0x0, 0x40a, /* CapPtr INT-D, IRQA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 0xc8020001, 0x0, 0x0, 0x0, /* Capabilities - 40 is R/O, 44 is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) mask 8103 (power control) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 0x1, 0x40080000, 0x0, 0x0, /* EECP - see EHCI spec section 2.1.7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 0x01000001, 0x0, 0x0, 0x0, /* EECP - see EHCI spec section 2.1.7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 0x2020, 0x0, 0x0, 0x0, /* (EHCI page 8) 60 SBRN (R/O),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 61 FLADJ (R/W), PORTWAKECAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static uint32_t ff_loc = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static uint32_t zero_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int bar_probing; /* Set after a write of ~0 to a BAR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static int is_lx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define NB_SLOT 0x1 /* Northbridge - GX chip - Device 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define SB_SLOT 0xf /* Southbridge - CS5536 chip - Device F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int is_simulated(unsigned int bus, unsigned int devfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return (!bus && ((PCI_SLOT(devfn) == NB_SLOT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) (PCI_SLOT(devfn) == SB_SLOT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static uint32_t *hdr_addr(const uint32_t *hdr, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) uint32_t addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * This is a little bit tricky. The header maps consist of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * 0x20 bytes of size masks, followed by 0x70 bytes of header data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * In the normal case, when not probing a BAR's size, we want
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * to access the header data, so we add 0x20 to the reg offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * thus skipping the size mask area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * In the BAR probing case, we want to access the size mask for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * the BAR, so we subtract 0x10 (the config header offset for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * BAR0), and don't skip the size mask area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) addr = (uint32_t)hdr + reg + (bar_probing ? -0x10 : 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) bar_probing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return (uint32_t *)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int pci_olpc_read(unsigned int seg, unsigned int bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) unsigned int devfn, int reg, int len, uint32_t *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) uint32_t *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) WARN_ON(seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* Use the hardware mechanism for non-simulated devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!is_simulated(bus, devfn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return pci_direct_conf1.read(seg, bus, devfn, reg, len, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * No device has config registers past 0x70, so we save table space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * by not storing entries for the nonexistent registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (reg >= 0x70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) addr = &zero_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) switch (devfn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case 0x8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) addr = hdr_addr(is_lx ? lxnb_hdr : gxnb_hdr, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) case 0x9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) addr = hdr_addr(is_lx ? lxfb_hdr : gxfb_hdr, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case 0xa:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) addr = is_lx ? hdr_addr(aes_hdr, reg) : &ff_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case 0x78:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) addr = hdr_addr(isa_hdr, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) case 0x7b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) addr = hdr_addr(ac97_hdr, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case 0x7c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) addr = hdr_addr(ohci_hdr, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) case 0x7d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) addr = hdr_addr(ehci_hdr, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) addr = &ff_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) switch (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *value = *(uint8_t *)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *value = *(uint16_t *)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *value = *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static int pci_olpc_write(unsigned int seg, unsigned int bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) unsigned int devfn, int reg, int len, uint32_t value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) WARN_ON(seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /* Use the hardware mechanism for non-simulated devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (!is_simulated(bus, devfn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return pci_direct_conf1.write(seg, bus, devfn, reg, len, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* XXX we may want to extend this to simulate EHCI power management */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * Mostly we just discard writes, but if the write is a size probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * (i.e. writing ~0 to a BAR), we remember it and arrange to return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * the appropriate size mask on the next read. This is cheating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * to some extent, because it depends on the fact that the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * access after such a write will always be a read to the same BAR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if ((reg >= 0x10) && (reg < 0x2c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* write is to a BAR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (value == ~0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) bar_probing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * No warning on writes to ROM BAR, CMD, LATENCY_TIMER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * CACHE_LINE_SIZE, or PM registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if ((reg != PCI_ROM_ADDRESS) && (reg != PCI_COMMAND_MASTER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) (reg != PCI_LATENCY_TIMER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) (reg != PCI_CACHE_LINE_SIZE) && (reg != 0x44))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) printk(KERN_WARNING "OLPC PCI: Config write to devfn"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) " %x reg %x value %x\n", devfn, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static const struct pci_raw_ops pci_olpc_conf = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .read = pci_olpc_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .write = pci_olpc_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int __init pci_olpc_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) printk(KERN_INFO "PCI: Using configuration type OLPC XO-1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) raw_pci_ops = &pci_olpc_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) is_lx = is_geode_lx();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }