Skip to content
Snippets Groups Projects
pci-uclass.c 25.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • ulong pci_conv_size_to_32(ulong old, ulong value, uint offset,
    			  enum pci_size_t size)
    {
    	uint off_mask;
    	uint val_mask, shift;
    	ulong ldata, mask;
    
    	switch (size) {
    	case PCI_SIZE_8:
    		off_mask = 3;
    		val_mask = 0xff;
    		break;
    	case PCI_SIZE_16:
    		off_mask = 2;
    		val_mask = 0xffff;
    		break;
    	default:
    		return value;
    	}
    	shift = (offset & off_mask) * 8;
    	ldata = (value & val_mask) << shift;
    	mask = val_mask << shift;
    	value = (old & ~mask) | ldata;
    
    	return value;
    }
    
    
    int pci_get_regions(struct udevice *dev, struct pci_region **iop,
    		    struct pci_region **memp, struct pci_region **prefp)
    {
    	struct udevice *bus = pci_get_controller(dev);
    	struct pci_controller *hose = dev_get_uclass_priv(bus);
    	int i;
    
    	*iop = NULL;
    	*memp = NULL;
    	*prefp = NULL;
    	for (i = 0; i < hose->region_count; i++) {
    		switch (hose->regions[i].flags) {
    		case PCI_REGION_IO:
    			if (!*iop || (*iop)->size < hose->regions[i].size)
    				*iop = hose->regions + i;
    			break;
    		case PCI_REGION_MEM:
    			if (!*memp || (*memp)->size < hose->regions[i].size)
    				*memp = hose->regions + i;
    			break;
    		case (PCI_REGION_MEM | PCI_REGION_PREFETCH):
    			if (!*prefp || (*prefp)->size < hose->regions[i].size)
    				*prefp = hose->regions + i;
    			break;
    		}
    	}
    
    	return (*iop != NULL) + (*memp != NULL) + (*prefp != NULL);
    }
    
    
    UCLASS_DRIVER(pci) = {
    	.id		= UCLASS_PCI,
    	.name		= "pci",
    
    	.flags		= DM_UC_FLAG_SEQ_ALIAS,
    
    	.post_bind	= pci_uclass_post_bind,
    	.pre_probe	= pci_uclass_pre_probe,
    	.post_probe	= pci_uclass_post_probe,
    	.child_post_bind = pci_uclass_child_post_bind,
    	.per_device_auto_alloc_size = sizeof(struct pci_controller),
    	.per_child_platdata_auto_alloc_size =
    			sizeof(struct pci_child_platdata),
    };
    
    static const struct dm_pci_ops pci_bridge_ops = {
    	.read_config	= pci_bridge_read_config,
    	.write_config	= pci_bridge_write_config,
    };
    
    static const struct udevice_id pci_bridge_ids[] = {
    	{ .compatible = "pci-bridge" },
    	{ }
    };
    
    U_BOOT_DRIVER(pci_bridge_drv) = {
    	.name		= "pci_bridge_drv",
    	.id		= UCLASS_PCI,
    	.of_match	= pci_bridge_ids,
    	.ops		= &pci_bridge_ops,
    };
    
    UCLASS_DRIVER(pci_generic) = {
    	.id		= UCLASS_PCI_GENERIC,
    	.name		= "pci_generic",
    };
    
    static const struct udevice_id pci_generic_ids[] = {
    	{ .compatible = "pci-generic" },
    	{ }
    };
    
    U_BOOT_DRIVER(pci_generic_drv) = {
    	.name		= "pci_generic_drv",
    	.id		= UCLASS_PCI_GENERIC,
    	.of_match	= pci_generic_ids,
    };