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 Parkuint32_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 Parkvoid 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