/* * Write a value to PCI configuration space */ static int octeon_write_config(struct pci_bus *bus, unsigned int devfn, int reg, int size, u32 val) { union octeon_pci_address pci_addr; pci_addr.u64 = 0; pci_addr.s.upper = 2; pci_addr.s.io = 1; pci_addr.s.did = 3; pci_addr.s.subdid = 1; pci_addr.s.endian_swap = 1; pci_addr.s.bus = bus->number; pci_addr.s.dev = devfn >> 3; pci_addr.s.func = devfn & 0x7; pci_addr.s.reg = reg; #if PCI_CONFIG_SPACE_DELAY udelay(PCI_CONFIG_SPACE_DELAY); #endif switch (size) { case 4: cvmx_write64_uint32(pci_addr.u64, cpu_to_le32(val)); return PCIBIOS_SUCCESSFUL; case 2: cvmx_write64_uint16(pci_addr.u64, cpu_to_le16(val)); return PCIBIOS_SUCCESSFUL; case 1: cvmx_write64_uint8(pci_addr.u64, val); return PCIBIOS_SUCCESSFUL; } return PCIBIOS_FUNC_NOT_SUPPORTED; }
static void octopci_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, uint32_t data, int bytes) { struct octopci_softc *sc; uint64_t addr; sc = device_get_softc(dev); addr = octopci_cs_addr(bus, slot, func, reg); switch (bytes) { case 4: cvmx_write64_uint32(addr, htole32(data)); return; case 2: cvmx_write64_uint16(addr, htole16(data)); return; case 1: cvmx_write64_uint8(addr, data); return; default: return; } }
/** * Write 32bits to a Device's config space * * @pcie_port: PCIe port the device is on * @bus: Sub bus * @dev: Device ID * @fn: Device sub function * @reg: Register to access * @val: Value to write */ static void cvmx_pcie_config_write32(int pcie_port, int bus, int dev, int fn, int reg, uint32_t val) { uint64_t address = __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg); if (address) cvmx_write64_uint32(address, cpu_to_le32(val)); }
void ehci_writel(volatile u32 *addr32, u32 val) { u64 addr64 = 0x80016F0000000000ull + (ulong)addr32; u32 val2 = 0; cvmx_write64_uint32(addr64, val); val2 = cvmx_read64_uint32(addr64); debug("%s: wrote 0x%08x to address %p (0x%llx), read back 0x%08x\n", __func__, val, addr32, addr64, val2); }
int do_mem_loopw64 (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint64_t addr, length, i, data, tmp_addr; int size; if (argc < 4) return CMD_RET_USAGE; /* Check for a size spefication. * Defaults to long if no or incorrect specification. */ if ((size = cmd_get_data_size(argv[0], 8)) < 0) return 1; /* Address is always specified. */ addr = simple_strtoull(argv[1], NULL, 16); /* Length is the number of objects, not number of bytes. */ length = simple_strtoull(argv[2], NULL, 16); /* data to write */ data = simple_strtoull(argv[3], NULL, 16); /* We want to optimize the loops to run as fast as possible. * If we have only one object, just run infinite loops. */ if (length == 1) { if (size == 8) { for (;;) cvmx_write_csr(addr, data); } if (size == 4) { for (;;) cvmx_write64_uint32(addr, data); } if (size == 2) { for (;;) cvmx_write64_uint16(addr, data); } cp = (u_char *)addr; for (;;) for (;;) cvmx_write64_uint8(addr, data); } if (size == 8) { tmp_addr = addr; i = length; while (i-- > 0) { cvmx_write_csr(tmp_addr, data); tmp_addr += size; } } }
int do_mem_mw64 ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint64_t addr, writeval, count; int size; int swap = 0; if ((argc < 3) || (argc > 4)) return CMD_RET_USAGE; /* Check for size specification. */ if ((size = cmd_get_data_size(argv[0], 8)) < 1) return 1; swap = cmd_get_data_swap64(argv[0]); /* Address is specified since argc > 1 */ addr = simple_strtoull(argv[1], NULL, 16); addr |= base_address64; /* Get the value to write. */ writeval = simple_strtoull(argv[2], NULL, 16); /* Count ? */ if (argc == 4) { count = simple_strtoul(argv[3], NULL, 16); } else { count = 1; } while (count-- > 0) { if (size == 8) { if (swap) writeval = swab64(writeval); cvmx_write_csr(addr, writeval); } else if (size == 4) { if (swap) writeval = swab32(writeval); cvmx_write64_uint32(addr, writeval); } else if (size == 2) { if (swap) writeval = swab16(writeval); cvmx_write64_uint16(addr, writeval); } else { cvmx_write64_uint8(addr, writeval); } addr += size; } return 0; }
int do_write64l(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { uint64_t addr; uint32_t val; if (argc != 3) return CMD_RET_USAGE; addr = simple_strtoull(argv[1], NULL, 16); addr += base_address64; val = simple_strtoull(argv[2], NULL, 16); printf("writing 0x%x to addr: 0x%llx\n", val, addr); cvmx_write64_uint32(addr, val); return (0); }
int do_mem_loop64(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint64_t addr, length, i, dummy; int size; if (argc < 3) return CMD_RET_USAGE; /* Check for a size spefication. * Defaults to long if no or incorrect specification. */ if ((size = cmd_get_data_size(argv[0], 8)) < 0) return 1; /* Address is always specified. */ addr = simple_strtoull(argv[1], NULL, 16); /* Length is the number of objects, not number of bytes. */ length = simple_strtoull(argv[2], NULL, 16); /* We want to optimize the loops to run as fast as possible. * If we have only one object, just run infinite loops. */ if (length == 1) { if (size == 8) { for (;;) i = cvmx_read_csr(addr); } else if (size == 4) { for (;;) i = cvmx_read64_uint32(addr); } if (size == 2) { for (;;) i = cvmx_read64_uint16(addr); } for (;;) i = cvmx_read64_uint8(addr); } if (size == 8) { for (;;) { dummy = addr; i = length; while (i-- > 0) cvmx_write_csr(dummy, cvmx_read_csr(dummy) + 1); } } else if (size == 4) { for (;;) { dummy = addr; i = length; while (i-- > 0) cvmx_write64_uint32(dummy, cvmx_read64_uint32(dummy) + 1); } } if (size == 2) { for (;;) { dummy = addr; i = length; while (i-- > 0) cvmx_write64_uint16(dummy, cvmx_read64_uint16(dummy) + 1); } } for (;;) { dummy = addr; i = length; while (i-- > 0) cvmx_write64_uint8(dummy, cvmx_read64_uint8(dummy) + 1); } return -1; }
int do_mem_cp64 ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint64_t addr, dest, count; int size; if (argc != 4) return CMD_RET_USAGE; /* Check for size specification. */ if ((size = cmd_get_data_size(argv[0], 8)) < 0) return 1; addr = simple_strtoull(argv[1], NULL, 16); addr |= base_address64; dest = simple_strtoull(argv[2], NULL, 16); dest |= base_address64; count = simple_strtoull(argv[3], NULL, 16); if (count == 0) { puts ("Zero length ???\n"); return 1; } #ifndef CONFIG_SYS_NO_FLASH /* check if we are copying to Flash */ if ( (dest < 0xc0000000 && addr2info(dest) != NULL) #ifdef CONFIG_HAS_DATAFLASH && (!addr_dataflash(dest)) #endif ) { int rc; if (addr + count >= 0x100000000ull) { puts("Source address too high to copy to flash\n"); return 1; } puts ("Copy to Flash... "); rc = flash_write ((char *)((uint32_t)addr), (uint32_t)dest, count * size); if (rc != 0) { flash_perror (rc); return (1); } puts ("done\n"); return 0; } #endif #ifdef CONFIG_HAS_DATAFLASH /* Check if we are copying from RAM or Flash to DataFlash */ if ((dest < 0xc0000000) && addr_dataflash((uint32_t)dest) && !addr_dataflash((uint32_t)addr)) { int rc; if (addr + count >= 0x100000000ull) { puts("Source address is too high to copy to flash\n"); return 1; } puts ("Copy to DataFlash... "); rc = write_dataflash (dest, addr, count*size); if (rc != 1) { dataflash_perror (rc); return (1); } puts ("done\n"); return 0; } /* Check if we are copying from DataFlash to RAM */ if ((addr < 0xc0000000) && addr_dataflash((uint32_t)addr) && (dest + count < 0x100000000ull) && !addr_dataflash((uint32_t)dest) #ifndef CONFIG_SYS_NO_FLASH && (addr2info((uint32_t)dest) == NULL) #endif ) { int rc; rc = read_dataflash((uint32_t)addr, count * size, (char *)((uint32_t)dest)); if (rc != 1) { dataflash_perror (rc); return (1); } return 0; } if ((addr | dest) < 0x10000000ull && addr_dataflash(addr) && addr_dataflash(dest)) { puts ("Unsupported combination of source/destination.\n\r"); return 1; } #endif while (count-- > 0) { if (size == 8) cvmx_write_csr(dest, cvmx_read_csr(addr)); else if (size == 4) cvmx_write64_uint32(dest, cvmx_read64_uint32(addr)); else if (size == 2) cvmx_write64_uint16(dest, cvmx_read64_uint16(addr)); else cvmx_write64_uint8(dest, cvmx_read64_uint8(addr)); addr += size; dest += size; /* reset watchdog from time to time */ if ((count % (64 << 10)) == 0) WATCHDOG_RESET(); } return 0; }
/** * @INTERNAL * Write a USB 32bit CSR. It performs the necessary address swizzle for 32bit * CSRs. * * @param usb USB device state populated by * cvmx_usbd_initialize(). * @param address 64bit address to write * @param value Value to write */ static inline void __cvmx_usbd_write_csr32(cvmx_usbd_state_t *usb, uint64_t address, uint32_t value) { cvmx_write64_uint32(address ^ 4, value); cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index)); }