@@ -73,8 +73,9 @@ struct chip_data {
73
73
#define LPSS_CAPS_CS_EN_MASK (0xf << LPSS_CAPS_CS_EN_SHIFT)
74
74
75
75
#define LPSS_PRIV_CLOCK_GATE 0x38
76
- #define LPSS_PRIV_CLOCK_GATE_CLK_CTL_MASK 0x3
77
- #define LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_ON 0x3
76
+ #define LPSS_PRIV_CLOCK_GATE_CLK_CTL_MASK 0x3
77
+ #define LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_ON 0x3
78
+ #define LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_OFF 0x0
78
79
79
80
struct lpss_config {
80
81
/* LPSS offset from drv_data->ioaddr */
@@ -321,6 +322,20 @@ static void __lpss_ssp_write_priv(struct driver_data *drv_data,
321
322
writel (value , drv_data -> lpss_base + offset );
322
323
}
323
324
325
+ static bool __lpss_ssp_update_priv (struct driver_data * drv_data , unsigned int offset ,
326
+ u32 mask , u32 value )
327
+ {
328
+ u32 new , curr ;
329
+
330
+ curr = __lpss_ssp_read_priv (drv_data , offset );
331
+ new = (curr & ~mask ) | (value & mask );
332
+ if (new == curr )
333
+ return false;
334
+
335
+ __lpss_ssp_write_priv (drv_data , offset , new );
336
+ return true;
337
+ }
338
+
324
339
/*
325
340
* lpss_ssp_setup - perform LPSS SSP specific setup
326
341
* @drv_data: pointer to the driver private data
@@ -337,21 +352,16 @@ static void lpss_ssp_setup(struct driver_data *drv_data)
337
352
drv_data -> lpss_base = drv_data -> ssp -> mmio_base + config -> offset ;
338
353
339
354
/* Enable software chip select control */
340
- value = __lpss_ssp_read_priv (drv_data , config -> reg_cs_ctrl );
341
- value &= ~(LPSS_CS_CONTROL_SW_MODE | LPSS_CS_CONTROL_CS_HIGH );
342
- value |= LPSS_CS_CONTROL_SW_MODE | LPSS_CS_CONTROL_CS_HIGH ;
343
- __lpss_ssp_write_priv (drv_data , config -> reg_cs_ctrl , value );
355
+ value = LPSS_CS_CONTROL_SW_MODE | LPSS_CS_CONTROL_CS_HIGH ;
356
+ __lpss_ssp_update_priv (drv_data , config -> reg_cs_ctrl , value , value );
344
357
345
358
/* Enable multiblock DMA transfers */
346
359
if (drv_data -> controller_info -> enable_dma ) {
347
- __lpss_ssp_write_priv (drv_data , config -> reg_ssp , 1 );
360
+ __lpss_ssp_update_priv (drv_data , config -> reg_ssp , BIT ( 0 ), BIT ( 0 ) );
348
361
349
362
if (config -> reg_general >= 0 ) {
350
- value = __lpss_ssp_read_priv (drv_data ,
351
- config -> reg_general );
352
- value |= LPSS_GENERAL_REG_RXTO_HOLDOFF_DISABLE ;
353
- __lpss_ssp_write_priv (drv_data ,
354
- config -> reg_general , value );
363
+ value = LPSS_GENERAL_REG_RXTO_HOLDOFF_DISABLE ;
364
+ __lpss_ssp_update_priv (drv_data , config -> reg_general , value , value );
355
365
}
356
366
}
357
367
}
@@ -361,65 +371,47 @@ static void lpss_ssp_select_cs(struct spi_device *spi,
361
371
{
362
372
struct driver_data * drv_data =
363
373
spi_controller_get_devdata (spi -> controller );
364
- u32 value , cs ;
374
+ u32 cs ;
365
375
366
- if (!config -> cs_sel_mask )
376
+ cs = spi_get_chipselect (spi , 0 ) << config -> cs_sel_shift ;
377
+ if (!__lpss_ssp_update_priv (drv_data , config -> reg_cs_ctrl , config -> cs_sel_mask , cs ))
367
378
return ;
368
379
369
- value = __lpss_ssp_read_priv (drv_data , config -> reg_cs_ctrl );
370
-
371
- cs = spi_get_chipselect (spi , 0 );
372
- cs <<= config -> cs_sel_shift ;
373
- if (cs != (value & config -> cs_sel_mask )) {
374
- /*
375
- * When switching another chip select output active the
376
- * output must be selected first and wait 2 ssp_clk cycles
377
- * before changing state to active. Otherwise a short
378
- * glitch will occur on the previous chip select since
379
- * output select is latched but state control is not.
380
- */
381
- value &= ~config -> cs_sel_mask ;
382
- value |= cs ;
383
- __lpss_ssp_write_priv (drv_data ,
384
- config -> reg_cs_ctrl , value );
385
- ndelay (1000000000 /
386
- (drv_data -> controller -> max_speed_hz / 2 ));
387
- }
380
+ /*
381
+ * When switching another chip select output active the output must be
382
+ * selected first and wait 2 ssp_clk cycles before changing state to
383
+ * active. Otherwise a short glitch will occur on the previous chip
384
+ * select since output select is latched but state control is not.
385
+ */
386
+ ndelay (1000000000 / (drv_data -> controller -> max_speed_hz / 2 ));
388
387
}
389
388
390
389
static void lpss_ssp_cs_control (struct spi_device * spi , bool enable )
391
390
{
392
391
struct driver_data * drv_data =
393
392
spi_controller_get_devdata (spi -> controller );
394
393
const struct lpss_config * config ;
395
- u32 value ;
394
+ u32 mask ;
396
395
397
396
config = lpss_get_config (drv_data );
398
397
399
398
if (enable )
400
399
lpss_ssp_select_cs (spi , config );
401
400
402
- value = __lpss_ssp_read_priv (drv_data , config -> reg_cs_ctrl );
403
- if (enable )
404
- value &= ~LPSS_CS_CONTROL_CS_HIGH ;
405
- else
406
- value |= LPSS_CS_CONTROL_CS_HIGH ;
407
- __lpss_ssp_write_priv (drv_data , config -> reg_cs_ctrl , value );
401
+ mask = LPSS_CS_CONTROL_CS_HIGH ;
402
+ __lpss_ssp_update_priv (drv_data , config -> reg_cs_ctrl , mask , enable ? mask : 0 );
408
403
if (config -> cs_clk_stays_gated ) {
409
- u32 clkgate ;
410
-
411
404
/*
412
405
* Changing CS alone when dynamic clock gating is on won't
413
406
* actually flip CS at that time. This ruins SPI transfers
414
407
* that specify delays, or have no data. Toggle the clock mode
415
408
* to force on briefly to poke the CS pin to move.
416
409
*/
417
- clkgate = __lpss_ssp_read_priv (drv_data , LPSS_PRIV_CLOCK_GATE );
418
- value = (clkgate & ~LPSS_PRIV_CLOCK_GATE_CLK_CTL_MASK ) |
419
- LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_ON ;
420
-
421
- __lpss_ssp_write_priv (drv_data , LPSS_PRIV_CLOCK_GATE , value );
422
- __lpss_ssp_write_priv (drv_data , LPSS_PRIV_CLOCK_GATE , clkgate );
410
+ mask = LPSS_PRIV_CLOCK_GATE_CLK_CTL_MASK ;
411
+ if (__lpss_ssp_update_priv (drv_data , LPSS_PRIV_CLOCK_GATE , mask ,
412
+ LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_ON ))
413
+ __lpss_ssp_update_priv (drv_data , LPSS_PRIV_CLOCK_GATE , mask ,
414
+ LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_OFF );
423
415
}
424
416
}
425
417
0 commit comments