Commit e8edded6 authored by Adam Aharon's avatar Adam Aharon Committed by Oded Gabbay
Browse files

habanalabs: calculate trace frequency from PLL



The profiler needs to know the PLL values for correctly showing the
profiling data. Because our firmware can use different PLL configurations,
we need to read the PLL values from the ASIC to pass them to the profiler.

Signed-off-by: default avatarAdam Aharon <aaharon@habana.ai>
Reviewed-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
parent 6ced9117
Loading
Loading
Loading
Loading
+29 −4
Original line number Diff line number Diff line
@@ -555,11 +555,36 @@ static int gaudi_early_fini(struct hl_device *hdev)
static void 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);

	if (div_sel == DIV_SEL_REF_CLK || div_sel == DIV_SEL_DIVIDED_REF) {
		if (div_sel == DIV_SEL_REF_CLK)
			trace_freq = PLL_REF_CLK;
		else
			trace_freq = PLL_REF_CLK / (div_fctr + 1);
	} else if (div_sel == DIV_SEL_PLL_CLK ||
					div_sel == DIV_SEL_DIVIDED_PLL) {
		pll_clk = PLL_REF_CLK * (nf + 1) / ((nr + 1) * (od + 1));
		if (div_sel == DIV_SEL_PLL_CLK)
			trace_freq = pll_clk;
		else
			trace_freq = pll_clk / (div_fctr + 1);
	} else {
		dev_warn(hdev->dev,
			"Received invalid div select value: %d", div_sel);
	}

	prop->psoc_pci_pll_nr = RREG32(mmPSOC_PCI_PLL_NR);
	prop->psoc_pci_pll_nf = RREG32(mmPSOC_PCI_PLL_NF);
	prop->psoc_pci_pll_od = RREG32(mmPSOC_PCI_PLL_OD);
	prop->psoc_pci_pll_div_factor = RREG32(mmPSOC_PCI_PLL_DIV_FACTOR_1);
	prop->psoc_timestamp_frequency = trace_freq;
	prop->psoc_pci_pll_nr = nr;
	prop->psoc_pci_pll_nf = nf;
	prop->psoc_pci_pll_od = od;
	prop->psoc_pci_pll_div_factor = div_fctr;
}

