X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fpci%2Fpci.c;h=ed113bf4022f2c3857d3c5a2c1699569f86c1ecd;hb=52de0e49dfdc6f1dd55f31e312a3f050be75b69e;hp=2a6d0a7593c8a8e2ff5989edb83553f6f2cfd1ee;hpb=7cdcaef0b286fa20926d750304442ad770a1fca8;p=u-boot diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2a6d0a7593..ed113bf402 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5,23 +5,7 @@ * (C) Copyright 2002, 2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ /* @@ -118,11 +102,11 @@ PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff) void *pci_map_bar(pci_dev_t pdev, int bar, int flags) { pci_addr_t pci_bus_addr; - pci_addr_t bar_response; + u32 bar_response; /* read BAR address */ pci_read_config_dword(pdev, bar, &bar_response); - pci_bus_addr = bar_response & ~0xf; + pci_bus_addr = (pci_addr_t)(bar_response & ~0xf); /* * Pass "0" as the length argument to pci_bus_to_virt. The arg @@ -389,7 +373,7 @@ int pci_hose_config_device(struct pci_controller *hose, pci_addr_t mem, unsigned long command) { - pci_addr_t bar_response; + u32 bar_response; unsigned int old_command; pci_addr_t bar_value; pci_size_t bar_size; @@ -738,3 +722,68 @@ void pci_init(void) /* now call board specific pci_init()... */ pci_init_board(); } + +/* Returns the address of the requested capability structure within the + * device's PCI configuration space or 0 in case the device does not + * support it. + * */ +int pci_hose_find_capability(struct pci_controller *hose, pci_dev_t dev, + int cap) +{ + int pos; + u8 hdr_type; + + pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &hdr_type); + + pos = pci_hose_find_cap_start(hose, dev, hdr_type & 0x7F); + + if (pos) + pos = pci_find_cap(hose, dev, pos, cap); + + return pos; +} + +/* Find the header pointer to the Capabilities*/ +int pci_hose_find_cap_start(struct pci_controller *hose, pci_dev_t dev, + u8 hdr_type) +{ + u16 status; + + pci_hose_read_config_word(hose, dev, PCI_STATUS, &status); + + if (!(status & PCI_STATUS_CAP_LIST)) + return 0; + + switch (hdr_type) { + case PCI_HEADER_TYPE_NORMAL: + case PCI_HEADER_TYPE_BRIDGE: + return PCI_CAPABILITY_LIST; + case PCI_HEADER_TYPE_CARDBUS: + return PCI_CB_CAPABILITY_LIST; + default: + return 0; + } +} + +int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos, int cap) +{ + int ttl = PCI_FIND_CAP_TTL; + u8 id; + u8 next_pos; + + while (ttl--) { + pci_hose_read_config_byte(hose, dev, pos, &next_pos); + if (next_pos < CAP_START_POS) + break; + next_pos &= ~3; + pos = (int) next_pos; + pci_hose_read_config_byte(hose, dev, + pos + PCI_CAP_LIST_ID, &id); + if (id == 0xff) + break; + if (id == cap) + return pos; + pos += PCI_CAP_LIST_NEXT; + } + return 0; +}