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