From e6d87036412b952cb083eff2dc716aee97a771f2 Mon Sep 17 00:00:00 2001 From: Roman Yeryomin Date: Fri, 17 May 2013 20:40:24 +0300 Subject: Move to rsdk 3.2.4. Compiles cleanly. Signed-off-by: Roman Yeryomin --- .../realtek/files/arch/rlx/bsp_rtl8196c/pci.c | 483 +++++++++++++++++++++ 1 file changed, 483 insertions(+) create mode 100644 target/linux/realtek/files/arch/rlx/bsp_rtl8196c/pci.c (limited to 'target/linux/realtek/files/arch/rlx/bsp_rtl8196c/pci.c') diff --git a/target/linux/realtek/files/arch/rlx/bsp_rtl8196c/pci.c b/target/linux/realtek/files/arch/rlx/bsp_rtl8196c/pci.c new file mode 100644 index 000000000..62f7b90b7 --- /dev/null +++ b/target/linux/realtek/files/arch/rlx/bsp_rtl8196c/pci.c @@ -0,0 +1,483 @@ +/* + * RTL8196C PCIE Host Controller Glue Driver + * Author: ghhuang@realtek.com.tw + * + * Notes: + * - Two host controllers available. + * - Each host direcly connects to one device + * - Supports PCI devices through PCIE-to-PCI bridges + * - If no PCI devices are connected to RC. Timeout monitor shall be + * enabled to prevent bus hanging. + */ +#include +#include +#include +#include +#include +//#include +#include "bspchip.h" + +#define PCI_8BIT_ACCESS 1 +#define PCI_16BIT_ACCESS 2 +#define PCI_32BIT_ACCESS 4 +#define PCI_ACCESS_READ 8 +#define PCI_ACCESS_WRITE 16 + +#define MAX_NUM_DEV 4 + +#define DEBUG_PRINTK 0 + +#define CLK_MANAGE 0xb8000010 +#define SYS_PCIE_PHY0 (0xb8000000 +0x50) +#define SYS_PCIE_PHY1 (0xb8000000 +0x54) +#define PCIE_PHY0 0xb8b01008 +#define PCIE_PHY1 0xb8b21008 + +#define MAX_PAYLOAD_SIZE_128B 0 + +static int pci0_bus_number = 0xff; + +static struct resource rtl8196b_pci0_io_resource = { + .name = "RTL8196C PCI0 IO", + .flags = IORESOURCE_IO, + .start = PADDR(BSP_PCIE0_D_IO), + .end = PADDR(BSP_PCIE0_D_IO + 0x1FFFFF) +}; + +static struct resource rtl8196b_pci0_mem_resource = { + .name = "RTL8196C PCI0 MEM", + .flags = IORESOURCE_MEM, + .start = PADDR(BSP_PCIE0_D_MEM), + .end = PADDR(BSP_PCIE0_D_MEM + 0xFFFFFF) +}; + +//HOST PCIE +#define PCIE0_RC_EXT_BASE (0xb8b01000) +//RC Extended register +#define PCIE0_MDIO (PCIE0_RC_EXT_BASE+0x00) +//MDIO +#define PCIE_MDIO_DATA_OFFSET (16) +#define PCIE_MDIO_DATA_MASK (0xffff <>PCIE_MDIO_DATA_OFFSET)&0xffff); + +} + + +void HostPCIe_SetPhyMdioWrite(unsigned int portnum, unsigned int regaddr, unsigned short val) +{ + unsigned int mdioaddr; + + mdioaddr=PCIE0_MDIO; + + REG32(mdioaddr)= ( (regaddr&0x1f)<number; + #if DEBUG_PRINTK + //printk("File: %s, Function: %s, Line: %d\n", __FILE__, __FUNCTION__, __LINE__); + //printk("Bus: %d, Slot: %d, Func: %d, Where: %d, Size: %d\n", bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size); + #endif + + if (bus->number == pci0_bus_number) + { + /* PCIE host controller */ + if (PCI_SLOT(devfn) == 0) + { + addr = BSP_PCIE0_H_CFG + where; + + if (rtl8196b_pcibios_config_access(PCI_ACCESS_READ | PCI_32BIT_ACCESS, addr & ~(0x3), &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (size == 1) + *val = (data >> ((where & 3) << 3)) & 0xff; + else if (size == 2) + *val = (data >> ((where & 3) << 3)) & 0xffff; + else + *val = data; + } + else + return PCIBIOS_DEVICE_NOT_FOUND; + } + else if (bus->number == (pci0_bus_number + 1)) + { + /* PCIE devices directly connected */ + if (PCI_SLOT(devfn) == 0) + { + addr = BSP_PCIE0_D_CFG0 + (PCI_FUNC(devfn) << 12) + where; + + if (rtl8196b_pcibios_config_access(PCI_ACCESS_READ | size, addr, val)) + return PCIBIOS_DEVICE_NOT_FOUND; + } + else + return PCIBIOS_DEVICE_NOT_FOUND; + } + else + { + /* Devices connected through bridge */ + if (PCI_SLOT(devfn) < MAX_NUM_DEV) + { + WRITE_MEM32(BSP_PCIE0_H_IPCFG, ((bus->number) << 8) | (PCI_SLOT(devfn) << 3) | PCI_FUNC(devfn)); + addr = BSP_PCIE0_D_CFG1 + where; + + if (rtl8196b_pcibios_config_access(PCI_ACCESS_READ | size, addr, val)) + return PCIBIOS_DEVICE_NOT_FOUND; + } + else + return PCIBIOS_DEVICE_NOT_FOUND; + } + + #if DEBUG_PRINTK + //printk("File: %s, Function: %s, Line: %d\n", __FILE__, __FUNCTION__, __LINE__); + //printk("Read Value: 0x%08X\n", *val); + #endif + + return PCIBIOS_SUCCESSFUL; +} + +//======================================================================================== +static int rtl8196b_pcibios0_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, unsigned int val) +{ + unsigned int data = 0; + unsigned int addr = 0; + + static int pci0_bus_number = 0xff; + if (pci0_bus_number == 0xff) + pci0_bus_number = bus->number; + + #if DEBUG_PRINTK + //printk("File: %s, Function: %s, Line: %d\n", __FILE__, __FUNCTION__, __LINE__); + //printk("Bus: %d, Slot: %d, Func: %d, Where: %d, Size: %d\n", bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size); + #endif + + if (bus->number == pci0_bus_number) + { + /* PCIE host controller */ + if (PCI_SLOT(devfn) == 0) + { + addr = BSP_PCIE0_H_CFG + where; + + if (rtl8196b_pcibios_config_access(PCI_ACCESS_READ | PCI_32BIT_ACCESS, addr & ~(0x3), &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (size == 1) + data = (data & ~(0xff << ((where & 3) << 3))) | (val << ((where & 3) << 3)); + else if (size == 2) + data = (data & ~(0xffff << ((where & 3) << 3))) | (val << ((where & 3) << 3)); + else + data = val; + + if (rtl8196b_pcibios_config_access(PCI_ACCESS_WRITE | PCI_32BIT_ACCESS, addr & ~(0x3), &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + } + else + return PCIBIOS_DEVICE_NOT_FOUND; + } + else if (bus->number == (pci0_bus_number + 1)) + { + /* PCIE devices directly connected */ + if (PCI_SLOT(devfn) == 0) + { + addr = BSP_PCIE0_D_CFG0 + (PCI_FUNC(devfn) << 12) + where; + + if (rtl8196b_pcibios_config_access(PCI_ACCESS_WRITE | size, addr, &val)) + return PCIBIOS_DEVICE_NOT_FOUND; + } + else + return PCIBIOS_DEVICE_NOT_FOUND; + } + else + { + /* Devices connected through bridge */ + if (PCI_SLOT(devfn) < MAX_NUM_DEV) + { + WRITE_MEM32(BSP_PCIE0_H_IPCFG, ((bus->number) << 8) | (PCI_SLOT(devfn) << 3) | PCI_FUNC(devfn)); + addr = BSP_PCIE0_D_CFG1 + where; + + if (rtl8196b_pcibios_config_access(PCI_ACCESS_WRITE | size, addr, &val)) + return PCIBIOS_DEVICE_NOT_FOUND; + } + else + return PCIBIOS_DEVICE_NOT_FOUND; + } + + return PCIBIOS_SUCCESSFUL; +} +//======================================================================================== + +//======================================================================================== +struct pci_ops rtl8196b_pci0_ops = { + .read = rtl8196b_pcibios0_read, + .write = rtl8196b_pcibios0_write +}; + +static struct pci_controller rtl8196b_pci0_controller = { + .pci_ops = &rtl8196b_pci0_ops, + .mem_resource = &rtl8196b_pci0_mem_resource, + .io_resource = &rtl8196b_pci0_io_resource, +}; + +//======================================================================================== +int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + #if DEBUG_PRINTK + printk("File: %s, Function: %s, Line: %d\n", __FILE__, __FUNCTION__, __LINE__); + printk("**Slot: %d\n", slot); + printk("**Pin: %d\n", pin); + printk("**Dev->BUS->Number: %d\n", dev->bus->number); + #endif + + return BSP_PCIE_IRQ; +} +//======================================================================================== +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + #if DEBUG_PRINTK + printk("File: %s, Function: %s, Line: %d\n", __FILE__, __FUNCTION__, __LINE__); + #endif + + return 0; +} + +static __init int bsp_pcie_init(void) +{ + + int result=0; + + printk("<<<<>>>>\n"); + mdelay(1); + + result=PCIE_reset_procedure(0, 0, 1); + if (result) + register_pci_controller(&rtl8196b_pci0_controller); + else + REG32(CLK_MANAGE) &= (~(1<<11)); //disable active_pcie0 + return 0; +} + +arch_initcall(bsp_pcie_init); -- cgit v1.2.3