1 | /* |
2 | * Header file for the Xilinx Zynq SPI controller |
3 | * |
4 | * Copyright (C) 2015 Xilinx Inc |
5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | * of this software and associated documentation files (the "Software"), to deal |
8 | * in the Software without restriction, including without limitation the rights |
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
10 | * copies of the Software, and to permit persons to whom the Software is |
11 | * furnished to do so, subject to the following conditions: |
12 | * |
13 | * The above copyright notice and this permission notice shall be included in |
14 | * all copies or substantial portions of the Software. |
15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
22 | * THE SOFTWARE. |
23 | */ |
24 | |
25 | #ifndef XILINX_SPIPS_H |
26 | #define XILINX_SPIPS_H |
27 | |
28 | #include "hw/ssi/ssi.h" |
29 | #include "qemu/fifo32.h" |
30 | #include "hw/stream.h" |
31 | #include "hw/sysbus.h" |
32 | |
33 | typedef struct XilinxSPIPS XilinxSPIPS; |
34 | |
35 | #define XLNX_SPIPS_R_MAX (0x100 / 4) |
36 | #define XLNX_ZYNQMP_SPIPS_R_MAX (0x830 / 4) |
37 | |
38 | /* Bite off 4k chunks at a time */ |
39 | #define LQSPI_CACHE_SIZE 1024 |
40 | |
41 | #define QSPI_DMA_MAX_BURST_SIZE 2048 |
42 | |
43 | typedef enum { |
44 | READ = 0x3, READ_4 = 0x13, |
45 | FAST_READ = 0xb, FAST_READ_4 = 0x0c, |
46 | DOR = 0x3b, DOR_4 = 0x3c, |
47 | QOR = 0x6b, QOR_4 = 0x6c, |
48 | DIOR = 0xbb, DIOR_4 = 0xbc, |
49 | QIOR = 0xeb, QIOR_4 = 0xec, |
50 | |
51 | PP = 0x2, PP_4 = 0x12, |
52 | DPP = 0xa2, |
53 | QPP = 0x32, QPP_4 = 0x34, |
54 | } FlashCMD; |
55 | |
56 | struct XilinxSPIPS { |
57 | SysBusDevice parent_obj; |
58 | |
59 | MemoryRegion iomem; |
60 | MemoryRegion mmlqspi; |
61 | |
62 | qemu_irq irq; |
63 | int irqline; |
64 | |
65 | uint8_t num_cs; |
66 | uint8_t num_busses; |
67 | |
68 | uint8_t snoop_state; |
69 | int cmd_dummies; |
70 | uint8_t link_state; |
71 | uint8_t link_state_next; |
72 | uint8_t link_state_next_when; |
73 | qemu_irq *cs_lines; |
74 | bool *cs_lines_state; |
75 | SSIBus **spi; |
76 | |
77 | Fifo8 rx_fifo; |
78 | Fifo8 tx_fifo; |
79 | |
80 | uint8_t num_txrx_bytes; |
81 | uint32_t rx_discard; |
82 | |
83 | uint32_t regs[XLNX_SPIPS_R_MAX]; |
84 | |
85 | bool man_start_com; |
86 | }; |
87 | |
88 | typedef struct { |
89 | XilinxSPIPS parent_obj; |
90 | |
91 | uint8_t lqspi_buf[LQSPI_CACHE_SIZE]; |
92 | hwaddr lqspi_cached_addr; |
93 | Error *migration_blocker; |
94 | bool mmio_execution_enabled; |
95 | } XilinxQSPIPS; |
96 | |
97 | typedef struct { |
98 | XilinxQSPIPS parent_obj; |
99 | |
100 | StreamSlave *dma; |
101 | int gqspi_irqline; |
102 | |
103 | uint32_t regs[XLNX_ZYNQMP_SPIPS_R_MAX]; |
104 | |
105 | /* GQSPI has seperate tx/rx fifos */ |
106 | Fifo8 rx_fifo_g; |
107 | Fifo8 tx_fifo_g; |
108 | Fifo32 fifo_g; |
109 | /* |
110 | * At the end of each generic command, misaligned extra bytes are discard |
111 | * or padded to tx and rx respectively to round it out (and avoid need for |
112 | * individual byte access. Since we use byte fifos, keep track of the |
113 | * alignment WRT to word access. |
114 | */ |
115 | uint8_t rx_fifo_g_align; |
116 | uint8_t tx_fifo_g_align; |
117 | bool man_start_com_g; |
118 | uint32_t dma_burst_size; |
119 | uint8_t dma_buf[QSPI_DMA_MAX_BURST_SIZE]; |
120 | } XlnxZynqMPQSPIPS; |
121 | |
122 | typedef struct XilinxSPIPSClass { |
123 | SysBusDeviceClass parent_class; |
124 | |
125 | const MemoryRegionOps *reg_ops; |
126 | |
127 | uint32_t rx_fifo_size; |
128 | uint32_t tx_fifo_size; |
129 | } XilinxSPIPSClass; |
130 | |
131 | #define TYPE_XILINX_SPIPS "xlnx.ps7-spi" |
132 | #define TYPE_XILINX_QSPIPS "xlnx.ps7-qspi" |
133 | #define TYPE_XLNX_ZYNQMP_QSPIPS "xlnx.usmp-gqspi" |
134 | |
135 | #define XILINX_SPIPS(obj) \ |
136 | OBJECT_CHECK(XilinxSPIPS, (obj), TYPE_XILINX_SPIPS) |
137 | #define XILINX_SPIPS_CLASS(klass) \ |
138 | OBJECT_CLASS_CHECK(XilinxSPIPSClass, (klass), TYPE_XILINX_SPIPS) |
139 | #define XILINX_SPIPS_GET_CLASS(obj) \ |
140 | OBJECT_GET_CLASS(XilinxSPIPSClass, (obj), TYPE_XILINX_SPIPS) |
141 | |
142 | #define XILINX_QSPIPS(obj) \ |
143 | OBJECT_CHECK(XilinxQSPIPS, (obj), TYPE_XILINX_QSPIPS) |
144 | |
145 | #define XLNX_ZYNQMP_QSPIPS(obj) \ |
146 | OBJECT_CHECK(XlnxZynqMPQSPIPS, (obj), TYPE_XLNX_ZYNQMP_QSPIPS) |
147 | |
148 | #endif /* XILINX_SPIPS_H */ |
149 | |