📄 2.6.20-rc1-at91.patch.gz
字号:
+ *+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+ */++#include <asm/hardware.h>+#include <asm/io.h>+#include <linux/delay.h>++#include <asm/arch/ics1523.h>+#include <asm/arch/at91_twi.h>+#include <asm/arch/gpio.h>++/* TWI Errors */+#define AT91_TWI_ERROR (AT91_TWI_NACK | AT91_TWI_UNRE | AT91_TWI_OVRE)+++//-----------------------------------------------------------------------------+//+// TWI Register access+//+//-----------------------------------------------------------------------------++static inline unsigned long at91_twi_read(unsigned int reg)+{+ void __iomem *twi_base = (void __iomem *)AT91_VA_BASE_TWI;++ return __raw_readl(twi_base + reg);+}++static inline void at91_twi_write(unsigned int reg, unsigned long value)+{+ void __iomem *twi_base = (void __iomem *)AT91_VA_BASE_TWI;++ __raw_writel(value, twi_base + reg);+}++//-----------------------------------------------------------------------------+//+// Initialization of TWI CLOCK+//+//-----------------------------------------------------------------------------++static void AT91F_SetTwiClock(unsigned int mck_khz)+{+ int sclock;++ /* Here, CKDIV = 1 and CHDIV = CLDIV ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6) */+ sclock = (10*mck_khz /ICS_TRANSFER_RATE);+ if (sclock % 10 >= 5)+ sclock = (sclock /10) - 5;+ else+ sclock = (sclock /10)- 6;+ sclock = (sclock + (4 - sclock %4)) >> 2; // div 4++ at91_twi_write(AT91_TWI_CWGR, 0x00010000 | sclock | (sclock << 8));+}++//-----------------------------------------------------------------------------+//+// Read a byte with TWI Interface from the Clock Generator ICS1523+//+//-----------------------------------------------------------------------------++static int AT91F_ICS1523_ReadByte(unsigned char reg_address, unsigned char *data_in)+{+ int Status, nb_trial;++ at91_twi_write(AT91_TWI_MMR, AT91_TWI_MREAD | AT91_TWI_IADRSZ_1 | ((ICS_ADD << 16) & AT91_TWI_DADR));+ at91_twi_write(AT91_TWI_IADR, reg_address);+ at91_twi_write(AT91_TWI_CR, AT91_TWI_START | AT91_TWI_STOP);++ // Program temporizing period (300us)+ udelay(300);++ // Wait TXcomplete ...+ nb_trial = 0;+ Status = at91_twi_read(AT91_TWI_SR);+ while (!(Status & AT91_TWI_TXCOMP) && (nb_trial < 10)) {+ nb_trial++;+ Status = at91_twi_read(AT91_TWI_SR);+ }++ if (Status & AT91_TWI_TXCOMP) {+ *data_in = (unsigned char) at91_twi_read(AT91_TWI_RHR);+ return ((int) ICS1523_ACCESS_OK);+ }+ return ((int) ICS1523_ACCESS_ERROR);+}++//-----------------------------------------------------------------------------+//+// Write a byte with TWI Interface to the Clock Generator ICS1523+//+//-----------------------------------------------------------------------------++static int AT91F_ICS1523_WriteByte(unsigned char reg_address, unsigned char data_out)+{+ int Status, nb_trial;++ at91_twi_write(AT91_TWI_MMR, AT91_TWI_IADRSZ_1 | ((ICS_ADD << 16) & AT91_TWI_DADR));+ at91_twi_write(AT91_TWI_IADR, reg_address);+ at91_twi_write(AT91_TWI_THR, data_out);+ at91_twi_write(AT91_TWI_CR, AT91_TWI_START | AT91_TWI_STOP);++ // Program temporizing period (300us)+ udelay(300);++ nb_trial = 0;+ Status = at91_twi_read(AT91_TWI_SR);+ while (!(Status & AT91_TWI_TXCOMP) && (nb_trial < 10)) {+ nb_trial++;+ if (Status & AT91_TWI_ERROR) {+ // Si Under run OR NACK Start again+ at91_twi_write(AT91_TWI_CR, AT91_TWI_START | AT91_TWI_STOP);++ // Program temporizing period (300us)+ udelay(300);+ }+ Status = at91_twi_read(AT91_TWI_SR);+ };++ if (Status & AT91_TWI_TXCOMP)+ return ((int) ICS1523_ACCESS_OK);+ else+ return ((int) ICS1523_ACCESS_ERROR);+}++//-----------------------------------------------------------------------------+//+// Initialization of the Clock Generator ICS1523+//+//-----------------------------------------------------------------------------++int AT91F_ICS1523_clockinit(void)+{+ int ack, nb_trial, error_status;+ unsigned int status = 0xffffffff;+ struct clk *twi_clk;++ error_status = (int) ICS1523_ACCESS_OK;++ /* pins used for TWI interface */+ at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */+ at91_set_multi_drive(AT91_PIN_PA25, 1);+ at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */+ at91_set_multi_drive(AT91_PIN_PA26, 1);++ // Enable the TWI clock.+ twi_clk = clk_get(NULL, "twi_clk");+ if (IS_ERR(twi_clk))+ return ICS1523_ACCESS_ERROR;+ clk_enable(twi_clk);++ // Disable interrupts+ at91_twi_write(AT91_TWI_IDR, -1);++ // Reset peripheral+ at91_twi_write(AT91_TWI_CR, AT91_TWI_SWRST);++ // Set Master mode+ at91_twi_write(AT91_TWI_CR, AT91_TWI_MSEN);++ // Set TWI Clock Waveform Generator Register+ AT91F_SetTwiClock(60000); // MCK in KHz = 60000 KHz++ // ICS1523 Initialisation+ ack = AT91F_ICS1523_WriteByte ((unsigned char) ICS_ICR, (unsigned char) 0);+ error_status |= ack;+ ack = AT91F_ICS1523_WriteByte ((unsigned char) ICS_OE, (unsigned char) (ICS_OEF | ICS_OET2 | ICS_OETCK));+ error_status |= ack;+ ack = AT91F_ICS1523_WriteByte ((unsigned char) ICS_OD, (unsigned char) (ICS_INSEL | 0x7F));+ error_status |= ack;+ ack = AT91F_ICS1523_WriteByte ((unsigned char) ICS_DPAO, (unsigned char) 0);+ error_status |= ack;++ nb_trial = 0;+ do {+ nb_trial++;+ ack = AT91F_ICS1523_WriteByte ((unsigned char) ICS_ICR, (unsigned char) (ICS_ENDLS | ICS_ENPLS | ICS_PDEN /*| ICS_FUNCSEL*/));+ error_status |= ack;+ ack = AT91F_ICS1523_WriteByte ((unsigned char) ICS_LCR, (unsigned char) (ICS_PSD | ICS_PFD));+ error_status |= ack;+ ack = AT91F_ICS1523_WriteByte ((unsigned char) ICS_FD0, (unsigned char) 0x39) ; /* 0x7A */+ error_status |= ack;+ ack = AT91F_ICS1523_WriteByte ((unsigned char) ICS_FD1, (unsigned char) 0x00);+ error_status |= ack;+ ack = AT91F_ICS1523_WriteByte ((unsigned char) ICS_SWRST, (unsigned char) (ICS_PLLR));+ error_status |= ack;++ // Program 1ms temporizing period+ mdelay(1);++ AT91F_ICS1523_ReadByte ((unsigned char) ICS_SR, (char *)&status);+ } while (!((unsigned int) status & (unsigned int) ICS_PLLLOCK) && (nb_trial < 10));++ ack = AT91F_ICS1523_WriteByte ((unsigned char) ICS_DPAC, (unsigned char) 0x03) ; /* 0x01 */+ error_status |= ack;+ ack = AT91F_ICS1523_WriteByte ((unsigned char) ICS_SWRST, (unsigned char) (ICS_DPAR));+ error_status |= ack;++ /* Program 1ms temporizing period */+ mdelay(1);++ ack = AT91F_ICS1523_WriteByte ((unsigned char) ICS_DPAO, (unsigned char) 0x00);+ error_status |= ack;++ /* Program 1ms temporizing period */+ mdelay(1);++ return (error_status);+}diff -urN -x CVS linux-2.6.20-rc1.orig/arch/arm/mach-at91rm9200/pm.c linux-2.6/arch/arm/mach-at91rm9200/pm.c--- linux-2.6.20-rc1.orig/arch/arm/mach-at91rm9200/pm.c Fri Dec 15 08:35:48 2006+++ linux-2.6/arch/arm/mach-at91rm9200/pm.c Fri Dec 15 09:00:50 2006@@ -63,6 +63,7 @@ * Verify that all the clocks are correct before entering * slow-clock mode. */+#warning "SAM9260 only has 3 programmable clocks." static int at91_pm_verify_clocks(void) { unsigned long scsr;@@ -205,16 +206,23 @@ .enter = at91_pm_enter, }; +#ifdef CONFIG_AT91_SLOW_CLOCK+extern void at91rm9200_slow_clock(void);+extern u32 at91rm9200_slow_clock_sz;+#endif+ static int __init at91_pm_init(void) {- printk("AT91: Power Management\n");--#ifdef CONFIG_AT91_PM_SLOW_CLOCK- /* REVISIT allocations of SRAM should be dynamically managed.+#ifdef CONFIG_AT91_SLOW_CLOCK+ /*+ * REVISIT allocations of SRAM should be dynamically managed. * FIQ handlers and other components will want SRAM/TCM too... */- slow_clock = (void *) (AT91_VA_BASE_SRAM + (3 * SZ_4K));+ slow_clock = (void *) (AT91_IO_VIRT_BASE - AT91RM9200_SRAM_SIZE + (3 * SZ_4K)); memcpy(slow_clock, at91rm9200_slow_clock, at91rm9200_slow_clock_sz);+ printk("AT91: Power Management (with slow clock mode)\n");+#else+ printk("AT91: Power Management\n"); #endif /* Disable SDRAM low-power mode. Cannot be used with self-refresh. */diff -urN -x CVS linux-2.6.20-rc1.orig/arch/arm/mach-at91rm9200/pm_slowclock.S linux-2.6/arch/arm/mach-at91rm9200/pm_slowclock.S--- linux-2.6.20-rc1.orig/arch/arm/mach-at91rm9200/pm_slowclock.S Thu Jan 1 02:00:00 1970+++ linux-2.6/arch/arm/mach-at91rm9200/pm_slowclock.S Tue Dec 12 12:20:09 2006@@ -0,0 +1,172 @@+/*+ * arch/arm/mach-at91rm9200/pm_slow_clock.S+ *+ * Copyright (C) 2006 Savin Zlobec+ *+ * 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 <linux/linkage.h>+#include <asm/hardware.h>+#include <asm/arch/at91_pmc.h>+#include <asm/arch/at91rm9200_mc.h>++#define MCKRDY_TIMEOUT 1000+#define MOSCRDY_TIMEOUT 1000+#define PLLALOCK_TIMEOUT 1000++ .macro wait_mckrdy+ mov r2, #MCKRDY_TIMEOUT+1: sub r2, r2, #1+ cmp r2, #0+ beq 2f+ ldr r3, [r1, #AT91_PMC_SR]+ tst r3, #AT91_PMC_MCKRDY+ beq 1b+2:+ .endm++ .macro wait_moscrdy+ mov r2, #MOSCRDY_TIMEOUT+1: sub r2, r2, #1+ cmp r2, #0+ beq 2f+ ldr r3, [r1, #AT91_PMC_SR]+ tst r3, #AT91_PMC_MOSCS+ beq 1b+2:+ .endm++ .macro wait_pllalock+ mov r2, #PLLALOCK_TIMEOUT+1: sub r2, r2, #1+ cmp r2, #0+ beq 2f+ ldr r3, [r1, #AT91_PMC_SR]+ tst r3, #AT91_PMC_LOCKA+ beq 1b+2:+ .endm++ .macro wait_plladis+ mov r2, #PLLALOCK_TIMEOUT+1: sub r2, r2, #1+ cmp r2, #0+ beq 2f+ ldr r3, [r1, #AT91_PMC_SR]+ tst r3, #AT91_PMC_LOCKA+ bne 1b+2:+ .endm++ .text++ENTRY(at91rm9200_slow_clock)++ ldr r1, .at91_va_base_sys++ /* Put SDRAM in self refresh mode */++ b 1f+ .align 5+1: mcr p15, 0, r0, c7, c10, 4+ mov r2, #1+ str r2, [r1, #AT91_SDRAMC_SRR]++ /* Save Master clock setting */++ ldr r2, [r1, #AT91_PMC_MCKR]+ str r2, .saved_mckr++ /*+ * Set the Master clock source to slow clock+ *+ * First set the CSS field, wait for MCKRDY+ * and than set the PRES and MDIV fields.+ *+ * See eratta #2[78] for details.+ */++ bic r2, r2, #3+ str r2, [r1, #AT91_PMC_MCKR]++ wait_mckrdy++ mov r2, #0+ str r2, [r1, #AT91_PMC_MCKR]++ /* Save PLLA setting and disable it */++ ldr r2, [r1, #AT91_CKGR_PLLAR]+ str r2, .saved_pllar++ mov r2, #0+ str r2, [r1, #AT91_CKGR_PLLAR]++ wait_plladis++ /* Turn off the main oscillator */++ ldr r2, [r1, #AT91_CKGR_MOR]+ bic r2, r2, #AT91_PMC_MOSCEN+ str r2, [r1, #AT91_CKGR_MOR]++ /* Wait for interrupt */++ mcr p15, 0, r0, c7, c0, 4++ /* Turn on the main oscillator */++ ldr r2, [r1, #AT91_CKGR_MOR]+ orr r2, r2, #AT91_PMC_MOSCEN+ str r2, [r1, #AT91_CKGR_MOR]++ wait_moscrdy++ /* Restore PLLA setting */++ ldr r2, .saved_pllar+ str r2, [r1, #AT91_CKGR_PLLAR]++ wait_pllalock++ /*+ * Restore master clock setting+ *+ * First set PRES if it was not 0,+ * than set CSS and MDIV fields.+ * After every change wait for+ * MCKRDY.+ *+ * See eratta #2[78] for details.+ */++ ldr r2, .saved_mckr+ tst r2, #0x1C+ beq 2f+ and r2, r2, #0x1C+ str r2, [r1, #AT91_PMC_MCKR]++ wait_mckrdy++2: ldr r2, .saved_mckr+ str r2, [r1, #AT91_PMC_MCKR]++ wait_mckrdy++ mov pc, lr++.saved_mckr:+ .word 0++.saved_pllar:+ .word 0++.at91_va_base_sys:+ .word AT91_VA_BASE_SYS++ENTRY(at91rm9200_slow_clock_sz)+ .word .-at91rm9200_slow_clockdiff -urN -x CVS linux-2.6.20-rc1.orig/drivers/char/Kconfig linux-2.6/drivers/char/Kconfig--- linux-2.6.20-rc1.orig/drivers/char/Kconfig Fri Dec 15 08:36:03 2006+++ linux-2.6/drivers/char/Kconfig Thu Dec 14 14:51:35 2006@@ -1030,5 +1030,21 @@ sysfs directory, /sys/devices/platform/telco_clock, with a number of files for controlling the behavior of this hardware.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -