Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4835e3b8 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "clk: qcom: clk-debug: Fix clk measurement algorithm"

parents 65fdc492 8ea693da
Loading
Loading
Loading
Loading
+31 −19
Original line number Diff line number Diff line
@@ -22,10 +22,12 @@ static DEFINE_MUTEX(clk_debug_lock);

#define TCXO_DIV_4_HZ		4800000
#define SAMPLE_TICKS_1_MS	0x1000
#define SAMPLE_TICKS_14_MS	0x10000
#define SAMPLE_TICKS_27_MS	0x20000

#define XO_DIV4_CNT_DONE	BIT(25)
#define CNT_EN			BIT(20)
#define CLR_CNT			BIT(21)
#define XO_DIV4_TERM_CNT_MASK	GENMASK(19, 0)
#define MEASURE_CNT		GENMASK(24, 0)
#define CBCR_ENA		BIT(0)

@@ -35,19 +37,31 @@ static u32 run_measurement(unsigned int ticks, struct regmap *regmap,
{
	u32 regval;

	/* Stop counters and set the XO4 counter start value. */
	regmap_write(regmap, ctl_reg, ticks);
	/*
	 * Clear CNT_EN to bring it to good known state and
	 * set CLK_CNT to clear previous count.
	 */
	regmap_update_bits(regmap, ctl_reg, CNT_EN, 0x0);
	regmap_update_bits(regmap, ctl_reg, CLR_CNT, CLR_CNT);

	regmap_read(regmap, status_reg, &regval);
	/*
	 * Wait for timer to become ready
	 * Ideally SW should poll for MEASURE_CNT
	 * but since CLR_CNT is not available across targets
	 * add 1 us delay to let CNT clear /
	 * counter will clear within 3 reference cycle of 4.8 MHz.
	 */
	udelay(1);

	/* Wait for timer to become ready. */
	while ((regval & XO_DIV4_CNT_DONE) != 0) {
		cpu_relax();
		regmap_read(regmap, status_reg, &regval);
	}
	regmap_update_bits(regmap, ctl_reg, CLR_CNT, 0x0);

	/*
	 * Run measurement and wait for completion.
	 */
	regmap_update_bits(regmap, ctl_reg, XO_DIV4_TERM_CNT_MASK,
			   ticks & XO_DIV4_TERM_CNT_MASK);

	/* Run measurement and wait for completion. */
	regmap_write(regmap, ctl_reg, (CNT_EN|ticks));
	regmap_update_bits(regmap, ctl_reg, CNT_EN, CNT_EN);

	regmap_read(regmap, status_reg, &regval);

@@ -56,13 +70,11 @@ static u32 run_measurement(unsigned int ticks, struct regmap *regmap,
		regmap_read(regmap, status_reg, &regval);
	}

	/* Return measured ticks. */
	regmap_update_bits(regmap, ctl_reg, CNT_EN, 0x0);

	regmap_read(regmap, status_reg, &regval);
	regval &= MEASURE_CNT;

	/* Stop the counters */
	regmap_write(regmap, ctl_reg, ticks);

	return regval;
}

@@ -98,8 +110,8 @@ static unsigned long clk_debug_mux_measure_rate(struct clk_hw *hw)
	raw_count_short = run_measurement(SAMPLE_TICKS_1_MS, meas->regmap,
				data->ctl_reg, data->status_reg);

	/* Run a full measurement. (~14 ms) */
	raw_count_full = run_measurement(SAMPLE_TICKS_14_MS, meas->regmap,
	/* Run a full measurement. (~27ms) */
	raw_count_full = run_measurement(SAMPLE_TICKS_27_MS, meas->regmap,
				data->ctl_reg, data->status_reg);

	gcc_xo4_reg &= ~BIT(0);
@@ -111,7 +123,7 @@ static unsigned long clk_debug_mux_measure_rate(struct clk_hw *hw)
	else {
		/* Compute rate in Hz. */
		raw_count_full = ((raw_count_full * 10) + 15) * TCXO_DIV_4_HZ;
		do_div(raw_count_full, ((SAMPLE_TICKS_14_MS * 10) + 35));
		do_div(raw_count_full, ((SAMPLE_TICKS_27_MS * 10) + 35));
		ret = (raw_count_full * multiplier);
	}