diff options
Diffstat (limited to 'include/hw/ssi')
-rw-r--r-- | include/hw/ssi/aspeed_smc.h | 116 | ||||
-rw-r--r-- | include/hw/ssi/imx_spi.h | 107 | ||||
-rw-r--r-- | include/hw/ssi/mss-spi.h | 59 | ||||
-rw-r--r-- | include/hw/ssi/npcm7xx_fiu.h | 73 | ||||
-rw-r--r-- | include/hw/ssi/pl022.h | 53 | ||||
-rw-r--r-- | include/hw/ssi/sifive_spi.h | 47 | ||||
-rw-r--r-- | include/hw/ssi/ssi.h | 109 | ||||
-rw-r--r-- | include/hw/ssi/stm32f2xx_spi.h | 71 | ||||
-rw-r--r-- | include/hw/ssi/xilinx_spips.h | 143 |
9 files changed, 778 insertions, 0 deletions
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h new file mode 100644 index 000000000..e26555581 --- /dev/null +++ b/include/hw/ssi/aspeed_smc.h @@ -0,0 +1,116 @@ +/* + * ASPEED AST2400 SMC Controller (SPI Flash Only) + * + * Copyright (C) 2016 IBM Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef ASPEED_SMC_H +#define ASPEED_SMC_H + +#include "hw/ssi/ssi.h" +#include "hw/sysbus.h" +#include "qom/object.h" + +struct AspeedSMCState; + +#define TYPE_ASPEED_SMC_FLASH "aspeed.smc.flash" +OBJECT_DECLARE_SIMPLE_TYPE(AspeedSMCFlash, ASPEED_SMC_FLASH) +struct AspeedSMCFlash { + SysBusDevice parent_obj; + + struct AspeedSMCState *controller; + uint8_t cs; + + MemoryRegion mmio; +}; + +#define TYPE_ASPEED_SMC "aspeed.smc" +OBJECT_DECLARE_TYPE(AspeedSMCState, AspeedSMCClass, ASPEED_SMC) + +#define ASPEED_SMC_R_MAX (0x100 / 4) +#define ASPEED_SMC_CS_MAX 5 + +struct AspeedSMCState { + SysBusDevice parent_obj; + + MemoryRegion mmio; + MemoryRegion mmio_flash_container; + MemoryRegion mmio_flash; + + qemu_irq irq; + + uint32_t num_cs; + qemu_irq *cs_lines; + bool inject_failure; + + SSIBus *spi; + + uint32_t regs[ASPEED_SMC_R_MAX]; + + /* depends on the controller type */ + uint8_t r_conf; + uint8_t r_ce_ctrl; + uint8_t r_ctrl0; + uint8_t r_timings; + uint8_t conf_enable_w0; + + AddressSpace flash_as; + MemoryRegion *dram_mr; + AddressSpace dram_as; + + AspeedSMCFlash flashes[ASPEED_SMC_CS_MAX]; + + uint8_t snoop_index; + uint8_t snoop_dummies; +}; + +typedef struct AspeedSegments { + hwaddr addr; + uint32_t size; +} AspeedSegments; + +struct AspeedSMCClass { + SysBusDeviceClass parent_obj; + + uint8_t r_conf; + uint8_t r_ce_ctrl; + uint8_t r_ctrl0; + uint8_t r_timings; + uint8_t nregs_timings; + uint8_t conf_enable_w0; + uint8_t max_peripherals; + const uint32_t *resets; + const AspeedSegments *segments; + hwaddr flash_window_base; + uint32_t flash_window_size; + uint32_t features; + hwaddr dma_flash_mask; + hwaddr dma_dram_mask; + uint32_t nregs; + uint32_t (*segment_to_reg)(const AspeedSMCState *s, + const AspeedSegments *seg); + void (*reg_to_segment)(const AspeedSMCState *s, uint32_t reg, + AspeedSegments *seg); + void (*dma_ctrl)(AspeedSMCState *s, uint32_t value); + int (*addr_width)(const AspeedSMCState *s); +}; + +#endif /* ASPEED_SMC_H */ diff --git a/include/hw/ssi/imx_spi.h b/include/hw/ssi/imx_spi.h new file mode 100644 index 000000000..eeaf49bba --- /dev/null +++ b/include/hw/ssi/imx_spi.h @@ -0,0 +1,107 @@ +/* + * IMX SPI Controller + * + * Copyright 2016 Jean-Christophe Dubois <jcd@tribudubois.net> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef IMX_SPI_H +#define IMX_SPI_H + +#include "hw/sysbus.h" +#include "hw/ssi/ssi.h" +#include "qemu/bitops.h" +#include "qemu/fifo32.h" +#include "qom/object.h" + +#define ECSPI_FIFO_SIZE 64 + +#define ECSPI_RXDATA 0 +#define ECSPI_TXDATA 1 +#define ECSPI_CONREG 2 +#define ECSPI_CONFIGREG 3 +#define ECSPI_INTREG 4 +#define ECSPI_DMAREG 5 +#define ECSPI_STATREG 6 +#define ECSPI_PERIODREG 7 +#define ECSPI_TESTREG 8 +#define ECSPI_MSGDATA 16 +#define ECSPI_MAX 17 + +/* ECSPI_CONREG */ +#define ECSPI_CONREG_EN (1 << 0) +#define ECSPI_CONREG_HT (1 << 1) +#define ECSPI_CONREG_XCH (1 << 2) +#define ECSPI_CONREG_SMC (1 << 3) +#define ECSPI_CONREG_CHANNEL_MODE_SHIFT 4 +#define ECSPI_CONREG_CHANNEL_MODE_LENGTH 4 +#define ECSPI_CONREG_DRCTL_SHIFT 16 +#define ECSPI_CONREG_DRCTL_LENGTH 2 +#define ECSPI_CONREG_CHANNEL_SELECT_SHIFT 18 +#define ECSPI_CONREG_CHANNEL_SELECT_LENGTH 2 +#define ECSPI_CONREG_BURST_LENGTH_SHIFT 20 +#define ECSPI_CONREG_BURST_LENGTH_LENGTH 12 + +/* ECSPI_CONFIGREG */ +#define ECSPI_CONFIGREG_SS_CTL_SHIFT 8 +#define ECSPI_CONFIGREG_SS_CTL_LENGTH 4 + +/* ECSPI_INTREG */ +#define ECSPI_INTREG_TEEN (1 << 0) +#define ECSPI_INTREG_TDREN (1 << 1) +#define ECSPI_INTREG_TFEN (1 << 2) +#define ECSPI_INTREG_RREN (1 << 3) +#define ECSPI_INTREG_RDREN (1 << 4) +#define ECSPI_INTREG_RFEN (1 << 5) +#define ECSPI_INTREG_ROEN (1 << 6) +#define ECSPI_INTREG_TCEN (1 << 7) + +/* ECSPI_DMAREG */ +#define ECSPI_DMAREG_RXTDEN (1 << 31) +#define ECSPI_DMAREG_RXDEN (1 << 23) +#define ECSPI_DMAREG_TEDEN (1 << 7) +#define ECSPI_DMAREG_RX_THRESHOLD_SHIFT 16 +#define ECSPI_DMAREG_RX_THRESHOLD_LENGTH 6 + +/* ECSPI_STATREG */ +#define ECSPI_STATREG_TE (1 << 0) +#define ECSPI_STATREG_TDR (1 << 1) +#define ECSPI_STATREG_TF (1 << 2) +#define ECSPI_STATREG_RR (1 << 3) +#define ECSPI_STATREG_RDR (1 << 4) +#define ECSPI_STATREG_RF (1 << 5) +#define ECSPI_STATREG_RO (1 << 6) +#define ECSPI_STATREG_TC (1 << 7) + +#define EXTRACT(value, name) extract32(value, name##_SHIFT, name##_LENGTH) + +/* number of chip selects supported */ +#define ECSPI_NUM_CS 4 + +#define TYPE_IMX_SPI "imx.spi" +OBJECT_DECLARE_SIMPLE_TYPE(IMXSPIState, IMX_SPI) + +struct IMXSPIState { + /* <private> */ + SysBusDevice parent_obj; + + /* <public> */ + MemoryRegion iomem; + + qemu_irq irq; + + qemu_irq cs_lines[ECSPI_NUM_CS]; + + SSIBus *bus; + + uint32_t regs[ECSPI_MAX]; + + Fifo32 rx_fifo; + Fifo32 tx_fifo; + + int16_t burst_length; +}; + +#endif /* IMX_SPI_H */ diff --git a/include/hw/ssi/mss-spi.h b/include/hw/ssi/mss-spi.h new file mode 100644 index 000000000..ce6279c43 --- /dev/null +++ b/include/hw/ssi/mss-spi.h @@ -0,0 +1,59 @@ +/* + * Microsemi SmartFusion2 SPI + * + * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef HW_MSS_SPI_H +#define HW_MSS_SPI_H + +#include "hw/sysbus.h" +#include "hw/ssi/ssi.h" +#include "qemu/fifo32.h" +#include "qom/object.h" + +#define TYPE_MSS_SPI "mss-spi" +OBJECT_DECLARE_SIMPLE_TYPE(MSSSpiState, MSS_SPI) + +#define R_SPI_MAX 16 + +struct MSSSpiState { + SysBusDevice parent_obj; + + MemoryRegion mmio; + + qemu_irq irq; + + qemu_irq cs_line; + + SSIBus *spi; + + Fifo32 rx_fifo; + Fifo32 tx_fifo; + + int fifo_depth; + uint32_t frame_count; + bool enabled; + + uint32_t regs[R_SPI_MAX]; +}; + +#endif /* HW_MSS_SPI_H */ diff --git a/include/hw/ssi/npcm7xx_fiu.h b/include/hw/ssi/npcm7xx_fiu.h new file mode 100644 index 000000000..a3a170428 --- /dev/null +++ b/include/hw/ssi/npcm7xx_fiu.h @@ -0,0 +1,73 @@ +/* + * Nuvoton NPCM7xx Flash Interface Unit (FIU) + * + * Copyright 2020 Google LLC + * + * 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. + */ +#ifndef NPCM7XX_FIU_H +#define NPCM7XX_FIU_H + +#include "hw/ssi/ssi.h" +#include "hw/sysbus.h" + +/* + * Number of registers in our device state structure. Don't change this without + * incrementing the version_id in the vmstate. + */ +#define NPCM7XX_FIU_NR_REGS (0x7c / sizeof(uint32_t)) + +typedef struct NPCM7xxFIUState NPCM7xxFIUState; + +/** + * struct NPCM7xxFIUFlash - Per-chipselect flash controller state. + * @direct_access: Memory region for direct flash access. + * @fiu: Pointer to flash controller shared state. + */ +typedef struct NPCM7xxFIUFlash { + MemoryRegion direct_access; + NPCM7xxFIUState *fiu; +} NPCM7xxFIUFlash; + +/** + * NPCM7xxFIUState - Device state for one Flash Interface Unit. + * @parent: System bus device. + * @mmio: Memory region for register access. + * @cs_count: Number of flash chips that may be connected to this module. + * @active_cs: Currently active chip select, or -1 if no chip is selected. + * @cs_lines: GPIO lines that may be wired to flash chips. + * @flash: Array of @cs_count per-flash-chip state objects. + * @spi: The SPI bus mastered by this controller. + * @regs: Register contents. + * + * Each FIU has a shared bank of registers, and controls up to four chip + * selects. Each chip select has a dedicated memory region which may be used to + * read and write the flash connected to that chip select as if it were memory. + */ +struct NPCM7xxFIUState { + SysBusDevice parent; + + MemoryRegion mmio; + + int32_t cs_count; + int32_t active_cs; + qemu_irq *cs_lines; + NPCM7xxFIUFlash *flash; + + SSIBus *spi; + + uint32_t regs[NPCM7XX_FIU_NR_REGS]; +}; + +#define TYPE_NPCM7XX_FIU "npcm7xx-fiu" +#define NPCM7XX_FIU(obj) OBJECT_CHECK(NPCM7xxFIUState, (obj), TYPE_NPCM7XX_FIU) + +#endif /* NPCM7XX_FIU_H */ diff --git a/include/hw/ssi/pl022.h b/include/hw/ssi/pl022.h new file mode 100644 index 000000000..25d58db5f --- /dev/null +++ b/include/hw/ssi/pl022.h @@ -0,0 +1,53 @@ +/* + * ARM PrimeCell PL022 Synchronous Serial Port + * + * Copyright (c) 2007 CodeSourcery. + * Written by Paul Brook + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the Arm PrimeCell PL022 synchronous serial port. + * The PL022 TRM is: + * https://developer.arm.com/documentation/ddi0194/latest + * + * QEMU interface: + * + sysbus IRQ: SSPINTR combined interrupt line + * + sysbus MMIO region 0: MemoryRegion for the device's registers + */ + +#ifndef HW_SSI_PL022_H +#define HW_SSI_PL022_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_PL022 "pl022" +OBJECT_DECLARE_SIMPLE_TYPE(PL022State, PL022) + +struct PL022State { + SysBusDevice parent_obj; + + MemoryRegion iomem; + uint32_t cr0; + uint32_t cr1; + uint32_t bitmask; + uint32_t sr; + uint32_t cpsr; + uint32_t is; + uint32_t im; + /* The FIFO head points to the next empty entry. */ + int tx_fifo_head; + int rx_fifo_head; + int tx_fifo_len; + int rx_fifo_len; + uint16_t tx_fifo[8]; + uint16_t rx_fifo[8]; + qemu_irq irq; + SSIBus *ssi; +}; + +#endif diff --git a/include/hw/ssi/sifive_spi.h b/include/hw/ssi/sifive_spi.h new file mode 100644 index 000000000..47d0d6a47 --- /dev/null +++ b/include/hw/ssi/sifive_spi.h @@ -0,0 +1,47 @@ +/* + * QEMU model of the SiFive SPI Controller + * + * Copyright (c) 2021 Wind River Systems, Inc. + * + * Author: + * Bin Meng <bin.meng@windriver.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_SIFIVE_SPI_H +#define HW_SIFIVE_SPI_H + +#define SIFIVE_SPI_REG_NUM (0x78 / 4) + +#define TYPE_SIFIVE_SPI "sifive.spi" +#define SIFIVE_SPI(obj) OBJECT_CHECK(SiFiveSPIState, (obj), TYPE_SIFIVE_SPI) + +typedef struct SiFiveSPIState { + SysBusDevice parent_obj; + + MemoryRegion mmio; + qemu_irq irq; + + uint32_t num_cs; + qemu_irq *cs_lines; + + SSIBus *spi; + + Fifo8 tx_fifo; + Fifo8 rx_fifo; + + uint32_t regs[SIFIVE_SPI_REG_NUM]; +} SiFiveSPIState; + +#endif /* HW_SIFIVE_SPI_H */ diff --git a/include/hw/ssi/ssi.h b/include/hw/ssi/ssi.h new file mode 100644 index 000000000..f411858ab --- /dev/null +++ b/include/hw/ssi/ssi.h @@ -0,0 +1,109 @@ +/* QEMU Synchronous Serial Interface support. */ + +/* + * In principle SSI is a point-point interface. As such the qemu + * implementation has a single peripheral on a "bus". + * However it is fairly common for boards to have multiple peripherals + * connected to a single master, and select devices with an external + * chip select. This is implemented in qemu by having an explicit mux device. + * It is assumed that master and peripheral are both using the same transfer + * width. + */ + +#ifndef QEMU_SSI_H +#define QEMU_SSI_H + +#include "hw/qdev-core.h" +#include "qom/object.h" + +typedef enum SSICSMode SSICSMode; + +#define TYPE_SSI_PERIPHERAL "ssi-peripheral" +OBJECT_DECLARE_TYPE(SSIPeripheral, SSIPeripheralClass, + SSI_PERIPHERAL) + +#define SSI_GPIO_CS "ssi-gpio-cs" + +enum SSICSMode { + SSI_CS_NONE = 0, + SSI_CS_LOW, + SSI_CS_HIGH, +}; + +/* Peripherals. */ +struct SSIPeripheralClass { + DeviceClass parent_class; + + void (*realize)(SSIPeripheral *dev, Error **errp); + + /* if you have standard or no CS behaviour, just override transfer. + * This is called when the device cs is active (true by default). + */ + uint32_t (*transfer)(SSIPeripheral *dev, uint32_t val); + /* called when the CS line changes. Optional, devices only need to implement + * this if they have side effects associated with the cs line (beyond + * tristating the txrx lines). + */ + int (*set_cs)(SSIPeripheral *dev, bool select); + /* define whether or not CS exists and is active low/high */ + SSICSMode cs_polarity; + + /* if you have non-standard CS behaviour override this to take control + * of the CS behaviour at the device level. transfer, set_cs, and + * cs_polarity are unused if this is overwritten. Transfer_raw will + * always be called for the device for every txrx access to the parent bus + */ + uint32_t (*transfer_raw)(SSIPeripheral *dev, uint32_t val); +}; + +struct SSIPeripheral { + DeviceState parent_obj; + + /* Chip select state */ + bool cs; +}; + +extern const VMStateDescription vmstate_ssi_peripheral; + +#define VMSTATE_SSI_PERIPHERAL(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(SSIPeripheral), \ + .vmsd = &vmstate_ssi_peripheral, \ + .flags = VMS_STRUCT, \ + .offset = vmstate_offset_value(_state, _field, SSIPeripheral), \ +} + +DeviceState *ssi_create_peripheral(SSIBus *bus, const char *name); +/** + * ssi_realize_and_unref: realize and unref an SSI peripheral + * @dev: SSI peripheral to realize + * @bus: SSI bus to put it on + * @errp: error pointer + * + * Call 'realize' on @dev, put it on the specified @bus, and drop the + * reference to it. Errors are reported via @errp and by returning + * false. + * + * This function is useful if you have created @dev via qdev_new() + * (which takes a reference to the device it returns to you), so that + * you can set properties on it before realizing it. If you don't need + * to set properties then ssi_create_peripheral() is probably better (as it + * does the create, init and realize in one step). + * + * If you are embedding the SSI peripheral into another QOM device and + * initialized it via some variant on object_initialize_child() then + * do not use this function, because that family of functions arrange + * for the only reference to the child device to be held by the parent + * via the child<> property, and so the reference-count-drop done here + * would be incorrect. (Instead you would want ssi_realize(), which + * doesn't currently exist but would be trivial to create if we had + * any code that wanted it.) + */ +bool ssi_realize_and_unref(DeviceState *dev, SSIBus *bus, Error **errp); + +/* Master interface. */ +SSIBus *ssi_create_bus(DeviceState *parent, const char *name); + +uint32_t ssi_transfer(SSIBus *bus, uint32_t val); + +#endif diff --git a/include/hw/ssi/stm32f2xx_spi.h b/include/hw/ssi/stm32f2xx_spi.h new file mode 100644 index 000000000..3683b4ad3 --- /dev/null +++ b/include/hw/ssi/stm32f2xx_spi.h @@ -0,0 +1,71 @@ +/* + * STM32F2XX SPI + * + * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef HW_STM32F2XX_SPI_H +#define HW_STM32F2XX_SPI_H + +#include "hw/sysbus.h" +#include "hw/ssi/ssi.h" +#include "qom/object.h" + +#define STM_SPI_CR1 0x00 +#define STM_SPI_CR2 0x04 +#define STM_SPI_SR 0x08 +#define STM_SPI_DR 0x0C +#define STM_SPI_CRCPR 0x10 +#define STM_SPI_RXCRCR 0x14 +#define STM_SPI_TXCRCR 0x18 +#define STM_SPI_I2SCFGR 0x1C +#define STM_SPI_I2SPR 0x20 + +#define STM_SPI_CR1_SPE (1 << 6) +#define STM_SPI_CR1_MSTR (1 << 2) + +#define STM_SPI_SR_RXNE 1 + +#define TYPE_STM32F2XX_SPI "stm32f2xx-spi" +OBJECT_DECLARE_SIMPLE_TYPE(STM32F2XXSPIState, STM32F2XX_SPI) + +struct STM32F2XXSPIState { + /* <private> */ + SysBusDevice parent_obj; + + /* <public> */ + MemoryRegion mmio; + + uint32_t spi_cr1; + uint32_t spi_cr2; + uint32_t spi_sr; + uint32_t spi_dr; + uint32_t spi_crcpr; + uint32_t spi_rxcrcr; + uint32_t spi_txcrcr; + uint32_t spi_i2scfgr; + uint32_t spi_i2spr; + + qemu_irq irq; + SSIBus *ssi; +}; + +#endif /* HW_STM32F2XX_SPI_H */ diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h new file mode 100644 index 000000000..06bfd1831 --- /dev/null +++ b/include/hw/ssi/xilinx_spips.h @@ -0,0 +1,143 @@ +/* + * Header file for the Xilinx Zynq SPI controller + * + * Copyright (C) 2015 Xilinx Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef XILINX_SPIPS_H +#define XILINX_SPIPS_H + +#include "hw/ssi/ssi.h" +#include "qemu/fifo32.h" +#include "hw/stream.h" +#include "hw/sysbus.h" +#include "qom/object.h" + +typedef struct XilinxSPIPS XilinxSPIPS; + +#define XLNX_SPIPS_R_MAX (0x100 / 4) +#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4) + +/* Bite off 4k chunks at a time */ +#define LQSPI_CACHE_SIZE 1024 + +#define QSPI_DMA_MAX_BURST_SIZE 2048 + +typedef enum { + READ = 0x3, READ_4 = 0x13, + FAST_READ = 0xb, FAST_READ_4 = 0x0c, + DOR = 0x3b, DOR_4 = 0x3c, + QOR = 0x6b, QOR_4 = 0x6c, + DIOR = 0xbb, DIOR_4 = 0xbc, + QIOR = 0xeb, QIOR_4 = 0xec, + + PP = 0x2, PP_4 = 0x12, + DPP = 0xa2, + QPP = 0x32, QPP_4 = 0x34, +} FlashCMD; + +struct XilinxSPIPS { + SysBusDevice parent_obj; + + MemoryRegion iomem; + MemoryRegion mmlqspi; + + qemu_irq irq; + int irqline; + + uint8_t num_cs; + uint8_t num_busses; + + uint8_t snoop_state; + int cmd_dummies; + uint8_t link_state; + uint8_t link_state_next; + uint8_t link_state_next_when; + qemu_irq *cs_lines; + bool *cs_lines_state; + SSIBus **spi; + + Fifo8 rx_fifo; + Fifo8 tx_fifo; + + uint8_t num_txrx_bytes; + uint32_t rx_discard; + + uint32_t regs[XLNX_SPIPS_R_MAX]; + + bool man_start_com; +}; + +struct XilinxQSPIPS { + XilinxSPIPS parent_obj; + + uint8_t lqspi_buf[LQSPI_CACHE_SIZE]; + hwaddr lqspi_cached_addr; + Error *migration_blocker; + bool mmio_execution_enabled; +}; +typedef struct XilinxQSPIPS XilinxQSPIPS; + +struct XlnxZynqMPQSPIPS { + XilinxQSPIPS parent_obj; + + StreamSink *dma; + int gqspi_irqline; + + uint32_t regs[XLNX_ZYNQMP_SPIPS_R_MAX]; + + /* GQSPI has seperate tx/rx fifos */ + Fifo8 rx_fifo_g; + Fifo8 tx_fifo_g; + Fifo32 fifo_g; + /* + * At the end of each generic command, misaligned extra bytes are discard + * or padded to tx and rx respectively to round it out (and avoid need for + * individual byte access. Since we use byte fifos, keep track of the + * alignment WRT to word access. + */ + uint8_t rx_fifo_g_align; + uint8_t tx_fifo_g_align; + bool man_start_com_g; + uint32_t dma_burst_size; + uint8_t dma_buf[QSPI_DMA_MAX_BURST_SIZE]; +}; + +struct XilinxSPIPSClass { + SysBusDeviceClass parent_class; + + const MemoryRegionOps *reg_ops; + + uint32_t rx_fifo_size; + uint32_t tx_fifo_size; +}; + +#define TYPE_XILINX_SPIPS "xlnx.ps7-spi" +#define TYPE_XILINX_QSPIPS "xlnx.ps7-qspi" +#define TYPE_XLNX_ZYNQMP_QSPIPS "xlnx.usmp-gqspi" + +OBJECT_DECLARE_TYPE(XilinxSPIPS, XilinxSPIPSClass, XILINX_SPIPS) + +OBJECT_DECLARE_SIMPLE_TYPE(XilinxQSPIPS, XILINX_QSPIPS) + +OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPQSPIPS, XLNX_ZYNQMP_QSPIPS) + +#endif /* XILINX_SPIPS_H */ |