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