diff --git a/src/soc/qualcomm/x1p42100/include/soc/addressmap.h b/src/soc/qualcomm/x1p42100/include/soc/addressmap.h index 6cb4b231e2..63d96a3ea4 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/addressmap.h +++ b/src/soc/qualcomm/x1p42100/include/soc/addressmap.h @@ -24,7 +24,15 @@ #define LPASS_AON_CC_BASE (LPASS_BASE + 0x00E08000) #define LPASS_AON_CC_PLL_CM_BASE (LPASS_BASE + 0x00E01000) #define LPASS_CORE_GDSC_REG_BASE (LPASS_BASE + 0x01E00000) +#define LPASS_LPASS_CORE_CC_REG_BASE (LPASS_BASE + 0x01B08000) +#define LPASS_LPICX_NOC_BASE (LPASS_BASE + 0x01430000) +#define LPASS_LPI_TCM_REG_BASE (LPASS_BASE + 0x0126A000) +#define LPASS_MCC_LPASS_REG_BASE (LPASS_BASE + 0x01250000) #define LPASS_QDSP6SS_PUB_BASE (LPASS_BASE + 0x00800000) +#define LPASS_QDSP6SS_PLL_BASE (LPASS_BASE + 0x00840000) +#define LPASS_QDSP6SS_CORE_CC_BASE (LPASS_BASE + 0x00848000) +#define LPASS_SSC_SCC_BASE (LPASS_BASE + 0x01A01000) + #define LPASS_EFUSE_Q6SS_BASE (LPASS_BASE + 0x0125B000) #define RPMH_BASE 0x17520000 @@ -172,6 +180,7 @@ #define PCIE6A_BQPHY_PCS_PCIE_LANE1 0x01BFFE00 /* TCSR */ +#define TCSR_BASE 0x01FC0000 #define TCSR_GCC_PCIE_4L_CLKREF_EN_PCIE_ENABLE ((void *)0x1FD512C) #define TCSR_PCIE_CTRL_4LN_CONFIG_SEL ((void *)0x1FDA000) diff --git a/src/soc/qualcomm/x1p42100/include/soc/adsp.h b/src/soc/qualcomm/x1p42100/include/soc/adsp.h index 5e156f210b..6c53e49ad8 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/adsp.h +++ b/src/soc/qualcomm/x1p42100/include/soc/adsp.h @@ -16,12 +16,22 @@ struct x1p42100_lpass_qdsp6ss { u8 _res0[0x10]; u32 rst_evb; - u8 _res1[0x60 - 0x14]; + u8 _res1[0x18 - 0x14]; + u32 dbg_cfg; + u32 ret_cfg; + u8 _res2[0x60 - 0x20]; u32 boot_params[6]; + u8 _res3[0x400 - 0x78]; + u32 boot_core_start; + u32 boot_cmd; + u32 boot_status; }; check_member(x1p42100_lpass_qdsp6ss, rst_evb, 0x10); +check_member(x1p42100_lpass_qdsp6ss, dbg_cfg, 0x18); check_member(x1p42100_lpass_qdsp6ss, boot_params, 0x60); +check_member(x1p42100_lpass_qdsp6ss, boot_core_start, 0x400); +check_member(x1p42100_lpass_qdsp6ss, boot_status, 0x408); /* LPASS EFUSE Q6SS Register Structure */ struct x1p42100_lpass_efuse_q6ss { diff --git a/src/soc/qualcomm/x1p42100/include/soc/clock.h b/src/soc/qualcomm/x1p42100/include/soc/clock.h index 934c0fdb34..b60ea039c8 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/clock.h +++ b/src/soc/qualcomm/x1p42100/include/soc/clock.h @@ -223,6 +223,36 @@ struct x1p42100_lpass_aon_cc_pll_clock { u32 pll_test_ctl_u2; }; +/* LPASS QDSP6SS PLL register structure */ +struct x1p42100_lpass_qdsp6ss_pll_clock { + u32 pll_mode; + u32 pll_opmode; + u32 pll_state; + u32 pll_status; + u32 pll_l_val; + u32 pll_alpha_val; + u32 pll_user_ctl; + u32 pll_user_ctl_u; + u32 pll_config_ctl; + u32 pll_config_ctl_u; + u32 pll_config_ctl_u1; + u32 pll_test_ctl; + u32 pll_test_ctl_u; + u32 pll_test_ctl_u1; + u32 pll_test_ctl_u2; +}; + +/* LPASS QDSP6SS Core CC register structure */ +struct x1p42100_lpass_qdsp6ss_core_cc { + u32 core_cmd_rcgr; + u32 core_cfg_rcgr; + u8 _res0[0x0020 - 0x0008]; + u32 core_cbcr; +}; + +check_member(x1p42100_lpass_qdsp6ss_core_cc, core_cfg_rcgr, 0x0004); +check_member(x1p42100_lpass_qdsp6ss_core_cc, core_cbcr, 0x0020); + /* LPASS Audio CC register structure */ struct x1p42100_lpass_audio_cc { u8 _res0[0x28018]; @@ -277,28 +307,102 @@ struct x1p42100_lpass_core_gdsc { check_member(x1p42100_lpass_core_gdsc, lpass_core_gds_hm_ready, 0x000B8); check_member(x1p42100_lpass_core_gdsc, lpass_top_cc_lpass_core_sway_ahb_ls_cbcr, 0x09000); -/* LPASS AON CC register structure */ -struct x1p42100_lpass_aon_cc { - u8 _res0[0x9060]; - u32 va_mem0_cbcr; - u8 _res1[0x2c]; - u32 lpass_audio_hm_gdscr; - u8 _res2[0x2f6c]; - u32 lpass_hm_collapse_vote_for_q6; - u8 _res3[0x6008]; - u32 va_2x_cbcr; - u8 _res4[0x4]; - u32 va_cbcr; - u8 _res5[0xffc]; - u32 tx_mclk_cbcr; +/* LPASS Core CC register structure */ +struct x1p42100_lpass_core_cc { + u8 _res0[0x23000]; + u32 lpass_lpass_core_cc_sysnoc_mport_core_cbcr; }; +check_member(x1p42100_lpass_core_cc, lpass_lpass_core_cc_sysnoc_mport_core_cbcr, 0x23000); + +/* LPASS AON CC register structure */ +struct x1p42100_lpass_aon_cc { + u8 _res0[0x2000]; + u32 lpass_noc_island_isolation; + u8 _res1[0x801C - 0x2004]; + u32 q6_xo_cbcr; + u8 _res2[0x901C - 0x8020]; + u32 q6_ahbm_cbcr; + u8 _res3[0x9060 - 0x9020]; + u32 va_mem0_cbcr; + u8 _res4[0x9090 - 0x9064]; + u32 lpass_audio_hm_gdscr; + u8 _res5[0x0A014 - 0x9094]; + u32 pclkdbg_cbcr; + u8 _res6[0x0A020 - 0x0A018]; + u32 at_cbcr; + u8 _res7[0xC000 - 0x0A024]; + u32 lpass_hm_collapse_vote_for_q6; + u8 _res8[0x1200C - 0xC004]; + u32 va_2x_cbcr; + u8 _res9[0x12014 - 0x12010]; + u32 va_cbcr; + u8 _res10[0x13014 - 0x12018]; + u32 tx_mclk_cbcr; + u8 _res11[0x19008 - 0x13018]; + u32 lpi_noc_hs_cbcr; + u8 _res12[0x1902C - 0x1900C]; + u32 q6_axim_cbcr; +}; + +check_member(x1p42100_lpass_aon_cc, lpass_noc_island_isolation, 0x02000); +check_member(x1p42100_lpass_aon_cc, q6_xo_cbcr, 0x801C); +check_member(x1p42100_lpass_aon_cc, q6_ahbm_cbcr, 0x901C); check_member(x1p42100_lpass_aon_cc, va_mem0_cbcr, 0x9060); check_member(x1p42100_lpass_aon_cc, lpass_audio_hm_gdscr, 0x9090); +check_member(x1p42100_lpass_aon_cc, pclkdbg_cbcr, 0x0A014); +check_member(x1p42100_lpass_aon_cc, at_cbcr, 0x0A020); check_member(x1p42100_lpass_aon_cc, lpass_hm_collapse_vote_for_q6, 0xc000); check_member(x1p42100_lpass_aon_cc, va_2x_cbcr, 0x1200C); check_member(x1p42100_lpass_aon_cc, va_cbcr, 0x12014); check_member(x1p42100_lpass_aon_cc, tx_mclk_cbcr, 0x13014); +check_member(x1p42100_lpass_aon_cc, lpi_noc_hs_cbcr, 0x19008); +check_member(x1p42100_lpass_aon_cc, q6_axim_cbcr, 0x1902C); + +/* LPASS LPICX NOC register structure */ +struct x1p42100_lpass_lpicx_noc { + u8 _res0[0x2040]; + u32 sidebandmanager_chipcx_sbm_faultinen0_low; + u8 _res1[0x6090 - 0x2044]; + u32 sidebandmanager_rcg_sbm_flagoutstatus0_low; +}; + +check_member(x1p42100_lpass_lpicx_noc, sidebandmanager_chipcx_sbm_faultinen0_low, 0x2040); +check_member(x1p42100_lpass_lpicx_noc, sidebandmanager_rcg_sbm_flagoutstatus0_low, 0x6090); + +/* LPASS MCC_LPASS_REG register block */ +struct x1p42100_lpass_mcc_lpass_reg { + u8 _res0[0x18]; + u32 rsc_wait_event_ovrd_mask; + u8 _res1[0x5014 - 0x001c]; + u32 atb_low_power_handshake; + u32 apb_low_power_handshake; + u8 _res2[0x5020 - 0x501c]; + u32 nts_low_power_handshake; + u32 dap_low_power_handshake; +}; + +check_member(x1p42100_lpass_mcc_lpass_reg, rsc_wait_event_ovrd_mask, 0x0018); +check_member(x1p42100_lpass_mcc_lpass_reg, atb_low_power_handshake, 0x5014); +check_member(x1p42100_lpass_mcc_lpass_reg, nts_low_power_handshake, 0x5020); + +/* LPASS SSC_SCC register block */ +struct x1p42100_lpass_ssc_scc { + u8 _res0[0x30]; + u32 ssc_scc_smem_cbcr; +}; + +check_member(x1p42100_lpass_ssc_scc, ssc_scc_smem_cbcr, 0x0030); + +/* LPASS LPI TCM register block */ +struct x1p42100_lpass_lpi_tcm { + u32 tcm_256kb_block_cbcr[10]; + u8 _res0[0x0300 - 0x0028]; + u32 axis_hs_cbcr; +}; + +check_member(x1p42100_lpass_lpi_tcm, tcm_256kb_block_cbcr, 0x0000); +check_member(x1p42100_lpass_lpi_tcm, axis_hs_cbcr, 0x0300); struct x1p42100_disp_cc { uint8_t _res0[0x00C]; @@ -335,7 +439,7 @@ struct x1p42100_disp_cc { uint32_t xo_cbcr; }; -/* Offset checks (relative to DISP_CC_BASE) */ +/* Offset checks */ check_member(x1p42100_disp_cc, mdss_mdp_cbcr, 0x00000C); check_member(x1p42100_disp_cc, mdss_vsync_cbcr, 0x000024); check_member(x1p42100_disp_cc, mdss_dptx3_pixel0_cbcr, 0x000094); @@ -521,82 +625,111 @@ struct x1p42100_gcc { u32 gcc_aggre_usb3_prim_axi_cbcr; u8 _res36[0x42004 - 0x39094]; struct qupv3_clock qup_wrap0_s[8]; - u8 _res37[0x47000 - 0x429c4]; - u32 lpass_cfg_noc_sway_cbcr; - u8 _res38[0x4b000 - 0x47004]; + u8 _res37[0x45150 - 0x429c4]; + /* LPASS boot clock */ + u32 gcc_noc_lpass_dcd_xo_cbcr; + u32 gcc_ddrss_lpass_shub_cbcr; + u8 _res38[0x47000 - 0x45158]; + u32 gcc_lpass_cfg_noc_sway_cbcr; + u32 gcc_qmip_lpass_qtb_ahb_cbcr; + u8 _res39[0x47010 - 0x47008]; + u32 gcc_lpass_aon_noc_ddrss_shub_cbcr; + u32 gcc_lpass_aggre_noc_mpu_client_ddrss_shub_cbcr; + u32 gcc_lpass_hw_af_noc_ddrss_shub_cbcr; + u8 _res40[0x47024 - 0x4701c]; + u32 gcc_lpass_aggre_noc_ddrss_shub_cbcr; + u8 _res41[0x4702c - 0x47028]; + struct clock_rcg lpass_ddrss_shub_rcg; + u8 _res42[0x47160 - 0x47034]; + u32 gcc_cfg_noc_lpass_cbcr; + u8 _res43[0x4b000 - 0x47164]; u32 qspi_bcr; u32 qspi_cnoc_ahb_cbcr; u32 qspi_core_cbcr; struct clock_rcg qspi_core; - u8 _res39[0x50000 - 0x4b014]; + u8 _res44[0x50000 - 0x4b014]; u32 gcc_usb3_phy_prim_bcr; u32 gcc_usb3phy_phy_prim_bcr; - u8 _res40[0x50010 - 0x50008]; + u8 _res45[0x50010 - 0x50008]; u32 gcc_usb4_0_dp0_phy_prim_bcr; - u8 _res41[0x52000 - 0x50014]; + u8 _res46[0x52000 - 0x50014]; u32 apcs_clk_br_en; - u8 _res42[0x52008 - 0x52004]; + u8 _res47[0x52008 - 0x52004]; u32 apcs_clk_br_en1; - u8 _res43[0x52010 - 0x5200c]; + u8 _res48[0x52010 - 0x5200c]; u32 apcs_clk_br_en2; - u8 _res44[0x52018 - 0x52014]; + u8 _res49[0x52018 - 0x52014]; u32 apcs_clk_br_en3; - u8 _res45[0x52020 - 0x5201c]; + u8 _res50[0x52020 - 0x5201c]; u32 apcs_clk_br_en4; - u8 _res46[0x52028 - 0x52024]; + u8 _res51[0x52028 - 0x52024]; u32 apcs_clk_br_en5; - u8 _res47[0x52030 - 0x5202c]; + u8 _res52[0x52030 - 0x5202c]; u32 apcs_pll_br_en; - u8 _res48[0x54000 - 0x52034]; + u8 _res53[0x54000 - 0x52034]; u32 usb3_uniphy_mp1_bcr; u32 usb3uniphy_phy_mp1_bcr; u32 gcc_usb3_mp_ss1_phy_bcr; u32 gcc_usb3_mp_ss1_phy_gdscr; - u8 _res49[0x8e000 - 0x54010]; + u8 _res54[0x55224 - 0x54010]; + u32 gcc_lpass_dsp_gdsc_sleep_ena_vote; + u8 _res55[0x8e000 - 0x55228]; u32 pcie_6_phy_gdscr; - u8 _res50[0xa1000 - 0x8e004]; + u8 _res56[0x99000 - 0x8e004]; + u32 gcc_lpass_qtb_gdscr; + u8 _res57[0x99014 - 0x99004]; + u32 gcc_lpass_qtb_ahb_cbcr; + u32 gcc_lpass_audio_qtb_cbcr; + u8 _res58[0x99024 - 0x9901c]; + u32 gcc_lpass_qosgen_extref_cbcr; + u32 gcc_lpass_qdss_tsctr_cbcr; + u32 gcc_lpass_qtb_at_cbcr; + u32 gcc_lpass_xo_cbcr; + u32 gcc_lpass_pwrctl_cbcr; + u32 gcc_tcu_lpass_audio_qtb_cbcr; + u8 _res59[0xa1000 - 0x9903c]; u32 gcc_usb30_sec_bcr; u32 gcc_usb30_sec_gdscr; - u8 _res51[0xa1018 - 0xa1008]; + u8 _res60[0xa1018 - 0xa1008]; u32 gcc_usb30_sec_master_cbcr; - u8 _res52[0xa1024 - 0xa101c]; + u8 _res61[0xa1024 - 0xa101c]; u32 gcc_usb30_sec_sleep_cbcr; u32 gcc_usb30_sec_mock_utmi_cbcr; struct clock_rcg usb30_sec_master_rcg; - u8 _res53[0xa1060 - 0xa1034]; + u8 _res62[0xa1060 - 0xa1034]; u32 gcc_usb3_sec_phy_aux_cbcr; u32 gcc_usb3_sec_phy_com_aux_cbcr; u32 gcc_usb3_sec_phy_pipe_cbcr; u32 gcc_usb3_sec_phy_pipe_muxr; - u8 _res54[0xa108c - 0xa1070]; + u8 _res63[0xa108c - 0xa1070]; u32 gcc_cfg_noc_usb3_sec_axi_cbcr; u32 gcc_aggre_usb3_sec_axi_cbcr; - u8 _res55[0xa2000 - 0xa1094]; + u8 _res64[0xa2000 - 0xa1094]; u32 gcc_usb30_tert_bcr; u32 gcc_usb30_tert_gdscr; - u8 _res56[0xa2018 - 0xa2008]; + u8 _res65[0xa2018 - 0xa2008]; u32 gcc_usb30_tert_master_cbcr; - u8 _res57[0xa2024 - 0xa201c]; + u8 _res66[0xa2024 - 0xa201c]; u32 gcc_usb30_tert_sleep_cbcr; u32 gcc_usb30_tert_mock_utmi_cbcr; - u8 _res58[0xa2034 - 0xa202c]; + u8 _res67[0xa2034 - 0xa202c]; u32 gcc_usb30_tert_master_m; u32 gcc_usb30_tert_master_n; u32 gcc_usb30_tert_master_d; - u8 _res59[0xa2060 - 0xa2040]; + u8 _res68[0xa2060 - 0xa2040]; u32 gcc_usb3_tert_phy_aux_cbcr; u32 gcc_usb3_tert_phy_com_aux_cbcr; u32 gcc_usb3_tert_phy_pipe_cbcr; u32 gcc_usb3_tert_phy_pipe_muxr; - u8 _res60[0xa208c - 0xa2070]; + u8 _res69[0xa208c - 0xa2070]; u32 gcc_cfg_noc_usb3_tert_axi_cbcr; u32 gcc_aggre_usb3_tert_axi_cbcr; - u8 _res61[0xa3000 - 0xa2094]; + u8 _res70[0xa3000 - 0xa2094]; u32 gcc_usb3_phy_tert_bcr; u32 gcc_usb3phy_phy_tert_bcr; - u8 _res62[0xa3010 - 0xa3008]; + u8 _res71[0xa3010 - 0xa3008]; u32 gcc_usb4_2_dp0_phy_tert_bcr; - u8 _res63[0xac01c - 0xa3014]; + u8 _res72[0xac01c - 0xa3014]; u32 pcie_6a_phy_bcr; }; @@ -645,7 +778,16 @@ check_member(x1p42100_gcc, gcc_aggre_usb_noc_axi_cbcr, 0x2d034); check_member(x1p42100_gcc, gcc_aggre_noc_usb_south_axi_cbcr, 0x2d174); check_member(x1p42100_gcc, gcc_aggre_noc_usb_north_axi_cbcr, 0x2d17c); check_member(x1p42100_gcc, qup_wrap0_s, 0x42004); -check_member(x1p42100_gcc, lpass_cfg_noc_sway_cbcr, 0x47000); +check_member(x1p42100_gcc, gcc_noc_lpass_dcd_xo_cbcr, 0x45150); +check_member(x1p42100_gcc, gcc_ddrss_lpass_shub_cbcr, 0x45154); +check_member(x1p42100_gcc, gcc_lpass_cfg_noc_sway_cbcr, 0x47000); +check_member(x1p42100_gcc, gcc_qmip_lpass_qtb_ahb_cbcr, 0x47004); +check_member(x1p42100_gcc, gcc_lpass_aon_noc_ddrss_shub_cbcr, 0x47010); +check_member(x1p42100_gcc, gcc_lpass_aggre_noc_mpu_client_ddrss_shub_cbcr, 0x47014); +check_member(x1p42100_gcc, gcc_lpass_hw_af_noc_ddrss_shub_cbcr, 0x47018); +check_member(x1p42100_gcc, gcc_lpass_aggre_noc_ddrss_shub_cbcr, 0x47024); +check_member(x1p42100_gcc, lpass_ddrss_shub_rcg, 0x4702c); +check_member(x1p42100_gcc, gcc_cfg_noc_lpass_cbcr, 0x47160); check_member(x1p42100_gcc, qspi_bcr, 0x4b000); check_member(x1p42100_gcc, apcs_clk_br_en, 0x52000); check_member(x1p42100_gcc, apcs_clk_br_en1, 0x52008); @@ -655,6 +797,16 @@ check_member(x1p42100_gcc, apcs_clk_br_en4, 0x52020); check_member(x1p42100_gcc, apcs_clk_br_en5, 0x52028); check_member(x1p42100_gcc, apcs_pll_br_en, 0x52030); check_member(x1p42100_gcc, pcie_6_phy_gdscr, 0x8e000); +check_member(x1p42100_gcc, gcc_lpass_qtb_gdscr, 0x99000); +check_member(x1p42100_gcc, gcc_lpass_qtb_ahb_cbcr, 0x99014); +check_member(x1p42100_gcc, gcc_lpass_audio_qtb_cbcr, 0x99018); +check_member(x1p42100_gcc, gcc_lpass_qosgen_extref_cbcr, 0x99024); +check_member(x1p42100_gcc, gcc_lpass_qdss_tsctr_cbcr, 0x99028); +check_member(x1p42100_gcc, gcc_lpass_qtb_at_cbcr, 0x9902c); +check_member(x1p42100_gcc, gcc_lpass_xo_cbcr, 0x99030); +check_member(x1p42100_gcc, gcc_lpass_pwrctl_cbcr, 0x99034); +check_member(x1p42100_gcc, gcc_tcu_lpass_audio_qtb_cbcr, 0x99038); +check_member(x1p42100_gcc, gcc_lpass_dsp_gdsc_sleep_ena_vote, 0x55224); check_member(x1p42100_gcc, pcie_6a_phy_bcr, 0xac01c); /* Generic QUPV3 wrapper structure - all wrappers have identical layout */ @@ -868,6 +1020,25 @@ enum clk_lpass { LPASS_CLK_COUNT }; +enum lpass_boot_clk { + DDRSS_LPASS_SHUB_CBCR, + LPASS_AGGRE_NOC_DDRSS_SHUB_CBCR, + LPASS_AGGRE_NOC_MPU_CLIENT_DDRSS_SHUB_CBCR, + LPASS_AON_NOC_DDRSS_SHUB_CBCR, + LPASS_AUDIO_QTB_CBCR, + LPASS_HW_AF_NOC_DDRSS_SHUB_CBCR, + LPASS_PWRCTL_CBCR, + LPASS_QDSS_TSCTR_CBCR, + LPASS_QOSGEN_EXTREF_CBCR, + LPASS_QTB_AHB_CBCR, + LPASS_QTB_AT_CBCR, + LPASS_XO_CBCR, + NOC_LPASS_DCD_XO_CBCR, + QMIP_LPASS_QTB_AHB_CBCR, + TCU_LPASS_AUDIO_QTB_CBCR, + LPASS_BOOT_CLK_COUNT +}; + enum subsystem_reset { AOP_RESET_SHFT, CORE_SW_RESET, @@ -919,6 +1090,13 @@ static struct x1p42100_lpass_audio_cc *const lpass_audio_cc = (void *)LPASS_AUDI static struct x1p42100_lpass_aon_cc *const lpass_aon_cc = (void *)LPASS_AON_CC_BASE; static struct x1p42100_lpass_aon_cc_pll_clock *const lpass_aon_cc_pll = (void *)LPASS_AON_CC_PLL_CM_BASE; static struct x1p42100_lpass_core_gdsc *const lpass_core_gdsc = (void *)LPASS_CORE_GDSC_REG_BASE; +static struct x1p42100_lpass_core_cc *const lpass_core_cc = (void *)LPASS_LPASS_CORE_CC_REG_BASE; +static struct x1p42100_lpass_lpicx_noc *const lpass_lpicx_noc = (void *)LPASS_LPICX_NOC_BASE; +static struct x1p42100_lpass_qdsp6ss_pll_clock *const lpass_qdsp6ss_pll = (void *)LPASS_QDSP6SS_PLL_BASE; +static struct x1p42100_lpass_qdsp6ss_core_cc *const lpass_qdsp6ss_core_cc = (void *)LPASS_QDSP6SS_CORE_CC_BASE; +static struct x1p42100_lpass_mcc_lpass_reg *const lpass_mcc_lpass_reg = (void *)LPASS_MCC_LPASS_REG_BASE; +static struct x1p42100_lpass_ssc_scc *const lpass_ssc_scc = (void *)LPASS_SSC_SCC_BASE; +static struct x1p42100_lpass_lpi_tcm *const lpass_lpi_tcm = (void *)LPASS_LPI_TCM_REG_BASE; /* Does nothing */ #define clock_reset_aop() do {} while (0) diff --git a/src/soc/qualcomm/x1p42100/include/soc/lpass.h b/src/soc/qualcomm/x1p42100/include/soc/lpass.h index 0b5a8bd4dd..c3abd43149 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/lpass.h +++ b/src/soc/qualcomm/x1p42100/include/soc/lpass.h @@ -3,6 +3,7 @@ #ifndef _SOC_QUALCOMM_X1P42100_LPASS_H_ #define _SOC_QUALCOMM_X1P42100_LPASS_H_ +#include #include /* LPASS AON CC PLL Settings */ @@ -20,12 +21,110 @@ #define HAL_CLK_LPASS_AON_CC_PLL_USER_CTL 0x00E00041 #define HAL_CLK_LPASS_AON_CC_PLL_USER_CTL_U 0x00000105 -#define LPASS_CORE_HM_READY BIT(0) -#define HW_CTL BIT(1) +enum lpass_voltage_level { + LPASS_VOLTAGE_LOWSVS_D1, + LPASS_VOLTAGE_LOWSVS, + LPASS_VOLTAGE_SVS, + LPASS_VOLTAGE_SVS_L1, + LPASS_VOLTAGE_NOMINAL, + LPASS_VOLTAGE_TURBO, + LPASS_VOLTAGE_MAX +}; + +/* Default voltage level for boot */ +#define LPASS_DEFAULT_VOLTAGE_LEVEL LPASS_VOLTAGE_SVS_L1 + +/* LPASS QDSP6SS PLL user control bit shifts */ +#define QDSP6SS_PLL_PLLOUT_MAIN_SHFT 0 + +/* LPASS QDSP6SS PLL Settings - Voltage-dependent values */ +#define HAL_CLK_LPASS_QDSP6SS_PLL_L_VALUE_LOWSVS_D1 0x00000018 +#define HAL_CLK_LPASS_QDSP6SS_PLL_ALPHA_VALUE_LOWSVS_D1 0x00000000 + +#define HAL_CLK_LPASS_QDSP6SS_PLL_L_VALUE_LOWSVS 0x0000001F +#define HAL_CLK_LPASS_QDSP6SS_PLL_ALPHA_VALUE_LOWSVS 0x00000000 + +#define HAL_CLK_LPASS_QDSP6SS_PLL_L_VALUE_SVS 0x00000029 +#define HAL_CLK_LPASS_QDSP6SS_PLL_ALPHA_VALUE_SVS 0x00000000 + +#define HAL_CLK_LPASS_QDSP6SS_PLL_L_VALUE_SVS_L1 0x00000032 +#define HAL_CLK_LPASS_QDSP6SS_PLL_ALPHA_VALUE_SVS_L1 0x00000000 + +#define HAL_CLK_LPASS_QDSP6SS_PLL_L_VALUE_NOMINAL 0x0000003E +#define HAL_CLK_LPASS_QDSP6SS_PLL_ALPHA_VALUE_NOMINAL 0x00000000 + +#define HAL_CLK_LPASS_QDSP6SS_PLL_L_VALUE_TURBO 0x0000004E +#define HAL_CLK_LPASS_QDSP6SS_PLL_ALPHA_VALUE_TURBO 0x00000000 + +#define HAL_CLK_LPASS_QDSP6SS_PLL_L_VALUE HAL_CLK_LPASS_QDSP6SS_PLL_L_VALUE_SVS_L1 +#define HAL_CLK_LPASS_QDSP6SS_PLL_ALPHA_VALUE HAL_CLK_LPASS_QDSP6SS_PLL_ALPHA_VALUE_SVS_L1 +#define HAL_CLK_LPASS_QDSP6SS_PLL_CAL_L_VALUE 0x00000044 +#define HAL_CLK_LPASS_QDSP6SS_PLL_CONFIG_CTL 0x20485699 +#define HAL_CLK_LPASS_QDSP6SS_PLL_CONFIG_CTL_U 0x00182261 +#define HAL_CLK_LPASS_QDSP6SS_PLL_CONFIG_CTL_U1 0x82AA299C +#define HAL_CLK_LPASS_QDSP6SS_PLL_TEST_CTL 0x00000000 +#define HAL_CLK_LPASS_QDSP6SS_PLL_TEST_CTL_U 0x00000003 +#define HAL_CLK_LPASS_QDSP6SS_PLL_TEST_CTL_U1 0x00009000 +#define HAL_CLK_LPASS_QDSP6SS_PLL_TEST_CTL_U2 0x00000034 +#define HAL_CLK_LPASS_QDSP6SS_PLL_USER_CTL 0x00000000 +#define HAL_CLK_LPASS_QDSP6SS_PLL_USER_CTL_U 0x00000005 + +#define LPASS_CORE_HM_READY (1 << 0) +#define HW_CTL (1 << 1) #define GDSC_ENABLE_BIT 0 +#define GDSC_RETAIN_FF_ENABLE (1 << 11) #define LPASS_CORE_HM_VOTE_POWER_ON 0x0 #define GDSC_PWR_ON BIT(31) - +#define LPASS_CORE_HM_VOTE_POWER_DOWN 0x1 #define BCM_LP0_VOTE_VALUE 0x60004001 + +/* NanoRCG status bits */ +#define LPASS_NANO_RCG_PORT2 (1 << 2) + +/* Low power handshake bits */ +#define LPASS_LP_HANDSHAKE_ACK (1 << 0) /* Bit 0: ACK status (RO) */ +#define LPASS_LP_HANDSHAKE_ACTIVE (1 << 1) /* Bit 1: ACTIVE status (RO) */ +#define LPASS_LP_HANDSHAKE_REQUEST (1 << 2) /* Bit 2: REQUEST control (RW) */ + +/* NTS debug bridge handshake tuning */ +#define LPASS_NTS_HANDSHAKE_TIMEOUT_US 500000 +#define LPASS_NTS_HANDSHAKE_DELAY_US 100 + +/* Q6 Core RCG configuration */ +#define Q6_CORE_RCG_CFG 0x201 +#define CLK_CTL_CMD_UPDATE_SHFT 0 +#define LPASS_RCG_UPDATE_TIMEOUT_US 100000 + +/* RSC wait event override mask */ +#define LPASS_RSC_WAIT_EVENT_MASK 0x8 + +/* CR QCTDD10442361 workaround - NOC island isolation bits */ +#define CHIP_CX_RSCC_BYPASS_EN (1 << 21) +#define AON_NOC_STALL_MASK (1 << 22) +#define CHIPCX_SBM_FAULTINEN0_PORT0 (1 << 0) + +/* TCM (Tightly Coupled Memory) control bits */ +#define LPASS_TCM_MAX_BLOCKS 9 + +/* Q6 Boot control bits */ +#define BOOT_CORE_START (1 << 0) +#define BOOT_FSM_START (1 << 0) +#define LPASS_BOOT_FSM_TIMEOUT_US 1000000 + +#define TCSR_BOOT_IMEM_DISABLE_OFF 0x013300 +#define TCSR_BOOT_IMEM_DISABLE ((void *)(TCSR_BASE + TCSR_BOOT_IMEM_DISABLE_OFF)) + +enum cb_err lpass_bring_up(void); + +/* + * Clock workarounds for LPASS clocks. + * + * Keep these lists declarative (CBCR pointers only); apply behavior in + * lpass_apply_clock_workarounds(). + */ +struct lpass_cbcr_list { + uint32_t *cbcr; +}; + #endif /* _SOC_QUALCOMM_X1P42100_LPASS_H_ */ diff --git a/src/soc/qualcomm/x1p42100/include/soc/rpmh_config.h b/src/soc/qualcomm/x1p42100/include/soc/rpmh_config.h index c1f9c4630c..f6abd98072 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/rpmh_config.h +++ b/src/soc/qualcomm/x1p42100/include/soc/rpmh_config.h @@ -31,6 +31,7 @@ #define RPMH_REGULATOR_LEVEL_MIN_MM0 1 #define RPMH_REGULATOR_LEVEL_TURBO_MM0 6 +#define RPMH_REGULATOR_LEVEL_NOM_L1 5 #define BCM_MM0_VOTE_VALUE 0x60004001 #define AOP_BOOT_COOKIE 0xA0C00C1E diff --git a/src/soc/qualcomm/x1p42100/lpass.c b/src/soc/qualcomm/x1p42100/lpass.c index fb96616dbd..f467bcef38 100644 --- a/src/soc/qualcomm/x1p42100/lpass.c +++ b/src/soc/qualcomm/x1p42100/lpass.c @@ -1,12 +1,40 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include +#include +#include #include +#include #include #include +#include +#include #include +/* Debug configuration value (0 = no debug, non-zero = 0x20000000 = enable debug) */ +u32 lpass_q6_debug_val = 0; + +static struct clock_freq_config lpass_ddrss_shub_cfg[] = { + { + .hz = 400 * MHz, + .src = SRC_GPLL0_MAIN_600MHZ, + .div = QCOM_CLOCK_DIV(1.5), + }, +}; + +/* Configure LPASS DDRSS SHUB RCG (RCGR + M/N) to 400 MHz */ +static void lpass_configure_ddrss_shub_rcg(void) +{ + if (clock_configure(&gcc->lpass_ddrss_shub_rcg, + lpass_ddrss_shub_cfg, + 400 * MHz, ARRAY_SIZE(lpass_ddrss_shub_cfg)) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to configure DDRSS SHUB RCG\n"); + return; + } +} + static enum cb_err lpass_aon_cc_pll_enable(void) { struct alpha_pll_reg_val_config pll_cfg = {0}; @@ -55,15 +83,79 @@ static enum cb_err lpass_aon_cc_pll_enable(void) return CB_SUCCESS; } +static enum cb_err lpass_qdsp6ss_pll_enable(void) +{ + struct alpha_pll_reg_val_config pll_cfg = {0}; + + pll_cfg.reg_mode = &lpass_qdsp6ss_pll->pll_mode; + pll_cfg.reg_l = &lpass_qdsp6ss_pll->pll_l_val; + pll_cfg.l_val = HAL_CLK_LPASS_QDSP6SS_PLL_L_VALUE_SVS_L1; + + pll_cfg.reg_alpha = &lpass_qdsp6ss_pll->pll_alpha_val; + pll_cfg.alpha_val = HAL_CLK_LPASS_QDSP6SS_PLL_ALPHA_VALUE_SVS_L1; + + pll_cfg.reg_cal_l = &lpass_qdsp6ss_pll->pll_l_val; + pll_cfg.cal_l_val = HAL_CLK_LPASS_QDSP6SS_PLL_CAL_L_VALUE; + + pll_cfg.reg_config_ctl = &lpass_qdsp6ss_pll->pll_config_ctl; + pll_cfg.config_ctl_val = HAL_CLK_LPASS_QDSP6SS_PLL_CONFIG_CTL; + pll_cfg.reg_config_ctl_hi = &lpass_qdsp6ss_pll->pll_config_ctl_u; + pll_cfg.config_ctl_hi_val = HAL_CLK_LPASS_QDSP6SS_PLL_CONFIG_CTL_U; + pll_cfg.reg_config_ctl_hi1 = &lpass_qdsp6ss_pll->pll_config_ctl_u1; + pll_cfg.config_ctl_hi1_val = HAL_CLK_LPASS_QDSP6SS_PLL_CONFIG_CTL_U1; + + pll_cfg.reg_user_ctl = &lpass_qdsp6ss_pll->pll_user_ctl; + pll_cfg.user_ctl_val = HAL_CLK_LPASS_QDSP6SS_PLL_USER_CTL; + pll_cfg.reg_user_ctl_hi = &lpass_qdsp6ss_pll->pll_user_ctl_u; + pll_cfg.user_ctl_hi_val = HAL_CLK_LPASS_QDSP6SS_PLL_USER_CTL_U; + + pll_cfg.reg_opmode = &lpass_qdsp6ss_pll->pll_opmode; + + if (clock_configure_enable_gpll(&pll_cfg, false, 0) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: QDSP6SS PLL configuration failed\n"); + return CB_ERR; + } + + write32(&lpass_qdsp6ss_pll->pll_test_ctl, HAL_CLK_LPASS_QDSP6SS_PLL_TEST_CTL); + write32(&lpass_qdsp6ss_pll->pll_test_ctl_u, HAL_CLK_LPASS_QDSP6SS_PLL_TEST_CTL_U); + write32(&lpass_qdsp6ss_pll->pll_test_ctl_u1, HAL_CLK_LPASS_QDSP6SS_PLL_TEST_CTL_U1); + write32(&lpass_qdsp6ss_pll->pll_test_ctl_u2, HAL_CLK_LPASS_QDSP6SS_PLL_TEST_CTL_U2); + + if (lucidole_pll_enable(&pll_cfg) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: QDSP6SS PLL enable failed\n"); + return CB_ERR; + } + + /* Enable PLLOUT_MAIN for QDSP6SS PLL */ + setbits32(&lpass_qdsp6ss_pll->pll_user_ctl, BIT(QDSP6SS_PLL_PLLOUT_MAIN_SHFT)); + + /* Configure Q6 Core RCG */ + write32(&lpass_qdsp6ss_core_cc->core_cfg_rcgr, Q6_CORE_RCG_CFG); + setbits32(&lpass_qdsp6ss_core_cc->core_cmd_rcgr, BIT(CLK_CTL_CMD_UPDATE_SHFT)); + + /* Wait for RCG update */ + if (!wait_us(LPASS_RCG_UPDATE_TIMEOUT_US, + !(read32(&lpass_qdsp6ss_core_cc->core_cmd_rcgr) & + BIT(CLK_CTL_CMD_UPDATE_SHFT)))) { + printk(BIOS_ERR, "LPASS: RCG update timeout\n"); + return CB_ERR; + } + + /* Enable QDSP6 core clock */ + setbits32(&lpass_qdsp6ss_core_cc->core_cbcr, BIT(CLK_CTL_EN_SHFT)); + + return CB_SUCCESS; +} + static enum cb_err lpass_setup_core_infrastructure(void) { - if (clock_enable(&gcc->lpass_cfg_noc_sway_cbcr) != CB_SUCCESS) { + if (clock_enable(&gcc->gcc_lpass_cfg_noc_sway_cbcr) != CB_SUCCESS) { printk(BIOS_ERR, "LPASS: Failed to enable CFG NOC SWAY clock\n"); return CB_ERR; } - setbits32(&lpass_core_gdsc->lpass_top_cc_lpass_core_sway_ahb_ls_cbcr, HW_CTL); + clock_configure_hw_ctl(&lpass_core_gdsc->lpass_top_cc_lpass_core_sway_ahb_ls_cbcr, true); write32(&lpass_aon_cc->lpass_hm_collapse_vote_for_q6, LPASS_CORE_HM_VOTE_POWER_ON); @@ -77,9 +169,49 @@ static enum cb_err lpass_setup_core_infrastructure(void) return CB_ERR; } + /* Enable retention */ + setbits32(&lpass_core_gdsc->core_hm_gdscr, GDSC_RETAIN_FF_ENABLE); + + /* Enable SYSNOC interface */ + if (clock_enable(&lpass_core_cc->lpass_lpass_core_cc_sysnoc_mport_core_cbcr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable SYSNOC interface\n"); + return CB_ERR; + } + return CB_SUCCESS; } +static const struct lpass_cbcr_list lpass_rpmh_ignore_clks[] = { + { &gcc->gcc_ddrss_lpass_shub_cbcr }, + { &gcc->gcc_tcu_lpass_audio_qtb_cbcr }, +}; + +static const struct lpass_cbcr_list lpass_pmu_ignore_clks[] = { + { &gcc->gcc_lpass_hw_af_noc_ddrss_shub_cbcr }, + { &gcc->gcc_lpass_aggre_noc_ddrss_shub_cbcr }, + { &gcc->gcc_lpass_aggre_noc_mpu_client_ddrss_shub_cbcr }, +}; + +/* Boot clocks (GCC CBCRs). */ +static u32 *lpass_boot_cbcr[LPASS_BOOT_CLK_COUNT] = { + [DDRSS_LPASS_SHUB_CBCR] = &gcc->gcc_ddrss_lpass_shub_cbcr, + [LPASS_AGGRE_NOC_DDRSS_SHUB_CBCR] = &gcc->gcc_lpass_aggre_noc_ddrss_shub_cbcr, + [LPASS_AGGRE_NOC_MPU_CLIENT_DDRSS_SHUB_CBCR] = &gcc->gcc_lpass_aggre_noc_mpu_client_ddrss_shub_cbcr, + [LPASS_AON_NOC_DDRSS_SHUB_CBCR] = &gcc->gcc_lpass_aon_noc_ddrss_shub_cbcr, + [LPASS_AUDIO_QTB_CBCR] = &gcc->gcc_lpass_audio_qtb_cbcr, + [LPASS_HW_AF_NOC_DDRSS_SHUB_CBCR] = &gcc->gcc_lpass_hw_af_noc_ddrss_shub_cbcr, + [LPASS_PWRCTL_CBCR] = &gcc->gcc_lpass_pwrctl_cbcr, + [LPASS_QDSS_TSCTR_CBCR] = &gcc->gcc_lpass_qdss_tsctr_cbcr, + [LPASS_QOSGEN_EXTREF_CBCR] = &gcc->gcc_lpass_qosgen_extref_cbcr, + [LPASS_QTB_AHB_CBCR] = &gcc->gcc_lpass_qtb_ahb_cbcr, + [LPASS_QTB_AT_CBCR] = &gcc->gcc_lpass_qtb_at_cbcr, + [LPASS_XO_CBCR] = &gcc->gcc_lpass_xo_cbcr, + [NOC_LPASS_DCD_XO_CBCR] = &gcc->gcc_noc_lpass_dcd_xo_cbcr, + [QMIP_LPASS_QTB_AHB_CBCR] = &gcc->gcc_qmip_lpass_qtb_ahb_cbcr, + [TCU_LPASS_AUDIO_QTB_CBCR] = &gcc->gcc_tcu_lpass_audio_qtb_cbcr, +}; + +/* Array mapping enum clk_lpass to actual CBCR registers */ static u32 *lpass_cbcr[LPASS_CLK_COUNT] = { [LPASS_CODEC_MEM_CBCR] = &lpass_audio_cc->codec_mem_cbcr, [LPASS_CODEC_MEM0_CBCR] = &lpass_audio_cc->codec_mem0_cbcr, @@ -114,15 +246,323 @@ static enum cb_err lpass_audio_clocks_enable(void) return CB_SUCCESS; } -enum cb_err lpass_init(void) +static enum cb_err lpass_rpmh_bcm_vote(void) { + struct rpmh_vreg arc_reg; + enum cb_err ret; int rc; + volatile u32 *boot_cookie = (volatile u32 *)AOP_BOOT_COOKIE_ADDR; + + if (!wait_us(AOP_BOOT_TIMEOUT_US, *boot_cookie == AOP_BOOT_COOKIE)) { + printk(BIOS_ERR, + "AOP not booted after %dus (cookie: 0x%x, expected: 0x%x)\n", + AOP_BOOT_TIMEOUT_US, *boot_cookie, AOP_BOOT_COOKIE); + return CB_ERR; + } + + ret = cmd_db_ready(); + if (ret != CB_SUCCESS) { + ret = cmd_db_init(CMD_DB_BASE_ADDR, CMD_DB_SIZE); + if (ret != CB_SUCCESS) { + printk(BIOS_ERR, "CMD_DB: init failed\n"); + return CB_ERR; + } + } + + rc = rpmh_rsc_init(); + if (rc) { + printk(BIOS_ERR, "RPMH_RSC: init failed\n"); + return CB_ERR; + } + + /* Initialize LCX ARC regulator for LPASS power rail */ + rc = rpmh_regulator_init(&arc_reg, "lcx.lvl", RPMH_REGULATOR_TYPE_ARC); + if (rc) { + printk(BIOS_ERR, "Failed to initialize LPASS power rail lcx ARC regulator\n"); + return CB_ERR; + } + + /* Set LCX level to NOM_L1 */ + rc = rpmh_regulator_arc_set_level(&arc_reg, RPMH_REGULATOR_LEVEL_NOM_L1, true, false); + if (rc) { + printk(BIOS_ERR, "Failed to set LCX ARC level\n"); + return CB_ERR; + } + rc = rpmh_bcm_vote("LP0", BCM_LP0_VOTE_VALUE); if (rc) { printk(BIOS_ERR, "LPASS: Failed to send BCM vote for LPASS bus clock manager LP0\n"); return CB_ERR; } + return CB_SUCCESS; +} + +static void lpass_apply_clock_workarounds(void) +{ + size_t i; + + /* CR QCTDD08205470: ignore RPMh clock disable for TCU-QTB link clocks. */ + for (i = 0; i < ARRAY_SIZE(lpass_rpmh_ignore_clks); i++) + clock_configure_ignore_rpmh_clk_dis(lpass_rpmh_ignore_clks[i].cbcr, true); + + /* CR-3409636: keep AON NOC DDRSS SHUB clock enabled during sleep fencing. */ + clock_configure_ignore_rpmh_clk_dis(&gcc->gcc_lpass_aon_noc_ddrss_shub_cbcr, true); + + /* PMU-GCC spec: ignore PMU clock disable for these clocks. */ + for (i = 0; i < ARRAY_SIZE(lpass_pmu_ignore_clks); i++) + clock_configure_ignore_pmu_clk_dis(lpass_pmu_ignore_clks[i].cbcr, true); + + /* Prevent automatic GDSC collapse (HW defaults enable it). */ + write32(&gcc->gcc_lpass_dsp_gdsc_sleep_ena_vote, 0x0); +} + +static enum cb_err lpass_enable_boot_clocks(void) +{ + size_t i; + enum cb_err ret; + + /* Configure LPASS DDRSS SHUB RCG */ + lpass_configure_ddrss_shub_rcg(); + + /* Enable QTB power domain */ + if (enable_and_poll_gdsc_status(&gcc->gcc_lpass_qtb_gdscr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable QTB GDSC\n"); + return CB_ERR; + } + + /* Ensure IGNORE_RPMH_CLK_DIS is set before enabling TCU-QTB link clock. */ + clock_configure_ignore_rpmh_clk_dis(&gcc->gcc_tcu_lpass_audio_qtb_cbcr, true); + + for (i = 0; i < LPASS_BOOT_CLK_COUNT; i++) { + ret = clock_enable(lpass_boot_cbcr[i]); + if (ret != CB_SUCCESS) + printk(BIOS_WARNING, "LPASS: Failed to enable boot clock %zu: %p\n", i, lpass_boot_cbcr[i]); + } + + return CB_SUCCESS; +} + +static enum cb_err lpass_enable_ssc_smem_clock(void) +{ + if (clock_enable(&lpass_ssc_scc->ssc_scc_smem_cbcr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable SSC_SCC_SMEM clock\n"); + return CB_ERR; + } + return CB_SUCCESS; +} + +static enum cb_err lpass_debug_bridge_setup(void) +{ + if (clock_enable(&lpass_aon_cc->at_cbcr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable AT clock\n"); + return CB_ERR; + } + + if (clock_enable(&lpass_aon_cc->pclkdbg_cbcr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable PCLKDBG clock\n"); + return CB_ERR; + } + + /* Allow debug bridge clocks/paths to settle before requesting handshake. */ + udelay(LPASS_NTS_HANDSHAKE_DELAY_US); + + /* + * In order to attach debugger T32 APB, DAP and NTS bridges need to be enabled + */ + setbits32(&lpass_mcc_lpass_reg->atb_low_power_handshake, LPASS_LP_HANDSHAKE_REQUEST); + setbits32(&lpass_mcc_lpass_reg->apb_low_power_handshake, LPASS_LP_HANDSHAKE_REQUEST); + setbits32(&lpass_mcc_lpass_reg->nts_low_power_handshake, LPASS_LP_HANDSHAKE_REQUEST); + dsb(); + + /* + * Wait for NTS ACK + */ + if (!wait_us(LPASS_NTS_HANDSHAKE_TIMEOUT_US, + read32(&lpass_mcc_lpass_reg->nts_low_power_handshake) & LPASS_LP_HANDSHAKE_ACK)) { + printk(BIOS_WARNING, "LPASS: NTS handshake timeout (NTS=0x%x)\n", + read32(&lpass_mcc_lpass_reg->nts_low_power_handshake)); + /* Non-fatal: continue boot even if debug bridge handshake doesn't complete */ + } + + return CB_SUCCESS; +} + +/* Enable TCM blocks for LPASS processor memory access. */ +static void lpass_tcm_init(void) +{ + uint32_t block; + + if (clock_enable(&lpass_lpi_tcm->axis_hs_cbcr) != CB_SUCCESS) { + printk(BIOS_WARNING, "LPASS: Failed to enable TCM AXIS HS clock\n"); + return; + } + + /* Initialize all TCM 256KB blocks (n=0..9) */ + for (block = 0; block <= LPASS_TCM_MAX_BLOCKS; block++) { + clock_configure_force_mem_core_on(&lpass_lpi_tcm->tcm_256kb_block_cbcr[block], true); + + if (clock_enable(&lpass_lpi_tcm->tcm_256kb_block_cbcr[block]) != CB_SUCCESS) { + printk(BIOS_WARNING, "LPASS: Failed to enable TCM block %d clock\n", block); + return; + } + } +} + +static enum cb_err setup_lpass_processor(void) +{ + /* HW_CTL settings */ + clock_configure_hw_ctl(&gcc->gcc_ddrss_lpass_shub_cbcr, false); + + /* Enable boot clocks */ + if (lpass_enable_boot_clocks() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable boot clocks\n"); + return CB_ERR; + } + + /* Apply clock workarounds */ + lpass_apply_clock_workarounds(); + + /* HPG Step 4: Enable LPASS access */ + if (clock_enable(&gcc->gcc_cfg_noc_lpass_cbcr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable CFG NOC access\n"); + return CB_ERR; + } + + /* HPG Step 11: Program LPASS_QDSP6SS_RET_CFG = 0x0 (CR QCTDD10415825) */ + write32(&lpass_qdsp6ss->ret_cfg, 0); + + /* HPG Step 12: Check NanoRCG and enable LPI_NOC_HS conditionally */ + if ((read32(&lpass_lpicx_noc->sidebandmanager_rcg_sbm_flagoutstatus0_low) & LPASS_NANO_RCG_PORT2) == 0) { + if (clock_enable(&lpass_aon_cc->lpi_noc_hs_cbcr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable LPI NOC HS clock\n"); + return CB_ERR; + } + } else { + if (clock_disable(&lpass_aon_cc->lpi_noc_hs_cbcr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to disable LPI NOC HS clock\n"); + return CB_ERR; + } + } + /* HPG Step 13: Enable Q6 AXIM clock after NanoRCG-based LPI_NOC_HS handling */ + if (clock_enable(&lpass_aon_cc->q6_axim_cbcr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable Q6 AXIM clock\n"); + return CB_ERR; + } + + /* Configure debug register */ + write32(&lpass_qdsp6ss->dbg_cfg, lpass_q6_debug_val); + + write32(&lpass_mcc_lpass_reg->rsc_wait_event_ovrd_mask, LPASS_RSC_WAIT_EVENT_MASK); + + /* Initialize TCM */ + lpass_tcm_init(); + + /* Enable Q6_AHBM clock for PRAM access */ + if (clock_enable(&lpass_aon_cc->q6_ahbm_cbcr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable Q6_AHBM clock\n"); + return CB_ERR; + } + + /* Enable SSC_SCC_SMEM clock */ + if (lpass_enable_ssc_smem_clock() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable SSC_SCC_SMEM clock\n"); + return CB_ERR; + } + + /* Setup debug bridges if debug is enabled */ + if (lpass_q6_debug_val != 0) { + if (lpass_debug_bridge_setup() != CB_SUCCESS) + printk(BIOS_WARNING, "LPASS: Debug bridge setup failed\n"); + } + /* Enable QDSP6SS PLL */ + if (lpass_qdsp6ss_pll_enable() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable QDSP6SS PLL\n"); + return CB_ERR; + } + + /* CR QCTDD10442361: mask RSCp trigger and disable CHIP_CX QCHANNEL timeout SBM. */ + /* HPG Step 24.e: Set CHIP_CX_RSCC_BYPASS_EN = 1 */ + setbits32(&lpass_aon_cc->lpass_noc_island_isolation, CHIP_CX_RSCC_BYPASS_EN); + + /* HPG Step 24.f: Set AON_NOC_STALL_MASK = 0 */ + clrbits32(&lpass_aon_cc->lpass_noc_island_isolation, AON_NOC_STALL_MASK); + + /* HPG Step 24.g: Set Port0 = 0 */ + clrbits32(&lpass_lpicx_noc->sidebandmanager_chipcx_sbm_faultinen0_low, + CHIPCX_SBM_FAULTINEN0_PORT0); + + clock_configure_hw_ctl(&gcc->gcc_lpass_aon_noc_ddrss_shub_cbcr, true); + + printk(BIOS_INFO, "LPASS: Processor setup complete\n"); + return CB_SUCCESS; +} + +static enum cb_err enable_lpass_processor(void) +{ + /* HPG Step 14: Q6 boot sequence */ + /* + * De-assert QDSP6 stop core. QDSP6 will execute instructions after out of reset. + */ + setbits32(&lpass_qdsp6ss->boot_core_start, BOOT_CORE_START); + + /* + * Trigger boot FSM to start QDSP6 out of reset sequence. + */ + write32(&lpass_qdsp6ss->boot_cmd, BOOT_FSM_START); + dsb(); + + /* Wait for boot FSM completion */ + if (!wait_us(LPASS_BOOT_FSM_TIMEOUT_US, read32(&lpass_qdsp6ss->boot_status) != 0)) { + printk(BIOS_ERR, "LPASS: Boot FSM timeout (boot_status=0x%x)\n", + read32(&lpass_qdsp6ss->boot_status)); + return CB_ERR; + } + + /* Wait for core to come out of reset */ + udelay(5); + + /* HPG Step 19: Disable Q6_AXIM clock after Q6 boots */ + if (clock_disable(&lpass_aon_cc->q6_axim_cbcr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to disable Q6_AXIM clock\n"); + return CB_ERR; + } + + printk(BIOS_INFO, "LPASS: Q6 processor enabled\n"); + return CB_SUCCESS; +} + +enum cb_err lpass_bring_up(void) +{ + if (lpass_init() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: lpass_init() failed\n"); + return CB_ERR; + } + + if (setup_lpass_processor() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to setup LPASS processor\n"); + return CB_ERR; + } + + /* Disable BOOT IMEM */ + write32((void *)TCSR_BOOT_IMEM_DISABLE, 0x1); + + /* Boot the LPASS Q6 processor */ + if (enable_lpass_processor() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable LPASS processor\n"); + return CB_ERR; + } + + return CB_SUCCESS; +} + +enum cb_err lpass_init(void) +{ + if (lpass_rpmh_bcm_vote() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to initialize RPMH BCM vote\n"); + return CB_ERR; + } + if (enable_and_poll_gdsc_status(&lpass_aon_cc->lpass_audio_hm_gdscr) != CB_SUCCESS) { printk(BIOS_ERR, "LPASS: Failed to enable Core HM GDSC\n"); return CB_ERR;