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