From: root Date: Fri, 25 Feb 2011 10:17:12 +0000 (+0800) Subject: swj add reboot code X-Git-Tag: firefly_0821_release~10749 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=ce61d0452b3f63422021752acfa4d80275ca1a58;p=firefly-linux-kernel-4.4.55.git swj add reboot code --- diff --git a/arch/arm/mach-rk29/Makefile b/arch/arm/mach-rk29/Makefile old mode 100755 new mode 100644 index 30d7eccf32b3..d5c001fc17e7 --- a/arch/arm/mach-rk29/Makefile +++ b/arch/arm/mach-rk29/Makefile @@ -1,4 +1,4 @@ -obj-y += timer.o io.o devices.o iomux.o clock.o rk29-pl330.o dma.o gpio.o ddr.o sram.o memcpy_dma.o +obj-y += timer.o io.o devices.o iomux.o clock.o rk29-pl330.o dma.o gpio.o ddr.o sram.o memcpy_dma.o reset.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_RK29_VPU) += vpu.o vpu_mem.o diff --git a/arch/arm/mach-rk29/include/mach/system.h b/arch/arm/mach-rk29/include/mach/system.h old mode 100644 new mode 100755 index e2a092e92e9a..18830e8659fc --- a/arch/arm/mach-rk29/include/mach/system.h +++ b/arch/arm/mach-rk29/include/mach/system.h @@ -23,6 +23,7 @@ #else #define restart_dbg(format, arg...) do {} while (0) #endif +extern void rk29_arch_reset(int mode, const char *cmd); static inline void arch_reset(int mode, const char *cmd) { @@ -31,8 +32,8 @@ static inline void arch_reset(int mode, const char *cmd) * debug trace */ restart_dbg("%s->%s->%d->mode=%c cmd=%s",__FILE__,__FUNCTION__,__LINE__,mode,cmd); - printk("Can't reboot. Please open rk2818 power manage!!\n"); - for(;;); + + rk29_arch_reset(mode, cmd); } static inline void arch_idle(void) diff --git a/arch/arm/mach-rk29/reset.c b/arch/arm/mach-rk29/reset.c new file mode 100644 index 000000000000..77b6fb8c3144 --- /dev/null +++ b/arch/arm/mach-rk29/reset.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include + +#define cru_readl(offset) readl(RK29_CRU_BASE + offset) +#define cru_writel(v, offset) do { writel(v, RK29_CRU_BASE + offset); readl(RK29_CRU_BASE + offset); } while (0) + +static inline void delay_500ns(void) +{ + int delay = 12; + while (delay--) + barrier(); +} + +void rk29_arch_reset(int mode, const char *cmd) +{ + u32 pll, reg; + + local_irq_disable(); + local_fiq_disable(); + + cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CPU_MODE_MASK) | CRU_CPU_MODE_SLOW, CRU_MODE_CON); + + delay_500ns(); + + cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_GENERAL_MODE_MASK) | CRU_GENERAL_MODE_SLOW, CRU_MODE_CON); + + delay_500ns(); + + cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CODEC_MODE_MASK) | CRU_CODEC_MODE_SLOW, CRU_MODE_CON); + + delay_500ns(); + + cru_writel(0, CRU_CLKGATE0_CON); + cru_writel(0, CRU_CLKGATE1_CON); + cru_writel(0, CRU_CLKGATE2_CON); + cru_writel(0, CRU_CLKGATE3_CON); + delay_500ns(); + + cru_writel(0, CRU_SOFTRST0_CON); + cru_writel(0, CRU_SOFTRST1_CON); + cru_writel(0, CRU_SOFTRST2_CON); + + + //SPI0 clock source = periph_pll_clk, SPI0 divider=8 + cru_writel((cru_readl(CRU_CLKSEL6_CON) & ~0x1FF) | (7 << 2), CRU_CLKSEL6_CON); + + //eMMC divider=0x17, SD/MMC0 clock source=arm_pll_clk + cru_writel((cru_readl(CRU_CLKSEL7_CON) & ~(3 | (0x3f << 18))) | (0x17 << 18), CRU_CLKSEL7_CON); + + //UART1 clock divider=0, UART1 clk =24MHz , UART0 and UART1 clock source=periph_pll_clk + cru_writel((cru_readl(CRU_CLKSEL8_CON) & ~(7 | (0x3f << 14) | (3 << 20))) | (2 << 20), CRU_CLKSEL8_CON); + + writel(readl(RK29_GRF_PHYS + 0xc0) & ~(1 << 21), RK29_GRF_PHYS + 0xc0); + writel(readl(RK29_GRF_PHYS + 0xbc) & ~(1 << 9), RK29_GRF_PHYS + 0xbc); + + writel(0, RK29_CPU_AXI_BUS0_PHYS); + writel(0, RK29_AXI1_PHYS); + + __cpuc_flush_kern_all(); + __cpuc_flush_user_all(); + + asm("mrc p15, 0, %0, c1, c0, 0\n\t" + "bic r0, %0, #(1 << 13) @set vector to 0x00000000\n\t" + "bic r0, %0, #(1 << 0) @disable mmu\n\t" + "bic r0, %0, #(1 << 12) @disable I CACHE\n\t" + "bic r0, %0, #(1 << 2) @disable D DACHE\n\t" + "mcr p15, 0, %0, c1, c0, 0\n\t" +// "mcr p15, 0, %0, c8, c7, 0 @ invalidate whole TLB\n\t" +// "mcr p15, 0, %0, c7, c5, 6 @ invalidate BTC\n\t" + :: "r" (reg)); + + asm("b 1f\n\t" + ".align 5\n\t" + "1:\n\t" + "mcr p15, 0, %0, c7, c10, 5\n\t" + "mcr p15, 0, %0, c7, c10, 4\n\t" + "mov pc, #0" : : "r" (reg)); +} + diff --git a/arch/arm/mach-rk29/rk29-pl330.c b/arch/arm/mach-rk29/rk29-pl330.c old mode 100755 new mode 100644 index 9f9fddb671f8..ec290ddce682 --- a/arch/arm/mach-rk29/rk29-pl330.c +++ b/arch/arm/mach-rk29/rk29-pl330.c @@ -1226,72 +1226,6 @@ static int pl330_remove(struct platform_device *pdev) return 0; } -static int pl330_shutdown(struct platform_device *pdev) -{ - struct rk29_pl330_dmac *dmac, *d; - struct rk29_pl330_chan *ch; - unsigned long flags; - int del, found; - - if (!pdev->dev.platform_data) - return -EINVAL; - - spin_lock_irqsave(&res_lock, flags); - - found = 0; - list_for_each_entry(d, &dmac_list, node) - if (d->pi->dev == &pdev->dev) { - found = 1; - break; - } - - if (!found) { - spin_unlock_irqrestore(&res_lock, flags); - return 0; - } - - dmac = d; - - /* Remove all Channels that are managed only by this DMAC */ - list_for_each_entry(ch, &chan_list, node) { - - /* Only channels that are handled by this DMAC */ - if (iface_of_dmac(dmac, ch->id)) - del = 1; - else - continue; - - /* Don't remove if some other DMAC has it too */ - list_for_each_entry(d, &dmac_list, node) - if (d != dmac && iface_of_dmac(d, ch->id)) { - del = 0; - break; - } - - if (del) { - //spin_unlock_irqrestore(&res_lock, flags); - - if (!ch || chan_free(ch)) - goto shutdown_exit; - - - /* Stop any active xfer, Flushe the queue and do callbacks */ - pl330_chan_ctrl(ch->pl330_chan_id, PL330_OP_FLUSH); - //spin_lock_irqsave(&res_lock, flags); - list_del(&ch->node); - kfree(ch); - } - } - - /* Remove the DMAC */ - list_del(&dmac->node); - kfree(dmac); -shutdown_exit: - spin_unlock_irqrestore(&res_lock, flags); - - return 0; -} - static struct platform_driver pl330_driver = { .driver = { .owner = THIS_MODULE, @@ -1299,7 +1233,6 @@ static struct platform_driver pl330_driver = { }, .probe = pl330_probe, .remove = pl330_remove, - .shutdown = pl330_shutdown,/* test */ }; static int __init pl330_init(void)