static int _gaudi_init_tpc_mem(struct hl_device *hdev,
+5 −1
Original line number Diff line number Diff line
@@ -392,6 +392,7 @@ static int gaudi_config_stm(struct hl_device *hdev,
{
	struct hl_debug_params_stm *input;
	u64 base_reg;
	u32 frequency;
	int rc;

	if (params->reg_idx >= ARRAY_SIZE(debug_stm_regs)) {
@@ -420,7 +421,10 @@ static int gaudi_config_stm(struct hl_device *hdev,
		WREG32(base_reg + 0xE00, lower_32_bits(input->sp_mask));
		WREG32(base_reg + 0xEF4, input->id);
		WREG32(base_reg + 0xDF4, 0x80);
		WREG32(base_reg + 0xE8C, input->frequency);
		frequency = hdev->asic_prop.psoc_timestamp_frequency;
		if (frequency == 0)
			frequency = input->frequency;
		WREG32(base_reg + 0xE8C, frequency);
		WREG32(base_reg + 0xE90, 0x7FF);

		/* SW-2176 - SW WA for HW bug */
+29 −4
Original line number Diff line number Diff line
@@ -594,11 +594,36 @@ static void goya_qman0_set_security(struct hl_device *hdev, bool secure)
static void goya_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_PCI_PLL_DIV_FACTOR_1);
	u32 div_sel = RREG32(mmPSOC_PCI_PLL_DIV_SEL_1);
	u32 nr = RREG32(mmPSOC_PCI_PLL_NR);
	u32 nf = RREG32(mmPSOC_PCI_PLL_NF);
	u32 od = RREG32(mmPSOC_PCI_PLL_OD);

	if (div_sel == DIV_SEL_REF_CLK || div_sel == DIV_SEL_DIVIDED_REF) {
		if (div_sel == DIV_SEL_REF_CLK)
			trace_freq = PLL_REF_CLK;
		else
			trace_freq = PLL_REF_CLK / (div_fctr + 1);
	} else if (div_sel == DIV_SEL_PLL_CLK ||
					div_sel == DIV_SEL_DIVIDED_PLL) {
		pll_clk = PLL_REF_CLK * (nf + 1) / ((nr + 1) * (od + 1));
		if (div_sel == DIV_SEL_PLL_CLK)
			trace_freq = pll_clk;
		else
			trace_freq = pll_clk / (div_fctr + 1);
	} else {
		dev_warn(hdev->dev,
			"Received invalid div select value: %d", div_sel);
	}

	prop->psoc_pci_pll_nr = RREG32(mmPSOC_PCI_PLL_NR);
	prop->psoc_pci_pll_nf = RREG32(mmPSOC_PCI_PLL_NF);
	prop->psoc_pci_pll_od = RREG32(mmPSOC_PCI_PLL_OD);
	prop->psoc_pci_pll_div_factor = RREG32(mmPSOC_PCI_PLL_DIV_FACTOR_1);
	prop->psoc_timestamp_frequency = trace_freq;
	prop->psoc_pci_pll_nr = nr;
	prop->psoc_pci_pll_nf = nf;
	prop->psoc_pci_pll_od = od;
	prop->psoc_pci_pll_div_factor = div_fctr;
}

int goya_late_init(struct hl_device *hdev)
+5 −1
Original line number Diff line number Diff line
@@ -232,6 +232,7 @@ static int goya_config_stm(struct hl_device *hdev,
{
	struct hl_debug_params_stm *input;
	u64 base_reg;
	u32 frequency;
	int rc;

	if (params->reg_idx >= ARRAY_SIZE(debug_stm_regs)) {
@@ -264,7 +265,10 @@ static int goya_config_stm(struct hl_device *hdev,
		WREG32(base_reg + 0xE20, 0xFFFFFFFF);
		WREG32(base_reg + 0xEF4, input->id);
		WREG32(base_reg + 0xDF4, 0x80);
		WREG32(base_reg + 0xE8C, input->frequency);
		frequency = hdev->asic_prop.psoc_timestamp_frequency;
		if (frequency == 0)
			frequency = input->frequency;
		WREG32(base_reg + 0xE8C, frequency);
		WREG32(base_reg + 0xE90, 0x7FF);
		WREG32(base_reg + 0xE80, 0x27 | (input->id << 16));
	} else {
+11 −0
Original line number Diff line number Diff line
@@ -247,6 +247,7 @@ struct hl_mmu_properties {
 * @psoc_pci_pll_nf: PCI PLL NF value.
 * @psoc_pci_pll_od: PCI PLL OD value.
 * @psoc_pci_pll_div_factor: PCI PLL DIV FACTOR 1 value.
 * @psoc_timestamp_frequency: frequency of the psoc timestamp clock.
 * @high_pll: high PLL frequency used by the device.
 * @cb_pool_cb_cnt: number of CBs in the CB pool.
 * @cb_pool_cb_size: size of each CB in the CB pool.
@@ -291,6 +292,7 @@ struct asic_fixed_properties {
	u32				psoc_pci_pll_nf;
	u32				psoc_pci_pll_od;
	u32				psoc_pci_pll_div_factor;
	u32				psoc_timestamp_frequency;
	u32				high_pll;
	u32				cb_pool_cb_cnt;
	u32				cb_pool_cb_size;
@@ -533,6 +535,15 @@ enum hl_pll_frequency {
	PLL_LAST
};

#define PLL_REF_CLK 50

enum div_select_defs {
	DIV_SEL_REF_CLK = 0,
	DIV_SEL_PLL_CLK = 1,
	DIV_SEL_DIVIDED_REF = 2,
	DIV_SEL_DIVIDED_PLL = 3,
};

/**
 * struct hl_asic_funcs - ASIC specific functions that are can be called from
 *                        common code.
Loading