From 6e03387da26ffb470c159bb8ed53f86b0434dc81 Mon Sep 17 00:00:00 2001 From: Zhangfei Gao Date: Sat, 16 Feb 2013 10:07:15 +0800 Subject: dma bug fix, still have issue --- arch/arm/boot/dts/hi3620.dtsi | 168 +++++++++++++++++----------- arch/arm/boot/dts/hi4511.dts | 41 +++---- arch/arm/common/timer-sp.c | 1 + arch/arm/kernel/smp_twd.c | 4 +- arch/arm/mach-hs/Makefile | 2 +- arch/arm/mach-hs/hs-dt.c | 50 +++++++++ arch/arm/mach-hs/localtimer.c | 252 ++++++++++++++++++++++++++++++++++++++++++ arch/arm/mm/init.c | 1 + drivers/clk/clk-fixed-rate.c | 1 + drivers/clk/clkdev.c | 3 +- drivers/dma/k3dma.c | 69 ++++++++++-- init/main.c | 1 + kernel/time/clockevents.c | 1 + 13 files changed, 502 insertions(+), 92 deletions(-) create mode 100644 arch/arm/mach-hs/localtimer.c diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi index d27827d8d496..b243ff097b66 100644 --- a/arch/arm/boot/dts/hi3620.dtsi +++ b/arch/arm/boot/dts/hi3620.dtsi @@ -17,6 +17,81 @@ serial1 = &uart1; }; + intc: interrupt-controller@fc001000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + /* gic dist base, gic cpu base */ + reg = <0xfc001000 0x1000>, <0xfc000100 0x100>; + }; + + sysctrl@fc802000 { + compatible = "hisilicon,sysctrl"; + reg = <0xfc802000 0x1000>; + smp_reg = <0x31c>; + reboot_reg = <0x4>; + }; + + l2: l2-cache { + compatible = "arm,pl310-cache"; + reg = <0xfc100000 0x100000>; + interrupts = <0 15 4>; + cache-unified; + cache-level = <2>; + hisilicon,l2cache-aux = <0x30070000 0xf00f0000>; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + device_type = "soc"; + interrupt-parent = <&intc>; + ranges; + + i2c0: i2c@fcb08000 { + compatible = "hisilicon,designware-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfcb08000 0x1000>; + interrupts = <0 28 4>; + clocks = <&clk_i2c0>; + dmas = <&dma0 18 /* read channel */ + &dma0 19>; /* write channel */ + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c1: i2c@fcb09000 { + compatible = "hisilicon,designware-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfcb09000 0x1000>; + interrupts = <0 29 4>; + clocks = <&clk_i2c1>; + dmas = <&dma0 20 /* read channel */ + &dma0 21>; /* write channel */ + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c2: i2c@fcb0c000 { + compatible = "hisilicon,designware-i2c"; + reg = <0xfcb0c000 0x1000>; + interrupts = <0 62 4>; + clocks = <&clk_i2c2>; + status = "disabled"; + }; + + i2c3: i2c@fcb0d000 { + compatible = "hisilicon,designware-i2c"; + reg = <0xfcb0d000 0x1000>; + interrupts = <0 63 4>; + clocks = <&clk_i2c3>; + status = "disabled"; + }; + amba { #address-cells = <1>; #size-cells = <1>; @@ -24,6 +99,14 @@ interrupt-parent = <&intc>; ranges; + timer@fc000600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0xfc000600 0x20>; + interrupts = <1 13 0xf01>; + clocks = <&armpll0>; + //clocks = <&smp_twd>; + }; + pmctrl: pmctrl@fca08000 { compatible = "hisilicon,pmctrl"; reg = <0xfca08000 0x1000>; @@ -84,6 +167,14 @@ clock-frequency = <1600000000>; clock-output-names = "clk_armpll1"; }; + /* + smp_twd: smp_twd{ + compatible = "hisilicon,pll"; + #clock-cells = <0>; + clock-frequency = <1600000000>; + clocks = <&armpll0>; + }; + */ peripll: pll2 { compatible = "hisilicon,pll"; #clock-cells = <0>; @@ -577,23 +668,7 @@ status = "disabled"; }; - l2: l2-cache { - compatible = "arm,pl310-cache"; - reg = <0xfc100000 0x100000>; - interrupts = <0 15 4>; - cache-unified; - cache-level = <2>; - hisilicon,l2cache-aux = <0x30070000 0xf00f0000>; - }; - intc: interrupt-controller@fc001000 { - compatible = "arm,cortex-a9-gic"; - #interrupt-cells = <3>; - #address-cells = <0>; - interrupt-controller; - /* gic dist base, gic cpu base */ - reg = <0xfc001000 0x1000>, <0xfc000100 0x100>; - }; timer0: timer@fc800000 { compatible = "arm,sp804", "arm,primecell"; @@ -620,6 +695,19 @@ status = "disabled"; }; + localtimer: localtimer@fca01000 { + compatible = "hisilicon,local-timer"; + reg = <0xfc800000 0x0020>, /* timer00 */ + <0xfca01000 0x0020>, /* timer20 */ + <0xfca01020 0x0040>, /* timer21 */ + <0xfca02000 0x0020>; /* timer30 */ + /* timer20 & timer21 */ + interrupts = <0 0 4>, /* timer00 */ + <0 4 4>, /* timer20 */ + <0 5 4>, /* timer21 */ + <0 6 4>; /* timer30 */ + }; + timer2: timer@fca01000 { compatible = "arm,sp804", "arm,primecell"; reg = <0xfca01000 0x1000>; @@ -1072,12 +1160,6 @@ pinctrl-single,register-width = <32>; }; - sysctrl@fc802000 { - compatible = "hisilicon,sysctrl"; - reg = <0xfc802000 0x1000>; - smp_reg = <0x31c>; - reboot_reg = <0x4>; - }; dma0: dma@fcd02000 { compatible = "hisilicon,k3-dma-1.0"; @@ -1089,46 +1171,6 @@ status = "disable"; }; - i2c0: i2c@fcb08000 { - compatible = "hisilicon,designware-i2c"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0xfcb08000 0x1000>; - interrupts = <0 28 4>; - clocks = <&clk_i2c0>; - dmas = <&dma0 18 /* read channel */ - &dma0 19>; /* write channel */ - dma-names = "rx", "tx"; - status = "disabled"; - }; - - i2c1: i2c@fcb09000 { - compatible = "hisilicon,designware-i2c"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0xfcb09000 0x1000>; - interrupts = <0 29 4>; - clocks = <&clk_i2c1>; - dmas = <&dma0 20 /* read channel */ - &dma0 21>; /* write channel */ - dma-names = "rx", "tx"; - status = "disabled"; - }; - - i2c2: i2c@fcb0c000 { - compatible = "hisilicon,designware-i2c"; - reg = <0xfcb0c000 0x1000>; - interrupts = <0 62 4>; - clocks = <&clk_i2c2>; - status = "disabled"; - }; - - i2c3: i2c@fcb0d000 { - compatible = "hisilicon,designware-i2c"; - reg = <0xfcb0d000 0x1000>; - interrupts = <0 63 4>; - clocks = <&clk_i2c3>; - status = "disabled"; - }; + }; }; }; diff --git a/arch/arm/boot/dts/hi4511.dts b/arch/arm/boot/dts/hi4511.dts index 70a5c45bd8ee..46a6f5e3cc24 100644 --- a/arch/arm/boot/dts/hi4511.dts +++ b/arch/arm/boot/dts/hi4511.dts @@ -54,7 +54,28 @@ memory { reg = <0x00000000 0x20000000>; }; + + + soc { + i2c0: i2c@fcb08000 { + status = "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pmx_func &i2c0_cfg_func>; + i2c_test: i2c_test@58 { + compatible = "hs,i2c_test_tpa2028"; + reg = <0x58>; + }; + }; + i2c1: i2c@fcb09000 { + status = "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pmx_func &i2c1_cfg_func>; + bq24161: charger@6b { + compatible = "hs,i2c_test_bq24161"; + reg = <0x6b>; + }; + }; amba { timer0: timer@fc800000 { status = "ok"; @@ -810,25 +831,6 @@ }; }; - i2c0: i2c@fcb08000 { - status = "ok"; - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pmx_func &i2c0_cfg_func>; - i2c_test: i2c_test@58 { - compatible = "hs,i2c_test_tpa2028"; - reg = <0x58>; - }; - }; - - i2c1: i2c@fcb09000 { - status = "ok"; - pinctrl-names = "default"; - pinctrl-0 = <&i2c1_pmx_func &i2c1_cfg_func>; - bq24161: charger@6b { - compatible = "hs,i2c_test_bq24161"; - reg = <0x6b>; - }; - }; regulators { compatible = "hisilicon,hi6421-pmic"; @@ -1325,4 +1327,5 @@ }; }; /* end of regulators */ }; /* end of amba */ + }; }; diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c index 9d2d3ba339ff..44af4f670c4d 100644 --- a/arch/arm/common/timer-sp.c +++ b/arch/arm/common/timer-sp.c @@ -34,6 +34,7 @@ static long __init sp804_get_clock_rate(const char *name) struct clk *clk; long rate; int err; + printk("gzf %s\n", __func__); clk = clk_get_sys("sp804", name); if (IS_ERR(clk)) { diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 49f335d301ba..6821abfebba7 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -244,6 +244,8 @@ static struct clk *twd_get_clock(void) struct clk *clk; int err; + printk("gzf %s\n", __func__); + clk = clk_get_sys("smp_twd", NULL); if (IS_ERR(clk)) { pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk)); @@ -404,7 +406,7 @@ void __init twd_local_timer_of_register(void) err = -ENOMEM; goto out; } - + printk("gzf %s, twd_ppd=%d, twd_base=0x%x\n", __func__, twd_ppi, twd_base); err = twd_local_timer_common_register(); out: diff --git a/arch/arm/mach-hs/Makefile b/arch/arm/mach-hs/Makefile index 56bd1be58d20..0a942cbcb977 100644 --- a/arch/arm/mach-hs/Makefile +++ b/arch/arm/mach-hs/Makefile @@ -3,4 +3,4 @@ # obj-$(CONFIG_MACH_HS_DT) += hs-dt.o -obj-$(CONFIG_SMP) += platsmp.o +obj-$(CONFIG_SMP) += platsmp.o #localtimer.o diff --git a/arch/arm/mach-hs/hs-dt.c b/arch/arm/mach-hs/hs-dt.c index 8394a26dc5c5..e9f46433da05 100644 --- a/arch/arm/mach-hs/hs-dt.c +++ b/arch/arm/mach-hs/hs-dt.c @@ -26,6 +26,7 @@ #include #include #include +#include static void __iomem *hs_sctrl_base; static int hs_smp_reg; @@ -35,12 +36,19 @@ static void __init hs_map_io(void) { struct device_node *np; + printk("gzf %s\n", __func__); np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl"); hs_sctrl_base = of_iomap(np, 0); of_property_read_u32(np, "smp_reg", &hs_smp_reg); of_property_read_u32(np, "reset_reg", &hs_reset_reg); } +void __init kirkwood_init_early(void) +{ + printk("gzf %s\n", __func__); +// hs_map_io(); +} + void hs_set_cpu_jump(int cpu, void *jump_addr) { int offset = hs_smp_reg; @@ -51,6 +59,25 @@ void hs_set_cpu_jump(int cpu, void *jump_addr) writel(virt_to_phys(jump_addr), hs_sctrl_base + offset); } +/* enable timer bit */ +#define TIMER2_ENABLE_BIT 1<<3 +#define TIMER3_ENABLE_BIT 1<<4 + +void local_timer_clkenable(int cpu) +{ + unsigned long ctrl=0; + + if((cpu == 1)||(cpu == 2)){ + //BIT MAP, only bit 1 take effect. + ctrl = TIMER2_ENABLE_BIT; + writel(ctrl,(hs_sctrl_base+0x40)); + } + else if(cpu == 3){ + ctrl = TIMER3_ENABLE_BIT; + writel(ctrl,(hs_sctrl_base+0x40)); + } +} + static struct of_device_id hs_timer_match[] __initdata = { { .compatible = "arm,sp804", }, {} @@ -61,12 +88,19 @@ static struct clk_lookup sp804_lookup = { .clk = NULL, }; +static struct clk_lookup twd_lookup = { + .dev_id = "smp_twd", + .clk = NULL, +}; + extern void __init hs_init_clocks(void); +extern void __init hs_local_timer_of_register(void); static void __init hs_timer_init(void) { struct device_node *node = NULL; void __iomem *base; int irq; + printk("gzf %s\n", __func__); hs_init_clocks(); @@ -83,11 +117,25 @@ static void __init hs_timer_init(void) irq = irq_of_parse_and_map(node, 0); WARN_ON(!irq); + printk("irq=%d\n", irq); + sp804_lookup.clk = of_clk_get(node, 0); clkdev_add(&sp804_lookup); sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE, "timer1"); sp804_clockevents_init(base, irq, "timer0"); + + node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-twd-timer"); + if (node) { + twd_lookup.clk = of_clk_get(node, 0); + clkdev_add(&twd_lookup); + twd_local_timer_of_register(); + } + /* + else { + hs_local_timer_of_register(); + } + */ } static struct sys_timer hs_timer = { @@ -109,6 +157,7 @@ static void __init hs_irq_init(void) struct device_node *node; int ret; u32 data[2]; + printk("gzf %s\n", __func__); hs_map_io(); of_irq_init(hs_irq_match); @@ -142,6 +191,7 @@ static const char *hs_compat[] __initdata = { extern struct smp_operations hs_smp_ops; DT_MACHINE_START(HS_DT, "Hisilicon Hi36xx/Hi37xx (Flattened Device Tree)") /* Maintainer: Haojian Zhuang */ + .init_early = kirkwood_init_early, .smp = smp_ops(hs_smp_ops), .map_io = debug_ll_io_init, .init_irq = hs_irq_init, diff --git a/arch/arm/mach-hs/localtimer.c b/arch/arm/mach-hs/localtimer.c new file mode 100644 index 000000000000..187b198f75fe --- /dev/null +++ b/arch/arm/mach-hs/localtimer.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2012-2013 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct device_node *hs_timer_node; +static DEFINE_PER_CPU(bool, percpu_setup_called); +static struct clock_event_device __percpu **lt_evt; + +static long __init sp804_get_clock_rate(const char *name) +{ + struct clk *clk; + long rate; + int err; + + clk = clk_get_sys("sp804", name); + if (IS_ERR(clk)) { + pr_err("sp804: %s clock not found: %d\n", name, + (int)PTR_ERR(clk)); + return PTR_ERR(clk); + } + + err = clk_prepare(clk); + if (err) { + pr_err("sp804: %s clock failed to prepare: %d\n", name, err); + clk_put(clk); + return err; + } + + err = clk_enable(clk); + if (err) { + pr_err("sp804: %s clock failed to enable: %d\n", name, err); + clk_unprepare(clk); + clk_put(clk); + return err; + } + + rate = clk_get_rate(clk); + if (rate < 0) { + pr_err("sp804: %s clock failed to get rate: %ld\n", name, rate); + clk_disable(clk); + clk_unprepare(clk); + clk_put(clk); + } + + return rate; +} + +static void __iomem *clkevt_base; +static unsigned long clkevt_reload; + +/* + * IRQ handler for the timer + */ +static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = dev_id; + + /* clear the interrupt */ + writel(1, clkevt_base + TIMER_INTCLR); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static void sp804_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE; + + writel(ctrl, clkevt_base + TIMER_CTRL); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + writel(clkevt_reload, clkevt_base + TIMER_LOAD); + ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; + break; + + case CLOCK_EVT_MODE_ONESHOT: + /* period set, and timer enabled in 'next_event' hook */ + ctrl |= TIMER_CTRL_ONESHOT; + break; + + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + default: + break; + } + + writel(ctrl, clkevt_base + TIMER_CTRL); +} + +static int sp804_set_next_event(unsigned long next, + struct clock_event_device *evt) +{ + unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); + + writel(next, clkevt_base + TIMER_LOAD); + writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); + + return 0; +} + +static struct clock_event_device sp804_clockevent = { + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_mode = sp804_set_mode, + .set_next_event = sp804_set_next_event, + .rating = 300, +}; + +static struct irqaction sp804_timer_irq = { + .name = "timer", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = sp804_timer_interrupt, + .dev_id = &sp804_clockevent, +}; + +void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, + const char *name) +{ + struct clock_event_device *evt = &sp804_clockevent; + long rate = sp804_get_clock_rate(name); + + if (rate < 0) + return; + + clkevt_base = base; + clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ); + evt->name = name; + evt->irq = irq; + evt->cpumask = cpu_possible_mask; + + setup_irq(irq, &sp804_timer_irq); + clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); +} + +static void hs_timer_stop(struct clock_event_device *clk) +{ + //remove_irq + printk("gzf %s, clk->irq=%d\n", __func__, clk->irq); +// hs_set_mode(CLOCK_EVT_MODE_UNUSED, clk); +// disable_percpu_irq(clk->irq); +} + +static unsigned char cpu_name[NR_CPUS][15]; + +/* + * Setup the local clock events for a CPU. + */ +static int __cpuinit hs_timer_setup(struct clock_event_device *clk) +{ + extern void local_timer_clkenable(int cpu); + struct clock_event_device **this_cpu_clk; + int cpu = smp_processor_id(), irq = 0; + void __iomem *base = NULL; + + printk("gzf %s cpu=%d \n", __func__, cpu); + if (cpu == 0) + return 0; + /* + * If the basic setup for this CPU has been done before don't + * bother with the below. + */ + if (per_cpu(percpu_setup_called, cpu)) { + printk("gzf %s already init \n", __func__); + return 0; + } + per_cpu(percpu_setup_called, cpu) = true; + + irq = irq_of_parse_and_map(hs_timer_node, cpu); + if (!irq) + return -EINVAL; + + base = of_iomap(hs_timer_node, cpu); + if (!base) + return -ENOMEM; + + snprintf(&cpu_name[cpu][0], 12, "localtimer%d", cpu); + + printk("base=0x%x, irq=%d, cpu_name[cpu][0]=%s", base, irq, cpu_name[cpu][0]); + clk->name = "local_timer"; + clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | + CLOCK_EVT_FEAT_C3STOP; + clk->rating = 350; + clk->set_mode = twd_set_mode; + clk->set_next_event = twd_set_next_event; + clk->irq = irq; + + this_cpu_clk = __this_cpu_ptr(lt_evt); + *this_cpu_clk = clk; + + clockevents_config_and_register(clk, twd_timer_rate, + 0xf, 0xffffffff); + local_timer_clkenable(cpu); + sp804_clockevents_init(base, irq, &cpu_name[cpu][0]); + irq_set_affinity(irq, cpumask_of(cpu)); + return 0; +} + +static struct local_timer_ops hs_lt_ops __cpuinitdata = { + .setup = hs_timer_setup, + .stop = hs_timer_stop, +}; + +#ifdef CONFIG_OF +const static struct of_device_id hs_of_match[] __initconst = { + { .compatible = "hisilicon,local-timer", }, + { }, +}; + +void __init hs_local_timer_of_register(void) +{ + int err; + + printk("gzf %s\n", __func__); + + hs_timer_node = of_find_matching_node(NULL, hs_of_match); + if (!hs_timer_node) + return; + + lt_evt = alloc_percpu(struct clock_event_device *); + if (!lt_evt) + return -ENOMEM; + + err = local_timer_register(&hs_lt_ops); + if (err) { + WARN(err, "hs_local_timer_of_register failed (%d)\n", err); + return; + } +} +#endif diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index ad722f1208a5..ccec7c377a9d 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -600,6 +600,7 @@ void __init mem_init(void) extern u32 itcm_end; #endif + printk("gzf %s\n", __func__); max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map; /* this will put all unused low memory onto the freelists */ diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index af78ed6b67ef..cd088cdac65c 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -93,6 +93,7 @@ void __init of_fixed_clk_setup(struct device_node *node) if (of_property_read_u32(node, "clock-frequency", &rate)) return; + printk("clk_name=%s\n", clk_name); of_property_read_string(node, "clock-output-names", &clk_name); diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 442a31363873..9be0861970ac 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -114,8 +114,9 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) list_for_each_entry(p, &clocks, node) { match = 0; + printk("p->dev_id=%s, p->con_id=%s\n", p->dev_id, p->con_id); if (p->dev_id) { - if (!dev_id || strcmp(p->dev_id, dev_id)) + if (!dev_id || strcmp(p->dev_id, dev_id)) continue; match += 2; } diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index 84ddea449ef4..85a046d9cb1a 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -5,6 +5,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#define DEBUG #include #include #include @@ -126,11 +127,22 @@ static void terminate_chan(struct k3_dma_phy *phy, struct k3_dma_dev *d) static void set_desc(struct k3_dma_phy *phy, struct k3_desc_hw *hw) { + if (!(hw->config & CCFG_EN)) + printk("set_desc CCFG_EN not set\n"); writel_relaxed(hw->lli, phy->base + CX_LLI); writel_relaxed(hw->count, phy->base + CX_CNT); writel_relaxed(hw->saddr, phy->base + CX_SRC); writel_relaxed(hw->daddr, phy->base + CX_DST); writel_relaxed(hw->config, phy->base + CX_CONFIG); +// printk("set CX_CNT=0x%x\n", readl_relaxed(phy->base + CX_CNT)); +// printk("set CX_CONFIG=0x%x\n", readl_relaxed(phy->base + CX_CONFIG)); + { + u32 v = 0; + v= readl_relaxed(phy->base + CX_CONFIG); + if (!(v & CCFG_EN)) + printk("v set_desc CCFG_EN not set\n"); + + } } static u32 get_curr_cnt(struct k3_dma_dev *d, struct k3_dma_phy *phy) @@ -139,11 +151,13 @@ static u32 get_curr_cnt(struct k3_dma_dev *d, struct k3_dma_phy *phy) cnt = readl_relaxed(d->base + CX_CUR_CNT + phy->idx * 0x10); cnt &= 0xffff; + printk("cnt=0x%x\n", cnt); return cnt; } static u32 get_curr_lli(struct k3_dma_phy *phy) { + printk("phy->base=0x%x, phy->idx=%d\n", phy->base, phy->idx); return readl_relaxed(phy->base + CX_LLI); } @@ -174,23 +188,29 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id) { struct k3_dma_dev *d = (struct k3_dma_dev *)dev_id; struct k3_dma_phy *p; + struct k3_dma_chan *c; u32 stat = readl_relaxed(d->base + INT_STAT); u32 tc1 = readl_relaxed(d->base + INT_TC1); u32 err1 = readl_relaxed(d->base + INT_ERR1); u32 err2 = readl_relaxed(d->base + INT_ERR2); u32 i, irq_num = 0; - +// printk(KERN_DEBUG "stat=0x%x, tc1=0x%x\n", stat, tc1); while (stat) { i = __ffs(stat); stat &= (stat - 1); if (likely(tc1 & BIT(i))) { p = &d->phy[i]; + c = p->vchan; + spin_lock(&c->vc.lock); p->ds_done = p->ds_run; vchan_cookie_complete(&p->ds_run->vd); + spin_unlock(&c->vc.lock); irq_num++; } - if (unlikely((err1 & BIT(i)) || (err2 & BIT(i)))) + if (unlikely((err1 & BIT(i)) || (err2 & BIT(i)))) { + printk("err1=0x%x, err2=0x%x", err1, err2); dev_warn(d->slave.dev, "DMA ERR\n"); + } } writel_relaxed(tc1, d->base + INT_TC1_RAW); @@ -209,8 +229,11 @@ static int k3_dma_start_txd(struct k3_dma_chan *c) struct k3_dma_dev *d = to_k3_dma(c->vc.chan.device); struct virt_dma_desc *vd = vchan_next_desc(&c->vc); - if (BIT(c->phy->idx) & get_chan_stat(d)) - return -EAGAIN; + if (BIT(c->phy->idx) & get_chan_stat(d)) { + printk("should not error here\n"); + return 0; + //return -EAGAIN; + } if (vd) { struct k3_dma_desc_sw *ds = @@ -244,6 +267,7 @@ static void k3_dma_tasklet(unsigned long arg) list_for_each_entry(c, &d->slave.channels, vc.chan.device_node) { spin_lock_irq(&c->vc.lock); p = c->phy; + //if (p && !(BIT(p->idx) & get_chan_stat(d)) { if (p && p->ds_done) { if (k3_dma_start_txd(c)) { /* No current txd associated with this channel */ @@ -324,6 +348,7 @@ static enum dma_status k3_dma_tx_status(struct dma_chan *chan, if (ret == DMA_SUCCESS) return ret; + printk("c->vc.chan->completed_cookie=%d, cookie=%d, ret=%d\n", c->vc.chan.completed_cookie, cookie, ret); spin_lock_irqsave(&c->vc.lock, flags); p = c->phy; @@ -333,22 +358,49 @@ static enum dma_status k3_dma_tx_status(struct dma_chan *chan, */ vd = vchan_find_desc(&c->vc, cookie); if (vd) { + printk("not start, c->vd.tx.cookie=%d, cookie=%d\n", vd->tx.cookie, cookie); + printk("CX_CONFIG=0x%x\n", readl_relaxed(p->base + CX_CONFIG)); + printk("CX_SRC=0x%x\n", readl_relaxed(p->base + CX_SRC)); + printk("CX_DST=0x%x\n", readl_relaxed(p->base + CX_DST)); + printk("CX_CNT=0x%x\n", readl_relaxed(p->base + CX_CNT)); + printk("CX_LLI=0x%x\n", readl_relaxed(p->base + CX_LLI)); + if ((p) && (p->ds_run)) { + printk("p->ds_run->vd.tx.cookie=%d, p->idx=%d\n", p->ds_run->vd.tx.cookie, p->idx); + } bytes = container_of(vd, struct k3_dma_desc_sw, vd)->size; } else if ((!p) || (!p->ds_run)) { + printk("finish , \n"); bytes = 0; } else { struct k3_dma_desc_sw *ds = p->ds_run; u32 clli = 0, index = 0; - bytes = get_curr_cnt(d, p); clli = get_curr_lli(p); index = (clli - ds->desc_hw_lli) / sizeof(struct k3_desc_hw); + printk("clli=0x%x, ds->desc_hw_lli=0x%x,index=0x%x, LLI_MAX_NUM=0x%x\n", clli, ds->desc_hw_lli, index, LLI_MAX_NUM); for (; index < LLI_MAX_NUM; index++) { bytes += ds->desc_hw[index].count; /* end of lli */ if (!ds->desc_hw[index].lli) break; } + printk("CX_CONFIG=0x%x\n", readl_relaxed(p->base + CX_CONFIG)); + printk("CX_SRC=0x%x\n", readl_relaxed(p->base + CX_SRC)); + printk("CX_DST=0x%x\n", readl_relaxed(p->base + CX_DST)); + printk("CX_CNT=0x%x\n", readl_relaxed(p->base + CX_CNT)); + printk("CX_LLI=0x%x\n", readl_relaxed(p->base + CX_LLI)); + printk("int_stat=0x%x\n", readl_relaxed(d->base + INT_STAT)); + printk("int_tc1=0x%x\n", readl_relaxed(d->base + INT_TC1)); + printk("int_err1=0x%x\n", readl_relaxed(d->base + INT_ERR1)); + printk("INT_ERR2=0x%x\n", readl_relaxed(d->base + INT_ERR2)); + printk("INT_TC1_MASK=0x%x\n", readl_relaxed(d->base +INT_TC1_MASK)); + printk("INT_ERR1_MASK=0x%x\n", readl_relaxed(d->base + INT_ERR1_MASK)); + printk("INT_ERR2_MASK=0x%x\n", readl_relaxed(d->base + INT_ERR2_MASK)); + printk("CH_STAT=0x%x\n", readl_relaxed(d->base + CH_STAT)); + printk("INT_TC1_RAW=0x%x\n", readl_relaxed(d->base + INT_TC1_RAW)); + printk("INT_ERR1_RAW=0x%x\n", readl_relaxed(d->base + INT_ERR1_RAW)); + printk("INT_ERR2_RAW=0x%x\n", readl_relaxed(d->base + INT_ERR2_RAW)); + printk(" IN RUN , bytes=0x%x, p->idx=%d, ds->vd.tx.cookie=%d, p->ds_run=0x%x, p->ds_done=0x%x\n", bytes, p->idx, ds->vd.tx.cookie, p->ds_run, p->ds_done); } spin_unlock_irqrestore(&c->vc.lock, flags); dma_set_residue(state, bytes); @@ -384,7 +436,8 @@ static void k3_fill_desc(struct k3_dma_desc_sw *ds, dma_addr_t dst, dma_addr_t src, size_t len, u32 num, u32 ccfg) { BUG_ON(num >= LLI_MAX_NUM); - + if (!(ccfg & CCFG_EN)) + printk("CCFG_EN not set\n"); ds->desc_hw[num].lli = ds->desc_hw_lli + (num + 1) * sizeof(struct k3_desc_hw); ds->desc_hw[num].lli |= CX_LLI_CHAIN_EN; @@ -558,6 +611,7 @@ static int k3_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, case DMA_TERMINATE_ALL: dev_dbg(d->slave.dev, "vchan %p: terminate all\n", &c->vc); /* Clear the tx descriptor lists */ + printk(" DMA_TERMINATE_ALL \n"); spin_lock_irqsave(&c->vc.lock, flags); vchan_get_all_descriptors(&c->vc, &head); if (c) @@ -623,7 +677,7 @@ static int k3_dma_probe(struct platform_device *op) d->base = devm_request_and_ioremap(&op->dev, iores); if (!d->base) return -EADDRNOTAVAIL; - + printk("d->base=0x%x\n", d->base); of_id = of_match_device(k3_pdma_dt_ids, &op->dev); if (of_id) of_property_read_u32((&op->dev)->of_node, @@ -647,6 +701,7 @@ static int k3_dma_probe(struct platform_device *op) p->idx = i; p->base = d->base + i * 0x40; + printk("p[%d]->base=0x%x\n", i, p->base); } INIT_LIST_HEAD(&d->slave.channels); diff --git a/init/main.c b/init/main.c index 85d69dffe864..0141ea1fcd81 100644 --- a/init/main.c +++ b/init/main.c @@ -457,6 +457,7 @@ static void __init mm_init(void) * page_cgroup requires contiguous pages, * bigger than MAX_ORDER unless SPARSEMEM. */ + printk("gzf %s\n", __func__); page_cgroup_init_flatmem(); mem_init(); kmem_cache_init(); diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 30b6de0d977c..a9d35bf05008 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -280,6 +280,7 @@ static void clockevents_notify_released(void) void clockevents_register_device(struct clock_event_device *dev) { unsigned long flags; + printk("gzf %s dev->mode=%d dev=0x%x\n", __func__, dev->mode, dev); BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); if (!dev->cpumask) { -- cgit v1.2.3