1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2018 Xilinx, Inc. (Michal Simek) 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <errno.h> 9 #include <timer.h> 10 #include <asm/io.h> 11 12 #define CNT_CNTRL_RESET BIT(4) 13 14 struct cadence_ttc_regs { 15 u32 clk_cntrl1; /* 0x0 - Clock Control 1 */ 16 u32 clk_cntrl2; /* 0x4 - Clock Control 2 */ 17 u32 clk_cntrl3; /* 0x8 - Clock Control 3 */ 18 u32 counter_cntrl1; /* 0xC - Counter Control 1 */ 19 u32 counter_cntrl2; /* 0x10 - Counter Control 2 */ 20 u32 counter_cntrl3; /* 0x14 - Counter Control 3 */ 21 u32 counter_val1; /* 0x18 - Counter Control 1 */ 22 u32 counter_val2; /* 0x1C - Counter Control 2 */ 23 u32 counter_val3; /* 0x20 - Counter Control 3 */ 24 u32 reserved[15]; 25 u32 interrupt_enable1; /* 0x60 - Interrupt Enable 1 */ 26 u32 interrupt_enable2; /* 0x64 - Interrupt Enable 2 */ 27 u32 interrupt_enable3; /* 0x68 - Interrupt Enable 3 */ 28 }; 29 30 struct cadence_ttc_priv { 31 struct cadence_ttc_regs *regs; 32 }; 33 34 static int cadence_ttc_get_count(struct udevice *dev, u64 *count) 35 { 36 struct cadence_ttc_priv *priv = dev_get_priv(dev); 37 38 *count = readl(&priv->regs->counter_val1); 39 40 return 0; 41 } 42 43 static int cadence_ttc_probe(struct udevice *dev) 44 { 45 struct cadence_ttc_priv *priv = dev_get_priv(dev); 46 47 /* Disable interrupts for sure */ 48 writel(0, &priv->regs->interrupt_enable1); 49 writel(0, &priv->regs->interrupt_enable2); 50 writel(0, &priv->regs->interrupt_enable3); 51 52 /* Make sure that clocks are configured properly without prescaller */ 53 writel(0, &priv->regs->clk_cntrl1); 54 writel(0, &priv->regs->clk_cntrl2); 55 writel(0, &priv->regs->clk_cntrl3); 56 57 /* Reset and enable this counter */ 58 writel(CNT_CNTRL_RESET, &priv->regs->counter_cntrl1); 59 60 return 0; 61 } 62 63 static int cadence_ttc_ofdata_to_platdata(struct udevice *dev) 64 { 65 struct cadence_ttc_priv *priv = dev_get_priv(dev); 66 67 priv->regs = map_physmem(dev_read_addr(dev), 68 sizeof(struct cadence_ttc_regs), MAP_NOCACHE); 69 if (IS_ERR(priv->regs)) 70 return PTR_ERR(priv->regs); 71 72 return 0; 73 } 74 75 static const struct timer_ops cadence_ttc_ops = { 76 .get_count = cadence_ttc_get_count, 77 }; 78 79 static const struct udevice_id cadence_ttc_ids[] = { 80 { .compatible = "cdns,ttc" }, 81 {} 82 }; 83 84 U_BOOT_DRIVER(cadence_ttc) = { 85 .name = "cadence_ttc", 86 .id = UCLASS_TIMER, 87 .of_match = cadence_ttc_ids, 88 .ofdata_to_platdata = cadence_ttc_ofdata_to_platdata, 89 .priv_auto_alloc_size = sizeof(struct cadence_ttc_priv), 90 .probe = cadence_ttc_probe, 91 .ops = &cadence_ttc_ops, 92 .flags = DM_FLAG_PRE_RELOC, 93 }; 94