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