1313#include <linux/module.h>
1414#include <linux/platform_device.h>
1515#include <linux/spi/spi.h>
16+ #include <linux/timer.h>
1617
1718#define SPI_ENGINE_VERSION_MAJOR (x ) ((x >> 16) & 0xff)
1819#define SPI_ENGINE_VERSION_MINOR (x ) ((x >> 8) & 0xff)
@@ -114,6 +115,8 @@ struct spi_engine {
114115
115116 void __iomem * base ;
116117 struct ida sync_ida ;
118+ struct timer_list watchdog_timer ;
119+ struct spi_controller * controller ;
117120
118121 unsigned int int_enable ;
119122};
@@ -140,21 +143,6 @@ static unsigned int spi_engine_get_config(struct spi_device *spi)
140143 return config ;
141144}
142145
143- static unsigned int spi_engine_get_clk_div (struct spi_engine * spi_engine ,
144- struct spi_device * spi , struct spi_transfer * xfer )
145- {
146- unsigned int clk_div ;
147-
148- clk_div = DIV_ROUND_UP (clk_get_rate (spi_engine -> ref_clk ),
149- xfer -> speed_hz * 2 );
150- if (clk_div > 255 )
151- clk_div = 255 ;
152- else if (clk_div > 0 )
153- clk_div -= 1 ;
154-
155- return clk_div ;
156- }
157-
158146static void spi_engine_gen_xfer (struct spi_engine_program * p , bool dry ,
159147 struct spi_transfer * xfer )
160148{
@@ -183,22 +171,16 @@ static void spi_engine_gen_xfer(struct spi_engine_program *p, bool dry,
183171}
184172
185173static void spi_engine_gen_sleep (struct spi_engine_program * p , bool dry ,
186- struct spi_engine * spi_engine , unsigned int clk_div ,
187- struct spi_transfer * xfer )
174+ int delay_ns , u32 sclk_hz )
188175{
189- unsigned int spi_clk = clk_get_rate (spi_engine -> ref_clk );
190176 unsigned int t ;
191- int delay ;
192-
193- delay = spi_delay_to_ns (& xfer -> delay , xfer );
194- if (delay < 0 )
195- return ;
196- delay /= 1000 ;
197177
198- if (delay == 0 )
178+ /* negative delay indicates error, e.g. from spi_delay_to_ns() */
179+ if (delay_ns <= 0 )
199180 return ;
200181
201- t = DIV_ROUND_UP (delay * spi_clk , (clk_div + 1 ) * 2 );
182+ /* rounding down since executing the instruction adds a couple of ticks delay */
183+ t = DIV_ROUND_DOWN_ULL ((u64 )delay_ns * sclk_hz , NSEC_PER_SEC );
202184 while (t ) {
203185 unsigned int n = min (t , 256U );
204186
@@ -215,19 +197,41 @@ static void spi_engine_gen_cs(struct spi_engine_program *p, bool dry,
215197 if (assert )
216198 mask ^= BIT (spi_get_chipselect (spi , 0 ));
217199
218- spi_engine_program_add_cmd (p , dry , SPI_ENGINE_CMD_ASSERT (1 , mask ));
200+ spi_engine_program_add_cmd (p , dry , SPI_ENGINE_CMD_ASSERT (0 , mask ));
219201}
220202
221- static int spi_engine_compile_message (struct spi_engine * spi_engine ,
222- struct spi_message * msg , bool dry , struct spi_engine_program * p )
203+ /*
204+ * Performs precompile steps on the message.
205+ *
206+ * The SPI core does most of the message/transfer validation and filling in
207+ * fields for us via __spi_validate(). This fixes up anything remaining not
208+ * done there.
209+ *
210+ * NB: This is separate from spi_engine_compile_message() because the latter
211+ * is called twice and would otherwise result in double-evaluation.
212+ */
213+ static void spi_engine_precompile_message (struct spi_message * msg )
214+ {
215+ unsigned int clk_div , max_hz = msg -> spi -> controller -> max_speed_hz ;
216+ struct spi_transfer * xfer ;
217+
218+ list_for_each_entry (xfer , & msg -> transfers , transfer_list ) {
219+ clk_div = DIV_ROUND_UP (max_hz , xfer -> speed_hz );
220+ xfer -> effective_speed_hz = max_hz / min (clk_div , 256U );
221+ }
222+ }
223+
224+ static void spi_engine_compile_message (struct spi_message * msg , bool dry ,
225+ struct spi_engine_program * p )
223226{
224227 struct spi_device * spi = msg -> spi ;
228+ struct spi_controller * host = spi -> controller ;
225229 struct spi_transfer * xfer ;
226230 int clk_div , new_clk_div ;
227231 bool keep_cs = false;
228232 u8 bits_per_word = 0 ;
229233
230- clk_div = - 1 ;
234+ clk_div = 1 ;
231235
232236 spi_engine_program_add_cmd (p , dry ,
233237 SPI_ENGINE_CMD_WRITE (SPI_ENGINE_CMD_REG_CONFIG ,
@@ -237,12 +241,13 @@ static int spi_engine_compile_message(struct spi_engine *spi_engine,
237241 spi_engine_gen_cs (p , dry , spi , !xfer -> cs_off );
238242
239243 list_for_each_entry (xfer , & msg -> transfers , transfer_list ) {
240- new_clk_div = spi_engine_get_clk_div ( spi_engine , spi , xfer ) ;
244+ new_clk_div = host -> max_speed_hz / xfer -> effective_speed_hz ;
241245 if (new_clk_div != clk_div ) {
242246 clk_div = new_clk_div ;
247+ /* actual divider used is register value + 1 */
243248 spi_engine_program_add_cmd (p , dry ,
244249 SPI_ENGINE_CMD_WRITE (SPI_ENGINE_CMD_REG_CLK_DIV ,
245- clk_div ));
250+ clk_div - 1 ));
246251 }
247252
248253 if (bits_per_word != xfer -> bits_per_word ) {
@@ -253,7 +258,8 @@ static int spi_engine_compile_message(struct spi_engine *spi_engine,
253258 }
254259
255260 spi_engine_gen_xfer (p , dry , xfer );
256- spi_engine_gen_sleep (p , dry , spi_engine , clk_div , xfer );
261+ spi_engine_gen_sleep (p , dry , spi_delay_to_ns (& xfer -> delay , xfer ),
262+ xfer -> effective_speed_hz );
257263
258264 if (xfer -> cs_change ) {
259265 if (list_is_last (& xfer -> transfer_list , & msg -> transfers )) {
@@ -262,6 +268,10 @@ static int spi_engine_compile_message(struct spi_engine *spi_engine,
262268 if (!xfer -> cs_off )
263269 spi_engine_gen_cs (p , dry , spi , false);
264270
271+ spi_engine_gen_sleep (p , dry , spi_delay_to_ns (
272+ & xfer -> cs_change_delay , xfer ),
273+ xfer -> effective_speed_hz );
274+
265275 if (!list_next_entry (xfer , transfer_list )-> cs_off )
266276 spi_engine_gen_cs (p , dry , spi , true);
267277 }
@@ -274,7 +284,13 @@ static int spi_engine_compile_message(struct spi_engine *spi_engine,
274284 if (!keep_cs )
275285 spi_engine_gen_cs (p , dry , spi , false);
276286
277- return 0 ;
287+ /*
288+ * Restore clockdiv to default so that future gen_sleep commands don't
289+ * have to be aware of the current register state.
290+ */
291+ if (clk_div != 1 )
292+ spi_engine_program_add_cmd (p , dry ,
293+ SPI_ENGINE_CMD_WRITE (SPI_ENGINE_CMD_REG_CLK_DIV , 0 ));
278294}
279295
280296static void spi_engine_xfer_next (struct spi_message * msg ,
@@ -475,9 +491,11 @@ static irqreturn_t spi_engine_irq(int irq, void *devid)
475491 struct spi_engine_message_state * st = msg -> state ;
476492
477493 if (completed_id == st -> sync_id ) {
478- msg -> status = 0 ;
479- msg -> actual_length = msg -> frame_length ;
480- spi_finalize_current_message (host );
494+ if (timer_delete_sync (& spi_engine -> watchdog_timer )) {
495+ msg -> status = 0 ;
496+ msg -> actual_length = msg -> frame_length ;
497+ spi_finalize_current_message (host );
498+ }
481499 disable_int |= SPI_ENGINE_INT_SYNC ;
482500 }
483501 }
@@ -506,8 +524,10 @@ static int spi_engine_prepare_message(struct spi_controller *host,
506524 if (!st )
507525 return - ENOMEM ;
508526
527+ spi_engine_precompile_message (msg );
528+
509529 p_dry .length = 0 ;
510- spi_engine_compile_message (spi_engine , msg , true, & p_dry );
530+ spi_engine_compile_message (msg , true, & p_dry );
511531
512532 size = sizeof (* p -> instructions ) * (p_dry .length + 1 );
513533 p = kzalloc (sizeof (* p ) + size , GFP_KERNEL );
@@ -525,7 +545,7 @@ static int spi_engine_prepare_message(struct spi_controller *host,
525545
526546 st -> sync_id = ret ;
527547
528- spi_engine_compile_message (spi_engine , msg , false, p );
548+ spi_engine_compile_message (msg , false, p );
529549
530550 spi_engine_program_add_cmd (p , false, SPI_ENGINE_CMD_SYNC (st -> sync_id ));
531551
@@ -558,6 +578,8 @@ static int spi_engine_transfer_one_message(struct spi_controller *host,
558578 unsigned int int_enable = 0 ;
559579 unsigned long flags ;
560580
581+ mod_timer (& spi_engine -> watchdog_timer , jiffies + msecs_to_jiffies (5000 ));
582+
561583 spin_lock_irqsave (& spi_engine -> lock , flags );
562584
563585 if (spi_engine_write_cmd_fifo (spi_engine , msg ))
@@ -581,6 +603,20 @@ static int spi_engine_transfer_one_message(struct spi_controller *host,
581603 return 0 ;
582604}
583605
606+ static void spi_engine_timeout (struct timer_list * timer )
607+ {
608+ struct spi_engine * spi_engine = from_timer (spi_engine , timer , watchdog_timer );
609+ struct spi_controller * host = spi_engine -> controller ;
610+
611+ if (WARN_ON (!host -> cur_msg ))
612+ return ;
613+
614+ dev_err (& host -> dev ,
615+ "Timeout occurred while waiting for transfer to complete. Hardware is probably broken.\n" );
616+ host -> cur_msg -> status = - ETIMEDOUT ;
617+ spi_finalize_current_message (host );
618+ }
619+
584620static void spi_engine_release_hw (void * p )
585621{
586622 struct spi_engine * spi_engine = p ;
@@ -610,6 +646,8 @@ static int spi_engine_probe(struct platform_device *pdev)
610646
611647 spin_lock_init (& spi_engine -> lock );
612648 ida_init (& spi_engine -> sync_ida );
649+ timer_setup (& spi_engine -> watchdog_timer , spi_engine_timeout , TIMER_IRQSAFE );
650+ spi_engine -> controller = host ;
613651
614652 spi_engine -> clk = devm_clk_get_enabled (& pdev -> dev , "s_axi_aclk" );
615653 if (IS_ERR (spi_engine -> clk ))
0 commit comments