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