134
134
#define BOOT_FSM_TIMEOUT 10000
135
135
#define BHS_CHECK_MAX_LOOPS 200
136
136
137
+ /* External power block headswitch */
138
+ #define EXTERNAL_BHS_ON BIT(0)
139
+ #define EXTERNAL_BHS_STATUS BIT(4)
140
+ #define EXTERNAL_BHS_TIMEOUT_US 50
141
+
137
142
struct reg_info {
138
143
struct regulator * reg ;
139
144
int uV ;
@@ -161,6 +166,7 @@ struct rproc_hexagon_res {
161
166
bool has_mba_logs ;
162
167
bool has_spare_reg ;
163
168
bool has_qaccept_regs ;
169
+ bool has_ext_bhs_reg ;
164
170
bool has_ext_cntl_regs ;
165
171
bool has_vq6 ;
166
172
};
@@ -180,6 +186,7 @@ struct q6v5 {
180
186
u32 halt_nc ;
181
187
u32 halt_vq6 ;
182
188
u32 conn_box ;
189
+ u32 ext_bhs ;
183
190
184
191
u32 qaccept_mdm ;
185
192
u32 qaccept_cx ;
@@ -237,6 +244,7 @@ struct q6v5 {
237
244
bool has_mba_logs ;
238
245
bool has_spare_reg ;
239
246
bool has_qaccept_regs ;
247
+ bool has_ext_bhs_reg ;
240
248
bool has_ext_cntl_regs ;
241
249
bool has_vq6 ;
242
250
u64 mpss_perm ;
@@ -246,6 +254,7 @@ struct q6v5 {
246
254
};
247
255
248
256
enum {
257
+ MSS_MSM8226 ,
249
258
MSS_MSM8909 ,
250
259
MSS_MSM8916 ,
251
260
MSS_MSM8953 ,
@@ -415,6 +424,34 @@ static void q6v5_pds_disable(struct q6v5 *qproc, struct device **pds,
415
424
}
416
425
}
417
426
427
+ static int q6v5_external_bhs_enable (struct q6v5 * qproc )
428
+ {
429
+ u32 val ;
430
+ int ret = 0 ;
431
+
432
+ /*
433
+ * Enable external power block headswitch and wait for it to
434
+ * stabilize
435
+ */
436
+ regmap_set_bits (qproc -> conn_map , qproc -> ext_bhs , EXTERNAL_BHS_ON );
437
+
438
+ ret = regmap_read_poll_timeout (qproc -> conn_map , qproc -> ext_bhs ,
439
+ val , val & EXTERNAL_BHS_STATUS ,
440
+ 1 , EXTERNAL_BHS_TIMEOUT_US );
441
+
442
+ if (ret ) {
443
+ dev_err (qproc -> dev , "External BHS timed out\n" );
444
+ ret = - ETIMEDOUT ;
445
+ }
446
+
447
+ return ret ;
448
+ }
449
+
450
+ static void q6v5_external_bhs_disable (struct q6v5 * qproc )
451
+ {
452
+ regmap_clear_bits (qproc -> conn_map , qproc -> ext_bhs , EXTERNAL_BHS_ON );
453
+ }
454
+
418
455
static int q6v5_xfer_mem_ownership (struct q6v5 * qproc , u64 * current_perm ,
419
456
bool local , bool remote , phys_addr_t addr ,
420
457
size_t size )
@@ -1112,11 +1149,17 @@ static int q6v5_mba_load(struct q6v5 *qproc)
1112
1149
goto disable_proxy_clk ;
1113
1150
}
1114
1151
1152
+ if (qproc -> has_ext_bhs_reg ) {
1153
+ ret = q6v5_external_bhs_enable (qproc );
1154
+ if (ret < 0 )
1155
+ goto disable_vdd ;
1156
+ }
1157
+
1115
1158
ret = q6v5_clk_enable (qproc -> dev , qproc -> reset_clks ,
1116
1159
qproc -> reset_clk_count );
1117
1160
if (ret ) {
1118
1161
dev_err (qproc -> dev , "failed to enable reset clocks\n" );
1119
- goto disable_vdd ;
1162
+ goto disable_ext_bhs ;
1120
1163
}
1121
1164
1122
1165
ret = q6v5_reset_deassert (qproc );
@@ -1214,6 +1257,9 @@ static int q6v5_mba_load(struct q6v5 *qproc)
1214
1257
disable_reset_clks :
1215
1258
q6v5_clk_disable (qproc -> dev , qproc -> reset_clks ,
1216
1259
qproc -> reset_clk_count );
1260
+ disable_ext_bhs :
1261
+ if (qproc -> has_ext_bhs_reg )
1262
+ q6v5_external_bhs_disable (qproc );
1217
1263
disable_vdd :
1218
1264
q6v5_regulator_disable (qproc , qproc -> active_regs ,
1219
1265
qproc -> active_reg_count );
@@ -1281,6 +1327,8 @@ static void q6v5_mba_reclaim(struct q6v5 *qproc)
1281
1327
qproc -> reset_clk_count );
1282
1328
q6v5_clk_disable (qproc -> dev , qproc -> active_clks ,
1283
1329
qproc -> active_clk_count );
1330
+ if (qproc -> has_ext_bhs_reg )
1331
+ q6v5_external_bhs_disable (qproc );
1284
1332
q6v5_regulator_disable (qproc , qproc -> active_regs ,
1285
1333
qproc -> active_reg_count );
1286
1334
@@ -1750,6 +1798,23 @@ static int q6v5_init_mem(struct q6v5 *qproc, struct platform_device *pdev)
1750
1798
qproc -> qaccept_axi = args .args [2 ];
1751
1799
}
1752
1800
1801
+ if (qproc -> has_ext_bhs_reg ) {
1802
+ ret = of_parse_phandle_with_fixed_args (pdev -> dev .of_node ,
1803
+ "qcom,ext-bhs-reg" ,
1804
+ 1 , 0 , & args );
1805
+ if (ret < 0 ) {
1806
+ dev_err (& pdev -> dev , "failed to parse ext-bhs-reg index 0\n" );
1807
+ return - EINVAL ;
1808
+ }
1809
+
1810
+ qproc -> conn_map = syscon_node_to_regmap (args .np );
1811
+ of_node_put (args .np );
1812
+ if (IS_ERR (qproc -> conn_map ))
1813
+ return PTR_ERR (qproc -> conn_map );
1814
+
1815
+ qproc -> ext_bhs = args .args [0 ];
1816
+ }
1817
+
1753
1818
if (qproc -> has_ext_cntl_regs ) {
1754
1819
ret = of_parse_phandle_with_fixed_args (pdev -> dev .of_node ,
1755
1820
"qcom,ext-regs" ,
@@ -2021,6 +2086,7 @@ static int q6v5_probe(struct platform_device *pdev)
2021
2086
platform_set_drvdata (pdev , qproc );
2022
2087
2023
2088
qproc -> has_qaccept_regs = desc -> has_qaccept_regs ;
2089
+ qproc -> has_ext_bhs_reg = desc -> has_ext_bhs_reg ;
2024
2090
qproc -> has_ext_cntl_regs = desc -> has_ext_cntl_regs ;
2025
2091
qproc -> has_vq6 = desc -> has_vq6 ;
2026
2092
qproc -> has_spare_reg = desc -> has_spare_reg ;
@@ -2174,6 +2240,7 @@ static const struct rproc_hexagon_res sc7180_mss = {
2174
2240
.has_mba_logs = true,
2175
2241
.has_spare_reg = true,
2176
2242
.has_qaccept_regs = false,
2243
+ .has_ext_bhs_reg = false,
2177
2244
.has_ext_cntl_regs = false,
2178
2245
.has_vq6 = false,
2179
2246
.version = MSS_SC7180 ,
@@ -2202,6 +2269,7 @@ static const struct rproc_hexagon_res sc7280_mss = {
2202
2269
.has_mba_logs = true,
2203
2270
.has_spare_reg = false,
2204
2271
.has_qaccept_regs = true,
2272
+ .has_ext_bhs_reg = false,
2205
2273
.has_ext_cntl_regs = true,
2206
2274
.has_vq6 = true,
2207
2275
.version = MSS_SC7280 ,
@@ -2233,6 +2301,7 @@ static const struct rproc_hexagon_res sdm660_mss = {
2233
2301
.has_mba_logs = false,
2234
2302
.has_spare_reg = false,
2235
2303
.has_qaccept_regs = false,
2304
+ .has_ext_bhs_reg = false,
2236
2305
.has_ext_cntl_regs = false,
2237
2306
.has_vq6 = false,
2238
2307
.version = MSS_SDM660 ,
@@ -2268,6 +2337,7 @@ static const struct rproc_hexagon_res sdm845_mss = {
2268
2337
.has_mba_logs = false,
2269
2338
.has_spare_reg = false,
2270
2339
.has_qaccept_regs = false,
2340
+ .has_ext_bhs_reg = false,
2271
2341
.has_ext_cntl_regs = false,
2272
2342
.has_vq6 = false,
2273
2343
.version = MSS_SDM845 ,
@@ -2299,6 +2369,7 @@ static const struct rproc_hexagon_res msm8998_mss = {
2299
2369
.has_mba_logs = false,
2300
2370
.has_spare_reg = false,
2301
2371
.has_qaccept_regs = false,
2372
+ .has_ext_bhs_reg = false,
2302
2373
.has_ext_cntl_regs = false,
2303
2374
.has_vq6 = false,
2304
2375
.version = MSS_MSM8998 ,
@@ -2337,6 +2408,7 @@ static const struct rproc_hexagon_res msm8996_mss = {
2337
2408
.has_mba_logs = false,
2338
2409
.has_spare_reg = false,
2339
2410
.has_qaccept_regs = false,
2411
+ .has_ext_bhs_reg = false,
2340
2412
.has_ext_cntl_regs = false,
2341
2413
.has_vq6 = false,
2342
2414
.version = MSS_MSM8996 ,
@@ -2371,6 +2443,7 @@ static const struct rproc_hexagon_res msm8909_mss = {
2371
2443
.has_mba_logs = false,
2372
2444
.has_spare_reg = false,
2373
2445
.has_qaccept_regs = false,
2446
+ .has_ext_bhs_reg = false,
2374
2447
.has_ext_cntl_regs = false,
2375
2448
.has_vq6 = false,
2376
2449
.version = MSS_MSM8909 ,
@@ -2416,6 +2489,7 @@ static const struct rproc_hexagon_res msm8916_mss = {
2416
2489
.has_mba_logs = false,
2417
2490
.has_spare_reg = false,
2418
2491
.has_qaccept_regs = false,
2492
+ .has_ext_bhs_reg = false,
2419
2493
.has_ext_cntl_regs = false,
2420
2494
.has_vq6 = false,
2421
2495
.version = MSS_MSM8916 ,
@@ -2451,6 +2525,7 @@ static const struct rproc_hexagon_res msm8953_mss = {
2451
2525
.has_mba_logs = false,
2452
2526
.has_spare_reg = false,
2453
2527
.has_qaccept_regs = false,
2528
+ .has_ext_bhs_reg = false,
2454
2529
.has_ext_cntl_regs = false,
2455
2530
.has_vq6 = false,
2456
2531
.version = MSS_MSM8953 ,
@@ -2503,13 +2578,53 @@ static const struct rproc_hexagon_res msm8974_mss = {
2503
2578
.has_mba_logs = false,
2504
2579
.has_spare_reg = false,
2505
2580
.has_qaccept_regs = false,
2581
+ .has_ext_bhs_reg = false,
2506
2582
.has_ext_cntl_regs = false,
2507
2583
.has_vq6 = false,
2508
2584
.version = MSS_MSM8974 ,
2509
2585
};
2510
2586
2587
+ static const struct rproc_hexagon_res msm8226_mss = {
2588
+ .hexagon_mba_image = "mba.b00" ,
2589
+ .proxy_supply = (struct qcom_mss_reg_res []) {
2590
+ {
2591
+ .supply = "pll" ,
2592
+ .uA = 100000 ,
2593
+ },
2594
+ {
2595
+ .supply = "mx" ,
2596
+ .uV = 1050000 ,
2597
+ },
2598
+ {}
2599
+ },
2600
+ .proxy_clk_names = (char * []){
2601
+ "xo" ,
2602
+ NULL
2603
+ },
2604
+ .active_clk_names = (char * []){
2605
+ "iface" ,
2606
+ "bus" ,
2607
+ "mem" ,
2608
+ NULL
2609
+ },
2610
+ .proxy_pd_names = (char * []){
2611
+ "cx" ,
2612
+ NULL
2613
+ },
2614
+ .need_mem_protection = false,
2615
+ .has_alt_reset = false,
2616
+ .has_mba_logs = false,
2617
+ .has_spare_reg = false,
2618
+ .has_qaccept_regs = false,
2619
+ .has_ext_bhs_reg = true,
2620
+ .has_ext_cntl_regs = false,
2621
+ .has_vq6 = false,
2622
+ .version = MSS_MSM8226 ,
2623
+ };
2624
+
2511
2625
static const struct of_device_id q6v5_of_match [] = {
2512
2626
{ .compatible = "qcom,q6v5-pil" , .data = & msm8916_mss },
2627
+ { .compatible = "qcom,msm8226-mss-pil" , .data = & msm8226_mss },
2513
2628
{ .compatible = "qcom,msm8909-mss-pil" , .data = & msm8909_mss },
2514
2629
{ .compatible = "qcom,msm8916-mss-pil" , .data = & msm8916_mss },
2515
2630
{ .compatible = "qcom,msm8953-mss-pil" , .data = & msm8953_mss },
0 commit comments