/* * linux/arch/arm/mach-davinci/clock.c * * TI DaVinci clock config file * * Copyright (C) 2006 Texas Instruments. * * ---------------------------------------------------------------------------- * * 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 program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * 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. * ---------------------------------------------------------------------------- * */ /************************************************************************** * Included Files **************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "clock.h" struct system_regs *SYSTEM = (struct system_regs *)IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE); struct gpio_controller *GPIO[3] = { (struct system_regs *)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10), (struct system_regs *)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38), (struct system_regs *)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60) }; struct timer *TIMER0 = (struct timer *)IO_ADDRESS(DAVINCI_LPSC_TIMER0); struct timer *TIMER1 = (struct timer *)IO_ADDRESS(DAVINCI_LPSC_TIMER1); unsigned char *FLASH = (unsigned char *)EMIF_ADDRESS(0x02000000); /*--- struct timer *TIMER2 = (struct timer *)IO_ADDRESS(DAVINCI_LPSC_TIMER2); ---*/ #define PINMUX0 __REG(0x01c40000) #define PINMUX1 __REG(0x01c40004) #define CHP_SHRTSW __REG(0x01C40038) #define VPSS_CLKCTL __REG(0x01C40044) #define VDD3P3V_PWDN __REG(0x01C40048) #define PLL1_PLLM __REG(0x01c40800 + 0x110) #define PLL2_PLLCTL __REG(0x01c40C00 + 0x100) #define PLL2_PLLM __REG(0x01c40C00 + 0x110) #define PLL2_PLLD1 __REG(0x01c40C00 + 0x118) #define PLL2_PLLD2 __REG(0x01c40C00 + 0x11C) #define PLL2_POSTD __REG(0x01c40C00 + 0x128) #define PLL2_BPDIV __REG(0x01c40C00 + 0x12C) #define EPCPR __REG(0x01C41070) #define EPCCR __REG(0x01C41078) #define GBLCTL __REG(0x01C41010) #define PTCMD __REG(0x01C41120) #define PTSTAT __REG(0x01C41128) #define PDSTAT __REG(0x01C41200) #define PDSTAT1 __REG(0x01C41204) #define PDCTL1 __REG(0x01C41304) #define MDSTAT IO_ADDRESS(0x01C41800) #define MDCTL IO_ADDRESS(0x01C41A00) #define UARTPWREMU_MGMT1 __REG(0x01c20430) #define UARTPWREMU_MGMT2 __REG(0x01c20830) #define GPIO_DIR23 __REG(0x01C67038) #define GPIO_CLR23 __REG(0x01C67044) #define PWM0_PCR __REG(0x01c22004) #define PWM0_CFG __REG(0x01c22008) #define PWM0_START __REG(0x01c2200C) #define PWM0_PERIOD __REG(0x01c22014) #define PWM0_PHASE __REG(0x01c22018) static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clockfw_lock); static unsigned int fixedrate = 27000000; /* Clock Domain: CLKIN, 27 MHZ */ static unsigned int commonrate; static unsigned int dsprate; /* Clock Domain: CLKDIV2 */ static unsigned int armrate; /* Clock Domain: CLKDIV2 */ static unsigned int sequencerrate; static unsigned int edama3vpssrate; static unsigned int videorate; static unsigned int ddrramrate; /* DDR PHY */ static unsigned int vtprate; /* DDR VTP */ /************************************** Routine: board_setup_psc Description: Enable/Disable a PSC domain **************************************/ void board_setup_psc(unsigned int domain, unsigned int id, char enable) { volatile unsigned int *mdstat = (unsigned int *)((int)MDSTAT + 4 * id); volatile unsigned int *mdctl = (unsigned int *)((int)MDCTL + 4 * id); const unsigned int alwaysOnPdNum = 0; static unsigned int once = 1; if((id == DAVINCI_LPSC_IMCOP) && (enable == 1)) { printk(KERN_WARNING "[board_setup_psc] insted of DAVINCI_LPSC_IMCOP use DAVINCI_LPSC_GEM\n"); board_setup_psc(1, DAVINCI_LPSC_GEM, 1); return; } /*--- printk("[board_setup_psc] domain %d id %d ", domain, id); ---*/ if((id != DAVINCI_LPSC_GEM) || (enable == 0) || (enable == 2)) { unsigned int timeout = 100000; #if 0 if (enable) { *mdctl |= 0x00000003; /* Enable Module */ } else { *mdctl &= 0xFFFFFFF2; /* Disable Module */ } #else switch (enable) { case 2: *mdctl &= ~(1<<8); /*--- reset Module ---*/ /*--- printk("reset\n"); ---*/ break; case 1: *mdctl |= 0x00000003; /* Enable Module */ /*--- printk("enable\n"); ---*/ break; default: *mdctl &= 0xFFFFFFF2; /* Disable Module */ /*--- printk("disable\n"); ---*/ break; } #endif if ((PDSTAT & 0x00000001) == 0) { PDCTL1 |= 0x1; PTCMD = (1 << domain); timeout = 100000; while ((((EPCPR >> domain) & 1) == 0) && --timeout); if(timeout == 0) printk("(((EPCPR >> domain) & 1) == 0) timeout\n"); PDCTL1 |= 0x100; timeout = 100000; while (!(((PTSTAT >> domain) & 1) == 0) && --timeout); if(timeout == 0) printk("(((PSTAT >> domain) & 1) == 0) timeout\n"); } else { PTCMD = (1 << domain); timeout = 100000; while (!(((PTSTAT >> domain) & 1) == 0) && --timeout); if(timeout == 0) printk("(((PSTAT >> domain) & 1) == 0) timeout\n"); } if (enable == 2) return; if (enable) { while (!((*mdstat & 0x0000001F) == 0x3)); } else { timeout = 100000; while (!((*mdstat & 0x0000001F) == 0x2) && --timeout); if(timeout == 0) { printk("disable timeout\n"); } else { printk("disabled\n"); } } return; } printk(KERN_WARNING "[board_setup_psc] do DAVINCI_LPSC_IMCOP and DAVINCI_LPSC_GEM\n"); PTCMD = (1 << alwaysOnPdNum); /* Wait for PTSTAT.GOSTAT0 to clear to 0x0 */ while(! (((PTSTAT >> alwaysOnPdNum) & 0x00000001) == 0)); /* DO GEM AND IMCOP INITIALIZATION, ONLY IF DSP POWER DOMAIN IS OFF... */ /* NOTE: this is a precise and refined sequence - use extreme care if modifying! */ printk("[PDSTAT1 ] 0x%x\n", PDSTAT1 ); /*--- if ((PDSTAT1 & 0x1F) == 0) { ---*/ if(once) { unsigned int waiting, i; volatile unsigned int *mdstat_imcop = (unsigned int *)((int)MDSTAT + 4 * DAVINCI_LPSC_IMCOP); volatile unsigned int *mdctl_imcop = (unsigned int *)((int)MDCTL + 4 * DAVINCI_LPSC_IMCOP); const unsigned int dspPdNum = 1; if(PDSTAT1 & 0x1F) { PDCTL1 &= ~1; /* turn power domain off */ } /* set PSC FORCE mode; may not be necessary, added per reference code */ GBLCTL = GBLCTL | 0x01; /* set DSP power domain next state to ON */ PDCTL1 = PDCTL1 | 0x01; /* ensure external power indicator is cleared */ PDCTL1 = PDCTL1 & 0xFFFFFEFF; /* enable DSP module */ *mdctl = (*mdctl & 0xFFFFFFE0) | 0x00000003; /* Enable Module */ /*--- *(volatile unsigned int*) (PSC_ADDR+0xA00+4*LPSC_GEM) = ---*/ /*--- (*(volatile unsigned int*) (PSC_ADDR+0xA00+4*LPSC_GEM) & 0xFFFFFFE0) | 0x3; ---*/ /* hold DSP in reset on next power ON */ *mdctl &= ~0x00000100; /* Enable Module */ /*--- *(volatile unsigned int*) (PSC_ADDR+0xA00+4*LPSC_GEM) = ---*/ /*--- *(volatile unsigned int*) (PSC_ADDR+0xA00+4*LPSC_GEM) & 0xFFFFFEFF; ---*/ /* set IMCOP to Enable state */ *mdctl_imcop = (*mdctl_imcop & 0xFFFFFFE0) | 0x00000003; /* Enable Module */ /*--- *(volatile unsigned int*) (PSC_ADDR+0xA00+4*LPSC_IMCOP) = ---*/ /*--- (*(volatile unsigned int*) (PSC_ADDR+0xA00+4*LPSC_IMCOP) & 0xFFFFFFE0) | 0x3; ---*/ /* hold IMCOP in reset on next power ON */ *mdctl_imcop &= ~0x00000100; /* Enable Module */ /*--- *(volatile unsigned int*) (PSC_ADDR+0xA00+4*LPSC_IMCOP) = ---*/ /*--- *(volatile unsigned int*) (PSC_ADDR+0xA00+4*LPSC_IMCOP) & 0xFFFFFEFF; ---*/ /* start power state transitions for DSP power domain */ PTCMD = (1<> dspPdNum) & 0x00000001) == 1) { waiting = 0; } } /* close rail shorting switch */ CHP_SHRTSW = 0x1; /* set external power good indicator */ PDCTL1 = PDCTL1 | 0x0100; /* clear external power control pending register bit */ EPCCR = (1 << dspPdNum); /* wait for DSP domain transitions to complete */ for (i = 0, waiting = 1; (i < 100) && waiting; i++) { if (((PTSTAT >> dspPdNum) & 0x00000001) == 0) { waiting = 0; } } if(i == 100) printk(KERN_WARNING "[board_setup_psc] DAVINCI_LPSC_GEM wait for DSP domain transitions timeout\n"); /* turn off PSC FORCE mode */ GBLCTL = GBLCTL & 0xFFFFFFFE; once = 0; } else { printk(KERN_WARNING "[board_setup_psc] DAVINCI_LPSC_GEM already enabled, ignore second init\n"); } /* END GEM AND IMCOP INITIALIZATION */ } static char *domain_names[] = { "DAVINCI_LPSC_VPSSMSTR", /* DAVINCI_LPSC_VPSSMSTR 0 VPSS Master LPSC */ "DAVINCI_LPSC_VPSSSLV", /* DAVINCI_LPSC_VPSSSLV 1 VPSS Slave LPSC */ "DAVINCI_LPSC_TPCC", /* DAVINCI_LPSC_TPCC 2 TPCC LPSC */ "DAVINCI_LPSC_TPTC0", /* DAVINCI_LPSC_TPTC0 3 TPTC0 LPSC */ "DAVINCI_LPSC_TPTC1", /* DAVINCI_LPSC_TPTC1 4 TPTC1 LPSC */ "DAVINCI_LPSC_EMAC", /* DAVINCI_LPSC_EMAC 5 EMAC LPSC */ "DAVINCI_LPSC_EMAC_WRAPPER", /* DAVINCI_LPSC_EMAC_WRAPPER 6 EMAC WRAPPER LPSC */ "DAVINCI_LPSC_MDIO", /* DAVINCI_LPSC_MDIO 7 MDIO LPSC */ "DAVINCI_LPSC_IEEE1394", /* DAVINCI_LPSC_IEEE1394 8 IEEE1394 LPSC */ "DAVINCI_LPSC_USB", /* DAVINCI_LPSC_USB 9 USB LPSC */ "DAVINCI_LPSC_ATA", /* DAVINCI_LPSC_ATA 10 ATA LPSC */ "DAVINCI_LPSC_VLYNQ", /* DAVINCI_LPSC_VLYNQ 11 VLYNQ LPSC */ "DAVINCI_LPSC_UHPI", /* DAVINCI_LPSC_UHPI 12 UHPI LPSC */ "DAVINCI_LPSC_DDR_EMIF", /* DAVINCI_LPSC_DDR_EMIF 13 DDR_EMIF LPSC */ "DAVINCI_LPSC_AEMIF", /* DAVINCI_LPSC_AEMIF 14 AEMIF LPSC */ "DAVINCI_LPSC_MMC_SD", /* DAVINCI_LPSC_MMC_SD 15 MMC_SD LPSC */ "DAVINCI_LPSC_MEMSTICK", /* DAVINCI_LPSC_MEMSTICK 16 MEMSTICK LPSC */ "DAVINCI_LPSC_McBSP", /* DAVINCI_LPSC_McBSP 17 McBSP LPSC */ "DAVINCI_LPSC_I2C", /* DAVINCI_LPSC_I2C 18 I2C LPSC */ "DAVINCI_LPSC_UART0", /* DAVINCI_LPSC_UART0 19 UART0 LPSC */ "DAVINCI_LPSC_UART1", /* DAVINCI_LPSC_UART1 20 UART1 LPSC */ "DAVINCI_LPSC_UART2", /* DAVINCI_LPSC_UART2 21 UART2 LPSC */ "DAVINCI_LPSC_SPI", /* DAVINCI_LPSC_SPI 22 SPI LPSC */ "DAVINCI_LPSC_PWM0", /* DAVINCI_LPSC_PWM0 23 PWM0 LPSC */ "DAVINCI_LPSC_PWM1", /* DAVINCI_LPSC_PWM1 24 PWM1 LPSC */ "DAVINCI_LPSC_PWM2", /* DAVINCI_LPSC_PWM2 25 PWM2 LPSC */ "DAVINCI_LPSC_GPIO", /* DAVINCI_LPSC_GPIO 26 GPIO LPSC */ "DAVINCI_LPSC_TIMER0", /* DAVINCI_LPSC_TIMER0 27 TIMER0 LPSC */ "DAVINCI_LPSC_TIMER1", /* DAVINCI_LPSC_TIMER1 28 TIMER1 LPSC */ "DAVINCI_LPSC_TIMER2", /* DAVINCI_LPSC_TIMER2 29 TIMER2 LPSC */ "DAVINCI_LPSC_SYSTEM_SUBSYS", /* DAVINCI_LPSC_SYSTEM_SUBSYS 30 SYSTEM SUBSYSTEM LPSC */ "DAVINCI_LPSC_ARM", /* DAVINCI_LPSC_ARM 31 ARM LPSC */ "DAVINCI_LPSC_SCR2", /* DAVINCI_LPSC_SCR2 32 SCR2 LPSC */ "DAVINCI_LPSC_SCR3", /* DAVINCI_LPSC_SCR3 33 SCR3 LPSC */ "DAVINCI_LPSC_SCR4", /* DAVINCI_LPSC_SCR4 34 SCR4 LPSC */ "DAVINCI_LPSC_CROSSBAR", /* DAVINCI_LPSC_CROSSBAR 35 CROSSBAR LPSC */ "DAVINCI_LPSC_CFG27", /* DAVINCI_LPSC_CFG27 36 CFG27 LPSC */ "DAVINCI_LPSC_CFG3", /* DAVINCI_LPSC_CFG3 37 CFG3 LPSC */ "DAVINCI_LPSC_CFG5", /* DAVINCI_LPSC_CFG5 38 CFG5 LPSC */ "DAVINCI_LPSC_GEM", /* DAVINCI_LPSC_GEM 39 GEM LPSC */ "DAVINCI_LPSC_IMCOP", /* DAVINCI_LPSC_IMCOP 40 IMCOP LPSC */ NULL }; int davinci_show_domain_status(void) { unsigned int id; volatile unsigned int *mdstat; for(id = 0 ; id <= 40 ; id++) { unsigned int i; mdstat = (unsigned int *)((int)MDSTAT + 4 * id); i = *mdstat; printk("[domain:%s] (0x%x) Local Reset %s is %s ", domain_names[id], (i & ((1 << 5) - 1)) == 0 ? "reset-disable" : (i & ((1 << 5) - 1)) == 1 ? "sync-reset" : (i & ((1 << 5) - 1)) == 2 ? "disable" : (i & ((1 << 5) - 1)) == 3 ? "enable" : "in transaction", i & ((1 << 5) - 1), i & (1 << 8) ? "asserted" : "deasserted", i & (1 << 9) ? "not done" : "done"); printk("\n\tModule Reset %s is %s ", i & (1 << 10) ? "asserted" : "deasserted", i & (1 << 11) ? "not done" : "done", i & (1 << 12) ? "on" : "off"); printk("\n\talter module reset interrupt %s, alter module state interrupt %s\n", i & (1 << 16) ? "active" : "inactive", i & (1 << 17) ? "active" : "inactive"); } return 0; } EXPORT_SYMBOL(davinci_show_domain_status); /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static char *_pinmux_bits_vlyqwd[1 << 2] = { "VLYQ one Data Bit", "VLYQ two Data Bits", "VLYQ tree Data Bits", "VLYQ four Data Bits" }; static char *_pinmux_bits_aeaw[1 << 5] = { "[0] GPIO 52-53, 10-28, EM_A 1-2", /* 0 */ "[1] GPIO 53, 10-28, EMBA 1, EM_A 1-2", /* 1 */ "[2] GPIO 10-28, EMBA 1, EM_A 0-2", /* 2 */ "[3] GPIO 10-28, EMBA 1, EM_A 0-2", /* 3 */ "[4] GPIO 10-28, EMBA 1, EM_A 0-2", /* 4 */ "[5] GPIO 10-27, EMBA 1, EM_A 0-3", /* 5 */ "[6] GPIO 10-26, EMBA 1, EM_A 0-4", /* 6 */ "[7] GPIO 10-25, EMBA 1, EM_A 0-5", /* 7 */ "[8] GPIO 10-24, EMBA 1, EM_A 0-6", /* 8 */ "[9] GPIO 10-23, EMBA 1, EM_A 0-7", /* 9 */ "[10] GPIO 10-22, EMBA 1, EM_A 0-8", /* 10 */ "[11] GPIO 10-21, EMBA 1, EM_A 0-9", /* 11 */ "[12] GPIO 10-20, EMBA 1, EM_A 0-10", /* 12 */ "[13] GPIO 10-19, EMBA 1, EM_A 0-11", /* 13 */ "[14] GPIO 10-18, EMBA 1, EM_A 0-12", /* 14 */ "[15] GPIO 10-17, EMBA 1, EM_A 0-13", /* 15 */ "[16] GPIO 10-16, EMBA 1, EM_A 0-14", /* 16 */ "[17] GPIO 10-15, EMBA 1, EM_A 0-15", /* 17 */ "[18] GPIO 10-14, EMBA 1, EM_A 0-16", /* 18 */ "[19] GPIO 10-13, EMBA 1, EM_A 0-17", /* 19 */ "[20] GPIO 10-12, EMBA 1, EM_A 0-18", /* 20 */ "[21] GPIO 10-11, EMBA 1, EM_A 0-19", /* 21 */ "[22] GPIO 10, EMBA 1, EM_A 0-20", /* 22 */ "[23] EMBA 1, EM_A 0-21", /* 23 ++ */ "[24] EMBA 1, EM_A 0-21", /* 24 */ "[25] EMBA 1, EM_A 0-21", /* 25 */ "[26] EMBA 1, EM_A 0-21", /* 26 */ "[27] EMBA 1, EM_A 0-21", /* 27 */ "[28] EMBA 1, EM_A 0-21", /* 28 */ "[29] EMBA 1, EM_A 0-21", /* 29 */ "[30] EMBA 1, EM_A 0-21", /* 30 */ "[31] EMBA 1, EM_A 0-21", /* 31 */ }; static char *_pinmux0_bits[32] = { (char *)5, /* 0 */ (char *)_pinmux_bits_aeaw, /* 1 */ NULL, /* 2 */ NULL, /* 3 */ NULL, /* 4 */ NULL, /* 5 */ NULL, /* 6 */ NULL, /* 7 */ NULL, /* 8 */ NULL, /* 9 */ "AECS4", /* 10 */ "AECS5", /* 11 */ (char *)2, /* 12 */ (char *)_pinmux_bits_vlyqwd, /* 13 */ "VLSCR", /* 14 */ "VLYNQ", /* 15 */ "DHIRE", /* 16 */ "ATAEN", /* 17 */ NULL, /* 18 */ NULL, /* 19 */ NULL, /* 20 */ NULL, /* 21 */ "RGB66", /* 22 */ "RGB88", /* 23 */ "LOEEN", /* 24 */ "LFLDEN", /* 25 */ "CWEN", /* 26 */ "CFLDEN", /* 27 */ NULL, /* 28 */ NULL, /* 29 */ NULL, /* 30 */ "EMACEN" /* 31 */ }; static char *_pinmux1_bits[32] = { "UART0", /* 0 */ "UART1", /* 1 */ "UART2", /* 2 */ "U2FLO", /* 3 */ "PWM0", /* 4 */ "PWM1", /* 5 */ "PWM2", /* 6 */ "I2C", /* 7 */ "SPI", /* 8 */ NULL, /* 9 */ "ASP", /* 10 */ NULL, /* 11 */ NULL, /* 12 */ NULL, /* 13 */ NULL, /* 14 */ NULL, /* 15 */ "CLK0", /* 16 */ "CLK1", /* 17 */ "TIMIN", /* 18 */ NULL, /* 19 */ NULL, /* 20 */ NULL, /* 21 */ NULL, /* 22 */ NULL, /* 23 */ NULL, /* 24 */ NULL, /* 25 */ NULL, /* 26 */ NULL, /* 27 */ NULL, /* 28 */ NULL, /* 29 */ NULL, /* 30 */ NULL /* 31 */ }; /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void show_register_bits(char *text, char **bits, unsigned int register_value) { unsigned int i; unsigned int value; printk("%s: ", text); for(i = 0 ; i < 32 ; i++) { if(bits[i] == NULL) continue; if((unsigned int)bits[i] < 31) { char **p; unsigned int ii; ii = (unsigned int)bits[i]; p = (char **)bits[i + 1]; value = (register_value >> i) & ((1 << ii) - 1); printk(" %s\n", p[value]); i++; continue; } value = register_value & (1 << i); printk(" %s=%s", bits[i], value ? "ein" : "aus"); } printk("\n"); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void show_pinmux0(void) { show_register_bits("PINMUX0", _pinmux0_bits, PINMUX0); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void show_pinmux1(void) { show_register_bits("PINMUX1", _pinmux1_bits, PINMUX1); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int alloc_gpio_resource(unsigned int start, unsigned int end, unsigned long flags) { while(start <= end) if(board_setup_gpio("resource", start++)) return -EFAULT; return 0; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int board_setup_gpio(char *text, unsigned int gpio) { union _pinmux0_ *pinmux0 = (union _pinmux0_ *)io_p2v(PINMUX0); union _pinmux1_ *pinmux1 = (union _pinmux1_ *)io_p2v(PINMUX1); unsigned int aeaw = (unsigned int)-1; switch(gpio) { case 0: pinmux0->Bits.loeen = 0; break; case 1: pinmux0->Bits.cwen = 0; break; /*--- case 2: ---*/ /*--- case 3: ---*/ case 4: case 5: case 6: case 7: aeaw = 0x13; break; case 8: pinmux0->Bits.aecs5 = 0; pinmux0->Bits.vlynqen = 0; break; case 9: if(pinmux0->Bits.vlynqen == 1) { pinmux0->Bits.vlscren = 0; } pinmux0->Bits.aecs4 = 0; break; case 10: case 11: aeaw = 32 - gpio; pinmux0->Bits.vlynqen = 0; break; case 12: /* vlynqwd = 0 */ case 13: /* vlynqwd = 0 */ case 14: /* vlynqwd = 1 */ case 15: /* vlynqwd = 1 */ case 16: /* vlynqwd = 2 */ case 17: /* vlynqwd = 2 */ aeaw = 32 - gpio; if(pinmux0->Bits.vlynqen == 0) { break; } pinmux0->Bits.vlynqwd = (gpio >> 1) - 6; break; case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: aeaw = 32 - gpio; break; case 52: aeaw = 0; break; case 53: aeaw = 1; break; case 29: case 30: case 31: case 32: case 33: case 34: pinmux1->Bits.aspen = 0; break; case 35: case 36: pinmux1->Bits.uart0en = 0; break; case 42: pinmux0->Bits.hdiren = 0; /*--- kein break ---*/ case 37: case 38: case 39: case 40: case 41: /*--- * GPI41 = D201, yellow => SPI = 0 haengt am SPI Data Out und am /DVI_RESET_1V8 ---*/ pinmux1->Bits.spien = 0; break; case 43: case 44: pinmux1->Bits.i2cen = 0; break; case 46: case 47: pinmux0->Bits.rgb888 = 0; /*--- kein break ---*/ case 45: pinmux1->Bits.pwm2en = 0; pinmux1->Bits.pwm1en = 0; pinmux1->Bits.pwm0en = 0; break; case 48: break; /* immer GPIO */ case 49: pinmux1->Bits.timinen = 0; break; case 50: case 51: pinmux0->Bits.ataen = 0; break; default: printk("[board_setup_gpio] gpio %u not supported yet (%s)\n", gpio, text); return -EFAULT; } if(aeaw != (unsigned int)-1) { if(pinmux0->Bits.aeaw > aeaw) { printk("[board_setup_gpio] set new aeaw value %u in pinmux0\n", aeaw); pinmux0->Bits.aeaw = aeaw; } } printk("[board_setup_gpio] gpio %u (%s) enabled\n", gpio, text); return 0; } EXPORT_SYMBOL(board_setup_gpio); /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void board_setup_peripheral(unsigned int id) { switch (id) { case DAVINCI_LPSC_VLYNQ: /*--- PINMUX0 = (PINMUX0 & ~0xFFFF) | (19 << 0) | (1 << 15) | (1 << 14) | (1 << 12); ---*/ /*------------------------------------------------------------------------------*\ * da wir den GPIO fuer eine LED benoetigen muss das Bit 14 (VLSCREN) = 0 sein \*------------------------------------------------------------------------------*/ PINMUX0 = (PINMUX0 & ~0xFFFF) | (19 << 0) | (1 << 15) | (1 << 12); davinci_i2c_expander_op(CONFIG_DAVINCI_I2C_EXPANDER_ADDR, VLYNQ_ON, 0); break; case DAVINCI_LPSC_GEM: break; case DAVINCI_LPSC_ATA: PINMUX0 |= (1 << 17) | (1 << 16); break; case DAVINCI_LPSC_EMAC_WRAPPER: davinci_i2c_expander_op(CONFIG_DAVINCI_I2C_EXPANDER_ADDR, EPHY_RESET, 0); board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_EMAC, 1); /*--- kein break; ---*/ case DAVINCI_LPSC_EMAC: board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_MDIO, 1); /* VDD power manupulations are done in U-Boot for CPMAC * so applies to MMC as well */ PINMUX0 |= (1 << 31); VDD3P3V_PWDN = 0x0; break; case DAVINCI_LPSC_MMC_SD: /* VDD power manupulations are done in U-Boot for CPMAC * so applies to MMC as well */ /*Set up the pull regiter for MMC */ VDD3P3V_PWDN = 0x0; PINMUX1 &= (~(1 << 9)); break; case DAVINCI_LPSC_I2C: PINMUX1 |= (1 << 7); break; case DAVINCI_LPSC_McBSP: PINMUX1 |= (1 << 10); break; case DAVINCI_LPSC_UART0: /* UART1 run free */ PINMUX1 |= (1 << 0); break; case DAVINCI_LPSC_UART1: /* UART1 run free */ UARTPWREMU_MGMT1 = 0x0000E003; PINMUX1 |= (1 << 1); break; case DAVINCI_LPSC_UART2: /* UART2 run free */ UARTPWREMU_MGMT2 = 0x0000E003; PINMUX1 |= (1 << 2); break; case DAVINCI_LPSC_PWM0: PINMUX1 |= (1 << 4); /*GPIO_CLR23 |= (1<<13);*/ /*GPIO_DIR23 &= ~(1<<13);*/ /*printk("*** PWM0 enabled\n");*/ PWM0_PERIOD = 32*8-1; if(davinci_revision[1] != 0 ) { PWM0_PHASE = 32*4; } else { PWM0_PHASE = 32*3; } PWM0_PCR = 1; PWM0_CFG = (1<<17) | (1<<4) | (2<<0); PWM0_START = 1; case DAVINCI_LPSC_GPIO: /* used for LEDs: * GPIO0 = D100, yellow => LCD_OE = 0 * GPIO1 = D601, yellow => C_WEN = 0 * GPI41 = D201, yellow => SPI = 0 haengt am SPI Data Out und am /DVI_RESET_1V8 * GPI50 = D200, yellow => ATA = 0 * GPI09 = D400, yellow => VLYQEN = 1, VLSCREN = 1 or VLYQEN = 0, AECS4 = 0 */ /*--- board_setup_gpio("LED1, yellow, D100", 0); ---*/ /*--- board_setup_gpio("LED2, yellow, D601", 1); ---*/ /*--- board_setup_gpio("LED3, yellow", 9); ---*/ /*--- board_setup_gpio("LED4, yellow", 41); ---*/ /*--- board_setup_gpio("LED5, yellow", 50); ---*/ /* * used for other perpose * GPIO51 => ATA = 0 : /WLAN_INTR * GPIO07 => : /MSP430_INT * * */ break; case DAVINCI_LPSC_TIMER0: /* enable TIM_IN0 as ext clock source for timer module (AVSYNC) */ /* printk("*** TIM_IN0 enabled\n"); */ PINMUX1 |= (1 << 18); break; default: break; } /*--- show_pinmux0(); ---*/ /*--- show_pinmux1(); ---*/ /*--- davinci_show_domain_status(); ---*/ } /* * Returns a clock. Note that we first try to use device id on the bus * and clock name. If this fails, we try to use clock name only. */ struct clk *clk_get(struct device *dev, const char *id) { struct clk *p, *clk = ERR_PTR(-ENOENT); int idno; printk("[clk_get %s]\n", id); if (dev == NULL || dev->bus != &platform_bus_type) idno = -1; else idno = to_platform_device(dev)->id; mutex_lock(&clocks_mutex); list_for_each_entry(p, &clocks, node) { if (p->id == idno && strcmp(id, p->name) == 0 && try_module_get(p->owner)) { clk = p; goto found; } } list_for_each_entry(p, &clocks, node) { if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { clk = p; break; } } found: mutex_unlock(&clocks_mutex); return clk; } EXPORT_SYMBOL(clk_get); void clk_put(struct clk *clk) { if (clk && !IS_ERR(clk)) module_put(clk->owner); } EXPORT_SYMBOL(clk_put); int __clk_enable(struct clk *clk) { if (clk->flags & ALWAYS_ENABLED) return 0; printk("[clk_enable %s]\n", clk->name); board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 1); return 0; } void __clk_disable(struct clk *clk) { if (clk->usecount) return; printk("[clk_disable %s]\n", clk->name); board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 0); } int clk_enable(struct clk *clk) { unsigned long flags; int ret = 0; if (clk == NULL || IS_ERR(clk)) return -EINVAL; if (clk->usecount == -1) { clk->usecount = 0; } if (clk->usecount++ == 0) { spin_lock_irqsave(&clockfw_lock, flags); ret = __clk_enable(clk); spin_unlock_irqrestore(&clockfw_lock, flags); board_setup_peripheral(clk->lpsc); } return ret; } EXPORT_SYMBOL(clk_enable); void clk_disable(struct clk *clk) { unsigned long flags; if (clk == NULL || IS_ERR(clk)) return; if (clk->usecount > 0 && !(--clk->usecount)) { spin_lock_irqsave(&clockfw_lock, flags); __clk_disable(clk); spin_unlock_irqrestore(&clockfw_lock, flags); } } EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { if (clk == NULL || IS_ERR(clk)) return 0; return *(clk->rate); } EXPORT_SYMBOL(clk_get_rate); int clk_register(struct clk *clk) { if (clk == NULL || IS_ERR(clk)) return -EINVAL; mutex_lock(&clocks_mutex); list_add(&clk->node, &clocks); mutex_unlock(&clocks_mutex); return 0; } EXPORT_SYMBOL(clk_register); void clk_unregister(struct clk *clk) { if (clk == NULL || IS_ERR(clk)) return; mutex_lock(&clocks_mutex); list_del(&clk->node); mutex_unlock(&clocks_mutex); } EXPORT_SYMBOL(clk_unregister); static struct clk davinci_clks[] = { { .name = "ARMCLK", .rate = &armrate, .lpsc = -1, .flags = ALWAYS_ENABLED, }, { .name = "UART", .rate = &fixedrate, .lpsc = DAVINCI_LPSC_UART0, .usecount = -1, }, { .name = "UART1", .rate = &fixedrate, .lpsc = DAVINCI_LPSC_UART1, /*--- .usecount = -1, ---*/ }, { .name = "UART2", .rate = &fixedrate, .lpsc = DAVINCI_LPSC_UART2, .usecount = -1, }, { .name = "dummy_EMACCLK", .rate = &commonrate, .lpsc = DAVINCI_LPSC_EMAC, }, { .name = "EMACCLK", .rate = &commonrate, .lpsc = DAVINCI_LPSC_EMAC_WRAPPER, }, { .name = "I2CCLK", .rate = &fixedrate, .lpsc = DAVINCI_LPSC_I2C, }, { .name = "IDECLK", .rate = &commonrate, .lpsc = DAVINCI_LPSC_ATA, }, { .name = "McBSPCLK", .rate = &commonrate, .lpsc = DAVINCI_LPSC_McBSP, }, { .name = "MMCSDCLK", .rate = &commonrate, .lpsc = DAVINCI_LPSC_MMC_SD, }, { .name = "SPICLK", .rate = &commonrate, .lpsc = DAVINCI_LPSC_SPI, }, { .name = "gpio", .rate = &commonrate, .lpsc = DAVINCI_LPSC_GPIO, }, { .name = "PWM0", .rate = &commonrate, .lpsc = DAVINCI_LPSC_PWM0, .usecount = -1, }, { .name = "AEMIFCLK", .rate = &commonrate, .lpsc = DAVINCI_LPSC_AEMIF, .usecount = -1, }, { .name = "DDRRAMCLK", .rate = &ddrramrate, .lpsc = DAVINCI_LPSC_DDR_EMIF, .usecount = -1, }, { .name = "VIDEOCLK", .rate = &videorate, .lpsc = DAVINCI_LPSC_DDR_EMIF, }, { .name = "VTPCLK", .rate = &vtprate, .lpsc = -1, }, { .name = "DSPCLK", .rate = &dsprate, .lpsc = DAVINCI_LPSC_GEM, }, { .name = "VICPCLK", .rate = &dsprate, .lpsc = DAVINCI_LPSC_IMCOP, }, { .name = "VLYNQCLK", .rate = &commonrate, .lpsc = DAVINCI_LPSC_VLYNQ, }, { .name = "TIMERCLK", .rate = &commonrate, .lpsc = DAVINCI_LPSC_TIMER0, /*--- .usecount = -1, ---*/ }, }; int __init davinci_clk_init(void) { struct clk *clkp; int count = 0; dsprate = ((PLL1_PLLM + 1) * fixedrate) / 1; armrate = ((PLL1_PLLM + 1) * fixedrate) / 2; /* Clock Domain CLKDIV2 */ sequencerrate = ((PLL1_PLLM + 1) * fixedrate) / 4; edama3vpssrate = ((PLL1_PLLM + 1) * fixedrate) / 3; commonrate = ((PLL1_PLLM + 1) * fixedrate) / 6; count = fixedrate; vtprate = count / ((PLL2_BPDIV & ((1 << 5) - 1)) + 1); if(PLL2_PLLCTL & 0x01) count = (PLL2_PLLM + 1) * fixedrate; count /= ((PLL2_POSTD & ((1 << 5) - 1)) + 1); videorate = count / ((PLL2_PLLD1 & ((1 << 5) - 1)) + 1); ddrramrate = count / ((PLL2_PLLD2 & ((1 << 5) - 1)) + 1); count = 0; for (clkp = davinci_clks; count < ARRAY_SIZE(davinci_clks); count++, clkp++) { clk_register(clkp); /* Turn on clocks that have been enabled in the * table above */ if (clkp->usecount) clk_enable(clkp); } return 0; } #ifdef CONFIG_PROC_FS #include #include static void *davinci_ck_start(struct seq_file *m, loff_t *pos) { return *pos < 1 ? (void *)1 : NULL; } static void *davinci_ck_next(struct seq_file *m, void *v, loff_t *pos) { ++*pos; return NULL; } static void davinci_ck_stop(struct seq_file *m, void *v) { } int davinci_ck_show(struct seq_file *m, void *v) { struct clk *cp; list_for_each_entry(cp, &clocks, node) seq_printf(m,"%s %d %d\n", cp->name, *(cp->rate), cp->usecount); davinci_show_domain_status(); show_pinmux0(); show_pinmux1(); return 0; } static struct seq_operations davinci_ck_op = { .start = davinci_ck_start, .next = davinci_ck_next, .stop = davinci_ck_stop, .show = davinci_ck_show }; static int davinci_ck_open(struct inode *inode, struct file *file) { return seq_open(file, &davinci_ck_op); } static struct file_operations proc_davinci_ck_operations = { .open = davinci_ck_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, }; int __init davinci_ck_proc_init(void) { struct proc_dir_entry *entry; entry = create_proc_entry("davinci_clocks", 0, NULL); if (entry) entry->proc_fops = &proc_davinci_ck_operations; return 0; } static int davinci_dsp_enable(void) { printk(KERN_WARNING "[davinci_dsp_enable] init DSP subsystem\n"); davinci_i2c_expander_op(CONFIG_DAVINCI_I2C_EXPANDER_ADDR, VDDIMX_EN, 1); board_setup_psc(DAVINCI_GPSC_DSPDOMAIN, DAVINCI_LPSC_IMCOP, 1); return 0; } late_initcall(davinci_dsp_enable); /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #define MHZ(a) ((a) * 1000000) int davinci_clock_control(unsigned int pll_index, unsigned int output_index, unsigned int frequency) { unsigned int pll_base = pll_index == 0 ? PLL1_BASE : PLL2_BASE; volatile unsigned int *div_base; switch(output_index) { case 0: /* dummy all for disable */ break; case 1: div_base = (volatile unsigned int *)(pll_base + PLLDIV1_OFFSET); break; case 2: div_base = (volatile unsigned int *)(pll_base + PLLDIV2_OFFSET); break; case 3: div_base = (volatile unsigned int *)(pll_base + PLLDIV3_OFFSET); break; case 4: div_base = (volatile unsigned int *)(pll_base + PLLDIV4_OFFSET); break; case 5: div_base = (volatile unsigned int *)(pll_base + PLLDIV5_OFFSET); break; default: return -EIO; } if((frequency == MHZ(27)) && (output_index == 0)) { union _pll_ctl_ *pll_ctrl = (union _pll_ctl_ *)IO_ADDRESS(pll_base + PLLCTL_OFFSET); pll_ctrl ->Bits.pllen = 0; return 0; } return 1; } __initcall(davinci_ck_proc_init); #endif /* CONFIG_DEBUG_PROC_FS */