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

Commit 65d2cda1 authored by Banajit Goswami's avatar Banajit Goswami
Browse files

soc: avtimer: add support for decimal value MHz clock



Add support for clocks which has a decimal MHz frequency (e.g. 19.2MHz).
The support is added in such a way that this will avoid the need of
having a floating point operation to get the msec count from the
number of clock ticks.

Change-Id: Iee57a5b67139150a1ffb86e580d8a90e032a894f
Signed-off-by: default avatarBanajit Goswami <bgoswami@codeaurora.org>
parent 7a72141b
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -13,8 +13,16 @@ Required properties:
- compatible : Must be "qcom,avtimer"

Optional properties:
- clk-div : The clk is at 27MHz and hence ticks are to be
 divided by 27 to achive the msec value.
- clk-div : Divisor to divide the ticks value to get msec value.
 If the clock is at 27MHz, the ticks value read from AVTimer
 registers will have to be divided by 27, to achieve the msec value.
- clk-mult : Multiplier to multiply the ticks value in order to avoid
 a floating point operation if the clock is of decimal value.
 E.g. To get msec out of ticks from a 19.2MHz clock source, the ticks
 value will have to be divided by 19.2, which will then become a
 floating point operation. However, to avoid using a floating point
 operation, the msec can be calculated by multiplying ticks with 10
 and dividing the result by 192. i.e. msec = (ticks * 10) / 192;

Example:
	qcom,avtimer@90f7000 {
@@ -23,4 +31,5 @@ Example:
		      <0x90f7010 0x4>;
		reg-names = "avtimer_lsb_addr", "avtimer_msb_addr";
		qcom,clk-div = <27>;
		qcom,clk-mult = <10>;
	};
+15 −7
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ struct avtimer_t {
	void __iomem *p_avtimer_msw;
	void __iomem *p_avtimer_lsw;
	uint32_t clk_div;
	uint32_t clk_mult;
	atomic_t adsp_ready;
	int num_retries;
};
@@ -292,7 +293,6 @@ static void reset_work(struct work_struct *work)
int avcs_core_query_timer(uint64_t *avtimer_tick)
{
	uint32_t avtimer_msw = 0, avtimer_lsw = 0;
	uint32_t res = 0;
	uint64_t avtimer_tick_temp;

	if (!atomic_read(&avtimer.adsp_ready)) {
@@ -302,13 +302,13 @@ int avcs_core_query_timer(uint64_t *avtimer_tick)
	avtimer_lsw = ioread32(avtimer.p_avtimer_lsw);
	avtimer_msw = ioread32(avtimer.p_avtimer_msw);

	avtimer_tick_temp =
		(uint64_t)((uint64_t)avtimer_msw << 32)
	avtimer_tick_temp = (uint64_t)((uint64_t)avtimer_msw << 32)
			    | avtimer_lsw;
	res = do_div(avtimer_tick_temp, avtimer.clk_div);
	*avtimer_tick = avtimer_tick_temp;
	*avtimer_tick = mul_u64_u32_div(avtimer_tick_temp, avtimer.clk_mult,
					avtimer.clk_div);
	pr_debug_ratelimited("%s:Avtimer: msw: %u, lsw: %u, tick: %llu\n",
			__func__,
			avtimer_msw, avtimer_lsw, *avtimer_tick);
	return 0;
}
EXPORT_SYMBOL(avcs_core_query_timer);
@@ -374,6 +374,7 @@ static int dev_avtimer_probe(struct platform_device *pdev)
	struct device *device_handle;
	struct resource *reg_lsb = NULL, *reg_msb = NULL;
	uint32_t clk_div_val;
	uint32_t clk_mult_val;

	if (!pdev) {
		pr_err("%s: Invalid params\n", __func__);
@@ -462,7 +463,14 @@ static int dev_avtimer_probe(struct platform_device *pdev)
	else
		avtimer.clk_div = clk_div_val;

	pr_debug("avtimer.clk_div = %d\n", avtimer.clk_div);
	if (of_property_read_u32(pdev->dev.of_node,
			"qcom,clk-mult", &clk_mult_val))
		avtimer.clk_mult = 1;
	else
		avtimer.clk_mult = clk_mult_val;

	pr_debug("%s: avtimer.clk_div = %d, avtimer.clk_mult = %d\n",
		 __func__, avtimer.clk_div, avtimer.clk_mult);
	return 0;

class_destroy: