📄 update-2.4.22-mipsorg-0.030928.1.patch
字号:
-}---void __init time_init(void)-{- unsigned int est_freq;+ if (counter & SYS_CNTRL_E0) {+ unsigned long start, end;+ unsigned long counter;+ int trim_divide = 16;++ au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL);++ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);+ au_writel(trim_divide-1, SYS_RTCTRIM); /* RTC now ticks at 32.768/16 kHz */+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);++ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);+ au_writel (0, SYS_TOYWRITE);+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);++ start = au_readl(SYS_RTCREAD);+ start += 2;+ /* wait for the beginning of a new tick */+ while (au_readl(SYS_RTCREAD) < start);++ /* Start r4k counter. */+ write_c0_count(0);+ end = start + (32768 / trim_divide)/2; /* wait 0.5 seconds */ - printk("calculating r4koff... ");- r4k_offset = cal_r4koff();- printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);+ while (end > au_readl(SYS_RTCREAD)); - //est_freq = 2*r4k_offset*HZ;- est_freq = r4k_offset*HZ;- est_freq += 5000; /* round */- est_freq -= est_freq%10000;- printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,- (est_freq%1000000)*100/1000000);- set_au1x00_speed(est_freq);- set_au1x00_lcd_clock(); // program the LCD clock- r4k_cur = (read_c0_count() + r4k_offset);-- write_c0_compare(r4k_cur);-- /* no RTC on the pb1000 */- xtime.tv_sec = 0;- xtime.tv_usec = 0;--#ifdef CONFIG_PM- /*- * setup counter 0, since it keeps ticking after a- * 'wait' instruction has been executed. The CP0 timer and- * counter 1 do NOT continue running after 'wait'- *- * It's too early to call request_irq() here, so we handle- * counter 0 interrupt as a special irq and it doesn't show- * up under /proc/interrupts.+ count = read_c0_count();+ cpu_speed = count * 2;+ }+ else {+ /* The 32KHz oscillator isn't running, so assume there+ * isn't one and grab the processor speed from the PLL.+ * NOTE: some old silicon doesn't allow reading the PLL.+ */+ cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * 1000000 * AU1000_SRC_CLK;+ count = cpu_speed / 2;+ no_au1xxx_32khz = 1;+ }+#else+ /* Always read the processor speed from the PLL. Guessing this+ * value by using a 32KHz clock doesn't provide the accurate+ * clock speed. This causes problems for peripheral clock dividers+ * because their clocks are not accurate, either.+ * NOTE: some old silicon doesn't allow reading the PLL. */- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);- au_writel(0, SYS_TOYWRITE);- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);-- au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);- au_writel(~0, SYS_WAKESRC);- au_sync();- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);-- /* setup match20 to interrupt once every 10ms */- last_pc0 = last_match20 = au_readl(SYS_TOYREAD);- au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);- au_sync();- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);- startup_match20_interrupt();+ cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * 1000000 * 12;+ count = cpu_speed / 2;+ no_au1xxx_32khz = 1; #endif-- //set_c0_status(ALLINTS);- au_sync();+ mips_hpt_frequency = count;+ // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16)+ set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));+ spin_unlock_irqrestore(&time_lock, flags);+ return (cpu_speed / HZ); } /* This is for machines which generate the exact clock. */ #define USECS_PER_JIFFY (1000000/HZ) #define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff) -#ifndef CONFIG_PM+ static unsigned long div64_32(unsigned long v1, unsigned long v2, unsigned long v3) {@@ -276,30 +305,9 @@ do_div64_32(r0, v1, v2, v3); return r0; }-#endif -static unsigned long do_fast_gettimeoffset(void)+static unsigned long do_fast_cp0_gettimeoffset(void) {-#ifdef CONFIG_PM- unsigned long pc0;- unsigned long offset;-- pc0 = au_readl(SYS_TOYREAD);- if (pc0 < last_pc0) {- offset = 0xffffffff - last_pc0 + pc0;- printk("offset over: %x\n", (unsigned)offset);- }- else {- offset = (unsigned long)(((pc0 - last_pc0) * 305) / 10);- }- if ((pc0-last_pc0) > 2*MATCH20_INC) {- printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n",- (unsigned)offset, (unsigned)last_pc0,- (unsigned)last_match20, (unsigned)pc0);- }- au_sync();- return offset;-#else u32 count; unsigned long res, tmp; unsigned long r0;@@ -340,60 +348,114 @@ "r" (quotient)); /*- * Due to possible jiffies inconsistencies, we need to check+ * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) res = USECS_PER_JIFFY-1; return res;-#endif } -void do_gettimeofday(struct timeval *tv)+#ifdef CONFIG_PM+static unsigned long do_fast_pm_gettimeoffset(void) {- unsigned long flags;-- read_lock_irqsave (&xtime_lock, flags);- *tv = xtime;- tv->tv_usec += do_fast_gettimeoffset();-- /*- * xtime is atomically updated in timer_bh. jiffies - wall_jiffies- * is nonzero if the timer bottom half hasnt executed yet.- */- if (jiffies - wall_jiffies)- tv->tv_usec += USECS_PER_JIFFY;-- read_unlock_irqrestore (&xtime_lock, flags);+ unsigned long pc0;+ unsigned long offset; - if (tv->tv_usec >= 1000000) {- tv->tv_usec -= 1000000;- tv->tv_sec++;+ pc0 = au_readl(SYS_TOYREAD);+ au_sync();+ offset = pc0 - last_pc0;+ if (offset > 2*MATCH20_INC) {+ printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", + (unsigned)offset, (unsigned)last_pc0, + (unsigned)last_match20, (unsigned)pc0); }+ offset = (unsigned long)((offset * 305) / 10);+ return offset; }+#endif -void do_settimeofday(struct timeval *tv)+void __init au1xxx_timer_setup(void) {- write_lock_irq (&xtime_lock);+ unsigned int est_freq;+ extern unsigned long (*do_gettimeoffset)(void);+ extern void r4k_wait(void); - /* This is revolting. We need to set the xtime.tv_usec correctly.- * However, the value in this location is value at the last tick.- * Discover what correction gettimeofday would have done, and then- * undo it!- */- tv->tv_usec -= do_fast_gettimeoffset();+ printk("calculating r4koff... ");+ r4k_offset = cal_r4koff();+ printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);++ //est_freq = 2*r4k_offset*HZ; + est_freq = r4k_offset*HZ; + est_freq += 5000; /* round */+ est_freq -= est_freq%10000;+ printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, + (est_freq%1000000)*100/1000000);+ set_au1x00_speed(est_freq);+ set_au1x00_lcd_clock(); // program the LCD clock++ r4k_cur = (read_c0_count() + r4k_offset);+ write_c0_compare(r4k_cur); - if (tv->tv_usec < 0) {- tv->tv_usec += 1000000;- tv->tv_sec--;+ /* no RTC on the pb1000 */+ xtime.tv_sec = 0;+ xtime.tv_usec = 0;++#ifdef CONFIG_PM+ /*+ * setup counter 0, since it keeps ticking after a+ * 'wait' instruction has been executed. The CP0 timer and+ * counter 1 do NOT continue running after 'wait'+ *+ * It's too early to call request_irq() here, so we handle+ * counter 0 interrupt as a special irq and it doesn't show+ * up under /proc/interrupts.+ *+ * Check to ensure we really have a 32KHz oscillator before+ * we do this.+ */+ if (no_au1xxx_32khz) {+ printk("WARNING: no 32KHz clock found.\n");+ do_gettimeoffset = do_fast_cp0_gettimeoffset;++ /* Ensure we get CPO_COUNTER interrupts.+ */+ change_cp0_status(IE_IRQ5, IE_IRQ5);+ }+ else {+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);+ au_writel(0, SYS_TOYWRITE);+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);++ au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);+ au_writel(~0, SYS_WAKESRC);+ au_sync();+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);++ /* setup match20 to interrupt once every 10ms */+ last_pc0 = last_match20 = au_readl(SYS_TOYREAD);+ au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);+ au_sync();+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);+ startup_match20_interrupt();++ do_gettimeoffset = do_fast_pm_gettimeoffset;++ /* We can use the real 'wait' instruction.+ */+ au1k_wait_ptr = r4k_wait; } - xtime = *tv;- time_adjust = 0; /* stop active adjtime() */- time_status |= STA_UNSYNC;- time_maxerror = NTP_PHASE_LIMIT;- time_esterror = NTP_PHASE_LIMIT;+#else+ /* We have to do this here instead of in timer_init because+ * the generic code in arch/mips/kernel/time.c will write+ * over our function pointer.+ */+ do_gettimeoffset = do_fast_cp0_gettimeoffset;+#endif+} - write_unlock_irq (&xtime_lock);+void __init au1xxx_time_init(void)+{ }diff -Naur --exclude='*.orig' --exclude=CVS --exclude=.cvsignore --exclude='.#*' --exclude=README.Debian linux-2.4.22.clean/arch/mips/au1000/csb250/board_setup.c linux-2.4.22/arch/mips/au1000/csb250/board_setup.c--- linux-2.4.22.clean/arch/mips/au1000/csb250/board_setup.c 1970-01-01 01:00:00.000000000 +0100+++ linux-2.4.22/arch/mips/au1000/csb250/board_setup.c 2003-09-08 02:05:46.000000000 +0200@@ -0,0 +1,250 @@+/*+ *+ * BRIEF MODULE DESCRIPTION+ * Cogent CSB250 board setup.+ *+ * Copyright 2002 Cogent Computer Systems, Inc.+ * dan@embeddededge.com+ *+ * This program is free software; you can redistribute it and/or modify it+ * under the terms of the GNU General Public License as published by the+ * Free Software Foundation; either version 2 of the License, or (at your+ * option) any later version.+ *+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ * You should have received a copy of the GNU General Public License along+ * with this program; if not, write to the Free Software Foundation, Inc.,+ * 675 Mass Ave, Cambridge, MA 02139, USA.+ */+#include <linux/config.h>+#include <linux/init.h>+#include <linux/sched.h>+#include <linux/ioport.h>+#include <linux/mm.h>+#include <linux/console.h>+#include <linux/mc146818rtc.h>+#include <linux/delay.h>++#include <asm/cpu.h>+#include <asm/bootinfo.h>+#include <asm/irq.h>+#include <asm/keyboard.h>+#include <asm/mipsregs.h>+#include <asm/reboot.h>+#include <asm/pgtable.h>+#include <asm/au1000.h>+#include <asm/csb250.h>++#ifdef CONFIG_USB_OHCI+// Enable the workaround for the OHCI DoneHead+// register corruption problem.+#define CONFIG_AU1000_OHCI_FIX+#endif++#ifdef CONFIG_RTC+extern struct rtc_ops csb250_rtc_ops;+#endif++extern int (*board_pci_idsel)(unsigned int devsel, int assert);+int csb250_pci_idsel(unsigned int devsel, int assert);++void __init board_setup(void)+{+ u32 pin_func, pin_val;+ u32 sys_freqctrl, sys_clksrc;+++ // set AUX clock to 12MHz * 8 = 96 MHz+ au_writel(8, SYS_AUXPLL);+ au_writel(0, SYS_PINSTATERD);+ udelay(100);++#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)++ /* GPIO201 is input for PCMCIA card detect */+ /* GPIO203 is input for PCMCIA interrupt request */+ au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR);++ /* zero and disable FREQ2 */+ sys_freqctrl = au_readl(SYS_FREQCTRL0);+ sys_freqctrl &= ~0xFFF00000;+ au_writel(sys_freqctrl, SYS_FREQCTRL0);++ /* zero and disable USBH/USBD clocks */+ sys_clksrc = au_readl(SYS_CLKSRC);+ sys_clksrc &= ~0x00007FE0;+ au_writel(sys_clksrc, SYS_CLKSRC);++ sys_freqctrl = au_readl(SYS_FREQCTRL0);+ sys_freqctrl &= ~0xFFF00000;++ sys_clksrc = au_readl(SYS_CLKSRC);+ sys_clksrc &= ~0x00007FE0;++ // FREQ2 = aux/2 = 48 MHz+ sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));+ au_writel(sys_freqctrl, SYS_FREQCTRL0);++ /*+ * Route 48MHz FREQ2 into USB Host and/or Device+ */+#ifdef CONFIG_USB_OHCI+ sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));+#endif+#ifdef CONFIG_AU1X00_USB_DEVICE+ sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));+#endif+ au_writel(sys_clksrc, SYS_CLKSRC);+++ pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);+#ifndef CONFIG_AU1X00_USB_DEVICE+ // 2nd USB port is USB host
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -