P2020RDB-sata移植之U-BOOT篇

来源:互联网 发布:js checkbox按钮 编辑:程序博客网 时间:2024/06/06 19:16

硬件确认OK后,U-BOOT应该可以看到预期的PCIE1控制器枚举到需要的设备

PCIe1: Root Complex of mini PCIe SLOT, x1, regs @ 0xffe0a000  01:00.0     - 1095:3132 - Mass storage controllerPCIe1: Bus 00 - 01PCIe2: Root Complex of PCIe SLOT, no link, regs @ 0xffe09000PCIe2: Bus 02 - 02

U-BOOT是依靠头文件的宏配置,来确定初始化需要的基本信息的,不像内核要依赖设备树,所以U-BOOT对于硬件调试很重要。那么U-BOOT是如何枚举到PCIE1下面的sata控制器的呢。

首先看一下函数调用路线

board_init_r(board.c)

--->pci_init(drivers/pci/pci.c)

--->pci_init_board(boar/freescale/p1_p2_rdb/pci.c)

--->fsl_pcie_init_board(drivers/pci/fsl_pci_init.c)

--->fsl_pcie_init_ctrl(drivers/pci/fsl_pci_init.c)

-->fsl_configure_pcie(drivers/pci/fsl_pci_init.c)

关键的调用是fsl_pcie_init_ctrlfsl_configure_pcie

重点看一下这两个函数

int fsl_pcie_init_board(int busno){struct fsl_pci_info pci_info;ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC8xxx_GUTS_ADDR;u32 devdisr;u32 *addr;#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2addr = &gur->devdisr3;#elseaddr = &gur->devdisr;#endifdevdisr = in_be32(addr);#ifdef CONFIG_PCIE1SET_STD_PCIE_INFO(pci_info, 1);busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE1, &pci_info);#elsesetbits_be32(addr, _DEVDISR_PCIE1); /* disable */#endif#ifdef CONFIG_PCIE2SET_STD_PCIE_INFO(pci_info, 2);busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE2, &pci_info);#elsesetbits_be32(addr, _DEVDISR_PCIE2); /* disable */#endif#ifdef CONFIG_PCIE3SET_STD_PCIE_INFO(pci_info, 3);busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE3, &pci_info);#elsesetbits_be32(addr, _DEVDISR_PCIE3); /* disable */#endif#ifdef CONFIG_PCIE4SET_STD_PCIE_INFO(pci_info, 4);busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE4, &pci_info);#elsesetbits_be32(addr, _DEVDISR_PCIE4); /* disable */#endif return busno;}

可以看到如果有需要的话,会对每个PCIE控制器进行初始化设置,

设置的开始首先是设定PCI控制器的基本寄存器位置,这些位置在U-BOOT里通过头文件宏来提供,linux使用DTB获取。

看一下宏SET_STD_PCIE_INFO就一目了然了

#define SET_STD_PCIE_INFO(x, num) \{\x.regs = CONFIG_SYS_PCIE##num##_ADDR;\x.mem_bus = CONFIG_SYS_PCIE##num##_MEM_BUS; \x.mem_phys = CONFIG_SYS_PCIE##num##_MEM_PHYS; \x.mem_size = CONFIG_SYS_PCIE##num##_MEM_SIZE; \x.io_bus = CONFIG_SYS_PCIE##num##_IO_BUS; \x.io_phys = CONFIG_SYS_PCIE##num##_IO_PHYS; \x.io_size = CONFIG_SYS_PCIE##num##_IO_SIZE; \x.law = LAW_TRGT_IF_PCIE_##num; \x.pci_num = num; \}


U-BOOT获取了相应的寄存器位置后,就会配置对应的PCIE控制器

int fsl_pcie_init_ctrl(int busno, u32 devdisr, enum srds_prtcl dev,struct fsl_pci_info *pci_info){struct pci_controller *hose;int num = dev - PCIE1;hose = calloc(1, sizeof(struct pci_controller));if (!hose)return busno;if (is_serdes_configured(dev) && !(devdisr & devdisr_mask[num])) {busno = fsl_configure_pcie(pci_info, hose,board_serdes_name(dev), busno);} else {printf("PCIe%d: disabled\n", num + 1);}return busno;}

端口硬件禁能的会输出printf("PCIe%d: disabled\n", num + 1);

硬件使能的,开始fsl_configure_pcie枚举控制器

int fsl_configure_pcie(struct fsl_pci_info *info,struct pci_controller *hose,const char *connected, int busno){int is_endpoint;set_next_law(info->mem_phys, law_size_bits(info->mem_size), info->law);set_next_law(info->io_phys, law_size_bits(info->io_size), info->law);is_endpoint = fsl_setup_hose(hose, info->regs);printf("PCIe%u: %s", info->pci_num,is_endpoint ? "Endpoint" : "Root Complex");if (connected)printf(" of %s", connected);puts(", ");return fsl_pci_init_port(info, hose, busno);}

函数的最后调用,枚举总线。

fsl_pci_init_port

->fsl_pci_init

->pci_hose_scan_bus

int pci_hose_scan_bus(struct pci_controller *hose, int bus){unsigned int sub_bus, found_multi = 0;unsigned short vendor, device, class;unsigned char header_type;#ifndef CONFIG_PCI_PNPstruct pci_config_table *cfg;#endifpci_dev_t dev;#ifdef CONFIG_PCI_SCAN_SHOWstatic int indent = 0;#endifsub_bus = bus;for (dev =  PCI_BDF(bus,0,0);     dev <  PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1,PCI_MAX_PCI_FUNCTIONS - 1);     dev += PCI_BDF(0, 0, 1)) {if (pci_skip_dev(hose, dev))continue;if (PCI_FUNC(dev) && !found_multi)continue;pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);if (vendor == 0xffff || vendor == 0x0000)continue;if (!PCI_FUNC(dev))found_multi = header_type & 0x80;debug("PCI Scan: Found Bus %d, Device %d, Function %d\n",PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);#ifdef CONFIG_PCI_SCAN_SHOWindent++;/* Print leading space, including bus indentation */printf("%*c", indent + 1, ' ');if (pci_print_dev(hose, dev)) {printf("%02x:%02x.%-*x - %04x:%04x - %s\n",       PCI_BUS(dev), PCI_DEV(dev), 6 - indent, PCI_FUNC(dev),       vendor, device, pci_class_str(class >> 8));}#endif#ifdef CONFIG_PCI_PNPsub_bus = max(pciauto_config_device(hose, dev), sub_bus);#elsecfg = pci_find_config(hose, class, vendor, device,      PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));if (cfg) {cfg->config_device(hose, dev, cfg);sub_bus = max(sub_bus, hose->current_busno);}#endif#ifdef CONFIG_PCI_SCAN_SHOWindent--;#endifif (hose->fixup_irq)hose->fixup_irq(hose, dev);}return sub_bus;}







0 0
原创粉丝点击