1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2017 Microchip Corporation 4 * Wenyou.Yang <wenyou.yang@microchip.com> 5 */ 6 7 #include <common.h> 8 #include <clk.h> 9 #include <dm.h> 10 #include <timer.h> 11 #include <asm/io.h> 12 13 #define AT91_PIT_VALUE 0xfffff 14 #define AT91_PIT_PITEN BIT(24) /* Timer Enabled */ 15 16 struct atmel_pit_regs { 17 u32 mode; 18 u32 status; 19 u32 value; 20 u32 value_image; 21 }; 22 23 struct atmel_pit_platdata { 24 struct atmel_pit_regs *regs; 25 }; 26 27 static int atmel_pit_get_count(struct udevice *dev, u64 *count) 28 { 29 struct atmel_pit_platdata *plat = dev_get_platdata(dev); 30 struct atmel_pit_regs *const regs = plat->regs; 31 u32 val = readl(®s->value_image); 32 33 *count = timer_conv_64(val); 34 35 return 0; 36 } 37 38 static int atmel_pit_probe(struct udevice *dev) 39 { 40 struct atmel_pit_platdata *plat = dev_get_platdata(dev); 41 struct atmel_pit_regs *const regs = plat->regs; 42 struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); 43 struct clk clk; 44 ulong clk_rate; 45 int ret; 46 47 ret = clk_get_by_index(dev, 0, &clk); 48 if (ret) 49 return -EINVAL; 50 51 clk_rate = clk_get_rate(&clk); 52 if (!clk_rate) 53 return -EINVAL; 54 55 uc_priv->clock_rate = clk_rate / 16; 56 57 writel(AT91_PIT_VALUE | AT91_PIT_PITEN, ®s->mode); 58 59 return 0; 60 } 61 62 static int atmel_pit_ofdata_to_platdata(struct udevice *dev) 63 { 64 struct atmel_pit_platdata *plat = dev_get_platdata(dev); 65 66 plat->regs = (struct atmel_pit_regs *)devfdt_get_addr_ptr(dev); 67 68 return 0; 69 } 70 71 static const struct timer_ops atmel_pit_ops = { 72 .get_count = atmel_pit_get_count, 73 }; 74 75 static const struct udevice_id atmel_pit_ids[] = { 76 { .compatible = "atmel,at91sam9260-pit" }, 77 { } 78 }; 79 80 U_BOOT_DRIVER(atmel_pit) = { 81 .name = "atmel_pit", 82 .id = UCLASS_TIMER, 83 .of_match = atmel_pit_ids, 84 .ofdata_to_platdata = atmel_pit_ofdata_to_platdata, 85 .platdata_auto_alloc_size = sizeof(struct atmel_pit_platdata), 86 .probe = atmel_pit_probe, 87 .ops = &atmel_pit_ops, 88 .flags = DM_FLAG_PRE_RELOC, 89 }; 90