5353#define MSI_IOVA_BASE 0x8000000
5454#define MSI_IOVA_LENGTH 0x100000
5555
56+ /* Interconnect bandwidth vote values for the SMMU register access path */
57+ #define ARM_SMMU_ICC_AVG_BW 0
58+ #define ARM_SMMU_ICC_PEAK_BW_HIGH 1000
59+ #define ARM_SMMU_ICC_PEAK_BW_LOW 0
60+
5661static int force_stage ;
5762module_param (force_stage , int , S_IRUGO );
5863MODULE_PARM_DESC (force_stage ,
@@ -86,6 +91,36 @@ static inline void arm_smmu_rpm_put(struct arm_smmu_device *smmu)
8691 }
8792}
8893
94+ static int arm_smmu_icc_get (struct arm_smmu_device * smmu )
95+ {
96+ smmu -> icc_path = devm_of_icc_get (smmu -> dev , NULL );
97+ if (IS_ERR (smmu -> icc_path )) {
98+ int err = PTR_ERR (smmu -> icc_path );
99+
100+ if (err == - ENODATA ) {
101+ smmu -> icc_path = NULL ;
102+ return 0 ;
103+ }
104+ return dev_err_probe (smmu -> dev , err ,
105+ "failed to get interconnect path\n" );
106+ }
107+ return 0 ;
108+ }
109+
110+ static void arm_smmu_icc_enable (struct arm_smmu_device * smmu )
111+ {
112+ if (smmu -> icc_path )
113+ WARN_ON (icc_set_bw (smmu -> icc_path , ARM_SMMU_ICC_AVG_BW ,
114+ ARM_SMMU_ICC_PEAK_BW_HIGH ));
115+ }
116+
117+ static void arm_smmu_icc_disable (struct arm_smmu_device * smmu )
118+ {
119+ if (smmu -> icc_path )
120+ WARN_ON (icc_set_bw (smmu -> icc_path , ARM_SMMU_ICC_AVG_BW ,
121+ ARM_SMMU_ICC_PEAK_BW_LOW ));
122+ }
123+
89124static void arm_smmu_rpm_use_autosuspend (struct arm_smmu_device * smmu )
90125{
91126 /*
@@ -2209,6 +2244,17 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
22092244 if (err )
22102245 return err ;
22112246
2247+ /*
2248+ * Acquire and vote the interconnect path before accessing any SMMU
2249+ * registers (including ARM_SMMU_GR0_ID0 in arm_smmu_device_cfg_probe).
2250+ */
2251+ err = arm_smmu_icc_get (smmu );
2252+ if (err ) {
2253+ clk_bulk_disable_unprepare (smmu -> num_clks , smmu -> clks );
2254+ return err ;
2255+ }
2256+ arm_smmu_icc_enable (smmu );
2257+
22122258 err = arm_smmu_device_cfg_probe (smmu );
22132259 if (err )
22142260 return err ;
@@ -2309,9 +2355,13 @@ static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
23092355 struct arm_smmu_device * smmu = dev_get_drvdata (dev );
23102356 int ret ;
23112357
2358+ arm_smmu_icc_enable (smmu );
2359+
23122360 ret = clk_bulk_enable (smmu -> num_clks , smmu -> clks );
2313- if (ret )
2361+ if (ret ) {
2362+ arm_smmu_icc_disable (smmu );
23142363 return ret ;
2364+ }
23152365
23162366 arm_smmu_device_reset (smmu );
23172367
@@ -2323,6 +2373,7 @@ static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
23232373 struct arm_smmu_device * smmu = dev_get_drvdata (dev );
23242374
23252375 clk_bulk_disable (smmu -> num_clks , smmu -> clks );
2376+ arm_smmu_icc_disable (smmu );
23262377
23272378 return 0 ;
23282379}
0 commit comments