@@ -73,8 +73,9 @@ struct chip_data {
7373#define LPSS_CAPS_CS_EN_MASK (0xf << LPSS_CAPS_CS_EN_SHIFT)
7474
7575#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
7879
7980struct lpss_config {
8081 /* LPSS offset from drv_data->ioaddr */
@@ -321,6 +322,20 @@ static void __lpss_ssp_write_priv(struct driver_data *drv_data,
321322 writel (value , drv_data -> lpss_base + offset );
322323}
323324
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+
324339/*
325340 * lpss_ssp_setup - perform LPSS SSP specific setup
326341 * @drv_data: pointer to the driver private data
@@ -337,21 +352,16 @@ static void lpss_ssp_setup(struct driver_data *drv_data)
337352 drv_data -> lpss_base = drv_data -> ssp -> mmio_base + config -> offset ;
338353
339354 /* 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 );
344357
345358 /* Enable multiblock DMA transfers */
346359 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 ) );
348361
349362 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 );
355365 }
356366 }
357367}
@@ -361,65 +371,47 @@ static void lpss_ssp_select_cs(struct spi_device *spi,
361371{
362372 struct driver_data * drv_data =
363373 spi_controller_get_devdata (spi -> controller );
364- u32 value , cs ;
374+ u32 cs ;
365375
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 ))
367378 return ;
368379
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 ));
388387}
389388
390389static void lpss_ssp_cs_control (struct spi_device * spi , bool enable )
391390{
392391 struct driver_data * drv_data =
393392 spi_controller_get_devdata (spi -> controller );
394393 const struct lpss_config * config ;
395- u32 value ;
394+ u32 mask ;
396395
397396 config = lpss_get_config (drv_data );
398397
399398 if (enable )
400399 lpss_ssp_select_cs (spi , config );
401400
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 );
408403 if (config -> cs_clk_stays_gated ) {
409- u32 clkgate ;
410-
411404 /*
412405 * Changing CS alone when dynamic clock gating is on won't
413406 * actually flip CS at that time. This ruins SPI transfers
414407 * that specify delays, or have no data. Toggle the clock mode
415408 * to force on briefly to poke the CS pin to move.
416409 */
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 );
423415 }
424416}
425417
0 commit comments