Commit f5076f869855045e527de7f1367c65f55a2b1448

Authored by rick
Committed by Andes
1 parent 86132af799

nds32: Support AG101P timer DM.

Support AG101P timer device tree flow.

Signed-off-by: rick <rick@andestech.com>

Showing 6 changed files with 141 additions and 1 deletions Side-by-side Diff

arch/nds32/cpu/n1213/ag101/timer.c
... ... @@ -8,7 +8,7 @@
8 8 *
9 9 * SPDX-License-Identifier: GPL-2.0+
10 10 */
11   -
  11 +#ifndef CONFIG_TIMER
12 12 #include <common.h>
13 13 #include <asm/io.h>
14 14 #include <faraday/fttmr010.h>
... ... @@ -189,4 +189,5 @@
189 189 return CONFIG_SYS_CLK_FREQ;
190 190 #endif
191 191 }
  192 +#endif /* CONFIG_TIMER */
arch/nds32/dts/ag101p.dts
... ... @@ -13,6 +13,7 @@
13 13 /* bootargs = "console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0x99600000 debug bootmem_debug memblock=debug loglevel=7"; */
14 14 bootargs = "console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0x99600000 debug loglevel=7";
15 15 stdout-path = "uart0:38400n8";
  16 + tick-timer = &timer0;
16 17 };
17 18  
18 19 memory@0 {
... ... @@ -44,6 +45,13 @@
44 45 clock-frequency = <14745600>;
45 46 reg-shift = <2>;
46 47 no-loopback-test = <1>;
  48 + };
  49 +
  50 + timer0: timer@98400000 {
  51 + compatible = "andestech,attmr010";
  52 + reg = <0x98400000 0x1000>;
  53 + interrupts = <19 4>;
  54 + clock-frequency = <15000000>;
47 55 };
48 56  
49 57 };
configs/adp-ag101p_defconfig
... ... @@ -18,4 +18,6 @@
18 18 CONFIG_DM=y
19 19 CONFIG_DM_SERIAL=y
20 20 CONFIG_SYS_NS16550=y
  21 +CONFIG_TIMER=y
  22 +CONFIG_AG101P_TIMER=y
drivers/timer/Kconfig
... ... @@ -74,5 +74,11 @@
74 74 usually at least one of them exists. Either of them is supported
75 75 in U-Boot.
76 76  
  77 +config AG101P_TIMER
  78 + bool "Ag101p timer support"
  79 + depends on TIMER
  80 + help
  81 + Select this to enable a timer for Ag101p devices.
  82 +
77 83 endmenu
drivers/timer/Makefile
... ... @@ -12,4 +12,5 @@
12 12 obj-$(CONFIG_AST_TIMER) += ast_timer.o
13 13 obj-$(CONFIG_STI_TIMER) += sti-timer.o
14 14 obj-$(CONFIG_ARC_TIMER) += arc_timer.o
  15 +obj-$(CONFIG_AG101P_TIMER) += ag101p_timer.o
