Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * PCI ROM access routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * (C) Copyright 2004 Jon Smirl <jonsmirl@yahoo.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "pci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * pci_enable_rom - enable ROM decoding for a PCI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * @pdev: PCI device to enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * Enable ROM decoding on @dev.  This involves simply turning on the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * bit of the PCI ROM BAR.  Note that some cards may share address decoders
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * between the ROM and other resources, so enabling it may disable access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * to MMIO registers or other card memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) int pci_enable_rom(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	struct pci_bus_region region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	u32 rom_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	if (!res->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	/* Nothing to enable if we're using a shadow copy in RAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	if (res->flags & IORESOURCE_ROM_SHADOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	 * Ideally pci_update_resource() would update the ROM BAR address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	 * and we would only set the enable bit here.  But apparently some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	 * devices have buggy ROM BARs that read as zero when disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	pcibios_resource_to_bus(pdev->bus, &region, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	rom_addr &= ~PCI_ROM_ADDRESS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	rom_addr |= region.start | PCI_ROM_ADDRESS_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) EXPORT_SYMBOL_GPL(pci_enable_rom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * pci_disable_rom - disable ROM decoding for a PCI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * @pdev: PCI device to disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * Disable ROM decoding on a PCI device by turning off the last bit in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * ROM BAR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) void pci_disable_rom(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	u32 rom_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	if (res->flags & IORESOURCE_ROM_SHADOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) EXPORT_SYMBOL_GPL(pci_disable_rom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * pci_get_rom_size - obtain the actual size of the ROM image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * @pdev: target PCI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * @rom: kernel virtual pointer to image of ROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * @size: size of PCI window
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  *  return: size of actual ROM image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * Determine the actual length of the ROM image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * The PCI window size could be much larger than the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * actual image size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) static size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			       size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	void __iomem *image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	int last_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	unsigned length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	image = rom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		void __iomem *pds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		/* Standard PCI ROMs start out with these bytes 55 AA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		if (readw(image) != 0xAA55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			pci_info(pdev, "Invalid PCI ROM header signature: expecting 0xaa55, got %#06x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 				 readw(image));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		/* get the PCI data structure and check its "PCIR" signature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		pds = image + readw(image + 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		if (readl(pds) != 0x52494350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			pci_info(pdev, "Invalid PCI ROM data signature: expecting 0x52494350, got %#010x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 				 readl(pds));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		last_image = readb(pds + 21) & 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		length = readw(pds + 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		image += length * 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		/* Avoid iterating through memory outside the resource window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		if (image >= rom + size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		if (!last_image) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			if (readw(image) != 0xAA55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 				pci_info(pdev, "No more image in the PCI ROM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	} while (length && !last_image);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	/* never return a size larger than the PCI resource window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	/* there are known ROMs that get the size wrong */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	return min((size_t)(image - rom), size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * pci_map_rom - map a PCI ROM to kernel space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * @pdev: pointer to pci device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  * @size: pointer to receive size of pci window over ROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * Return: kernel virtual pointer to image of ROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * Map a PCI ROM into kernel space. If ROM is boot video ROM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  * the shadow BIOS copy will be returned instead of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * actual ROM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	loff_t start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	void __iomem *rom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	/* assign the ROM an address if it doesn't have one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	if (res->parent == NULL && pci_assign_resource(pdev, PCI_ROM_RESOURCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	if (*size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	/* Enable ROM space decodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	if (pci_enable_rom(pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	rom = ioremap(start, *size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	if (!rom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		goto err_ioremap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	 * Try to find the true size of the ROM since sometimes the PCI window
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	 * size is much larger than the actual size of the ROM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	 * True size is important if the ROM is going to be copied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	*size = pci_get_rom_size(pdev, rom, *size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (!*size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		goto invalid_rom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	return rom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) invalid_rom:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	iounmap(rom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) err_ioremap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	/* restore enable if ioremap fails */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	if (!(res->flags & IORESOURCE_ROM_ENABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		pci_disable_rom(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) EXPORT_SYMBOL(pci_map_rom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * pci_unmap_rom - unmap the ROM from kernel space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  * @pdev: pointer to pci device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * @rom: virtual address of the previous mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  * Remove a mapping of a previously mapped ROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	iounmap(rom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	/* Disable again before continuing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	if (!(res->flags & IORESOURCE_ROM_ENABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		pci_disable_rom(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) EXPORT_SYMBOL(pci_unmap_rom);