1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2016 Google Inc. 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <errno.h> 9 #include <timer.h> 10 #include <asm/io.h> 11 #include <asm/arch/timer.h> 12 13 #define AST_TICK_TIMER 1 14 #define AST_TMC_RELOAD_VAL 0xffffffff 15 16 struct ast_timer_priv { 17 struct ast_timer *regs; 18 struct ast_timer_counter *tmc; 19 }; 20 21 static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer *timer, 22 int n) 23 { 24 if (n > 3) 25 return &timer->timers2[n - 4]; 26 else 27 return &timer->timers1[n - 1]; 28 } 29 30 static int ast_timer_probe(struct udevice *dev) 31 { 32 struct ast_timer_priv *priv = dev_get_priv(dev); 33 struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); 34 35 writel(AST_TMC_RELOAD_VAL, &priv->tmc->reload_val); 36 37 /* 38 * Stop the timer. This will also load reload_val into 39 * the status register. 40 */ 41 clrbits_le32(&priv->regs->ctrl1, 42 AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER)); 43 /* Start the timer from the fixed 1MHz clock. */ 44 setbits_le32(&priv->regs->ctrl1, 45 (AST_TMC_EN | AST_TMC_1MHZ) << 46 AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER)); 47 48 uc_priv->clock_rate = AST_TMC_RATE; 49 50 return 0; 51 } 52 53 static int ast_timer_get_count(struct udevice *dev, u64 *count) 54 { 55 struct ast_timer_priv *priv = dev_get_priv(dev); 56 57 *count = AST_TMC_RELOAD_VAL - readl(&priv->tmc->status); 58 59 return 0; 60 } 61 62 static int ast_timer_ofdata_to_platdata(struct udevice *dev) 63 { 64 struct ast_timer_priv *priv = dev_get_priv(dev); 65 66 priv->regs = devfdt_get_addr_ptr(dev); 67 if (IS_ERR(priv->regs)) 68 return PTR_ERR(priv->regs); 69 70 priv->tmc = ast_get_timer_counter(priv->regs, AST_TICK_TIMER); 71 72 return 0; 73 } 74 75 static const struct timer_ops ast_timer_ops = { 76 .get_count = ast_timer_get_count, 77 }; 78 79 static const struct udevice_id ast_timer_ids[] = { 80 { .compatible = "aspeed,ast2500-timer" }, 81 { .compatible = "aspeed,ast2400-timer" }, 82 { } 83 }; 84 85 U_BOOT_DRIVER(ast_timer) = { 86 .name = "ast_timer", 87 .id = UCLASS_TIMER, 88 .of_match = ast_timer_ids, 89 .probe = ast_timer_probe, 90 .priv_auto_alloc_size = sizeof(struct ast_timer_priv), 91 .ofdata_to_platdata = ast_timer_ofdata_to_platdata, 92 .ops = &ast_timer_ops, 93 .flags = DM_FLAG_PRE_RELOC, 94 }; 95