powerpc/of/pci: Rewrite pci_parse_of_flags
The existing code uses bunch of hardcoded values from the PCI Bus Binding to IEEE Std 1275 spec; and it does so in quite non-obvious way. This defines fields from the cell#0 of the "reg" property of a PCI device and uses them for parsing. This should cause no behavioral change. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> [mpe: Unsplit some 80/81 char lines, space the code with some newlines] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20190829084417.71873-1-aik@ozlabs.ru
This commit is contained in:
parent
f2902a2fb4
commit
bc605cd79e
|
@ -34,31 +34,75 @@ static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
|
|||
* pci_parse_of_flags - Parse the flags cell of a device tree PCI address
|
||||
* @addr0: value of 1st cell of a device tree PCI address.
|
||||
* @bridge: Set this flag if the address is from a bridge 'ranges' property
|
||||
*
|
||||
* PCI Bus Binding to IEEE Std 1275-1994
|
||||
*
|
||||
* Bit# 33222222 22221111 11111100 00000000
|
||||
* 10987654 32109876 54321098 76543210
|
||||
* phys.hi cell: npt000ss bbbbbbbb dddddfff rrrrrrrr
|
||||
* phys.mid cell: hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh
|
||||
* phys.lo cell: llllllll llllllll llllllll llllllll
|
||||
*
|
||||
* where:
|
||||
* n is 0 if the address is relocatable, 1 otherwise
|
||||
* p is 1 if the addressable region is "prefetchable", 0 otherwise
|
||||
* t is 1 if the address is aliased (for non-relocatable I/O),
|
||||
* below 1 MB (for Memory),or below 64 KB (for relocatable I/O).
|
||||
* ss is the space code, denoting the address space:
|
||||
* 00 denotes Configuration Space
|
||||
* 01 denotes I/O Space
|
||||
* 10 denotes 32-bit-address Memory Space
|
||||
* 11 denotes 64-bit-address Memory Space
|
||||
* bbbbbbbb is the 8-bit Bus Number
|
||||
* ddddd is the 5-bit Device Number
|
||||
* fff is the 3-bit Function Number
|
||||
* rrrrrrrr is the 8-bit Register Number
|
||||
*/
|
||||
#define OF_PCI_ADDR0_SPACE(ss) (((ss)&3)<<24)
|
||||
#define OF_PCI_ADDR0_SPACE_CFG OF_PCI_ADDR0_SPACE(0)
|
||||
#define OF_PCI_ADDR0_SPACE_IO OF_PCI_ADDR0_SPACE(1)
|
||||
#define OF_PCI_ADDR0_SPACE_MMIO32 OF_PCI_ADDR0_SPACE(2)
|
||||
#define OF_PCI_ADDR0_SPACE_MMIO64 OF_PCI_ADDR0_SPACE(3)
|
||||
#define OF_PCI_ADDR0_SPACE_MASK OF_PCI_ADDR0_SPACE(3)
|
||||
#define OF_PCI_ADDR0_RELOC (1UL<<31)
|
||||
#define OF_PCI_ADDR0_PREFETCH (1UL<<30)
|
||||
#define OF_PCI_ADDR0_ALIAS (1UL<<29)
|
||||
#define OF_PCI_ADDR0_BUS 0x00FF0000UL
|
||||
#define OF_PCI_ADDR0_DEV 0x0000F800UL
|
||||
#define OF_PCI_ADDR0_FN 0x00000700UL
|
||||
#define OF_PCI_ADDR0_BARREG 0x000000FFUL
|
||||
|
||||
unsigned int pci_parse_of_flags(u32 addr0, int bridge)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
unsigned int flags = 0, as = addr0 & OF_PCI_ADDR0_SPACE_MASK;
|
||||
|
||||
if (addr0 & 0x02000000) {
|
||||
if (as == OF_PCI_ADDR0_SPACE_MMIO32 || as == OF_PCI_ADDR0_SPACE_MMIO64) {
|
||||
flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
|
||||
flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
|
||||
if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
|
||||
flags |= IORESOURCE_MEM_64;
|
||||
flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
|
||||
if (addr0 & 0x40000000)
|
||||
flags |= IORESOURCE_PREFETCH
|
||||
| PCI_BASE_ADDRESS_MEM_PREFETCH;
|
||||
|
||||
if (as == OF_PCI_ADDR0_SPACE_MMIO64)
|
||||
flags |= PCI_BASE_ADDRESS_MEM_TYPE_64 | IORESOURCE_MEM_64;
|
||||
|
||||
if (addr0 & OF_PCI_ADDR0_ALIAS)
|
||||
flags |= PCI_BASE_ADDRESS_MEM_TYPE_1M;
|
||||
|
||||
if (addr0 & OF_PCI_ADDR0_PREFETCH)
|
||||
flags |= IORESOURCE_PREFETCH |
|
||||
PCI_BASE_ADDRESS_MEM_PREFETCH;
|
||||
|
||||
/* Note: We don't know whether the ROM has been left enabled
|
||||
* by the firmware or not. We mark it as disabled (ie, we do
|
||||
* not set the IORESOURCE_ROM_ENABLE flag) for now rather than
|
||||
* do a config space read, it will be force-enabled if needed
|
||||
*/
|
||||
if (!bridge && (addr0 & 0xff) == 0x30)
|
||||
if (!bridge && (addr0 & OF_PCI_ADDR0_BARREG) == PCI_ROM_ADDRESS)
|
||||
flags |= IORESOURCE_READONLY;
|
||||
} else if (addr0 & 0x01000000)
|
||||
|
||||
} else if (as == OF_PCI_ADDR0_SPACE_IO)
|
||||
flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
|
||||
|
||||
if (flags)
|
||||
flags |= IORESOURCE_SIZEALIGN;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue