"Das U-Boot" Source Tree
at master 137 lines 2.7 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved 4 * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. 5 */ 6 7#define LOG_CATEGORY UCLASS_TIMER 8 9#include <config.h> 10#include <clk.h> 11#include <dm.h> 12#include <fdtdec.h> 13#include <timer.h> 14#include <dm/device_compat.h> 15#include <linux/bitops.h> 16 17#include <asm/io.h> 18 19/* Timer control1 register */ 20#define CR1_CEN BIT(0) 21#define CR1_ARPE BIT(7) 22 23/* Event Generation Register register */ 24#define EGR_UG BIT(0) 25 26/* Auto reload register for free running config */ 27#define GPT_FREE_RUNNING 0xFFFFFFFF 28 29struct stm32_timer_regs { 30 u32 cr1; 31 u32 cr2; 32 u32 smcr; 33 u32 dier; 34 u32 sr; 35 u32 egr; 36 u32 ccmr1; 37 u32 ccmr2; 38 u32 ccer; 39 u32 cnt; 40 u32 psc; 41 u32 arr; 42 u32 reserved; 43 u32 ccr1; 44 u32 ccr2; 45 u32 ccr3; 46 u32 ccr4; 47 u32 reserved1; 48 u32 dcr; 49 u32 dmar; 50 u32 tim2_5_or; 51}; 52 53struct stm32_timer_priv { 54 struct stm32_timer_regs *base; 55}; 56 57static u64 stm32_timer_get_count(struct udevice *dev) 58{ 59 struct stm32_timer_priv *priv = dev_get_priv(dev); 60 struct stm32_timer_regs *regs = priv->base; 61 62 return readl(&regs->cnt); 63} 64 65static int stm32_timer_probe(struct udevice *dev) 66{ 67 struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); 68 struct stm32_timer_priv *priv = dev_get_priv(dev); 69 struct stm32_timer_regs *regs; 70 struct clk clk; 71 fdt_addr_t addr; 72 int ret; 73 u32 rate, psc; 74 75 addr = dev_read_addr(dev); 76 if (addr == FDT_ADDR_T_NONE) 77 return -EINVAL; 78 79 priv->base = (struct stm32_timer_regs *)addr; 80 81 ret = clk_get_by_index(dev, 0, &clk); 82 if (ret < 0) 83 return ret; 84 85 ret = clk_enable(&clk); 86 if (ret) { 87 dev_err(dev, "failed to enable clock\n"); 88 return ret; 89 } 90 91 regs = priv->base; 92 93 /* Stop the timer */ 94 clrbits_le32(&regs->cr1, CR1_CEN); 95 96 /* get timer clock */ 97 rate = clk_get_rate(&clk); 98 99 /* we set timer prescaler to obtain a 1MHz timer counter frequency */ 100 psc = (rate / CFG_SYS_HZ_CLOCK) - 1; 101 writel(psc, &regs->psc); 102 103 /* Set timer frequency to 1MHz */ 104 uc_priv->clock_rate = CFG_SYS_HZ_CLOCK; 105 106 /* Configure timer for auto-reload */ 107 setbits_le32(&regs->cr1, CR1_ARPE); 108 109 /* load value for auto reload */ 110 writel(GPT_FREE_RUNNING, &regs->arr); 111 112 /* start timer */ 113 setbits_le32(&regs->cr1, CR1_CEN); 114 115 /* Update generation */ 116 setbits_le32(&regs->egr, EGR_UG); 117 118 return 0; 119} 120 121static const struct timer_ops stm32_timer_ops = { 122 .get_count = stm32_timer_get_count, 123}; 124 125static const struct udevice_id stm32_timer_ids[] = { 126 { .compatible = "st,stm32-timer" }, 127 {} 128}; 129 130U_BOOT_DRIVER(stm32_timer) = { 131 .name = "stm32_timer", 132 .id = UCLASS_TIMER, 133 .of_match = stm32_timer_ids, 134 .priv_auto = sizeof(struct stm32_timer_priv), 135 .probe = stm32_timer_probe, 136 .ops = &stm32_timer_ops, 137};