1 /* SPDX-License-Identifier: GPL-2.0-only */
2 #ifndef __SOC_SIFIVE_HIFIVE_U_SPI_INTERNAL_H__
3 #define __SOC_SIFIVE_HIFIVE_U_SPI_INTERNAL_H__
7 #define _ASSERT_SIZEOF(type, size) _Static_assert( \
8 sizeof(type) == (size), \
9 #type " must be " #size " bytes wide")
11 #define FU540_SPI_CSMODE_AUTO 0
12 #define FU540_SPI_CSMODE_HOLD 2
13 #define FU540_SPI_CSMODE_OFF 3
19 uint32_t reserved
: 30;
23 _ASSERT_SIZEOF(spi_reg_sckmode
, 4);
28 uint32_t reserved
: 30;
32 _ASSERT_SIZEOF(spi_reg_csmode
, 4);
37 uint32_t reserved0
: 8;
39 uint32_t reserved1
: 8;
43 _ASSERT_SIZEOF(spi_reg_delay0
, 4);
48 uint32_t reserved0
: 8;
49 uint32_t interxfr
: 8;
50 uint32_t reserved1
: 8;
54 _ASSERT_SIZEOF(spi_reg_delay1
, 4);
61 uint32_t reserved0
: 12;
63 uint32_t reserved1
: 12;
67 _ASSERT_SIZEOF(spi_reg_fmt
, 4);
72 uint32_t reserved
: 23;
77 _ASSERT_SIZEOF(spi_reg_txdata
, 4);
82 uint32_t reserved
: 23;
87 _ASSERT_SIZEOF(spi_reg_rxdata
, 4);
92 uint32_t reserved
: 29;
96 _ASSERT_SIZEOF(spi_reg_txmark
, 4);
101 uint32_t reserved
: 29;
105 _ASSERT_SIZEOF(spi_reg_rxmark
, 4);
110 uint32_t reserved
: 31;
114 _ASSERT_SIZEOF(spi_reg_fctrl
, 4);
119 uint32_t addr_len
: 3;
120 uint32_t pad_cnt
: 4;
121 uint32_t command_proto
: 2;
122 uint32_t addr_proto
: 2;
123 uint32_t data_proto
: 2;
124 uint32_t reserved
: 2;
125 uint32_t command_code
: 8;
126 uint32_t pad_code
: 8;
130 _ASSERT_SIZEOF(spi_reg_ffmt
, 4);
136 uint32_t reserved
: 30;
140 typedef spi_reg_ie spi_reg_ip
;
141 _ASSERT_SIZEOF(spi_reg_ie
, 4);
142 _ASSERT_SIZEOF(spi_reg_ip
, 4);
144 #undef _ASSERT_SIZEOF
147 * SPI control register memory map.
149 * All functions take a pointer to a SPI device's control registers.
153 spi_reg_sckmode sckmode
;
159 spi_reg_csmode csmode
;
164 spi_reg_delay0 delay0
;
165 spi_reg_delay1 delay1
;
174 spi_reg_txdata txdata
;
175 spi_reg_rxdata rxdata
;
177 spi_reg_txmark txmark
;
178 spi_reg_rxmark rxmark
;
192 * Get smallest clock divisor that divides input_khz to a quotient less than or
193 * equal to max_target_khz;
195 static inline unsigned int
196 spi_min_clk_divisor(unsigned int input_khz
, unsigned int max_target_khz
)
198 // f_sck = f_in / (2 * (div + 1)) => div = (f_in / (2*f_sck)) - 1
200 // The nearest integer solution for div requires rounding up as to not
201 // exceed max_target_khz.
203 // div = ceil(f_in / (2*f_sck)) - 1
204 // = floor((f_in - 1 + 2*f_sck) / (2*f_sck)) - 1
206 // This should not overflow as long as (f_in - 1 + 2*f_sck) does not
207 // exceed 2^32 - 1, which is unlikely since we represent frequencies
209 unsigned int quotient
=
210 (input_khz
+ 2 * max_target_khz
- 1) / (2 * max_target_khz
);
217 #endif /* __SOC_SIFIVE_HIFIVE_U_SPI_INTERNAL_H__ */