13
13
#include <linux/completion.h>
14
14
#include <linux/dma-mapping.h>
15
15
#include <linux/iopoll.h>
16
+ #include <linux/interrupt.h>
16
17
#include <linux/mm.h>
17
18
#include <linux/module.h>
18
19
#include <linux/of.h>
20
+ #include <linux/pinctrl/consumer.h>
19
21
#include <linux/platform_device.h>
22
+ #include <linux/pm_runtime.h>
20
23
#include <linux/slab.h>
21
- #include <linux/interrupt.h>
22
24
#include <linux/spi/spi-mem.h>
23
25
24
26
/* System control */
150
152
/* Data */
151
153
#define SFC_DATA 0x108
152
154
153
- /* The controller and documentation reports that it supports up to 4 CS
154
- * devices (0-3), however I have only been able to test a single CS (CS 0)
155
- * due to the configuration of my device.
156
- */
157
- #define SFC_MAX_CHIPSELECT_NUM 4
155
+ #define SFC_CS1_REG_OFFSET 0x200
156
+
157
+ #define SFC_MAX_CHIPSELECT_NUM 2
158
158
159
159
/* The SFC can transfer max 16KB - 1 at one time
160
160
* we set it to 15.5KB here for alignment.
169
169
*/
170
170
#define SFC_MAX_SPEED (150 * 1000 * 1000)
171
171
172
+ #define ROCKCHIP_AUTOSUSPEND_DELAY 2000
173
+
172
174
struct rockchip_sfc {
173
175
struct device * dev ;
174
176
void __iomem * regbase ;
175
177
struct clk * hclk ;
176
178
struct clk * clk ;
177
- u32 frequency ;
179
+ u32 speed [ SFC_MAX_CHIPSELECT_NUM ] ;
178
180
/* virtual mapped addr for dma_buffer */
179
181
void * buffer ;
180
182
dma_addr_t dma_buffer ;
@@ -301,6 +303,7 @@ static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
301
303
u32 len )
302
304
{
303
305
u32 ctrl = 0 , cmd = 0 ;
306
+ u8 cs = spi_get_chipselect (mem -> spi , 0 );
304
307
305
308
/* set CMD */
306
309
cmd = op -> cmd .opcode ;
@@ -314,7 +317,8 @@ static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
314
317
cmd |= SFC_CMD_ADDR_24BITS << SFC_CMD_ADDR_SHIFT ;
315
318
} else {
316
319
cmd |= SFC_CMD_ADDR_XBITS << SFC_CMD_ADDR_SHIFT ;
317
- writel (op -> addr .nbytes * 8 - 1 , sfc -> regbase + SFC_ABIT );
320
+ writel (op -> addr .nbytes * 8 - 1 ,
321
+ sfc -> regbase + cs * SFC_CS1_REG_OFFSET + SFC_ABIT );
318
322
}
319
323
320
324
ctrl |= ((op -> addr .buswidth >> 1 ) << SFC_CTRL_ADDR_BITS_SHIFT );
@@ -346,15 +350,15 @@ static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
346
350
347
351
/* set the Controller */
348
352
ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE ;
349
- cmd |= spi_get_chipselect ( mem -> spi , 0 ) << SFC_CMD_CS_SHIFT ;
353
+ cmd |= cs << SFC_CMD_CS_SHIFT ;
350
354
351
355
dev_dbg (sfc -> dev , "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n" ,
352
356
op -> addr .nbytes , op -> addr .buswidth ,
353
357
op -> dummy .nbytes , op -> dummy .buswidth );
354
358
dev_dbg (sfc -> dev , "sfc ctrl=%x cmd=%x addr=%llx len=%x\n" ,
355
359
ctrl , cmd , op -> addr .val , len );
356
360
357
- writel (ctrl , sfc -> regbase + SFC_CTRL );
361
+ writel (ctrl , sfc -> regbase + cs * SFC_CS1_REG_OFFSET + SFC_CTRL );
358
362
writel (cmd , sfc -> regbase + SFC_CMD );
359
363
if (op -> addr .nbytes )
360
364
writel (op -> addr .val , sfc -> regbase + SFC_ADDR );
@@ -500,14 +504,22 @@ static int rockchip_sfc_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op
500
504
struct rockchip_sfc * sfc = spi_controller_get_devdata (mem -> spi -> controller );
501
505
u32 len = op -> data .nbytes ;
502
506
int ret ;
507
+ u8 cs = spi_get_chipselect (mem -> spi , 0 );
508
+
509
+ ret = pm_runtime_get_sync (sfc -> dev );
510
+ if (ret < 0 ) {
511
+ pm_runtime_put_noidle (sfc -> dev );
512
+ return ret ;
513
+ }
503
514
504
- if (unlikely (mem -> spi -> max_speed_hz != sfc -> frequency ) && !has_acpi_companion (sfc -> dev )) {
515
+ if (unlikely (mem -> spi -> max_speed_hz != sfc -> speed [cs ]) &&
516
+ !has_acpi_companion (sfc -> dev )) {
505
517
ret = clk_set_rate (sfc -> clk , mem -> spi -> max_speed_hz );
506
518
if (ret )
507
- return ret ;
508
- sfc -> frequency = mem -> spi -> max_speed_hz ;
519
+ goto out ;
520
+ sfc -> speed [ cs ] = mem -> spi -> max_speed_hz ;
509
521
dev_dbg (sfc -> dev , "set_freq=%dHz real_freq=%ldHz\n" ,
510
- sfc -> frequency , clk_get_rate (sfc -> clk ));
522
+ sfc -> speed [ cs ] , clk_get_rate (sfc -> clk ));
511
523
}
512
524
513
525
rockchip_sfc_adjust_op_work ((struct spi_mem_op * )op );
@@ -524,11 +536,17 @@ static int rockchip_sfc_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op
524
536
if (ret != len ) {
525
537
dev_err (sfc -> dev , "xfer data failed ret %d dir %d\n" , ret , op -> data .dir );
526
538
527
- return - EIO ;
539
+ ret = - EIO ;
540
+ goto out ;
528
541
}
529
542
}
530
543
531
- return rockchip_sfc_xfer_done (sfc , 100000 );
544
+ ret = rockchip_sfc_xfer_done (sfc , 100000 );
545
+ out :
546
+ pm_runtime_mark_last_busy (sfc -> dev );
547
+ pm_runtime_put_autosuspend (sfc -> dev );
548
+
549
+ return ret ;
532
550
}
533
551
534
552
static int rockchip_sfc_adjust_op_size (struct spi_mem * mem , struct spi_mem_op * op )
@@ -570,6 +588,7 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
570
588
struct spi_controller * host ;
571
589
struct rockchip_sfc * sfc ;
572
590
int ret ;
591
+ u32 i , val ;
573
592
574
593
host = devm_spi_alloc_host (& pdev -> dev , sizeof (* sfc ));
575
594
if (!host )
@@ -602,9 +621,12 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
602
621
"Failed to get sfc ahb clk\n" );
603
622
604
623
if (has_acpi_companion (& pdev -> dev )) {
605
- ret = device_property_read_u32 (& pdev -> dev , "clock-frequency" , & sfc -> frequency );
624
+ ret = device_property_read_u32 (& pdev -> dev , "clock-frequency" , & val );
606
625
if (ret )
607
- return dev_err_probe (& pdev -> dev , ret , "Failed to find clock-frequency\n" );
626
+ return dev_err_probe (& pdev -> dev , ret ,
627
+ "Failed to find clock-frequency in ACPI\n" );
628
+ for (i = 0 ; i < SFC_MAX_CHIPSELECT_NUM ; i ++ )
629
+ sfc -> speed [i ] = val ;
608
630
}
609
631
610
632
sfc -> use_dma = !of_property_read_bool (sfc -> dev -> of_node , "rockchip,sfc-no-dma" );
@@ -646,19 +668,36 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
646
668
goto err_irq ;
647
669
}
648
670
671
+ platform_set_drvdata (pdev , sfc );
672
+
649
673
ret = rockchip_sfc_init (sfc );
650
674
if (ret )
651
675
goto err_irq ;
652
676
653
677
sfc -> max_iosize = rockchip_sfc_get_max_iosize (sfc );
654
678
sfc -> version = rockchip_sfc_get_version (sfc );
655
679
656
- ret = spi_register_controller (host );
680
+ pm_runtime_set_autosuspend_delay (dev , ROCKCHIP_AUTOSUSPEND_DELAY );
681
+ pm_runtime_use_autosuspend (dev );
682
+ pm_runtime_set_active (dev );
683
+ pm_runtime_enable (dev );
684
+ pm_runtime_get_noresume (dev );
685
+
686
+ ret = devm_spi_register_controller (dev , host );
657
687
if (ret )
658
- goto err_irq ;
688
+ goto err_pm_runtime_free ;
689
+
690
+ pm_runtime_mark_last_busy (dev );
691
+ pm_runtime_put_autosuspend (dev );
659
692
660
693
return 0 ;
661
694
695
+ err_pm_runtime_free :
696
+ pm_runtime_get_sync (dev );
697
+ pm_runtime_put_noidle (dev );
698
+ pm_runtime_disable (dev );
699
+ pm_runtime_set_suspended (dev );
700
+ pm_runtime_dont_use_autosuspend (dev );
662
701
err_irq :
663
702
clk_disable_unprepare (sfc -> clk );
664
703
err_clk :
@@ -678,6 +717,74 @@ static void rockchip_sfc_remove(struct platform_device *pdev)
678
717
clk_disable_unprepare (sfc -> hclk );
679
718
}
680
719
720
+ #ifdef CONFIG_PM
721
+ static int rockchip_sfc_runtime_suspend (struct device * dev )
722
+ {
723
+ struct rockchip_sfc * sfc = dev_get_drvdata (dev );
724
+
725
+ clk_disable_unprepare (sfc -> clk );
726
+ clk_disable_unprepare (sfc -> hclk );
727
+
728
+ return 0 ;
729
+ }
730
+
731
+ static int rockchip_sfc_runtime_resume (struct device * dev )
732
+ {
733
+ struct rockchip_sfc * sfc = dev_get_drvdata (dev );
734
+ int ret ;
735
+
736
+ ret = clk_prepare_enable (sfc -> hclk );
737
+ if (ret < 0 )
738
+ return ret ;
739
+
740
+ ret = clk_prepare_enable (sfc -> clk );
741
+ if (ret < 0 )
742
+ clk_disable_unprepare (sfc -> hclk );
743
+
744
+ return ret ;
745
+ }
746
+ #endif /* CONFIG_PM */
747
+
748
+ #ifdef CONFIG_PM_SLEEP
749
+ static int rockchip_sfc_suspend (struct device * dev )
750
+ {
751
+ pinctrl_pm_select_sleep_state (dev );
752
+
753
+ return pm_runtime_force_suspend (dev );
754
+ }
755
+
756
+ static int rockchip_sfc_resume (struct device * dev )
757
+ {
758
+ struct rockchip_sfc * sfc = dev_get_drvdata (dev );
759
+ int ret ;
760
+
761
+ ret = pm_runtime_force_resume (dev );
762
+ if (ret < 0 )
763
+ return ret ;
764
+
765
+ pinctrl_pm_select_default_state (dev );
766
+
767
+ ret = pm_runtime_get_sync (dev );
768
+ if (ret < 0 ) {
769
+ pm_runtime_put_noidle (dev );
770
+ return ret ;
771
+ }
772
+
773
+ rockchip_sfc_init (sfc );
774
+
775
+ pm_runtime_mark_last_busy (dev );
776
+ pm_runtime_put_autosuspend (dev );
777
+
778
+ return 0 ;
779
+ }
780
+ #endif /* CONFIG_PM_SLEEP */
781
+
782
+ static const struct dev_pm_ops rockchip_sfc_pm_ops = {
783
+ SET_RUNTIME_PM_OPS (rockchip_sfc_runtime_suspend ,
784
+ rockchip_sfc_runtime_resume , NULL )
785
+ SET_SYSTEM_SLEEP_PM_OPS (rockchip_sfc_suspend , rockchip_sfc_resume )
786
+ };
787
+
681
788
static const struct of_device_id rockchip_sfc_dt_ids [] = {
682
789
{ .compatible = "rockchip,sfc" },
683
790
{ /* sentinel */ }
@@ -688,6 +795,7 @@ static struct platform_driver rockchip_sfc_driver = {
688
795
.driver = {
689
796
.name = "rockchip-sfc" ,
690
797
.of_match_table = rockchip_sfc_dt_ids ,
798
+ .pm = & rockchip_sfc_pm_ops ,
691
799
},
692
800
.probe = rockchip_sfc_probe ,
693
801
.remove = rockchip_sfc_remove ,
0 commit comments