2
2
// Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
3
3
4
4
#include <linux/clk.h>
5
+ #include <linux/interconnect.h>
5
6
#include <linux/interrupt.h>
6
7
#include <linux/io.h>
7
8
#include <linux/module.h>
@@ -139,7 +140,8 @@ struct qcom_qspi {
139
140
struct device * dev ;
140
141
struct clk_bulk_data * clks ;
141
142
struct qspi_xfer xfer ;
142
- /* Lock to protect xfer and IRQ accessed registers */
143
+ struct icc_path * icc_path_cpu_to_qspi ;
144
+ /* Lock to protect data accessed by IRQs */
143
145
spinlock_t lock ;
144
146
};
145
147
@@ -229,6 +231,7 @@ static int qcom_qspi_transfer_one(struct spi_master *master,
229
231
int ret ;
230
232
unsigned long speed_hz ;
231
233
unsigned long flags ;
234
+ unsigned int avg_bw_cpu ;
232
235
233
236
speed_hz = slv -> max_speed_hz ;
234
237
if (xfer -> speed_hz )
@@ -241,6 +244,18 @@ static int qcom_qspi_transfer_one(struct spi_master *master,
241
244
return ret ;
242
245
}
243
246
247
+ /*
248
+ * Set BW quota for CPU as driver supports FIFO mode only.
249
+ * We don't have explicit peak requirement so keep it equal to avg_bw.
250
+ */
251
+ avg_bw_cpu = Bps_to_icc (speed_hz );
252
+ ret = icc_set_bw (ctrl -> icc_path_cpu_to_qspi , avg_bw_cpu , avg_bw_cpu );
253
+ if (ret ) {
254
+ dev_err (ctrl -> dev , "%s: ICC BW voting failed for cpu: %d\n" ,
255
+ __func__ , ret );
256
+ return ret ;
257
+ }
258
+
244
259
spin_lock_irqsave (& ctrl -> lock , flags );
245
260
246
261
/* We are half duplex, so either rx or tx will be set */
@@ -458,6 +473,29 @@ static int qcom_qspi_probe(struct platform_device *pdev)
458
473
if (ret )
459
474
goto exit_probe_master_put ;
460
475
476
+ ctrl -> icc_path_cpu_to_qspi = devm_of_icc_get (dev , "qspi-config" );
477
+ if (IS_ERR (ctrl -> icc_path_cpu_to_qspi )) {
478
+ ret = PTR_ERR (ctrl -> icc_path_cpu_to_qspi );
479
+ if (ret != - EPROBE_DEFER )
480
+ dev_err (dev , "Failed to get cpu path: %d\n" , ret );
481
+ goto exit_probe_master_put ;
482
+ }
483
+ /* Set BW vote for register access */
484
+ ret = icc_set_bw (ctrl -> icc_path_cpu_to_qspi , Bps_to_icc (1000 ),
485
+ Bps_to_icc (1000 ));
486
+ if (ret ) {
487
+ dev_err (ctrl -> dev , "%s: ICC BW voting failed for cpu: %d\n" ,
488
+ __func__ , ret );
489
+ goto exit_probe_master_put ;
490
+ }
491
+
492
+ ret = icc_disable (ctrl -> icc_path_cpu_to_qspi );
493
+ if (ret ) {
494
+ dev_err (ctrl -> dev , "%s: ICC disable failed for cpu: %d\n" ,
495
+ __func__ , ret );
496
+ goto exit_probe_master_put ;
497
+ }
498
+
461
499
ret = platform_get_irq (pdev , 0 );
462
500
if (ret < 0 )
463
501
goto exit_probe_master_put ;
@@ -511,16 +549,32 @@ static int __maybe_unused qcom_qspi_runtime_suspend(struct device *dev)
511
549
{
512
550
struct spi_master * master = dev_get_drvdata (dev );
513
551
struct qcom_qspi * ctrl = spi_master_get_devdata (master );
552
+ int ret ;
514
553
515
554
clk_bulk_disable_unprepare (QSPI_NUM_CLKS , ctrl -> clks );
516
555
556
+ ret = icc_disable (ctrl -> icc_path_cpu_to_qspi );
557
+ if (ret ) {
558
+ dev_err_ratelimited (ctrl -> dev , "%s: ICC disable failed for cpu: %d\n" ,
559
+ __func__ , ret );
560
+ return ret ;
561
+ }
562
+
517
563
return 0 ;
518
564
}
519
565
520
566
static int __maybe_unused qcom_qspi_runtime_resume (struct device * dev )
521
567
{
522
568
struct spi_master * master = dev_get_drvdata (dev );
523
569
struct qcom_qspi * ctrl = spi_master_get_devdata (master );
570
+ int ret ;
571
+
572
+ ret = icc_enable (ctrl -> icc_path_cpu_to_qspi );
573
+ if (ret ) {
574
+ dev_err_ratelimited (ctrl -> dev , "%s: ICC enable failed for cpu: %d\n" ,
575
+ __func__ , ret );
576
+ return ret ;
577
+ }
524
578
525
579
return clk_bulk_prepare_enable (QSPI_NUM_CLKS , ctrl -> clks );
526
580
}
0 commit comments