drivers/timer/ag101p_timer.c
  1 +/*
  2 + * Andestech ATFTMR010 timer driver
  3 + *
  4 + * (C) Copyright 2016
  5 + * Rick Chen, NDS32 Software Engineering, rick@andestech.com
  6 + *
  7 + * SPDX-License-Identifier: GPL-2.0+
  8 + */
  9 +#include <common.h>
  10 +#include <dm.h>
  11 +#include <errno.h>
  12 +#include <timer.h>
  13 +#include <linux/io.h>
  14 +
  15 +DECLARE_GLOBAL_DATA_PTR;
  16 +
  17 +/*
  18 + * Timer Control Register
  19 + */
  20 +#define T3_UPDOWN (1 << 11)
  21 +#define T2_UPDOWN (1 << 10)
  22 +#define T1_UPDOWN (1 << 9)
  23 +#define T3_OFENABLE (1 << 8)
  24 +#define T3_CLOCK (1 << 7)
  25 +#define T3_ENABLE (1 << 6)
  26 +#define T2_OFENABLE (1 << 5)
  27 +#define T2_CLOCK (1 << 4)
  28 +#define T2_ENABLE (1 << 3)
  29 +#define T1_OFENABLE (1 << 2)
  30 +#define T1_CLOCK (1 << 1)
  31 +#define T1_ENABLE (1 << 0)
  32 +
  33 +/*
  34 + * Timer Interrupt State & Mask Registers
  35 + */
  36 +#define T3_OVERFLOW (1 << 8)
  37 +#define T3_MATCH2 (1 << 7)
  38 +#define T3_MATCH1 (1 << 6)
  39 +#define T2_OVERFLOW (1 << 5)
  40 +#define T2_MATCH2 (1 << 4)
  41 +#define T2_MATCH1 (1 << 3)
  42 +#define T1_OVERFLOW (1 << 2)
  43 +#define T1_MATCH2 (1 << 1)
  44 +#define T1_MATCH1 (1 << 0)
  45 +
  46 +struct atftmr_timer_regs {
  47 + u32 t1_counter; /* 0x00 */
  48 + u32 t1_load; /* 0x04 */
  49 + u32 t1_match1; /* 0x08 */
  50 + u32 t1_match2; /* 0x0c */
  51 + u32 t2_counter; /* 0x10 */
  52 + u32 t2_load; /* 0x14 */
  53 + u32 t2_match1; /* 0x18 */
  54 + u32 t2_match2; /* 0x1c */
  55 + u32 t3_counter; /* 0x20 */
  56 + u32 t3_load; /* 0x24 */
  57 + u32 t3_match1; /* 0x28 */
  58 + u32 t3_match2; /* 0x2c */
  59 + u32 cr; /* 0x30 */
  60 + u32 int_state; /* 0x34 */
  61 + u32 int_mask; /* 0x38 */
  62 +};
  63 +
  64 +struct atftmr_timer_platdata {
  65 + struct atftmr_timer_regs *regs;
  66 +};
  67 +
  68 +static int atftmr_timer_get_count(struct udevice *dev, u64 *count)
  69 +{
  70 + struct atftmr_timer_platdata *plat = dev->platdata;
  71 + struct atftmr_timer_regs *const regs = plat->regs;
  72 + u32 val;
  73 + val = readl(&regs->t3_counter);
  74 + *count = timer_conv_64(val);
  75 + return 0;
  76 +}
  77 +
  78 +static int atftmr_timer_probe(struct udevice *dev)
  79 +{
  80 + struct atftmr_timer_platdata *plat = dev->platdata;
  81 + struct atftmr_timer_regs *const regs = plat->regs;
  82 + u32 cr;
  83 + writel(0, &regs->t3_load);
  84 + writel(0, &regs->t3_counter);
  85 + writel(TIMER_LOAD_VAL, &regs->t3_match1);
  86 + writel(TIMER_LOAD_VAL, &regs->t3_match2);
  87 + /* disable interrupts */
  88 + writel(T3_MATCH1|T3_MATCH2|T3_OVERFLOW , &regs->int_mask);
  89 + cr = readl(&regs->cr);
  90 + cr |= (T3_ENABLE|T3_UPDOWN);
  91 + writel(cr, &regs->cr);
  92 + return 0;
  93 +}
  94 +
  95 +static int atftme_timer_ofdata_to_platdata(struct udevice *dev)
  96 +{
  97 + struct atftmr_timer_platdata *plat = dev_get_platdata(dev);
  98 + plat->regs = map_physmem(dev_get_addr(dev),
  99 + sizeof(struct atftmr_timer_regs),
  100 + MAP_NOCACHE);
  101 + return 0;
  102 +}
  103 +
  104 +static const struct timer_ops ag101p_timer_ops = {
  105 + .get_count = atftmr_timer_get_count,
  106 +};
  107 +
  108 +static const struct udevice_id ag101p_timer_ids[] = {
  109 + { .compatible = "andestech,attmr010" },
  110 + {}
  111 +};
  112 +
  113 +U_BOOT_DRIVER(altera_timer) = {
  114 + .name = "ag101p_timer",
  115 + .id = UCLASS_TIMER,
  116 + .of_match = ag101p_timer_ids,
  117 + .ofdata_to_platdata = atftme_timer_ofdata_to_platdata,
  118 + .platdata_auto_alloc_size = sizeof(struct atftmr_timer_platdata),
  119 + .probe = atftmr_timer_probe,
  120 + .ops = &ag101p_timer_ops,
  121 + .flags = DM_FLAG_PRE_RELOC,
  122 +};