From: Ofir Bitton <obit...@habana.ai>

Once FW security is enabled there is no access to PLL registers,
need to read values from FW using a dedicated interface.

Signed-off-by: Ofir Bitton <obit...@habana.ai>
Reviewed-by: Oded Gabbay <ogab...@kernel.org>
Signed-off-by: Oded Gabbay <ogab...@kernel.org>
---
 drivers/misc/habanalabs/common/firmware_if.c | 26 +++++++++++++
 drivers/misc/habanalabs/common/habanalabs.h  |  4 ++
 drivers/misc/habanalabs/gaudi/gaudi.c        | 41 +++++++++++++++-----
 3 files changed, 62 insertions(+), 9 deletions(-)

diff --git a/drivers/misc/habanalabs/common/firmware_if.c 
b/drivers/misc/habanalabs/common/firmware_if.c
index 8de6a8690b1b..d84a70ec0ce1 100644
--- a/drivers/misc/habanalabs/common/firmware_if.c
+++ b/drivers/misc/habanalabs/common/firmware_if.c
@@ -448,6 +448,32 @@ int hl_fw_cpucp_total_energy_get(struct hl_device *hdev, 
u64 *total_energy)
        return rc;
 }
 
+int hl_fw_cpucp_pll_info_get(struct hl_device *hdev,
+               enum cpucp_pll_type_attributes pll_type,
+               enum cpucp_pll_reg_attributes pll_reg,
+               u32 *pll_info)
+{
+       struct cpucp_packet pkt;
+       long result;
+       int rc;
+
+       memset(&pkt, 0, sizeof(pkt));
+
+       pkt.ctl = cpu_to_le32(CPUCP_PACKET_PLL_REG_GET <<
+                               CPUCP_PKT_CTL_OPCODE_SHIFT);
+       pkt.pll_type = __cpu_to_le16(pll_type);
+       pkt.pll_reg = __cpu_to_le16(pll_reg);
+
+       rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
+                       HL_CPUCP_INFO_TIMEOUT_USEC, &result);
+       if (rc)
+               dev_err(hdev->dev, "Failed to read PLL info, error %d\n", rc);
+
+       *pll_info = result;
+
+       return rc;
+}
+
 static void fw_read_errors(struct hl_device *hdev, u32 boot_err0_reg,
                u32 cpu_security_boot_status_reg)
 {
diff --git a/drivers/misc/habanalabs/common/habanalabs.h 
b/drivers/misc/habanalabs/common/habanalabs.h
index fee68fc121d7..ce516e9e1ebe 100644
--- a/drivers/misc/habanalabs/common/habanalabs.h
+++ b/drivers/misc/habanalabs/common/habanalabs.h
@@ -2113,6 +2113,10 @@ int hl_fw_cpucp_pci_counters_get(struct hl_device *hdev,
                struct hl_info_pci_counters *counters);
 int hl_fw_cpucp_total_energy_get(struct hl_device *hdev,
                        u64 *total_energy);
+int hl_fw_cpucp_pll_info_get(struct hl_device *hdev,
+               enum cpucp_pll_type_attributes pll_type,
+               enum cpucp_pll_reg_attributes pll_reg,
+               u32 *pll_info);
 int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg,
                        u32 msg_to_cpu_reg, u32 cpu_msg_status_reg,
                        u32 cpu_security_boot_status_reg, u32 boot_err0_reg,
diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c 
b/drivers/misc/habanalabs/gaudi/gaudi.c
index 5df06c63ceb8..9e38ac6f7264 100644
--- a/drivers/misc/habanalabs/gaudi/gaudi.c
+++ b/drivers/misc/habanalabs/gaudi/gaudi.c
@@ -673,16 +673,33 @@ static int gaudi_early_fini(struct hl_device *hdev)
  * @hdev: pointer to hl_device structure
  *
  */
-static void gaudi_fetch_psoc_frequency(struct hl_device *hdev)
+static int gaudi_fetch_psoc_frequency(struct hl_device *hdev)
 {
        struct asic_fixed_properties *prop = &hdev->asic_prop;
-       u32 trace_freq = 0;
-       u32 pll_clk = 0;
-       u32 div_fctr = RREG32(mmPSOC_CPU_PLL_DIV_FACTOR_2);
-       u32 div_sel = RREG32(mmPSOC_CPU_PLL_DIV_SEL_2);
-       u32 nr = RREG32(mmPSOC_CPU_PLL_NR);
-       u32 nf = RREG32(mmPSOC_CPU_PLL_NF);
-       u32 od = RREG32(mmPSOC_CPU_PLL_OD);
+       u32 trace_freq = 0, pll_clk = 0;
+       u32 div_fctr, div_sel, nr, nf, od;
+       int rc;
+
+       if (hdev->asic_prop.fw_security_disabled) {
+               div_fctr = RREG32(mmPSOC_CPU_PLL_DIV_FACTOR_2);
+               div_sel = RREG32(mmPSOC_CPU_PLL_DIV_SEL_2);
+               nr = RREG32(mmPSOC_CPU_PLL_NR);
+               nf = RREG32(mmPSOC_CPU_PLL_NF);
+               od = RREG32(mmPSOC_CPU_PLL_OD);
+       } else {
+               rc = hl_fw_cpucp_pll_info_get(hdev, cpucp_pll_cpu,
+                               cpucp_pll_div_factor_reg, &div_fctr);
+               rc |= hl_fw_cpucp_pll_info_get(hdev, cpucp_pll_cpu,
+                               cpucp_pll_div_sel_reg, &div_sel);
+               rc |= hl_fw_cpucp_pll_info_get(hdev, cpucp_pll_cpu,
+                               cpucp_pll_nr_reg, &nr);
+               rc |= hl_fw_cpucp_pll_info_get(hdev, cpucp_pll_cpu,
+                               cpucp_pll_nf_reg, &nf);
+               rc |= hl_fw_cpucp_pll_info_get(hdev, cpucp_pll_cpu,
+                               cpucp_pll_od_reg, &od);
+               if (rc)
+                       return rc;
+       }
 
        if (div_sel == DIV_SEL_REF_CLK || div_sel == DIV_SEL_DIVIDED_REF) {
                if (div_sel == DIV_SEL_REF_CLK)
@@ -706,6 +723,8 @@ static void gaudi_fetch_psoc_frequency(struct hl_device 
*hdev)
        prop->psoc_pci_pll_nf = nf;
        prop->psoc_pci_pll_od = od;
        prop->psoc_pci_pll_div_factor = div_fctr;
+
+       return 0;
 }
 
 static int _gaudi_init_tpc_mem(struct hl_device *hdev,
@@ -1319,7 +1338,11 @@ static int gaudi_late_init(struct hl_device *hdev)
 
        WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_INTS_REGISTER);
 
-       gaudi_fetch_psoc_frequency(hdev);
+       rc = gaudi_fetch_psoc_frequency(hdev);
+       if (rc) {
+               dev_err(hdev->dev, "Failed to fetch psoc frequency\n");
+               goto disable_pci_access;
+       }
 
        rc = gaudi_mmu_clear_pgt_range(hdev);
        if (rc) {
-- 
2.17.1

Reply via email to