134134#define BOOT_FSM_TIMEOUT 10000
135135#define BHS_CHECK_MAX_LOOPS 200
136136
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+
137142struct reg_info {
138143 struct regulator * reg ;
139144 int uV ;
@@ -161,6 +166,7 @@ struct rproc_hexagon_res {
161166 bool has_mba_logs ;
162167 bool has_spare_reg ;
163168 bool has_qaccept_regs ;
169+ bool has_ext_bhs_reg ;
164170 bool has_ext_cntl_regs ;
165171 bool has_vq6 ;
166172};
@@ -180,6 +186,7 @@ struct q6v5 {
180186 u32 halt_nc ;
181187 u32 halt_vq6 ;
182188 u32 conn_box ;
189+ u32 ext_bhs ;
183190
184191 u32 qaccept_mdm ;
185192 u32 qaccept_cx ;
@@ -237,6 +244,7 @@ struct q6v5 {
237244 bool has_mba_logs ;
238245 bool has_spare_reg ;
239246 bool has_qaccept_regs ;
247+ bool has_ext_bhs_reg ;
240248 bool has_ext_cntl_regs ;
241249 bool has_vq6 ;
242250 u64 mpss_perm ;
@@ -246,6 +254,7 @@ struct q6v5 {
246254};
247255
248256enum {
257+ MSS_MSM8226 ,
249258 MSS_MSM8909 ,
250259 MSS_MSM8916 ,
251260 MSS_MSM8953 ,
@@ -415,6 +424,34 @@ static void q6v5_pds_disable(struct q6v5 *qproc, struct device **pds,
415424 }
416425}
417426
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+
418455static int q6v5_xfer_mem_ownership (struct q6v5 * qproc , u64 * current_perm ,
419456 bool local , bool remote , phys_addr_t addr ,
420457 size_t size )
@@ -1112,11 +1149,17 @@ static int q6v5_mba_load(struct q6v5 *qproc)
11121149 goto disable_proxy_clk ;
11131150 }
11141151
1152+ if (qproc -> has_ext_bhs_reg ) {
1153+ ret = q6v5_external_bhs_enable (qproc );
1154+ if (ret < 0 )
1155+ goto disable_vdd ;
1156+ }
1157+
11151158 ret = q6v5_clk_enable (qproc -> dev , qproc -> reset_clks ,
11161159 qproc -> reset_clk_count );
11171160 if (ret ) {
11181161 dev_err (qproc -> dev , "failed to enable reset clocks\n" );
1119- goto disable_vdd ;
1162+ goto disable_ext_bhs ;
11201163 }
11211164
11221165 ret = q6v5_reset_deassert (qproc );
@@ -1214,6 +1257,9 @@ static int q6v5_mba_load(struct q6v5 *qproc)
12141257disable_reset_clks :
12151258 q6v5_clk_disable (qproc -> dev , qproc -> reset_clks ,
12161259 qproc -> reset_clk_count );
1260+ disable_ext_bhs :
1261+ if (qproc -> has_ext_bhs_reg )
1262+ q6v5_external_bhs_disable (qproc );
12171263disable_vdd :
12181264 q6v5_regulator_disable (qproc , qproc -> active_regs ,
12191265 qproc -> active_reg_count );
@@ -1281,6 +1327,8 @@ static void q6v5_mba_reclaim(struct q6v5 *qproc)
12811327 qproc -> reset_clk_count );
12821328 q6v5_clk_disable (qproc -> dev , qproc -> active_clks ,
12831329 qproc -> active_clk_count );
1330+ if (qproc -> has_ext_bhs_reg )
1331+ q6v5_external_bhs_disable (qproc );
12841332 q6v5_regulator_disable (qproc , qproc -> active_regs ,
12851333 qproc -> active_reg_count );
12861334
@@ -1750,6 +1798,23 @@ static int q6v5_init_mem(struct q6v5 *qproc, struct platform_device *pdev)
17501798 qproc -> qaccept_axi = args .args [2 ];
17511799 }
17521800
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+
17531818 if (qproc -> has_ext_cntl_regs ) {
17541819 ret = of_parse_phandle_with_fixed_args (pdev -> dev .of_node ,
17551820 "qcom,ext-regs" ,
@@ -2021,6 +2086,7 @@ static int q6v5_probe(struct platform_device *pdev)
20212086 platform_set_drvdata (pdev , qproc );
20222087
20232088 qproc -> has_qaccept_regs = desc -> has_qaccept_regs ;
2089+ qproc -> has_ext_bhs_reg = desc -> has_ext_bhs_reg ;
20242090 qproc -> has_ext_cntl_regs = desc -> has_ext_cntl_regs ;
20252091 qproc -> has_vq6 = desc -> has_vq6 ;
20262092 qproc -> has_spare_reg = desc -> has_spare_reg ;
@@ -2174,6 +2240,7 @@ static const struct rproc_hexagon_res sc7180_mss = {
21742240 .has_mba_logs = true,
21752241 .has_spare_reg = true,
21762242 .has_qaccept_regs = false,
2243+ .has_ext_bhs_reg = false,
21772244 .has_ext_cntl_regs = false,
21782245 .has_vq6 = false,
21792246 .version = MSS_SC7180 ,
@@ -2202,6 +2269,7 @@ static const struct rproc_hexagon_res sc7280_mss = {
22022269 .has_mba_logs = true,
22032270 .has_spare_reg = false,
22042271 .has_qaccept_regs = true,
2272+ .has_ext_bhs_reg = false,
22052273 .has_ext_cntl_regs = true,
22062274 .has_vq6 = true,
22072275 .version = MSS_SC7280 ,
@@ -2233,6 +2301,7 @@ static const struct rproc_hexagon_res sdm660_mss = {
22332301 .has_mba_logs = false,
22342302 .has_spare_reg = false,
22352303 .has_qaccept_regs = false,
2304+ .has_ext_bhs_reg = false,
22362305 .has_ext_cntl_regs = false,
22372306 .has_vq6 = false,
22382307 .version = MSS_SDM660 ,
@@ -2268,6 +2337,7 @@ static const struct rproc_hexagon_res sdm845_mss = {
22682337 .has_mba_logs = false,
22692338 .has_spare_reg = false,
22702339 .has_qaccept_regs = false,
2340+ .has_ext_bhs_reg = false,
22712341 .has_ext_cntl_regs = false,
22722342 .has_vq6 = false,
22732343 .version = MSS_SDM845 ,
@@ -2299,6 +2369,7 @@ static const struct rproc_hexagon_res msm8998_mss = {
22992369 .has_mba_logs = false,
23002370 .has_spare_reg = false,
23012371 .has_qaccept_regs = false,
2372+ .has_ext_bhs_reg = false,
23022373 .has_ext_cntl_regs = false,
23032374 .has_vq6 = false,
23042375 .version = MSS_MSM8998 ,
@@ -2337,6 +2408,7 @@ static const struct rproc_hexagon_res msm8996_mss = {
23372408 .has_mba_logs = false,
23382409 .has_spare_reg = false,
23392410 .has_qaccept_regs = false,
2411+ .has_ext_bhs_reg = false,
23402412 .has_ext_cntl_regs = false,
23412413 .has_vq6 = false,
23422414 .version = MSS_MSM8996 ,
@@ -2371,6 +2443,7 @@ static const struct rproc_hexagon_res msm8909_mss = {
23712443 .has_mba_logs = false,
23722444 .has_spare_reg = false,
23732445 .has_qaccept_regs = false,
2446+ .has_ext_bhs_reg = false,
23742447 .has_ext_cntl_regs = false,
23752448 .has_vq6 = false,
23762449 .version = MSS_MSM8909 ,
@@ -2416,6 +2489,7 @@ static const struct rproc_hexagon_res msm8916_mss = {
24162489 .has_mba_logs = false,
24172490 .has_spare_reg = false,
24182491 .has_qaccept_regs = false,
2492+ .has_ext_bhs_reg = false,
24192493 .has_ext_cntl_regs = false,
24202494 .has_vq6 = false,
24212495 .version = MSS_MSM8916 ,
@@ -2451,6 +2525,7 @@ static const struct rproc_hexagon_res msm8953_mss = {
24512525 .has_mba_logs = false,
24522526 .has_spare_reg = false,
24532527 .has_qaccept_regs = false,
2528+ .has_ext_bhs_reg = false,
24542529 .has_ext_cntl_regs = false,
24552530 .has_vq6 = false,
24562531 .version = MSS_MSM8953 ,
@@ -2503,13 +2578,53 @@ static const struct rproc_hexagon_res msm8974_mss = {
25032578 .has_mba_logs = false,
25042579 .has_spare_reg = false,
25052580 .has_qaccept_regs = false,
2581+ .has_ext_bhs_reg = false,
25062582 .has_ext_cntl_regs = false,
25072583 .has_vq6 = false,
25082584 .version = MSS_MSM8974 ,
25092585};
25102586
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+
25112625static const struct of_device_id q6v5_of_match [] = {
25122626 { .compatible = "qcom,q6v5-pil" , .data = & msm8916_mss },
2627+ { .compatible = "qcom,msm8226-mss-pil" , .data = & msm8226_mss },
25132628 { .compatible = "qcom,msm8909-mss-pil" , .data = & msm8909_mss },
25142629 { .compatible = "qcom,msm8916-mss-pil" , .data = & msm8916_mss },
25152630 { .compatible = "qcom,msm8953-mss-pil" , .data = & msm8953_mss },
0 commit comments