1 /*
2  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 
9 #include <drivers/delay_timer.h>
10 #include <lib/mmio.h>
11 
12 #include <imx_gpt.h>
13 
14 #define GPTCR_SWR		BIT(15)		/* Software reset */
15 #define GPTCR_24MEN		BIT(10)		/* Enable 24MHz clock input */
16 #define GPTCR_CLKSOURCE_OSC	(5 << 6)        /* Clock source OSC */
17 #define GPTCR_CLKSOURCE_MASK	(0x7 << 6)
18 #define GPTCR_TEN		1		/* Timer enable */
19 
20 #define GPTPR_PRESCL_24M_SHIFT 12
21 
22 #define SYS_COUNTER_FREQ_IN_MHZ 3
23 
24 #define GPTPR_TIMER_CTRL	(imx_base_addr + 0x000)
25 #define GPTPR_TIMER_PRESCL	(imx_base_addr + 0x004)
26 #define GPTPR_TIMER_CNTR	(imx_base_addr + 0x024)
27 
28 static uintptr_t imx_base_addr;
29 
imx_get_timer_value(void)30 uint32_t imx_get_timer_value(void)
31 {
32 	return ~mmio_read_32(GPTPR_TIMER_CNTR);
33 }
34 
35 static const timer_ops_t imx_gpt_ops = {
36 	.get_timer_value	= imx_get_timer_value,
37 	.clk_mult		= 1,
38 	.clk_div		= SYS_COUNTER_FREQ_IN_MHZ,
39 };
40 
imx_gpt_ops_init(uintptr_t base_addr)41 void imx_gpt_ops_init(uintptr_t base_addr)
42 {
43 	int val;
44 
45 	assert(base_addr != 0);
46 
47 	imx_base_addr = base_addr;
48 
49 	/* setup GP Timer */
50 	mmio_write_32(GPTPR_TIMER_CTRL, GPTCR_SWR);
51 	mmio_write_32(GPTPR_TIMER_CTRL, 0);
52 
53 	/* get 3MHz from 24MHz */
54 	mmio_write_32(GPTPR_TIMER_PRESCL, (7 << GPTPR_PRESCL_24M_SHIFT));
55 
56 	val = mmio_read_32(GPTPR_TIMER_CTRL);
57 	val &= ~GPTCR_CLKSOURCE_MASK;
58 	val |= GPTCR_24MEN | GPTCR_CLKSOURCE_OSC | GPTCR_TEN;
59 	mmio_write_32(GPTPR_TIMER_CTRL, val);
60 
61 	timer_init(&imx_gpt_ops);
62 }
63