Resending as the previous mail didnt go through Adding TI PRCM APIs for controlling the PRCM hardware Signed-off-by: Karthik Dasu <karthik-dp@xxxxxx> Acked-by: Richard Woodruff <r-woodruff2@xxxxxx> Acked-by: Vikram Pandita <vikram.pandita@xxxxxx> --- arch/arm/mach-omap2/prcm-regs.h | 322 +++++ arch/arm/mach-omap2/prcm_34xx.c | 2062 ++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/sram-fn_34xx.S | 156 ++ include/asm-arm/arch-omap/prcm_34xx.h | 785 ++++++++++++ 4 files changed, 3325 insertions(+) Index: git-latest5/arch/arm/mach-omap2/prcm-regs.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ git-latest5/arch/arm/mach-omap2/prcm-regs.h 2008-03-04 04:46:12.159937759 +0530 @@ -0,0 +1,322 @@ +/* + * linux/arch/arm/mach-omap2/prcm-reg.h + * + * OMAP34XX Power Reset and Clock Management (PRCM) registers + * + * Copyright (C) 2008 Texas Instruments, Inc. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ARCH_ARM_MACH_OMAP3_PRCM_H +#define __ARCH_ARM_MACH_OMAP3_PRCM_H + +#ifndef __ASSEMBLER__ + +#define PRM_REG32(offset) __REG32(PRM_BASE + (offset)) +#define CM_REG32(offset) __REG32(CM_BASE + (offset)) + +/* MASK values for some DPLL/CLOCK/POWER registers */ +/* DPLL1/2/3/5 enable/put_in_bypass MASK */ +#define DPLL_ENBIT_MASK 0xFFFFFFF8 +/* DPLL4 enable/put_in_bypass MASK */ +#define DPLL4_ENBIT_MASK 0xFFF8FFFF +/* DPLL1/2/4 Divisor(N) value MASK */ +#define DPLL_N_MASK 0xFFFFFF80 +/* DPLL3 Divisor(N_ value MASK */ +#define DPLL3_N_MASK 0xFFFF80FF +/* System clock divisor MASK */ +#define SYSCLK_DIV_MASK 0xFFFFFF3F +/* External output clock 1/2 control MASK */ +#define EXTCLK_OUTCTRL_MASK 0xFFFFFF7F +/* Power domain IN_TRANSITION MASK */ +#define PWSTST_INTRANS_MASK 0x00100000 +/* Power Domain state MASK */ +#define PWSTST_PWST_MASK 0x00000003 +/* Bit fields in RSTST registers */ +#define DOM_WKUP_RST 0x4 +#define COREDOM_WKUP_RST 0x8 + +/* CM Module Registers */ +/* IVA2_CM Registers */ +#define CM_FCLKEN_IVA2 CM_REG32(0x0) +#define CM_CLKEN_PLL_IVA2 CM_REG32(0x4) +#define CM_IDLEST_IVA2 CM_REG32(0x20) +#define CM_IDLEST_PLL_IVA2 CM_REG32(0x24) +#define CM_AUTOIDLE_PLL_IVA2 CM_REG32(0x34) +#define CM_CLKSEL1_PLL_IVA2 CM_REG32(0x40) +#define CM_CLKSEL2_PLL_IVA2 CM_REG32(0x44) +#define CM_CLKSTCTRL_IVA2 CM_REG32(0x48) +#define CM_CLKSTST_IVA2 CM_REG32(0x4C) + +/* OCP System Register CM */ +#define CM_REVISION CM_REG32(0x800) +#define CM_SYSCONFIG CM_REG32(0x810) + +/* MPU_CM Registers */ +#define CM_CLKEN_PLL_MPU CM_REG32(0x904) +#define CM_IDLEST_MPU CM_REG32(0x920) +#define CM_IDLEST_PLL_MPU CM_REG32(0x924) +#define CM_AUTOIDLE_PLL_MPU CM_REG32(0x934) +#define CM_CLKSEL1_PLL_MPU CM_REG32(0x940) +#define CM_CLKSEL2_PLL_MPU CM_REG32(0x944) +#define CM_CLKSTCTRL_MPU CM_REG32(0x948) +#define CM_CLKSTST_MPU CM_REG32(0x94C) + +/* CORE_CM Registers */ +#define CM_FCLKEN1_CORE CM_REG32(0xA00) +#define CM_ICLKEN1_CORE CM_REG32(0xA10) +#define CM_ICLKEN2_CORE CM_REG32(0xA14) +#define CM_IDLEST1_CORE CM_REG32(0xA20) +#define CM_IDLEST2_CORE CM_REG32(0xA24) +#define CM_AUTOIDLE1_CORE CM_REG32(0xA30) +#define CM_AUTOIDLE2_CORE CM_REG32(0xA34) +#define CM_CLKSEL_CORE CM_REG32(0xA40) +#define CM_CLKSTCTRL_CORE CM_REG32(0xA48) +#define CM_CLKSTST_CORE CM_REG32(0xA4C) + +#define CM_FCLKEN3_CORE CM_REG32(0xA08) +#define CM_ICLKEN3_CORE CM_REG32(0xA18) +#define CM_IDLEST3_CORE CM_REG32(0xA28) +#define CM_AUTOIDLE3_CORE CM_REG32(0xA38) + +/* GFX_CM Registers */ +#define CM_FCLKEN_SGX CM_REG32(0xB00) +#define CM_ICLKEN_SGX CM_REG32(0xB10) +#define CM_IDLEST_SGX CM_REG32(0xB20) +#define CM_CLKSEL_SGX CM_REG32(0xB40) +#define CM_SLEEPDEP_SGX CM_REG32(0xB44) +#define CM_CLKSTCTRL_SGX CM_REG32(0xB48) +#define CM_CLKSTST_SGX CM_REG32(0xB4C) + +/* WKUP_CM Registers */ +#define CM_FCLKEN_WKUP CM_REG32(0xC00) +#define CM_ICLKEN_WKUP CM_REG32(0xC10) +#define CM_IDLEST_WKUP CM_REG32(0xC20) +#define CM_AUTOIDLE_WKUP CM_REG32(0xC30) +#define CM_CLKSEL_WKUP CM_REG32(0xC40) + +/* CM Clock control registers */ +#define CM_CLKEN_PLL CM_REG32(0xD00) +#define CM_IDLEST_CKGEN CM_REG32(0xD20) +#define CM_AUTOIDLE_PLL CM_REG32(0xD30) +#define CM_CLKSEL1_PLL CM_REG32(0xD40) +#define CM_CLKSEL2_PLL CM_REG32(0xD44) +#define CM_CLKSEL3_PLL CM_REG32(0xD48) +#define CM_CLKOUT_CTRL CM_REG32(0xD70) + +#define CM_CLKEN2_PLL CM_REG32(0xD04) +#define CM_IDLEST2_CKGEN CM_REG32(0xD24) +#define CM_AUTOIDLE2_PLL CM_REG32(0xD34) +#define CM_CLKSEL4_PLL CM_REG32(0xD4C) +#define CM_CLKSEL5_PLL CM_REG32(0xD50) + +/* DSS_CM Registers */ +#define CM_FCLKEN_DSS CM_REG32(0xE00) +#define CM_ICLKEN_DSS CM_REG32(0xE10) +#define CM_IDLEST_DSS CM_REG32(0xE20) +#define CM_AUTOIDLE_DSS CM_REG32(0xE30) +#define CM_CLKSEL_DSS CM_REG32(0xE40) +#define CM_SLEEPDEP_DSS CM_REG32(0xE44) +#define CM_CLKSTCTRL_DSS CM_REG32(0xE48) +#define CM_CLKSTST_DSS CM_REG32(0xE4C) + +/* CAM_CM Registers */ +#define CM_FCLKEN_CAM CM_REG32(0xF00) +#define CM_ICLKEN_CAM CM_REG32(0xF10) +#define CM_IDLEST_CAM CM_REG32(0xF20) +#define CM_AUTOIDLE_CAM CM_REG32(0xF30) +#define CM_CLKSEL_CAM CM_REG32(0xF40) +#define CM_SLEEPDEP_CAM CM_REG32(0xF44) +#define CM_CLKSTCTRL_CAM CM_REG32(0xF48) +#define CM_CLKSTST_CAM CM_REG32(0xF4C) + +/* PER_CM Registers */ +#define CM_FCLKEN_PER CM_REG32(0x1000) +#define CM_ICLKEN_PER CM_REG32(0x1010) +#define CM_IDLEST_PER CM_REG32(0x1020) +#define CM_AUTOIDLE_PER CM_REG32(0x1030) +#define CM_CLKSEL_PER CM_REG32(0x1040) +#define CM_SLEEPDEP_PER CM_REG32(0x1044) +#define CM_CLKSTCTRL_PER CM_REG32(0x1048) +#define CM_CLKSTST_PER CM_REG32(0x104C) + +/* EMU_CM Registers */ +#define CM_CLKSEL1_EMU CM_REG32(0x1140) +#define CM_CLKSTCTRL_EMU CM_REG32(0x1148) +#define CM_CLKSTST_EMU CM_REG32(0x114C) +#define CM_CLKSEL2_EMU CM_REG32(0x1150) +#define CM_CLKSEL3_EMU CM_REG32(0x1154) + +/* Global Registers CM */ +#define CM_POLCTRL CM_REG32(0x129C) + +/* NEON_CM */ +#define CM_IDLEST_NEON CM_REG32(0x1320) +#define CM_CLKSTCTRL_NEON CM_REG32(0x1348) + +/* USBHOST_CM registers */ +#define CM_FCLKEN_USBHOST CM_REG32(0x1400) +#define CM_ICLKEN_USBHOST CM_REG32(0x1410) +#define CM_IDLEST_USBHOST CM_REG32(0x1420) +#define CM_AUTOIDLE_USBHOST CM_REG32(0x1430) +#define CM_SLEEPDEP_USBHOST CM_REG32(0x1444) +#define CM_CLKSTCTRL_USBHOST CM_REG32(0x1448) +#define CM_CLKSTST_USBHOST CM_REG32(0x144C) + +/* PRM Module Registers */ +/* IVA2_PRM */ +#define RM_RSTCTRL_IVA2 PRM_REG32(0x50) +#define RM_RSTST_IVA2 PRM_REG32(0x58) +#define PM_WKDEP_IVA2 PRM_REG32(0xC8) +#define PM_PWSTCTRL_IVA2 PRM_REG32(0xE0) +#define PM_PWSTST_IVA2 PRM_REG32(0xE4) +#define PM_PREPWSTST_IVA2 PRM_REG32(0xE8) +#define PRM_IRQSTATUS_IVA2 PRM_REG32(0xF8) +#define PRM_IRQENABLE_IVA2 PRM_REG32(0xFC) + +/* OCP System Registers PRM */ +#define PRM_REVISION PRM_REG32(0x804) +#define PRM_SYSCONFIG PRM_REG32(0x814) +#define PRM_IRQSTATUS_MPU PRM_REG32(0x818) +#define PRM_IRQENABLE_MPU PRM_REG32(0x81C) + +/* MPU_PRM Registers */ +#define RM_RSTST_MPU PRM_REG32(0x958) +#define PM_WKDEP_MPU PRM_REG32(0x9C8) +#define PM_EVGENCTRL_MPU PRM_REG32(0x9D4) +#define PM_EVGENONTIM_MPU PRM_REG32(0x9D8) +#define PM_EVGENOFFTIM_MPU PRM_REG32(0x9DC) +#define PM_PWSTCTRL_MPU PRM_REG32(0x9E0) +#define PM_PWSTST_MPU PRM_REG32(0x9E4) +#define PM_PREPWSTST_MPU PRM_REG32(0x9E8) + +/* CORE_PRM Registers */ +#define RM_RSTCTRL_CORE PRM_REG32(0xA50) +#define RM_RSTST_CORE PRM_REG32(0xA58) +#define PM_WKEN1_CORE PRM_REG32(0xAA0) +#define PM_MPUGRPSEL1_CORE PRM_REG32(0xAA4) +#define PM_IVA2GRPSEL1_CORE PRM_REG32(0xAA8) +#define PM_WKST1_CORE PRM_REG32(0xAB0) +#define PM_PWSTCTRL_CORE PRM_REG32(0xAE0) +#define PM_PWSTST_CORE PRM_REG32(0xAE4) +#define PM_PREPWSTST_CORE PRM_REG32(0xAE8) + +#define PM_WKST3_CORE PRM_REG32(0xAB8) +#define PM_WKEN3_CORE PRM_REG32(0xAF0) +#define PM_IVA2GRPSEL3_CORE PRM_REG32(0xAF4) +#define PM_MPUGRPSEL3_CORE PRM_REG32(0xAF8) + +/* GFX_PRM Registers */ +#define RM_RSTST_SGX PRM_REG32(0xB58) +#define PM_WKDEP_SGX PRM_REG32(0xBC8) +#define PM_PWSTCTRL_SGX PRM_REG32(0xBE0) +#define PM_PWSTST_SGX PRM_REG32(0xBE4) +#define PM_PREPWSTST_SGX PRM_REG32(0xBE8) + +/* WKUP_PRM Registers */ +#define PM_WKEN_WKUP PRM_REG32(0xCA0) +#define PM_MPUGRPSEL_WKUP PRM_REG32(0xCA4) +#define PM_IVA2GRPSEL_WKUP PRM_REG32(0xCA8) +#define PM_WKST_WKUP PRM_REG32(0xCB0) + +/* Clock control registers PRM */ +#define PRM_CLKSEL PRM_REG32(0xD40) +#define PRM_CLKOUT_CTRL PRM_REG32(0xD70) + +/* DSS_PRM registers */ +#define RM_RSTST_DSS PRM_REG32(0xE58) +#define PM_WKEN_DSS PRM_REG32(0xEA0) +#define PM_WKDEP_DSS PRM_REG32(0xEC8) +#define PM_PWSTCTRL_DSS PRM_REG32(0xEE0) +#define PM_PWSTST_DSS PRM_REG32(0xEE4) +#define PM_PREPWSTST_DSS PRM_REG32(0xEE8) + +/* CAM_PRM registers */ +#define RM_RSTST_CAM PRM_REG32(0xF58) +#define PM_WKDEP_CAM PRM_REG32(0xFC8) +#define PM_PWSTCTRL_CAM PRM_REG32(0xFE0) +#define PM_PWSTST_CAM PRM_REG32(0xFE4) +#define PM_PREPWSTST_CAM PRM_REG32(0xFE8) + +/* PER_PRM registers */ +#define RM_RSTST_PER PRM_REG32(0x1058) +#define PM_WKEN_PER PRM_REG32(0x10A0) +#define PM_MPUGRPSEL_PER PRM_REG32(0x10A4) +#define PM_IVA2GRPSEL_PER PRM_REG32(0x10A8) +#define PM_WKST_PER PRM_REG32(0x10B0) +#define PM_WKDEP_PER PRM_REG32(0x10C8) +#define PM_PWSTCTRL_PER PRM_REG32(0x10E0) +#define PM_PWSTST_PER PRM_REG32(0x10E4) +#define PM_PREPWSTST_PER PRM_REG32(0x10E8) + +/* EMU_PRM registers */ +#define RM_RSTST_EMU PRM_REG32(0x1158) +#define PM_PWSTST_EMU PRM_REG32(0x11E4) + +/* Global Registers PRM */ +#define PRM_VC_SMPS_SA PRM_REG32(0x1220) +#define PRM_VC_SMPS_VOL_RA PRM_REG32(0x1224) +#define PRM_VC_SMPS_CMD_RA PRM_REG32(0x1228) +#define PRM_VC_CMD_VAL_0 PRM_REG32(0x122C) +#define PRM_VC_CMD_VAL_1 PRM_REG32(0x1230) +#define PRM_VC_CH_CONF PRM_REG32(0x1234) +#define PRM_VC_I2C_CFG PRM_REG32(0x1238) +#define PRM_VC_BYPASS_VAL PRM_REG32(0x123C) +#define PRM_RSTCTRL PRM_REG32(0x1250) +#define PRM_RSTTIME PRM_REG32(0x1254) +#define PRM_RSTST PRM_REG32(0x1258) +#define PRM_VOLTCTRL PRM_REG32(0x1260) +#define PRM_SRAM_PCHARGE PRM_REG32(0x1264) +#define PRM_CLKSRC_CTRL PRM_REG32(0x1270) +#define PRM_VOLTSETUP1 PRM_REG32(0x1290) +#define PRM_VOLTOFFSET PRM_REG32(0x1294) +#define PRM_CLKSETUP PRM_REG32(0x1298) +#define PRM_POLCTRL PRM_REG32(0x129C) +#define PRM_VOLTSETUP2 PRM_REG32(0x12A0) +#define PRM_VP1_CONFIG PRM_REG32(0x12B0) +#define PRM_VP1_VSTEPMIN PRM_REG32(0x12B4) +#define PRM_VP1_VSTEPMAX PRM_REG32(0x12B8) +#define PRM_VP1_VLIMITTO PRM_REG32(0x12BC) +#define PRM_VP1_VOLTAGE PRM_REG32(0x12C0) +#define PRM_VP1_STATUS PRM_REG32(0x12C4) +#define PRM_VP2_CONFIG PRM_REG32(0x12D0) +#define PRM_VP2_VSTEPMIN PRM_REG32(0x12D4) +#define PRM_VP2_VSTEPMAX PRM_REG32(0x12D8) +#define PRM_VP2_VLIMITTO PRM_REG32(0x12DC) +#define PRM_VP2_VOLTAGE PRM_REG32(0x12E0) +#define PRM_VP2_STATUS PRM_REG32(0x12E4) + +/* NEON_PRM Registers */ +#define RM_RSTST_NEON PRM_REG32(0x1358) +#define PM_WKDEP_NEON PRM_REG32(0x13C8) +#define PM_PWSTCTRL_NEON PRM_REG32(0x13E0) +#define PM_PWSTST_NEON PRM_REG32(0x13E4) +#define PM_PREPWSTST_NEON PRM_REG32(0x13E8) + +/* USBHOST_PRM Registers */ +#define RM_RSTST_USBHOST PRM_REG32(0x1458) +#define PM_WKEN_USBHOST PRM_REG32(0x14A0) +#define PM_MPUGRPSEL_USBHOST PRM_REG32(0x14A4) +#define PM_IVA2GRPSEL_USBHOST PRM_REG32(0x14A8) +#define PM_WKST_USBHOST PRM_REG32(0x14B0) +#define PM_WKDEP_USBHOST PRM_REG32(0x14C8) +#define PM_PWSTCTRL_USBHOST PRM_REG32(0x14E0) +#define PM_PWSTST_USBHOST PRM_REG32(0x14E4) +#define PM_PREPWSTST_USBHOST PRM_REG32(0x14E8) + +#endif + +#endif Index: git-latest5/arch/arm/mach-omap2/prcm_34xx.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ git-latest5/arch/arm/mach-omap2/prcm_34xx.c 2008-03-04 05:27:55.805326789 +0530 @@ -0,0 +1,2062 @@ +/* + * linux/arch/arm/mach-omap2/prcm_34xx.c + * + * OMAP 34xx Power Reset and Clock Management (PRCM) functions + * + * Copyright (C) 2008 Texas Instruments, Inc. + * Karthik Dasu/Rajendra Nayak/Pavan Chinnabhandar + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include <linux/module.h> +#include <linux/init.h> +#include <asm/arch/prcm_34xx.h> +#include <asm/io.h> + +#include "prcm-regs.h" +#include "ti-compat.h" + +const u32 MAXLOOPCNT = 50; +const u32 MAXRETRIES = 5; + +#define IOPAD_WKUP 1 + +/* Using 32K sync timer to generate delays in usecs */ +#define OMAP_TIMER32K_SYNC_CR (OMAP3430_32KSYNCT_BASE + 0x10) +#define OMAP_TIMER32K_SYNC_CR_READ (omap_readl(OMAP_TIMER32K_SYNC_CR)) +#define OMAP_MAX_32K_CR 0xFFFFFFFF + +#ifndef CONFIG_PM +#define omap_sram_idle() \ + { \ + __asm__ __volatile__ ("wfi"); \ + } +#endif + +/* Table to store domain registers */ +struct domain_registers dom_reg[PRCM_NUM_DOMAINS] = { + { + /* IVA2 domain */ + { + {0x1, (u32 *)&CM_FCLKEN_IVA2}, + {0, 0}, + {0x1, (u32 *)&CM_IDLEST_IVA2}, + {0, 0}, + {0, 0}, + {0, 0}, + {0x3, (u32 *)&CM_CLKSTCTRL_IVA2}, + {0x1, (u32 *)&CM_CLKSTST_IVA2}, + {0xFF0F0F, (u32 *)&PM_PWSTCTRL_IVA2}, + {0x100FF7, (u32 *)&PM_PWSTST_IVA2}, + {0xFF7, (u32 *)&PM_PREPWSTST_IVA2}, + {0, 0}, + {0x3F0F, (u32 *)&RM_RSTST_IVA2}, + } + }, + { + /* MPU domain */ + { + {0, 0}, + {0, 0}, + {0x1, (u32 *)&CM_IDLEST_MPU}, + {0, 0}, + {0, 0}, + {0, 0}, + {0x3, (u32 *)&CM_CLKSTCTRL_MPU}, + {0x1, (u32 *)&CM_CLKSTST_MPU}, + {0x3010F, (u32 *)&PM_PWSTCTRL_MPU}, + {0x1000C7, (u32 *)&PM_PWSTST_MPU}, + {0xC7, (u32 *)&PM_PREPWSTST_MPU}, + {0, 0}, + {0x80F, (u32 *)&RM_RSTST_MPU}, + } + }, + { + /* CORE1 */ + { + {0x43FFFE01, (u32 *)&CM_FCLKEN1_CORE}, + {0x7FFFFED3, (u32 *)&CM_ICLKEN1_CORE}, + {0x7FFFFFF7, (u32 *)&CM_IDLEST1_CORE}, + {0x7FFFFED1, (u32 *)&CM_AUTOIDLE1_CORE}, + {0x433FFE10, (u32 *)&PM_WKEN1_CORE}, + {0x433FFE10, (u32 *)&PM_WKST1_CORE}, + {0x0F, (u32 *)&CM_CLKSTCTRL_CORE}, + {0x3, (u32 *)&CM_CLKSTST_CORE}, + {0xF031F, (u32 *)&PM_PWSTCTRL_CORE}, + {0x1000F7, (u32 *)&PM_PWSTST_CORE}, + {0xF7, (u32 *)&PM_PREPWSTST_CORE}, + {0xC0, (u32 *)&CM_CLKSEL_CORE}, + {0x7, (u32 *)&RM_RSTST_CORE}, + } + }, + { + /* CORE2 */ + { + {0, 0}, + {0x1F, (u32 *)&CM_ICLKEN2_CORE}, + {0x1F, (u32 *)&CM_IDLEST2_CORE}, + {0x1F, (u32 *)&CM_AUTOIDLE2_CORE}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + } + }, + { + /* SGX */ + { + {0x2, (u32 *)&CM_FCLKEN_SGX}, + {0x1, (u32 *)&CM_ICLKEN_SGX}, + {0x1, (u32 *)&CM_IDLEST_SGX}, + {0, 0}, + {0, 0}, + {0, 0}, + {0x3, (u32 *)&CM_CLKSTCTRL_SGX}, + {0x1, (u32 *)&CM_CLKSTST_SGX}, + {0x30107, (u32 *)&PM_PWSTCTRL_SGX}, + {0x100003, (u32 *)&PM_PWSTST_SGX}, + {0x3, (u32 *)&PM_PREPWSTST_SGX}, + {0, 0}, + {0xF, (u32 *)&RM_RSTST_SGX}, + } + }, + { + /* WKUP */ + { + {0x2E9, (u32 *)&CM_FCLKEN_WKUP}, + {0x23F, (u32 *)&CM_ICLKEN_WKUP}, + {0x2FF, (u32 *)&CM_IDLEST_WKUP}, + {0x23F, (u32 *)&CM_AUTOIDLE_WKUP}, + {0x3CB, (u32 *)&PM_WKEN_WKUP}, + {0x3CB, (u32 *)&PM_WKST_WKUP}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0x7F, (u32 *)&CM_CLKSEL_WKUP}, + {0, 0}, + } + }, + { + /* DSS */ + { + {0x7, (u32 *)&CM_FCLKEN_DSS}, + {0x1, (u32 *)&CM_ICLKEN_DSS}, + {0x3, (u32 *)&CM_IDLEST_DSS}, + {0x1, (u32 *)&CM_AUTOIDLE_DSS}, + {0x1, (u32 *)&PM_WKEN_DSS}, + {0, 0}, + {0x3, (u32 *)&CM_CLKSTCTRL_DSS}, + {0x1, (u32 *)&CM_CLKSTST_DSS}, + {0x30107, (u32 *)&PM_PWSTCTRL_DSS}, + {0x100003, (u32 *)&PM_PWSTST_DSS}, + {0x3, (u32 *)&PM_PREPWSTST_DSS}, + {0, 0}, + {0xF, (u32 *)&RM_RSTST_DSS}, + } + }, + { + /* CAM */ + { + {0x3, (u32 *)&CM_FCLKEN_CAM}, + {0x1, (u32 *)&CM_ICLKEN_CAM}, + {0x1, (u32 *)&CM_IDLEST_CAM}, + {0x1, (u32 *)&CM_AUTOIDLE_CAM}, + {0, 0}, + {0, 0}, + {0x3, (u32 *)&CM_CLKSTCTRL_CAM}, + {0x1, (u32 *)&CM_CLKSTST_CAM}, + {0x30107, (u32 *)&PM_PWSTCTRL_CAM}, + {0x100003, (u32 *)&PM_PWSTST_CAM}, + {0x3, (u32 *)&PM_PREPWSTST_CAM}, + {0, 0}, + {0xF, (u32 *)&RM_RSTST_CAM}, + } + }, + { + /* PER */ + { + {0x3FFFF, (u32 *)&CM_FCLKEN_PER}, + {0x3FFFF, (u32 *)&CM_ICLKEN_PER}, + {0x3FFFF, (u32 *)&CM_IDLEST_PER}, + {0x3FFFF, (u32 *)&CM_AUTOIDLE_PER}, + {0x3EFFF, (u32 *)&PM_WKEN_PER}, + {0x3EFFF, (u32 *)&PM_WKST_PER}, + {0x3, (u32 *)&CM_CLKSTCTRL_PER}, + {0x1, (u32 *)&CM_CLKSTST_PER}, + {0x30107, (u32 *)&PM_PWSTCTRL_PER}, + {0x100003, (u32 *)&PM_PWSTST_PER}, + {0x3, (u32 *)&PM_PREPWSTST_PER}, + {0xFF, (u32 *)&CM_CLKSEL_PER}, + {0xF, (u32 *)&RM_RSTST_PER}, + } + }, + { + /* EMU */ + { + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0x3, (u32 *)&CM_CLKSTCTRL_EMU}, + {0x1, (u32 *)&CM_CLKSTST_EMU}, + {0, 0}, + {0x100003, (u32 *)&PM_PWSTST_EMU}, + {0, 0}, + {0, 0}, + {0x7, (u32 *)&RM_RSTST_EMU}, + } + }, + { + /* NEON */ + { + {0, 0}, + {0, 0}, + {0x1, (u32 *)&CM_IDLEST_NEON}, + {0, 0}, + {0, 0}, + {0, 0}, + {0x3, (u32 *)&CM_CLKSTCTRL_NEON}, + {0, 0}, + {0x7, (u32 *)&PM_PWSTCTRL_NEON}, + {0x100003, (u32 *)&PM_PWSTST_NEON}, + {0x3, (u32 *)&PM_PREPWSTST_NEON}, + {0, 0}, + {0xF, (u32 *)&RM_RSTST_NEON}, + } + }, + { + /* CORE3 */ + { + {0x7, (u32 *)&CM_FCLKEN3_CORE}, + {0x4, (u32 *)&CM_ICLKEN3_CORE}, + {0x5, (u32 *)&CM_IDLEST3_CORE}, + {0x4, (u32 *)&CM_AUTOIDLE3_CORE}, + {0x4, (u32 *)&PM_WKEN3_CORE}, + {0x4, (u32 *)&PM_WKST3_CORE}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + } + }, + { + /* USBHOST */ + { + {0x3, (u32 *)&CM_FCLKEN_USBHOST}, + {0x1, (u32 *)&CM_ICLKEN_USBHOST}, + {0x3, (u32 *)&CM_IDLEST_USBHOST}, + {0x1, (u32 *)&CM_AUTOIDLE_USBHOST}, + {0x1, (u32 *)&PM_WKEN_USBHOST}, + {0x1, (u32 *)&PM_WKST_USBHOST}, + {0x3, (u32 *)&CM_CLKSTCTRL_USBHOST}, + {0x1, (u32 *)&CM_CLKSTST_USBHOST}, + {0x30117, (u32 *)&PM_PWSTCTRL_USBHOST}, + {0x100003, (u32 *)&PM_PWSTST_USBHOST}, + {0x3, (u32 *)&PM_PREPWSTST_USBHOST}, + {0, 0}, + {0xF, (u32 *)&RM_RSTST_USBHOST}, + } + }, +}; + +/* Table to store DPLL registers */ +struct dpll_registers dpll_reg[NO_OF_DPLL] = { + { + /* DPLL1_MPU */ + { + {0xFFFFFF0F, (u32 *)&CM_CLKEN_PLL_MPU}, + {0x7, (u32 *)&CM_AUTOIDLE_PLL_MPU}, + {0xFFF800FF, (u32 *)&CM_CLKSEL1_PLL_MPU}, + {0, (u32 *)&CM_IDLEST_PLL_MPU}, + {0xFFFFFFE0, (u32 *)&CM_CLKSEL2_PLL_MPU}, + {0xFFFFFFE0, (u32 *)&CM_CLKSEL2_PLL_MPU}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + } + }, + { + /* DPLL2_IVA2 */ + { + {0xFFFFFF0F, (u32 *)&CM_CLKEN_PLL_IVA2}, + {0x7, (u32 *)&CM_AUTOIDLE_PLL_IVA2}, + {0xFFF800FF, (u32 *)&CM_CLKSEL1_PLL_IVA2}, + {0, (u32 *)&CM_IDLEST_PLL_IVA2}, + {0xFFFFFFE0, (u32 *)&CM_CLKSEL2_PLL_IVA2}, + {0xFFFFFFE0, (u32 *)&CM_CLKSEL2_PLL_IVA2}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + } + }, + { + /* DPLL3_CORE */ + { + {0xFFFFFF0F, (u32 *)&CM_CLKEN_PLL}, + {0x7, (u32 *)&CM_AUTOIDLE_PLL}, + {0xF800FFFF, (u32 *)&CM_CLKSEL1_PLL}, + {0, (u32 *)&CM_IDLEST_CKGEN}, + {0x07FFFFFF, (u32 *)&CM_CLKSEL1_PLL}, + {0x07FFFFFF, (u32 *)&CM_CLKSEL1_PLL}, + {0xFFE0FFFF, (u32 *)&CM_CLKSEL1_EMU}, + {0, 0}, + {0, 0}, + {0, 0}, + } + }, + { + /* DPLL4_PER */ + { + {0xFF0FFFFF, (u32 *)&CM_CLKEN_PLL}, + {0x38, (u32 *)&CM_AUTOIDLE_PLL}, + {0xFFF800FF, (u32 *)&CM_CLKSEL2_PLL}, + {0, (u32 *)&CM_IDLEST_CKGEN}, + {0xFFFFFFE0, (u32 *)&CM_CLKSEL3_PLL}, + {0xFFFFFFE0, (u32 *)&CM_CLKSEL3_PLL}, + {0xFFFFE0FF, (u32 *)&CM_CLKSEL_DSS}, + {0xFFFFFFE0, (u32 *)&CM_CLKSEL_DSS}, + {0xFFFFFFE0, (u32 *)&CM_CLKSEL_CAM}, + {0xE0FFFFFF, (u32 *)&CM_CLKSEL1_EMU}, + } + }, + { + /* DPLL5_PER2 */ + { + {0xFFFFFF0F, (u32 *)&CM_CLKEN2_PLL}, + {0x7, (u32 *)&CM_AUTOIDLE2_PLL}, + {0xFFF800FF, (u32 *)&CM_CLKSEL4_PLL}, + {0, (u32 *)&CM_IDLEST2_CKGEN}, + {0xFFFFFFE0, (u32 *)&CM_CLKSEL5_PLL}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + } + } +}; + +/* Table to store clksel registers for various clocks */ +struct reg_def clksel_reg[PRCM_NO_OF_CLKS] = { + {0x3, (u32 *)&CM_CLKSEL_CORE}, /* L3_ICLK */ + {0xC, (u32 *)&CM_CLKSEL_CORE}, /* L4_ICLK */ + {0x6, (u32 *)&CM_CLKSEL_WKUP}, /* RM_ICLK */ + {0x00, NULL}, + {0x38, (u32 *)&CM_CLKOUT_CTRL}, /* SYS_CLOCKOUT2 */ + {0x7, (u32 *)&CM_CLKSEL_SGX}, /* SGX_L3_FCLK */ + {0xF00, (u32 *)&CM_CLKSEL_CORE}, /* SSI */ + {0x180000, (u32 *)&CM_CLKSEL1_PLL_MPU}, /* DPLL1_FCLK */ + {0x180000, (u32 *)&CM_CLKSEL1_PLL_IVA2}, /* DPLL2_FCLK */ + {0x78, (u32 *)&CM_CLKSEL_WKUP}, /* USIM_FCLK */ + +}; + +/* Array containing possible divider values for all clocks + which have dividers */ +u32 div_arr[] = { + /* L3 divs */ + 1, 2, 0, 0, 0, 0, + /* L4 divs */ + 1, 2, 0, 0, 0, 0, + /* RM divs */ + 1, 2, 0, 0, 0, 0, + /* USB L4 divs */ + 0, 0, 0, 0, 0, 0, + /* sys clkout2 divs */ + 1, 2, 4, 8, 16, 0, + /* sgx divs */ + 3, 4, 6, 0, 0, 0, + /* SSI divs */ + 1, 2, 3, 4, 5, 6, + /* dpll1 fclk divs */ + 1, 2, 4, 0, 0, 0, + /* dpll2 fclk divs */ + 1, 2, 4, 0, 0, 0, + /* cm usim divs */ + 2, 4, 8, 10, 16, 20, +}; + +/* Possible values for Dpll dividers */ +u32 div_dpll[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; +u32 div_dpll3[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\ + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; + +u32 dpll_mx_shift[NO_OF_DPLL][NO_DPLL_DIV] = { + {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + {0x1B, 0x1B, 0x10, 0x0, 0x0, 0x0}, + {0x0, 0x0, 0x8, 0x0, 0x0, 0x18}, + {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, +}; + +/* Offset values in registers for clocks which have dividers */ +u32 clk_div_offset[PRCM_NO_OF_CLKS] = { + /* L3_ICLK */ + 0x0, + /* L4_ICLK */ + 0x2, + /* RM_ICLK */ + 0x1, + /* USB_L4_ICLK */ + 0x0, + /* SYS_CLKOUT2 */ + 0x3, + /* SGX_L3_FCLK */ + 0x0, + /* SSI_CLK */ + 0x8, + /* DPLL1_FCLK */ + 0x13, + /* DPLL2_FCLK */ + 0x13, + /* SYS_USIM_CLK */ + 0x3, +}; + +/* Tables having M,N,M2 and FreqSel values for different sys_clk speeds & OPPs*/ +/* The tables are organized as follows: */ +/* Rows : 1 - 12M, 2 - 13M, 3 - 19.2M, 4 - 26M, 5 - 38.4M */ +/* Columns : 1 - OPP1, 2 - OPP2, 3 - OPP3, 4 - OPP4 5 - OPP5 */ + +/* MPU parameters */ +struct dpll_param mpu_dpll_param[5][PRCM_NO_VDD1_OPPS] = { + /* 12M values */ + /* OPP1(125 Mhz) and OPP2(250 Mhz)*/ + {{0x0FA, 0x05, 0x07, 0x04}, {0x0FA, 0x05, 0x07, 0x02}, + /* OPP3(500 Mhz) and OPP4(550 Mhz)*/ + {0x0FA, 0x05, 0x07, 0x01}, {0x113, 0x05, 0x07, 0x01}, + /* OPP5 (625 Mhz) */ + {0x271, 0x0B, 0x03, 0x01} }, + /* 13M values */ + /* OPP1(125 Mhz) and OPP2(250 Mhz)*/ + {{0x1F4, 0x0C, 0x03, 0x04}, {0x1F4, 0x0C, 0x03, 0x02}, + /* OPP3(500 Mhz) and OPP4(550 Mhz)*/ + {0x1F4, 0x0C, 0x03, 0x01}, {0x226, 0x0C, 0x03, 0x01}, + /* OPP5 (625 Mhz) */ + {0x271, 0x0C, 0x03, 0x01} }, + /* 19.2M values */ + /* OPP1(125 Mhz) and OPP2(250 Mhz)*/ + {{0x271, 0x17, 0x03, 0x04}, {0x271, 0x17, 0x03, 0x02}, + /* OPP3(500 Mhz) and OPP4(550 Mhz)*/ + {0x271, 0x17, 0x03, 0x01}, {0x191, 0x0D, 0x05, 0x01}, + /* OPP5 (625 Mhz) */ + {0x28B, 0x13, 0x03, 0x01} }, + /* 26M values */ + /* OPP1(125 Mhz) and OPP2(250 Mhz)*/ + {{0x0FA, 0x0C, 0x07, 0x04}, {0x0FA, 0x0C, 0x07, 0x02}, + /* OPP3(500 Mhz) and OPP4(550 Mhz)*/ + {0x0FA, 0x0C, 0x07, 0x01}, {0x113, 0x0C, 0x07, 0x01}, + /* OPP5 (625 Mhz) */ + {0x271, 0x19, 0x03, 0x01} }, + /* 38.4M values */ + /* OPP1(125 Mhz) and OPP2(250 Mhz)*/ + {{0x271, 0x2F, 0x03, 0x04}, {0x271, 0x2F, 0x03, 0x02}, + /* OPP3(500 Mhz) and OPP4(550 Mhz)*/ + {0x271, 0x2F, 0x03, 0x01}, {0x1BC, 0x1E, 0x04, 0x01}, + /* OPP5 (625 Mhz) */ + {0x1D8, 0x1C, 0x05, 0x01} }, +}; + + +/* IVA parameters */ +struct dpll_param iva_dpll_param[5][PRCM_NO_VDD1_OPPS] = { + /* 12M values */ + /* OPP1(90 Mhz) and OPP2(180 Mhz)*/ + {{0x0B4, 0x05, 0x07, 0x04}, {0x0B4, 0x05, 0x07, 0x02}, + /* OPP3(360 Mhz) and OPP4(396 Mhz)*/ + {0x0B4, 0x05, 0x07, 0x01}, {0x0C6, 0x05, 0x07, 0x01}, + /* OPP5 (430 Mhz) */ + {0x0D7, 0x05, 0x07, 0x01} }, + /* 13M values */ + /* OPP1(90 Mhz) and OPP2(180 Mhz)*/ + {{0x168, 0x0C, 0x03, 0x04}, {0x168, 0x0C, 0x03, 0x02}, + /* OPP3(360 Mhz) and OPP4(396 Mhz)*/ + {0x168, 0x0C, 0x03, 0x01}, {0x18C, 0x0C, 0x03, 0x01}, + /* OPP5 (430 Mhz) */ + {0x1AE, 0x0C, 0x03, 0x01} }, + /* 19.2M values */ + /* OPP1(90 Mhz) and OPP2(180 Mhz)*/ + {{0x0E1, 0x0B, 0x06, 0x04}, {0x0E1, 0x0B, 0x06, 0x02}, + /* OPP3(360 Mhz) and OPP4(396 Mhz)*/ + {0x0E1, 0x0B, 0x06, 0x01}, {0x14A, 0x0F, 0x04, 0x01}, + /* OPP5 (430 Mhz) */ + {0x203, 0x16, 0x03, 0x01} }, + /* 26M values */ + /* OPP1(90 Mhz) and OPP2(180 Mhz)*/ + {{0x0B4, 0x0C, 0x07, 0x04}, {0x0B4, 0x0C, 0x07, 0x02}, + /* OPP3(360 Mhz) and OPP4(396 Mhz)*/ + {0x0B4, 0x0C, 0x07, 0x01}, {0x0C6, 0x0C, 0x07, 0x01}, + /* OPP5 (430 Mhz) */ + {0x0D7, 0x0C, 0x07, 0x01} }, + /* 38.4M values */ + /* OPP1(90 Mhz) and OPP2(180 Mhz)*/ + {{0x0E1, 0x17, 0x06, 0x04}, {0x0E1, 0x17, 0x06, 0x02}, + /* OPP3(360 Mhz) and OPP4(396 Mhz)*/ + {0x0E1, 0x17, 0x06, 0x01}, {0x14A, 0x1F, 0x04, 0x01}, + /* OPP5 (430 Mhz) */ + {0x23B, 0x32, 0x01, 0x01} }, +}; + +/* CORE parameters */ +struct dpll_param core_dpll_param[5][PRCM_NO_VDD2_OPPS] = { + /* 12M values */ + /* OPP1(83 Mhz) and OPP2(166 Mhz) */ + {{0, 0, 0, 0}, {0x0A6, 0x05, 0x07, 0x02}, {0x0A6, 0x05, 0x07, 0x01} }, + /* 13M values */ + /* OPP1(83 Mhz) and OPP2(166 Mhz) */ + {{0, 0, 0, 0}, {0x14C, 0x0C, 0x03, 0x02}, {0x14C, 0x0C, 0x03, 0x01} }, + /* 19.2M values */ + /* OPP1(83 Mhz) and OPP2(166 Mhz) */ + {{0, 0, 0, 0}, {0x19F, 0x17, 0x03, 0x02}, {0x19F, 0x17, 0x03, 0x01} }, + /* 26M values */ + /* OPP1(83 Mhz) and OPP2(166 Mhz) */ + {{0, 0, 0, 0}, {0x0A6, 0x0C, 0x07, 0x02}, {0x0A6, 0x0C, 0x07, 0x01} }, + /* 38.4M values */ + /* OPP1(83 Mhz) and OPP2(166 Mhz) */ + {{0, 0, 0, 0}, {0x19F, 0x2F, 0x03, 0x02}, {0x19F, 0x2F, 0x03, 0x01} }, +}; + +struct dpll_param usb_dpll_param[5] = { + /* 12M values */ + {0x3C, 0x05, 0x07, 0x01}, + /* 13M values */ + {0x78, 0x0C, 0x03, 0x01}, + /* 19.2M values */ + {0x4B, 0x0B, 0x06, 0x01}, + /* 26M values */ + {0x3C, 0x0C, 0x07, 0x01}, + /* 38.4M values */ + {0x4B, 0x17, 0x06, 0x01}, +}; + +u8 mpu_iva2_vdd1_volts [PRCM_NO_VDD1_OPPS] = { + /* Vsel corresponding to 0.9V (OPP1), 1.00V (OPP2), + 1.20V (OPP3), 1.27V (OPP4), 1.35 (OPP5) */ + 0x18, 0x20, 0x30, 0x36, 0x3C +}; + +u8 core_l3_vdd2_volts [PRCM_NO_VDD2_OPPS] = { /* only 3 OPPs */ + /* Vsel corresponding to 0.9V (OPP1), 1.00V (OPP2), 1.15 (OPP3) */ + 0x18, 0x20, 0x2C +}; + +u32 omap_prcm_get_reset_sources(void) +{ + omap3_clk_prepare_for_reboot(); + return PRM_RSTST & 0x7fb; +} +EXPORT_SYMBOL(omap_prcm_get_reset_sources); + +void omap_udelay(u32 udelay) +{ + u32 counter_val, timeout_val; + + counter_val = OMAP_TIMER32K_SYNC_CR_READ; + /* Since the 32 sync timer runs on a 32K clock, + the granularity of the delay achieved is around 30 + us, hence divide the delay provided by user by 30 */ + timeout_val = counter_val + (udelay / 30); + if (timeout_val < counter_val) + /* There seems to be a overflow */ + /* take care of the overflow by waiting first for the + CR to reach the MAX value */ + while (OMAP_MAX_32K_CR > OMAP_TIMER32K_SYNC_CR_READ) ; + /* wait for the specified delay */ + while (timeout_val > OMAP_TIMER32K_SYNC_CR_READ) ; + return; +} + +inline int loop_wait(u32 *lcnt, u32 *rcnt, u32 delay) +{ + (*lcnt)++; + if (*lcnt > MAXLOOPCNT) { + *lcnt = 0; + if (*rcnt < MAXRETRIES) + omap_udelay(delay); + else + return PRCM_FAIL; + (*rcnt)++; + } + return PRCM_PASS; +} + +/* Resets clock rates and reboots the system. Only called from system.h */ +void omap_prcm_arch_reset(char mode) +{ + omap3_clk_prepare_for_reboot(); + /* Assert global software reset */ + PRM_RSTCTRL |= 2; +} + +static int check_device_status(u32 deviceid, u8 control) +{ + u8 curr_state; + u32 loop_cnt = 0, retries_cnt = 0; + int ret; + + if ((control != PRCM_ENABLE) && (control != PRCM_DISABLE)) + return PRCM_FAIL; + + curr_state = !control; + while (curr_state != control) { + ret = prcm_is_device_accessible(deviceid, &curr_state); + if (ret != PRCM_PASS) + return ret; + ret = loop_wait(&loop_cnt, &retries_cnt, 100); + if (ret != PRCM_PASS) { + printk(KERN_INFO "Loop count exceeded in check " + "device status for device:%u\n", deviceid); + return ret; + } + } + return PRCM_PASS; +} + +static int get_dpll_mx(u32 dpll_id, u32 dpll_div, u32 dpll_mxsft) +{ + u32 valid; + u32 *addr; + + addr = get_addr_pll(dpll_id, dpll_div + MX_ARRAY_OFFSET); + valid = get_val_bits_pll(dpll_id, dpll_div + MX_ARRAY_OFFSET); + return (*addr & ~valid) >> dpll_mxsft; +} + +int get_dpll_m_n(u32 dpll_id, u32 *mult, u32 *div) +{ + u32 valid; + u32 *addr; + + addr = get_addr_pll(dpll_id, REG_CLKSEL1_PLL); + if (!addr) + return PRCM_FAIL; + + valid = get_val_bits_pll(dpll_id, REG_CLKSEL1_PLL); + if (dpll_id == DPLL3_CORE) { + *mult = (*addr & ~valid) >> 16; + *div = (*addr & ~DPLL3_N_MASK) >> 8; + } else { + *mult = (*addr & ~valid) >> 8; + *div = (*addr & ~DPLL_N_MASK); + } + return PRCM_PASS; +} + +static int is_dpll_locked(u32 dpll_id, int *result) +{ + u32 *addr; + u32 dpll_enbit_mask, dpll_idlest_lock_bit; + + addr = get_addr_pll(dpll_id, REG_CLKEN_PLL); + if (!addr) + return PRCM_FAIL; + + dpll_enbit_mask = get_dpll_enbitmask(dpll_id); + dpll_idlest_lock_bit = get_idlest_lock_bit(dpll_id); + + if ((*addr & (~dpll_enbit_mask)) == (~dpll_enbit_mask)) + *result = PRCM_TRUE; + else + *result = PRCM_FALSE; + return PRCM_PASS; +} + +static int check_accessibility(u32 deviceid, u8 clk_type) +{ + u32 valid = 0, enbit, type, domain; + u32 *addr = 0; + + enbit = DEV_BIT_POS(deviceid); + domain = DOMAIN_ID(deviceid); + type = DEV_TYPE(deviceid); + + if (type == TARGET) { + /* Skip devices without CM_IDLEST register bit support */ + addr = get_addr(domain, REG_IDLEST); + valid = get_val_bits(domain, REG_IDLEST); + if (!(addr) || !(valid & (1 << enbit))) + return PRCM_PASS; + /* Check if FCLK/ICLK is absent or ICLK is ON if present. */ + if (clk_type == ICLK) { + addr = get_addr(domain, REG_FCLKEN); + valid = get_val_bits(domain, REG_FCLKEN); + } else if (clk_type == FCLK) { + addr = get_addr(domain, REG_ICLKEN); + valid = get_val_bits(domain, REG_ICLKEN); + } + if (!(addr) || !(valid & (1 << enbit)) + || (*addr & (1 << enbit))) + /* FCLK/ICLK present and is ON */ + return check_device_status(deviceid, PRCM_ENABLE); + } else { /* type = INITIATOR or INITIATOR+TARGET + * IDLEST bit cannot be polled, + * it only specifies the + * standby status + * Check if the ICLK is present and ON */ + if (clk_type == FCLK) { + addr = get_addr(domain, REG_ICLKEN); + valid = get_val_bits(domain, REG_ICLKEN); + } else if (clk_type == ICLK) { + addr = get_addr(domain, REG_FCLKEN); + valid = get_val_bits(domain, REG_FCLKEN); + } + if (!(addr) || !(valid & (1 << enbit)) + || (*addr & (1 << enbit))) { + /* FCLK/ICLK present and is ON + * Wait for sometime for the clocks to stabilize*/ + omap_udelay(100); + return PRCM_PASS; + } + } + return PRCM_PASS; +} + +static int calc_dpll_lock_delay(u32 dpll_id, u32 *delay) +{ + u32 f_ref, f_int, m, n; + /* Calcluate an appropriate delay based on the below formula */ + /* This is a worst case formula which assumes there was a + M/N reprogramming. + 2us + 350Fint_cycles (Fint_cycles = Fref/N+1)*/ + f_ref = prcm_get_system_clock_speed(); + if (f_ref == PRCM_FAIL) { + printk(KERN_INFO "Unable to get system clock\n"); + return PRCM_FAIL; + } + + if (get_dpll_m_n(dpll_id, &m, &n) == PRCM_FAIL) { + printk(KERN_INFO "Failed to get the M and N values\n"); + return PRCM_FAIL; + } + + f_int = f_ref / (n + 1); + *delay = (2 + (350*1000)/f_int); + return PRCM_PASS; +} + +int prcm_clock_control(u32 deviceid, u8 clk_type, u8 control, + u8 checkaccessibility) +{ + u32 domain, omap, valid, enbit; + u32 *addr; + + + omap = OMAP(deviceid); + enbit = DEV_BIT_POS(deviceid); + domain = DOMAIN_ID(deviceid); + + if (cpu_is_omap3430() && !(omap & (AT_3430|AT_3430_ES2))) + return PRCM_FAIL; + + switch (clk_type) { + case ICLK: + addr = get_addr(domain, REG_ICLKEN); + valid = get_val_bits(domain, REG_ICLKEN); + break; + case FCLK: + addr = get_addr(domain, REG_FCLKEN); + valid = get_val_bits(domain, REG_FCLKEN); + break; + default: + return PRCM_FAIL; + } + + /* No functional/Interface Clk control for the device */ + if (!(addr) || !(valid & (1 << enbit))) + return PRCM_FAIL; + + if (control == PRCM_ENABLE) + *addr |= (1 << enbit); + else if (control == PRCM_DISABLE) + *addr &= ~(1 << enbit); + + if (checkaccessibility) + return check_accessibility(deviceid, clk_type); + + return PRCM_PASS; +} + +int prcm_is_device_accessible(u32 deviceid, u8 *result) +{ + u32 domain, omap, valid, enbit; + u32 *addr; + + omap = OMAP(deviceid); + enbit = DEV_BIT_POS(deviceid); + domain = DOMAIN_ID(deviceid); + + if (cpu_is_omap3430() && !(omap & (AT_3430|AT_3430_ES2))) + return PRCM_FAIL; + + addr = get_addr(domain, REG_IDLEST); + valid = get_val_bits(domain, REG_IDLEST); + + if (!(addr) || !(valid & (1 << enbit))) + return PRCM_FAIL; + + + if (!(*addr & (1 << enbit))) { + *result = PRCM_TRUE; + } else { + *result = PRCM_FALSE; + } + return PRCM_PASS; +} + +int prcm_enable_dpll(u32 dpll_id) +{ + u32 dpll_idlest_lock_bit, dpll_enbit_mask, delay; + u32 *addr, *addr_auto; + u32 dpll_autoidle; + int ret, enabled; + u32 loop_cnt = 0, retries_cnt = 0; + + if (dpll_id > NO_OF_DPLL) + return PRCM_FAIL; + + /* Currently, this API does not allow locking of core DPLL */ + /* Locking of core DPLL needs to be done without access to SDRAM */ + /* This can be done safely if execution is done from SRAM */ + if (dpll_id == DPLL3_CORE) + return PRCM_FAIL; + + /* Store the DPLL autoidle */ + addr_auto = get_addr_pll(dpll_id, REG_AUTOIDLE_PLL); + dpll_autoidle = *addr_auto; + *addr_auto = 0x0; + + ret = is_dpll_locked(dpll_id, &enabled); + if (ret != PRCM_PASS) { + *addr_auto = dpll_autoidle; + return ret; + } + if (enabled == PRCM_TRUE) { + *addr_auto = dpll_autoidle; + return PRCM_PASS; + } + + addr = get_addr_pll(dpll_id, REG_CLKEN_PLL); + + if (!addr) { + *addr_auto = dpll_autoidle; + return PRCM_FAIL; + } + + dpll_enbit_mask = get_dpll_enbitmask(dpll_id); + dpll_idlest_lock_bit = get_idlest_lock_bit(dpll_id); + + *addr |= ~dpll_enbit_mask; /* enable DPLL in lock mode */ + + if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) { + /* WORKAROUND FOR SILICON ERRATA 1.56 */ + ret = calc_dpll_lock_delay(dpll_id, &delay); + if (ret != PRCM_PASS) { + *addr_auto = dpll_autoidle; + return ret; + } + omap_udelay(delay); + } + + ret = calc_dpll_lock_delay(dpll_id, &delay); + if (ret != PRCM_PASS) { + *addr_auto = dpll_autoidle; + return ret; + } + while (!(*get_addr_pll(dpll_id, REG_IDLEST_PLL) & + dpll_idlest_lock_bit)) { + /* wait for DPLL to lock */ + ret = loop_wait(&loop_cnt, &retries_cnt, delay/5); + if (ret != PRCM_PASS) { + printk(KERN_INFO "Loop count exceeded in" + "prcm_enable_dpll for dpll:%u\n", dpll_id); + *addr_auto = dpll_autoidle; + return ret; + } + } + /* Restore the autoidle for the DPLL back */ + *addr_auto = dpll_autoidle; + return PRCM_PASS; +} + +int prcm_configure_dpll(u32 dpll_id, u32 mult, u8 div, u8 freq_sel) +{ + u32 valid; + u32 *addr, *addr_auto; + u32 new_reg_val = 0x0; + int ret, enabled, index; + u32 sys_clkspeed, dpll_autoidle; + + if (dpll_id > NO_OF_DPLL) + return PRCM_FAIL; + + if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) { + /* WORKAROUND FOR Limitation 2.5 */ + if (dpll_id == DPLL4_PER) + return PRCM_FAIL; + } + + /* Store the DPLL autoidle */ + addr_auto = get_addr_pll(dpll_id, REG_AUTOIDLE_PLL); + dpll_autoidle = *addr_auto; + *addr_auto = 0x0; + + /* DPLL M,N,FreqSel values should be changed only if the DPLL + * is in bypass mode. If it is not in bypass mode, return error */ + ret = is_dpll_locked(dpll_id, &enabled); + + if (enabled == PRCM_TRUE) { + printk(KERN_INFO "Dpll enabled - m,n values cannot be" + "changed\n"); + *addr_auto = dpll_autoidle; + return PRCM_FAIL; + } + + /* Configure M and N values */ + addr = get_addr_pll(dpll_id, REG_CLKSEL1_PLL); + if (!addr) + return PRCM_FAIL; + if (dpll_id == DPLL5_PER2) { + /* get the M/N/freqsel values */ + sys_clkspeed = prcm_get_system_clock_speed(); + switch (sys_clkspeed) { + case (int)(12000): + index = 0; + break; + case (int)(13000): + index = 1; + break; + case (int)(19200): + index = 2; + break; + case (int)(26000): + index = 3; + break; + case (int)(38400): + index = 4; + break; + default: + return PRCM_FAIL; + } + mult = usb_dpll_param[index].dpll_m; + div = usb_dpll_param[index].dpll_n; + freq_sel = usb_dpll_param[index].dpll_freqsel; + } + valid = get_val_bits_pll(dpll_id, REG_CLKSEL1_PLL); + if (dpll_id == DPLL3_CORE) { + new_reg_val = *addr & valid & DPLL3_N_MASK; + new_reg_val |= (mult << 16) | (div << 8); + *addr = new_reg_val; + } else { + new_reg_val = *addr & valid & DPLL_N_MASK; + new_reg_val |= (mult << 8) | div; + *addr = new_reg_val; + } + + /* Configure FreqSel values */ + addr = get_addr_pll(dpll_id, REG_CLKEN_PLL); + if (!addr) + return PRCM_FAIL; + valid = get_val_bits_pll(dpll_id, REG_CLKEN_PLL); + if (dpll_id == DPLL4_PER) { + new_reg_val = *addr & valid; + new_reg_val |= (freq_sel << 20); + *addr = new_reg_val; + } else { + new_reg_val = *addr & valid; + new_reg_val |= (freq_sel << 4); + *addr = new_reg_val; + } + *addr_auto = dpll_autoidle; + return PRCM_PASS; +} + +int prcm_put_dpll_in_bypass(u32 dpll_id, u32 bypass_mode) +{ + u32 new_val; + u32 *addr, *addr_auto; + u32 dpll_autoidle; + u32 loop_cnt = 0, retries_cnt = 0; + int ret = PRCM_FAIL; + + if (dpll_id > NO_OF_DPLL) + return ret; + + /* Currently, the API does not allow putting CORE dpll in bypass mode + * To safely put dpll in bypass mode, it is better to execute code + * from sram so that there is no access to sdram */ + if (dpll_id == DPLL3_CORE) + return ret; + + addr = get_addr_pll(dpll_id, REG_CLKEN_PLL); + if (!addr) + return ret; + + /* This is needed if the condition in while loop returns true the */ + /*very first time*/ + ret = PRCM_PASS; + + /* Store the DPLL autoidle */ + addr_auto = get_addr_pll(dpll_id, REG_AUTOIDLE_PLL); + dpll_autoidle = *addr_auto; + *addr_auto = 0x0; + + if (dpll_id == DPLL1_MPU) { + new_val = (*addr & DPLL_ENBIT_MASK) | LOW_POWER_BYPASS; + *addr = new_val; + while (*get_addr_pll(dpll_id, REG_IDLEST_PLL) & 0x1) { + ret = loop_wait(&loop_cnt, &retries_cnt, 1000); + if (ret != PRCM_PASS) + break; + } + } else if (dpll_id == DPLL4_PER) { + new_val = (*addr & DPLL4_ENBIT_MASK) | (LOW_POWER_STOP << 16); + *addr = new_val; + while (*get_addr_pll(dpll_id, REG_IDLEST_PLL) & 0x2) { + ret = loop_wait(&loop_cnt, &retries_cnt, 1000); + if (ret != PRCM_PASS) + break; + } + } else { + if ((dpll_id == DPLL5_PER2) && (bypass_mode != LOW_POWER_STOP)) + return ret; + new_val = (*addr & DPLL_ENBIT_MASK) | bypass_mode; + *addr = new_val; + while (*get_addr_pll(dpll_id, REG_IDLEST_PLL) & 0x1) { + ret = loop_wait(&loop_cnt, &retries_cnt, 1000); + if (ret != PRCM_PASS) + break; + } + } + if (ret != PRCM_PASS) + printk(KERN_INFO "Loop count exceeded in " + "prcm_put_dpll_in_bypass for dpll:%u\n", dpll_id); + + /* Restore the autoidle for the DPLL back */ + *addr_auto = dpll_autoidle; + return ret; +} + +int prcm_get_dpll_mn_output(u32 dpll, u32 *mn_output) +{ + u32 dpll_idlest_lock_bit, clksel1_pll, dpll_id; + u32 sys_clkspeed, core_clkspeed; + int bypassclk_divider; + u32 mult, div; + u32 *addr; + + dpll_id = (dpll >> DPLL_NO_POS) & DPLL_NO_MASK; + + if (dpll_id > NO_OF_DPLL) + return PRCM_FAIL; + + dpll_idlest_lock_bit = get_idlest_lock_bit(dpll_id); + + addr = get_addr_pll(dpll_id, REG_IDLEST_PLL); + /* Get the sys clock speed */ + sys_clkspeed = prcm_get_system_clock_speed(); + + if (*addr & dpll_idlest_lock_bit) { + /* dpll locked */ + get_dpll_m_n(dpll_id, &mult, &div); + *mn_output = ((sys_clkspeed * mult) / (div + 1)); + } else { + /* dpll is in bypass mode */ + if ((dpll_id == DPLL3_CORE) || (dpll_id == DPLL4_PER) + || (dpll_id == DPLL5_PER2)) + * mn_output = sys_clkspeed; + else { /* DPLL1 and DPLL2 + * Check if DPLL3 is in bypass */ + prcm_get_dpll_rate(PRCM_DPLL3_M2X2_CLK, &core_clkspeed); + if (dpll_id == DPLL1_MPU) + clksel1_pll = CM_CLKSEL1_PLL_MPU; + else + clksel1_pll = CM_CLKSEL1_PLL_IVA2; + bypassclk_divider = (clksel1_pll >> 19) & 0x3; + *mn_output = core_clkspeed / bypassclk_divider; + } + } + return PRCM_PASS; +} + +int prcm_get_dpll_rate(u32 dpll, u32 *output) +{ + u32 dpll_id, dpll_div, dpll_mxsft, id_type; + u32 mx, omap; + u32 mn_output; + + id_type = get_id_type(dpll); + if (!(id_type & ID_DPLL_OP)) + return PRCM_FAIL; /*Not dpll op */ + + omap = OMAP(dpll); + + if (cpu_is_omap3430() && !(omap & (AT_3430|AT_3430_ES2))) + return PRCM_FAIL; + + dpll_id = (dpll >> DPLL_NO_POS) & DPLL_NO_MASK; + if (dpll_id > NO_OF_DPLL) + return PRCM_FAIL; + + dpll_div = (dpll >> DPLL_DIV_POS) & DPLL_DIV_MASK; + dpll_mxsft = dpll_mx_shift[dpll_id-1][dpll_div]; + mx = get_dpll_mx(dpll_id, dpll_div, dpll_mxsft); + + prcm_get_dpll_mn_output(dpll, &mn_output); + + /* Except for DPLL_M2 all clocks are (mn_output*2)/mx */ + if (dpll_div == DPLL_M2) + *output = (mn_output) / mx; + else + *output = (2 * mn_output) / mx; + return PRCM_PASS; +} + +int prcm_configure_dpll_divider(u32 dpll, u32 setting) +{ + u32 dpll_id, valid, dpll_mxsft, omap, id_type; + u32 dpll_div, new_val = 0x00000000; + u32 *addr; + + id_type = get_id_type(dpll); + if (!(id_type & ID_DPLL_OP)) + return PRCM_FAIL; /*Not DPLL OP */ + + omap = OMAP(dpll); + + if (cpu_is_omap3430() && !(omap & (AT_3430|AT_3430_ES2))) + return PRCM_FAIL; + + dpll_id = (dpll >> DPLL_NO_POS) & DPLL_NO_MASK; + if (dpll_id > NO_OF_DPLL) + return PRCM_FAIL; + + if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) { + /* Workaround for limiation 2.5 */ + /* On ES 1.0, DPLL4 dividers cannot be changed */ + if (dpll_id == DPLL4_PER) + return PRCM_FAIL; + } + + dpll_div = (dpll >> DPLL_DIV_POS) & DPLL_DIV_MASK; + dpll_mxsft = dpll_mx_shift[dpll_id-1][dpll_div]; + addr = get_addr_pll(dpll_id, dpll_div + MX_ARRAY_OFFSET); + valid = get_val_bits_pll(dpll_id, dpll_div + MX_ARRAY_OFFSET); + + new_val = (*addr & valid) | (setting << dpll_mxsft); + + *addr = new_val; + return PRCM_PASS; +} + +int prcm_get_crystal_rate(void) +{ + u32 osc_clkspeed; + + osc_clkspeed = PRM_CLKSEL & 0x7; + + switch (osc_clkspeed) { + case 0: + return (int)(12000); /*12MHz*/ + case 1: + return (int)(13000); /*13MHz*/ + case 2: + return (int)(19200); /*19.2MHz*/ + case 3: + return (int)(26000); /*26MHz*/ + case 4: + return (int)(38400); /*38.4MHz*/ + } + + return PRCM_FAIL; +} + +int prcm_get_system_clock_speed(void) +{ + u32 osc_clkspeed, sys_clkdiv; + + osc_clkspeed = prcm_get_crystal_rate(); + sys_clkdiv = (PRM_CLKSRC_CTRL >> 6) & 0x3; + if (osc_clkspeed == PRCM_FAIL) + return PRCM_FAIL; + else + return osc_clkspeed / sys_clkdiv; +} + +int prcm_select_system_clock_divider(u32 setting) +{ + u32 new_value = 0x00000000; + + new_value = (PRM_CLKSRC_CTRL & SYSCLK_DIV_MASK); + new_value = new_value | (setting << 6); + PRM_CLKSRC_CTRL = new_value; + + return PRCM_PASS; +} + +int prcm_control_external_output_clock1(u32 control) +{ + u32 new_value = 0x00000000; + + new_value = (PRM_CLKOUT_CTRL & EXTCLK_OUTCTRL_MASK); + new_value = new_value | (control << 7); + PRM_CLKOUT_CTRL = new_value; + + return PRCM_PASS; +} + +int prcm_control_external_output_clock2(u32 control) +{ + u32 new_value = 0x00000000; + + new_value = (CM_CLKOUT_CTRL & EXTCLK_OUTCTRL_MASK); + new_value = new_value | (control << 7); + CM_CLKOUT_CTRL = new_value; + + return PRCM_PASS; +} + +int prcm_clksel_get_divider(u32 clk, u32 *div) +{ + u32 valid, offset, clk_id, omap, id_type; + u32 *addr; + + id_type = get_id_type(clk); + if (!(id_type & ID_CLK_DIV)) + return PRCM_FAIL; /*No divider */ + + omap = OMAP(clk); + + if (cpu_is_omap3430() && !(omap & (AT_3430|AT_3430_ES2))) + return PRCM_FAIL; + + /* In case of 48m_fclk and 12m_fclk, the dividers are fixed */ + /* So this information is not stored in an array */ + if (clk == PRCM_48M_FCLK) { + (*div) = 2; + return PRCM_PASS; + } else if (clk == PRCM_12M_FCLK) { + (*div) = 4; + return PRCM_PASS; + } + clk_id = (clk >> CLK_NO_POS) & CLK_NO_MASK; + offset = clk_div_offset[clk_id-1]; + + if (clk_id > PRCM_NO_OF_CLKS) + return PRCM_FAIL; + + addr = clksel_reg[clk_id - 1].reg_addr; + if (!addr) + return PRCM_FAIL; + valid = clksel_reg[clk_id - 1].valid_bits; + + *div = (*addr & valid) >> offset; + /* For sys_clkout2, the divider is not same as value in register */ + /* Need to do bit shifting to get actual divider value */ + if (clk == PRCM_SYS_CLKOUT2) + *div = (1 << (*div)); + if (clk == PRCM_USIM) { + switch (*div) { + case 0x3: + *div = 2; + break; + case 0x5: + *div = 8; + break; + case 0x6: + *div = 10; + break; + case 0x7: + *div = 4; + break; + case 0x9: + *div = 16; + break; + case 0xA: + *div = 20; + break; + default: + break; + } + } + if (clk == PRCM_SGX_FCLK) { + switch (*div) { + case 0x0: + *div = 3; + break; + case 0x1: + *div = 4; + break; + case 0x2: + *div = 6; + break; + case 0x3: + *div = 1; + break; + default: + break; + } + } + return PRCM_PASS; +} + +int prcm_clksel_set_divider(u32 clk, u32 div) +{ + u32 valid, offset, clk_id, new_val, omap, id_type; + u32 *addr; + u32 divider = 0; + u8 reenable_clk = PRCM_FALSE; + u32 parent_id; + + id_type = get_id_type(clk); + if (!(id_type & ID_CLK_DIV)) + return PRCM_FAIL; /*No divider */ + + omap = OMAP(clk); + + if (cpu_is_omap3430() && !(omap & (AT_3430|AT_3430_ES2))) + return PRCM_FAIL; + + if (clk == PRCM_48M_FCLK) + return PRCM_FAIL; + else if (clk == PRCM_12M_FCLK) + return PRCM_FAIL; + if (clk == PRCM_USIM) { + prcm_clk_get_source(PRCM_USIM, &parent_id); + switch (div) { + case 2: + if (parent_id == PRCM_DPLL4_M2X2_CLK) + div = 0x3; + break; + case 4: + if (parent_id == PRCM_DPLL5_M2_CLK) + div = 0x7; + break; + case 8: + if (parent_id == PRCM_DPLL4_M2X2_CLK) + div = 0x5; + break; + case 10: + div = 0x6; + break; + case 16: + div = 0x9; + break; + case 20: + div = 0xA; + break; + default: + break; + } + } + if (clk == PRCM_SGX_FCLK) { + switch (div) { + case 3: + div = 0x0; + break; + case 4: + div = 0x1; + break; + case 6: + div = 0x2; + break; + case 1: + div = 0x3; + break; + default: + break; + } + } + clk_id = (clk >> CLK_NO_POS) & CLK_NO_MASK; + offset = clk_div_offset[clk_id-1]; + + if (clk_id > PRCM_NO_OF_CLKS) + return PRCM_FAIL; + + addr = clksel_reg[clk_id - 1].reg_addr; + if (!addr) + return PRCM_FAIL; + valid = clksel_reg[clk_id - 1].valid_bits; + + /* In case of sysclkout2, the value to be programmed in the register + is 0 for divider 1, 1 for divider 2, 2 for divider 4, + 3 for divider 8 and 4 for divider 16 */ + if (clk == PRCM_SYS_CLKOUT2) { + if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) { + /* WORKAROUND FOR SILICON ERRATA 1.37 */ + /* Disabling sysclkout2, bit 7 of CM_CLKOUT_CTRL */ + if (*addr&(1 << 7)) { + *addr &= (~(1 << 7)); + reenable_clk = PRCM_TRUE; + } + } + + for (divider = 0; divider <= 4; divider++) { + if (div & 0x1) { + div = divider; + break; + } + div >>= 1; + } + } + new_val = (*addr & ~valid) | (div << offset); + *addr = new_val; + + if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0) && (clk == PRCM_SYS_CLKOUT2) + && (reenable_clk)) { + /* WORKAROUND FOR SILCON ERRATA 1.37 */ + /* Enabling sysclkout2, bit 7 of CM_CLKOUT_CTRL */ + *addr |= (1 << 7); + } + return PRCM_PASS; +} + +int prcm_get_processor_speed(u32 domainid, u32 *processor_speed) +{ + int ret = PRCM_PASS; + switch (domainid) { + case DOM_MPU: + ret = prcm_get_dpll_rate(PRCM_DPLL1_M2X2_CLK, processor_speed); + if (ret != PRCM_PASS) + break; + else + /*There is a divider in mpu which makes the actual + processor speed half the dpll output */ + *processor_speed = *processor_speed / 2; + break; + case PRCM_IVA2: + ret = prcm_get_dpll_rate(PRCM_DPLL2_M2X2_CLK, processor_speed); + if (ret != PRCM_PASS) + break; + else + /*There is a divider in iva which makes the actual + processor speed half the dpll output */ + *processor_speed = *processor_speed / 2; + break; + default: + ret = PRCM_FAIL; + break; + } + return ret; +} + +int prcm_clksel_round_rate(u32 clk, u32 parent_rate, u32 target_rate, + u32 *newdiv) +{ + u32 omap, max_div = 6, div; + u32 index, clk_id, test_rate, dpll_id; + u32 id_type; + u32 div_96M[] = {2, 4, 8, 10, 0, 0}; + u32 div_120M[] = {4, 8, 16, 20, 0, 0}; + u32 div_sys[] = {1, 2, 0, 0, 0, 0}; + u32 div_core[] = {3, 4, 6, 0, 0, 0}; + u32 *div_array = NULL; + + + *newdiv = 0; + omap = OMAP(clk); + + if (cpu_is_omap3430() && !(omap & (AT_3430|AT_3430_ES2))) + return PRCM_FAIL; + + id_type = get_id_type(clk); + + if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) { + /* Workaround for limiation 2.5 */ + /* On ES 1.0, DPLL4 dividers cannot be changed */ + if (id_type & ID_DPLL_OP) { + dpll_id = (clk >> DPLL_NO_POS) & DPLL_NO_MASK; + if (dpll_id == DPLL4_PER) + return PRCM_FAIL; + /* For DPLL3, divider can only be changed */ + /*through OPP change */ + if (clk == PRCM_DPLL3_M3X2_CLK) + return PRCM_FAIL; + } + } + + if (id_type & ID_DPLL_OP) { + switch (clk) { + case PRCM_DPLL3_M3X2_CLK: + for (index = 0; index < 31; index++) { + if (!div_dpll[index]) + return PRCM_FAIL; + test_rate = parent_rate / div_dpll[index]; + if (test_rate <= target_rate) { + *newdiv = div_dpll[index]; + return PRCM_PASS; + } + } + case PRCM_DPLL5_M2_CLK: + case PRCM_DPLL4_M2X2_CLK: + case PRCM_DPLL4_M3X2_CLK: + case PRCM_DSS: + case PRCM_CAM: + case PRCM_DPLL4_M6X2_CLK: + for (index = 0; index < 16; index++) { + if (!div_dpll[index]) { + /* We have hit a NULL element + * which means dividers are exhausted */ + return PRCM_FAIL; + } + test_rate = parent_rate / div_dpll[index]; + if (test_rate <= target_rate) { + *newdiv = div_dpll[index]; + return PRCM_PASS; + } + } + break; + default: + /* No acceptable divider or divider + cannot be changed on the fly */ + return PRCM_FAIL; + } + } + + if (!(id_type & ID_CLK_DIV)) + return PRCM_FAIL; /* Clock rate cannot be changed */ + + /* For 48M Fclk and 12M Fclk, the dividers are fixed. + *So we return the fixed dividers */ + if (clk == PRCM_48M_FCLK) { + *newdiv = 2; + return PRCM_PASS; + } + if (clk == PRCM_12M_FCLK) { + *newdiv = 4; + return PRCM_PASS; + } + if (clk == PRCM_USIM) { + if (parent_rate == 96000000) + div_array = div_96M; + else if (parent_rate == 120000000) + div_array = div_120M; + else + div_array = div_sys; + for (index = 0; index < max_div; index++) { + if (!(*div_array)) + return PRCM_FAIL; + test_rate = parent_rate / *div_array; + if (test_rate <= target_rate) { + *newdiv = *div_array; + return PRCM_PASS; + } + ++div_array; + } + return PRCM_FAIL; + } + if (clk == PRCM_SGX_FCLK) { + if (parent_rate == 96000000) { + *newdiv = 1; + return PRCM_PASS; + } + else { + div_array = div_core; + for (index = 0; index < max_div; index++) { + if (!(*div_array)) + return PRCM_FAIL; + test_rate = parent_rate / *div_array; + if (test_rate <= target_rate) { + *newdiv = *div_array; + return PRCM_PASS; + } + ++div_array; + } + return PRCM_FAIL; + } + } + clk_id = clk & CLK_NO_MASK; + if (clk_id > PRCM_NO_OF_CLKS) + return PRCM_FAIL; + + for (index = 0; index < max_div; index++) { + if (!div_arr[index]) { + /* We have hit a NULL element which means + dividers are exhausted */ + return PRCM_FAIL; + } + div = div_arr[(clk_id * max_div) + index]; + test_rate = parent_rate / div; + if (test_rate <= target_rate) { + *newdiv = div; + return PRCM_PASS; + } + } + return PRCM_FAIL; /*No acceptable divider */ +} + +int prcm_clk_set_source(u32 clk_id, u32 parent_id) +{ + u32 valid, bit_pos, domain, bit_val, src_bit = 0, omap, id_type; + u8 ret = PRCM_PASS, result = -1; + + u32 *addr; + + id_type = get_id_type(clk_id); + if (!(id_type & ID_CLK_SRC)) + return PRCM_FAIL; /*Rate cannot be selected */ + + omap = OMAP(clk_id); + + if (cpu_is_omap3430() && !(omap & (AT_3430|AT_3430_ES2))) + return PRCM_FAIL; + + switch (clk_id) { + case PRCM_48M_FCLK: + /* Check the parent for this clock */ + if (parent_id == PRCM_DPLL4_M2X2_CLK) + src_bit = 0; + else if (parent_id == PRCM_SYS_ALT_CLK) + src_bit = 1; + else + return PRCM_FAIL; + addr = (u32 *)&CM_CLKSEL1_PLL; + bit_pos = 0x3; + break; + case PRCM_USIM: + addr = (u32 *)&CM_CLKSEL_WKUP; + valid = *addr & 0xFFFFFF87; + if (parent_id == PRCM_SYS_CLK) { + valid |= (0x1 << 3); + *addr = valid; + } + else if (parent_id == PRCM_DPLL4_M2X2_CLK) { + valid |= (0x3 << 3); + *addr = valid; + } + else if (parent_id == PRCM_DPLL5_M2_CLK) { + valid |= (0x7 << 3); + *addr = valid; + } + return PRCM_PASS; + break; + case PRCM_SGX_FCLK: + if (parent_id == PRCM_EXT_MCBSP_CLK) + CM_CLKSEL_SGX = 0x3; + else if (parent_id == PRCM_DPLL3_M2_CLK) + CM_CLKSEL_SGX = 0x0; /*Default divider is 3 */ + return PRCM_PASS; + break; + case PRCM_96M_CLK: + if (parent_id == PRCM_DPLL4_M2X2_CLK) + src_bit = 0; + else if (parent_id == PRCM_SYS_CLK) + src_bit = 1; + addr = (u32 *)&CM_CLKSEL1_PLL; + bit_pos = 0x6; + break; + case PRCM_TVOUT: + /* Check the parent for this clock */ + if (parent_id == PRCM_DPLL4_M3X2_CLK) + src_bit = 0; + else if (parent_id == PRCM_SYS_ALT_CLK) + src_bit = 1; + else + return PRCM_FAIL; + addr = (u32 *)&CM_CLKSEL1_PLL; + bit_pos = 0x5; + break; + case PRCM_SYS_CLKOUT2: + /* Check the parent for this clock */ + if (parent_id == PRCM_DPLL3_M2_CLK) + src_bit = 0; + else if (parent_id == PRCM_SYS_CLK) + src_bit = 1; + else if (parent_id == PRCM_DPLL4_M2X2_CLK) + src_bit = 2; + else if (parent_id == PRCM_TVOUT) + src_bit = 3; + else + return PRCM_FAIL; + addr = (u32 *)&CM_CLKOUT_CTRL; + bit_pos = 0x0; + valid = 0x3; + *addr = (*addr & ~valid) | src_bit; + /* Returning from here because we have already + *updated the register */ + return PRCM_PASS; + break; + case PRCM_MCBSP1: + case PRCM_MCBSP2: + ret = prcm_is_device_accessible(PRCM_OMAP_CTRL, &result); + if (ret == PRCM_PASS) { + if (result == PRCM_FALSE) { + /* + * The device is not accessible. + * So enable the interface clock. + */ + prcm_clock_control(PRCM_OMAP_CTRL, ICLK, + PRCM_ENABLE, PRCM_TRUE); + } + bit_pos = CLK_SRC_BIT_POS(clk_id); + addr = (u32 *)&OMAP2_CONTROL_DEVCONF0; + + if (parent_id == PRCM_DPLL4_M2X2_CLK) + src_bit = 0; + else if (parent_id == PRCM_EXT_MCBSP_CLK) + src_bit = 1; + else + return PRCM_FAIL; + } else + return ret; + break; + case PRCM_MCBSP3: + case PRCM_MCBSP4: + case PRCM_MCBSP5: + ret = prcm_is_device_accessible(PRCM_OMAP_CTRL, &result); + if (ret == PRCM_PASS) { + if (result == PRCM_FALSE) { + /* + * The device is not accessible. + * So enable the interface clock. + */ + prcm_clock_control(PRCM_OMAP_CTRL, ICLK, + PRCM_ENABLE, PRCM_TRUE); + } + bit_pos = CLK_SRC_BIT_POS(clk_id); + addr = (u32 *)&OMAP2_CONTROL_DEVCONF1; + + if (parent_id == PRCM_DPLL4_M2X2_CLK) + src_bit = 0; + else if (parent_id == PRCM_EXT_MCBSP_CLK) + src_bit = 1; + else + return PRCM_FAIL; + } else + return PRCM_FAIL; + break; + case PRCM_GPT1: + case PRCM_GPT2: + case PRCM_GPT3: + case PRCM_GPT4: + case PRCM_GPT5: + case PRCM_GPT6: + case PRCM_GPT7: + case PRCM_GPT8: + case PRCM_GPT9: + case PRCM_GPT10: + case PRCM_GPT11: + /* Setting clock source for GP timers. */ + if (parent_id == PRCM_SYS_32K_CLK) + src_bit = 0; + else if (parent_id == PRCM_SYS_CLK) + src_bit = 1; + else + return PRCM_FAIL; + bit_pos = CLK_SRC_BIT_POS(clk_id); + domain = DOMAIN_ID(clk_id); + addr = get_addr(domain, REG_CLK_SRC); + if (!addr) + return PRCM_FAIL; + break; + default: + printk(KERN_INFO "Invalid clock ID in prcm_clk_set_source\n"); + return PRCM_FAIL; + } + bit_val = ((1 << bit_pos) & *addr) >> bit_pos; + + if (bit_val && !(src_bit)) + *addr &= (~(1 << bit_pos)); + else if (!(bit_val) && src_bit) + *addr |= (1 << bit_pos); + + return PRCM_PASS; +} + +int prcm_clk_get_source(u32 clk_id, u32 *parent_id) +{ + u32 valid, valid_val, bit_pos, domain, omap, id_type; + u8 ret = PRCM_PASS, result = -1; + u32 *addr; + + id_type = get_id_type(clk_id); + if (!(id_type & ID_CLK_SRC)) + return PRCM_FAIL; /*Rate cannot be selected */ + + omap = OMAP(clk_id); + + if (cpu_is_omap3430() && !(omap & (AT_3430|AT_3430_ES2))) + return PRCM_FAIL; + + switch (clk_id) { + case PRCM_48M_FCLK: + addr = (u32 *)&CM_CLKSEL1_PLL; + bit_pos = 0x3; + if (((*addr & (1 << bit_pos)) >> bit_pos) == 0) + *parent_id = PRCM_DPLL4_M2X2_CLK; + else + *parent_id = PRCM_SYS_ALT_CLK; + break; + case PRCM_TVOUT: + addr = (u32 *)&CM_CLKSEL1_PLL; + bit_pos = 0x5; + if (((*addr & (1 << bit_pos)) >> bit_pos) == 0) + *parent_id = PRCM_DPLL4_M3X2_CLK; + else + *parent_id = PRCM_SYS_ALT_CLK; + break; + case PRCM_USIM: + addr = (u32 *)&CM_CLKSEL_WKUP; + bit_pos = 0x3; + valid = 0x78; + valid_val = (*addr & valid) >> bit_pos; + if ((valid_val == 0x1) || (valid_val == 0x2)) + *parent_id = PRCM_SYS_CLK; + else if ((valid_val >= 0x3) && (valid_val <= 0x6)) + *parent_id = PRCM_DPLL4_M2X2_CLK; + else if ((valid_val >= 0x7) && (valid_val <= 0xA)) + *parent_id = PRCM_DPLL5_M2_CLK; + break; + case PRCM_SGX_FCLK: + addr = (u32 *)&CM_CLKSEL_SGX; + bit_pos = 0x0; + valid = 0x7; + valid_val = (*addr & valid) >> bit_pos; + if ((valid_val >= 0x0) && (valid_val <= 0x2)) + *parent_id = PRCM_DPLL3_M2_CLK; + else + *parent_id = PRCM_EXT_MCBSP_CLK; + break; + case PRCM_96M_CLK: + addr = (u32 *)&CM_CLKSEL1_PLL; + bit_pos = 0x6; + valid_val = *addr & (1<<bit_pos); + if (valid_val == 0) + *parent_id = PRCM_DPLL4_M2X2_CLK; + else + *parent_id = PRCM_SYS_CLK; + break; + case PRCM_SYS_CLKOUT2: + addr = (u32 *)&CM_CLKOUT_CTRL; + bit_pos = 0x0; + valid = 0x3; + valid_val = *addr & (valid << bit_pos); + if (valid_val == 0) + *parent_id = PRCM_DPLL3_M2_CLK; + else if (valid_val == 1) + *parent_id = PRCM_SYS_CLK; + else if (valid_val == 2) + *parent_id = PRCM_DPLL4_M2X2_CLK; + else + *parent_id = PRCM_TVOUT; + break; + case PRCM_MCBSP1: + case PRCM_MCBSP2: + ret = prcm_is_device_accessible(PRCM_OMAP_CTRL, &result); + if (ret == PRCM_PASS) { + if (result == PRCM_FALSE) { + /* + * The device is not accessible. + * So enable the interface clock. + */ + prcm_clock_control(PRCM_OMAP_CTRL, ICLK, + PRCM_ENABLE, PRCM_TRUE); + } + + else { + addr = (u32 *)&OMAP2_CONTROL_DEVCONF0; + bit_pos = CLK_SRC_BIT_POS(clk_id); + + if (((*addr & (1 << bit_pos)) >> bit_pos) == 0) + *parent_id = PRCM_DPLL4_M2X2_CLK; + else + *parent_id = PRCM_EXT_MCBSP_CLK; + } + } else + return PRCM_FAIL; + break; + case PRCM_MCBSP3: + case PRCM_MCBSP4: + case PRCM_MCBSP5: + ret = prcm_is_device_accessible(PRCM_OMAP_CTRL, &result); + if (ret == PRCM_PASS) { + if (result == PRCM_FALSE) { + /* + * The device is not accessible. + * So enable the interface clock. + */ + prcm_clock_control(PRCM_OMAP_CTRL, ICLK, + PRCM_ENABLE, PRCM_TRUE); + } + + else { + addr = (u32 *)&OMAP2_CONTROL_DEVCONF1; + bit_pos = CLK_SRC_BIT_POS(clk_id); + + if (((*addr & (1 << bit_pos)) >> bit_pos) == 0) + *parent_id = PRCM_DPLL4_M2X2_CLK; + else + *parent_id = PRCM_EXT_MCBSP_CLK; + } + } else + return PRCM_FAIL; + break; + case PRCM_GPT1: + case PRCM_GPT2: + case PRCM_GPT3: + case PRCM_GPT4: + case PRCM_GPT5: + case PRCM_GPT6: + case PRCM_GPT7: + case PRCM_GPT8: + case PRCM_GPT9: + case PRCM_GPT10: + case PRCM_GPT11: + + bit_pos = CLK_SRC_BIT_POS(clk_id); + domain = DOMAIN_ID(clk_id); + addr = get_addr(domain, REG_CLK_SRC); + if (!addr) + return PRCM_FAIL; + + if (((*addr & (1 << bit_pos)) >> bit_pos) == 0) + *parent_id = PRCM_SYS_32K_CLK; + else + *parent_id = PRCM_SYS_CLK; + + break; + + default: + printk(KERN_INFO "Invalid clock ID in prcm_clk_get_source\n"); + return PRCM_FAIL; + } + return PRCM_PASS; +} + +int prcm_do_frequency_scaling(u32 target_opp_id, u32 current_opp_id) +{ + u32 id_type, vdd; + u32 curr_m, curr_n, tar_m, tar_n, tar_freqsel, tar_m2; + int curr_opp_no, target_opp_no, index; + u32 sys_clkspeed; + unsigned long flags; + u32 rfr_ctrl = 0, actim_ctrla = 0, actim_ctrlb = 0; + + if (target_opp_id == current_opp_id) + return PRCM_PASS; + + id_type = get_other_id_type(target_opp_id); + if (!(id_type & ID_OPP)) + return PRCM_FAIL; + + id_type = get_other_id_type(current_opp_id); + if (!(id_type & ID_OPP)) + return PRCM_FAIL; + + vdd = get_vdd(target_opp_id); + if (vdd != get_vdd(current_opp_id)) + return PRCM_FAIL; + + sys_clkspeed = prcm_get_system_clock_speed(); + switch (sys_clkspeed) { + case (int)(12000): + index = 0; + break; + case (int)(13000): + index = 1; + break; + case (int)(19200): + index = 2; + break; + case (int)(26000): + index = 3; + break; + case (int)(38400): + index = 4; + break; + default: + return PRCM_FAIL; + } + + if (vdd == PRCM_VDD1) { + curr_opp_no = current_opp_id & OPP_NO_MASK; + target_opp_no = target_opp_id & OPP_NO_MASK; + curr_m = (mpu_dpll_param[index][curr_opp_no - 1].dpll_m); + curr_n = (mpu_dpll_param[index][curr_opp_no - 1].dpll_n); + tar_m = (mpu_dpll_param[index][target_opp_no - 1].dpll_m); + tar_n = (mpu_dpll_param[index][target_opp_no - 1].dpll_n); + + if ((curr_m != tar_m) || (curr_n != tar_n)) { + /* M/N need to be changed - so put DPLL in bypass */ + prcm_put_dpll_in_bypass(DPLL1_MPU, LOW_POWER_BYPASS); + /* Reset M2 divider */ + prcm_configure_dpll_divider(PRCM_DPLL1_M2X2_CLK, 0x1); + /* Set M,N,Freqsel values */ + tar_freqsel = (mpu_dpll_param[index] + [target_opp_no - 1].dpll_freqsel); + prcm_configure_dpll + (DPLL1_MPU, tar_m, tar_n, tar_freqsel); + /* Lock the DPLL */ + prcm_enable_dpll(DPLL1_MPU); + } + /* Configure M2 */ + tar_m2 = (mpu_dpll_param[index][target_opp_no - 1].dpll_m2); + prcm_configure_dpll_divider(PRCM_DPLL1_M2X2_CLK, tar_m2); + + curr_m = (iva_dpll_param[index][curr_opp_no - 1].dpll_m); + curr_n = (iva_dpll_param[index][curr_opp_no - 1].dpll_n); + tar_m = (iva_dpll_param[index][target_opp_no - 1].dpll_m); + tar_n = (iva_dpll_param[index][target_opp_no - 1].dpll_n); + + if ((curr_m != tar_m) || (curr_n != tar_n)) { + /* M/N need to be changed - so put DPLL in bypass */ + prcm_put_dpll_in_bypass(DPLL2_IVA2, LOW_POWER_BYPASS); + /* Reset M2 divider */ + prcm_configure_dpll_divider(PRCM_DPLL2_M2X2_CLK, 0x1); + /* Set M,N,Freqsel values */ + tar_freqsel = (iva_dpll_param[index] + [target_opp_no - 1].dpll_freqsel); + prcm_configure_dpll + (DPLL2_IVA2, tar_m, tar_n, tar_freqsel); + /* Lock the DPLL */ + prcm_enable_dpll(DPLL2_IVA2); + } + /* Configure M2 */ + tar_m2 = (iva_dpll_param[index][target_opp_no - 1].dpll_m2); + prcm_configure_dpll_divider(PRCM_DPLL2_M2X2_CLK, tar_m2); + + /* Todo: Find out if some recalibation needs to be done + * in the OS since MPU freq has been changed */ + } + else if (vdd == PRCM_VDD2) { + target_opp_no = target_opp_id & OPP_NO_MASK; + tar_m = (core_dpll_param[index][target_opp_no - 1].dpll_m); + tar_n = (core_dpll_param[index][target_opp_no - 1].dpll_n); + tar_freqsel = (core_dpll_param[index] + [target_opp_no - 1].dpll_freqsel); + tar_m2 = (core_dpll_param[index][target_opp_no - 1].dpll_m2); + /* This function is executed from SRAM */ + local_irq_save(flags); + omap3_configure_core_dpll(rfr_ctrl, actim_ctrla, + actim_ctrlb, tar_m2); + local_irq_restore(flags); + } + return PRCM_PASS; +} Index: git-latest5/include/asm-arm/arch-omap/prcm_34xx.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ git-latest5/include/asm-arm/arch-omap/prcm_34xx.h 2008-03-04 05:25:50.501306385 +0530 @@ -0,0 +1,785 @@ +/* + * linux/include/asm-arm/arch-omap/prcm_34xx.h + * + * Access definitions for use in OMAP34XX clock and power management + * + * Copyright (C) 2008 Texas Instruments, Inc. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + */ + +#ifndef __ASM_ARM_ARCH_PRCM_H +#define __ASM_ARM_ARCH_PRCM_H + +/* Return Values of PRCM Lib API's */ +#define PRCM_PASS 0 +#define PRCM_FAIL 1 + + +/* Definitions for enable/ disable */ +#define PRCM_ENABLE 1 +#define PRCM_DISABLE 0 + +#define PRCM_TRUE 1 +#define PRCM_FALSE 0 + +/* Check accessibility or dont check accessibility*/ +#define PRCM_ACCESS_CHK 1 +#define PRCM_NO_ACCESS_CHK 0 + +/* IDLE METHOD */ +#define PRCM_AUTO 1 +#define PRCM_FORCE 2 +#define PRCM_MANUAL 3 + +/* POWER DOMAIN STATES */ +#define PRCM_OFF 0x0 +#define PRCM_RET 0x1 +#define PRCM_INACTIVE 0x2 +#define PRCM_ON 0x3 + +/* CLOCK STATE TRANSITIONS */ +#define PRCM_NO_AUTO 0x0 +#define PRCM_SWSUP_SLEEP 0x1 +#define PRCM_SWSUP_WKUP 0x2 +#define PRCM_HWSUP_AUTO 0x3 + +#define PRCM_FORCE_IDLE 0x0 +#define PRCM_NO_IDLE 0x1 +#define PRCM_SMART_IDLE 0x2 +#define PRCM_SIDLEMODE_DONTCARE 0x3 + +#define PRCM_FORCE_STANDBY 0x0 +#define PRCM_NO_STANDBY 0x1 +#define PRCM_SMART_STANDBY 0x2 +#define PRCM_MIDLEMODE_DONTCARE 0x3 + +/* Masks for standby, idle and auto idle modes */ +#define PRCM_AUTO_IDLE_MASK 0x1 +#define PRCM_IDLE_MASK 0x18 +#define PRCM_STANDBY_MASK 0x3000 + +/* Offsets for standby, idle and auto idle modes */ +#define PRCM_AUTO_IDLE_OFF 0x0 +#define PRCM_IDLE_OFF 0x3 +#define PRCM_STANDBY_OFF 0xC + +/* Mask for setting wakeup dependency */ +#define PRCM_WKDEP_EN_CORE 0x1 +#define PRCM_WKDEP_EN_MPU 0x2 +#define PRCM_WKDEP_EN_IVA2 0x4 +#define PRCM_WKDEP_EN_WKUP 0x10 +#define PRCM_WKDEP_EN_DSS 0x20 +#define PRCM_WKDEP_EN_PER 0x80 + +/* Mask for setting sleep dependency */ +#define PRCM_SLEEPDEP_EN_CORE 0x1 +#define PRCM_SLEEPDEP_EN_MPU 0x2 +#define PRCM_SLEEPDEP_EN_IVA2 0x4 + +/* Mask for H/W supervised transitions L3, L4 and D2D CLKS */ +#define CLK_D2D_HW_SUP_ENABLE 0x30 +#define CLK_L4_HW_SUP_ENABLE 0xC +#define CLK_L3_HW_SUP_ENABLE 0x3 + +/* VDDs*/ +#define PRCM_VDD1 1 +#define PRCM_VDD2 2 +#define PRCM_MAX_SYSC_REGS 30 + + +/* OMAP Revisions */ +#define AT_3430 1 /*3430 ES 1.0 */ +#define AT_3430_ES2 2 /*3430 ES 2.0 */ + +/* Domains */ +#define DOM_IVA2 1 +#define DOM_MPU 2 +#define DOM_CORE1 3 +#define DOM_CORE2 4 +#define DOM_SGX 5 +#define DOM_WKUP 6 +#define DOM_DSS 7 +#define DOM_CAM 8 +#define DOM_PER 9 +#define DOM_EMU 10 +#define DOM_NEON 11 +#define DOM_CORE3 12 +#define DOM_USBHOST 13 +#define PRCM_NUM_DOMAINS 13 + +/* DPLL's */ +#define DPLL1_MPU 1 +#define DPLL2_IVA2 2 +#define DPLL3_CORE 3 +#define DPLL4_PER 4 +#define DPLL5_PER2 5 +#define NO_OF_DPLL 5 + +/* PUT_DPLL_IN_BYPASS PARAMETERS */ +#define LOW_POWER_STOP 1 +#define LOW_POWER_BYPASS 5 +#define FAST_RELOCK_BYPASS 6 + +/* DPLL dividers */ +#define DPLL_M2 0x0 +#define DPLL_M2X2 0x1 +#define DPLL_M3X2 0x2 +#define DPLL_M4X2 0x3 +#define DPLL_M5X2 0x4 +#define DPLL_M6X2 0x5 +#define NO_DPLL_DIV 0x6 + +/* Device Type */ +#define INITIATOR 1 +#define TARGET 2 +#define INIT_TAR 3 + +/* Clock Type */ +#define FCLK 1 +#define ICLK 2 + +/* Initiator masks for all domains */ +#define IVA2_IMASK 0x1 +#define MPU_IMASK 0x1 +#define CORE2_IMASK 0x0 +#define CORE1_IMASK 0x15 +#define CORE3_IMASK 0x0 +#define SGX_IMASK 0x1 +#define USBHOST_IMASK 0x1 +#define WKUP_IMASK 0x0 +#define DSS_IMASK 0x1 +#define CAM_IMASK 0x1 +#define PER_IMASK 0x0 +#define NEON_IMASK 0x1 + +/* Type of device IDs - Note that a particular device It + can be of multiple types*/ +#define ID_DEV 0x0 /*Leaf node eg:uart */ +#define ID_DPLL_OP 0x1 /*Dpll output */ +#define ID_CLK_DIV 0x2 /*Clock has a divider */ +#define ID_CLK_SRC 0x4 /*Source of the clock can be selected */ + +#define ID_CLK_PARENT 0xE1 /*Parent of some other clock */ +#define ID_OPP 0xE2 /*OPP*/ +#define ID_MPU_DOM_STATE 0xE4 /*Mpu power domain state*/ +#define ID_CORE_DOM_STATE 0xE8 /*Core power domain state*/ +#define ID_SYSCONF 0xF0 + +#define ID_CONSTRAINT_CLK 0xF1 /* a clock rampup constraint */ +#define ID_CONSTRAINT_OPP 0xF2 /* OPP constraint */ +#define ID_CONSTRAINT_FREQ 0xF3 /* Frequnecy constraint */ +#define ID_MEMORY_RES 0xF4 /* Memory resource */ +#define ID_LOGIC_RES 0xF5 /* Logic resource */ + +/* DEVICE ID: bits 0-4 for Device bit position */ +#define DEV_BIT_POS_SHIFT 0 +#define DEV_BIT_POS_MASK 0x1F +/* DEVICE ID: bits 5-8 for domainid */ +#define DOMAIN_ID_SHIFT 5 +#define DOMAIN_ID_MASK 0xF +/* DEVICE ID: bits 9-10 for device type */ +#define DEV_TYPE_SHIFT 9 +#define DEV_TYPE_MASK 0x3 +/* DEVICE ID: bits 11-13 for clk src*/ +#define CLK_SRC_BIT_POS_SHIFT 11 +#define CLK_SRC_BIT_POS_MASK 0x7 +/* CLK ID: bits 14-18 for the clk number */ +#define CLK_NO_POS 14 +#define CLK_NO_MASK 0x1F +/* DPLL ID: bits 19-21 for the DPLL number */ +#define DPLL_NO_POS 19 +#define DPLL_NO_MASK 0x7 +/* DPLL ID: bits 22-24 for Divider */ +#define DPLL_DIV_POS 22 +#define DPLL_DIV_MASK 0x7 +/* DEVICE ID/DPLL ID/CLOCK ID: bits 25-27 for ID type */ +#define ID_TYPE_SHIFT 25 +#define ID_TYPE_MASK 0x7 +/* DEVICE ID/DPLL ID/CLOCK ID: bits 28-31 for OMAP type */ +#define OMAP_TYPE_SHIFT 28 +#define OMAP_TYPE_MASK 0xF + +/* Other IDs: bits 20-27 for ID type */ +/* These IDs have bits 25,26,27 as 1 */ +#define OTHER_ID_TYPE_SHIFT 20 +#define OTHER_ID_TYPE_MASK 0xFF + +/* OPP ID: bits: 0-4 for OPP number */ +#define OPP_NO_POS 0 +#define OPP_NO_MASK 0x1F +/* OPP ID: bits: 5-6 for VDD */ +#define VDD_NO_POS 5 +#define VDD_NO_MASK 0x3 +/* COMMMON bits in DEVICE ID/DPLL ID/CLOCK ID */ +/* Macros */ +#define ID_DEV_BIT_POS(X) ((X & DEV_BIT_POS_MASK)<<\ + DEV_BIT_POS_SHIFT) +#define ID_CLK_SRC_BIT_POS(X) ((X & CLK_SRC_BIT_POS_MASK)\ + << CLK_SRC_BIT_POS_SHIFT) +#define ID_DOMAIN(X) ((X & DOMAIN_ID_MASK) <<\ + DOMAIN_ID_SHIFT) +#define ID_DEV_TYPE(X) ((X & DEV_TYPE_MASK) <<\ + DEV_TYPE_SHIFT) +#define ID_DPLL_NO(X) ((X & DPLL_NO_MASK) <<\ + DPLL_NO_POS) +#define ID_DPLL_DIV(X) ((X & DPLL_DIV_MASK) << DPLL_DIV_POS) +#define ID_CLK_NO(X) ((X & CLK_NO_MASK) << CLK_NO_POS) +#define ID_TYPE(X) ((X & ID_TYPE_MASK) << ID_TYPE_SHIFT) +#define OTHER_ID_TYPE(X) ((X & OTHER_ID_TYPE_MASK) <<\ + OTHER_ID_TYPE_SHIFT) +#define ID_ES(X) ((X & ES_TYPE_MASK) << ES_TYPE_SHIFT) +#define ID_OMAP(X) ((X & OMAP_TYPE_MASK) <<\ + OMAP_TYPE_SHIFT) +#define ID_OPP_NO(X) ((X & OPP_NO_MASK) << OPP_NO_POS) +#define ID_VDD(X) ((X & VDD_NO_MASK) << VDD_NO_POS) +#define DEV_BIT_POS(X) ((X >> DEV_BIT_POS_SHIFT) &\ + DEV_BIT_POS_MASK) +#define CLK_SRC_BIT_POS(X) ((X >> CLK_SRC_BIT_POS_SHIFT) &\ + CLK_SRC_BIT_POS_MASK) +#define DOMAIN_ID(X) ((X >> DOMAIN_ID_SHIFT) &\ + DOMAIN_ID_MASK) +#define DEV_TYPE(X) ((X >> DEV_TYPE_SHIFT) &\ + DEV_TYPE_MASK) +#define OMAP(X) ((X >> OMAP_TYPE_SHIFT) &\ + OMAP_TYPE_MASK) +#define get_id_type(X) ((X >> ID_TYPE_SHIFT) & ID_TYPE_MASK) +#define get_other_id_type(X) ((X >> OTHER_ID_TYPE_SHIFT) &\ + OTHER_ID_TYPE_MASK) +#define get_opp_no(X) ((X >> OPP_NO_POS) & OPP_NO_MASK) +#define get_vdd(X) ((X >> VDD_NO_POS) & VDD_NO_MASK) +#define get_addr(domainId, regId) (dom_reg[domainId-1].regdef[regId]\ + .reg_addr) +#define get_val_bits(domainId, regId) (dom_reg[domainId-1].regdef[regId]\ + .valid_bits) +#define get_addr_pll(dpll, regId) (dpll_reg[dpll-1].regdef[regId]\ + .reg_addr) +#define get_val_bits_pll(dpll, regId) (dpll_reg[dpll-1].regdef[regId]\ + .valid_bits) +#define get_idlest_lock_bit(dpll_id) ((dpll_id == DPLL4_PER)?0x2:0x1) +#define get_dpll_enbitmask(dpll_id) ((dpll_id == DPLL4_PER)?\ + DPLL4_ENBIT_MASK\ + :DPLL_ENBIT_MASK) +/* DEVICE ID's */ +/* Devices in Core1 registers */ +#define PRCM_SSI (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_DIV)) |\ + ID_DEV_TYPE(INITIATOR) | ID_DOMAIN(DOM_CORE1)\ + | ID_DEV_BIT_POS(0x0) | ID_CLK_NO(0x7)) +#define PRCM_SDRC (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_CORE1)\ + | ID_DEV_BIT_POS(0x1)) +#define PRCM_SDMA (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(INITIATOR)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x2)) +#define PRCM_D2D (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(INITIATOR)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x3)) +#define PRCM_HSOTG (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(INITIATOR)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x4)) + +#define PRCM_OMAP_CTRL (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x6)) +#define PRCM_MBOXES (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x7)) +#define PRCM_FAC (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x8)) +#define PRCM_MCBSP1 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | \ + ID_CLK_SRC_BIT_POS(0x2) | ID_DEV_BIT_POS(0x9)) +#define PRCM_MCBSP5 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_CORE1) |\ + ID_CLK_SRC_BIT_POS(0x4) | ID_DEV_BIT_POS(0xA)) +#define PRCM_GPT10 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_CORE1) |\ + ID_CLK_SRC_BIT_POS(0x6) | ID_DEV_BIT_POS(0xB)) +#define PRCM_GPT11 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_CORE1) |\ + ID_CLK_SRC_BIT_POS(0x7) | ID_DEV_BIT_POS(0xC)) +#define PRCM_UART1 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0xD)) +#define PRCM_UART2 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0xE)) +#define PRCM_I2C1 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0xF)) +#define PRCM_I2C2 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x10)) +#define PRCM_I2C3 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x11)) +#define PRCM_MCSPI1 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x12)) +#define PRCM_MCSPI2 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x13)) +#define PRCM_MCSPI3 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x14)) +#define PRCM_MCSPI4 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x15)) +#define PRCM_HDQ (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x16)) +#define PRCM_MSPRO (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x17)) +#define PRCM_MMC1 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x18)) +#define PRCM_MMC2 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x19)) +#define PRCM_DES2 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x1A)) +#define PRCM_SHA12 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x1B)) +#define PRCM_AES2 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x1C)) +#define PRCM_ICR (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x1D)) +#define PRCM_MMC3 (ID_OMAP(AT_3430_ES2) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x1E)) +#define PRCM_SMS (ID_OMAP(AT_3430) | OTHER_ID_TYPE(ID_SYSCONF) |\ + ID_DEV_TYPE(TARGET) | \ + ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x18)) +#define PRCM_GPMC (ID_OMAP(AT_3430) | OTHER_ID_TYPE(ID_SYSCONF) |\ + ID_DEV_TYPE(TARGET) | \ + ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x19)) +#define PRCM_MPU_INTC (ID_OMAP(AT_3430) | OTHER_ID_TYPE(ID_SYSCONF) |\ + ID_DEV_TYPE(TARGET) | \ + ID_DOMAIN(DOM_CORE1) | ID_DEV_BIT_POS(0x1A)) +#define PRCM_CORE1_CONSTRAINT (ID_OMAP(AT_3430) | \ + OTHER_ID_TYPE(ID_CONSTRAINT_CLK) | \ + ID_DOMAIN(DOM_CORE1)) +/* Devices in Core2 registers */ +#define PRCM_DES1 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE2) | ID_DEV_BIT_POS(0x0)) +#define PRCM_SHA11 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE2) | ID_DEV_BIT_POS(0x1)) +#define PRCM_RNG (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE2) | ID_DEV_BIT_POS(0x2)) +#define PRCM_AES1 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE2) | ID_DEV_BIT_POS(0x3)) +#define PRCM_PKA (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE2) | ID_DEV_BIT_POS(0x4)) + +/* Devices in Core3 registers */ +#define PRCM_CPEFUSE (ID_OMAP(AT_3430_ES2) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE3) | ID_DEV_BIT_POS(0x0)) +#define PRCM_TS (ID_OMAP(AT_3430_ES2) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE3) | ID_DEV_BIT_POS(0x1)) +#define PRCM_USBTLL (ID_OMAP(AT_3430_ES2) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_CORE3) | ID_DEV_BIT_POS(0x2)) +/* Devices in SGX registers */ +#define PRCM_SGX_ICLK (ID_OMAP(AT_3430_ES2) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(INITIATOR) | ID_DOMAIN(DOM_SGX)\ + | ID_DEV_BIT_POS(0x0)) +#define PRCM_SGX_FCLK (ID_OMAP(AT_3430_ES2) |\ + ID_TYPE((ID_DEV | ID_CLK_DIV | ID_CLK_SRC))\ + | ID_DOMAIN(DOM_SGX) | ID_DEV_TYPE(TARGET) |\ + ID_CLK_NO(0x6) | ID_DEV_BIT_POS(0x1)) +#define PRCM_3D_CONSTRAINT (ID_OMAP(AT_3430) |\ + OTHER_ID_TYPE(ID_CONSTRAINT_CLK) | \ + ID_DOMAIN(DOM_SGX)) + +/* Devices in WKUP registers */ +#define PRCM_GPT1 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_WKUP) | \ + ID_CLK_SRC_BIT_POS(0x0) | ID_DEV_BIT_POS(0x0)) +#define PRCM_GPT12 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_WKUP) | ID_DEV_BIT_POS(0x1)) +#define PRCM_32KSYNC (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_WKUP) | ID_DEV_BIT_POS(0x2)) +#define PRCM_GPIO1 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_WKUP) | ID_DEV_BIT_POS(0x3)) +#define PRCM_WDT1 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_WKUP) | ID_DEV_BIT_POS(0x4)) +#define PRCM_WDT2 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_WKUP) | ID_DEV_BIT_POS(0x5)) +#define PRCM_SR1 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_WKUP) | ID_DEV_BIT_POS(0x6)) +#define PRCM_SR2 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_WKUP) | ID_DEV_BIT_POS(0x7)) +#define PRCM_USIM (ID_OMAP(AT_3430_ES2) | ID_TYPE((ID_DEV | ID_CLK_DIV |\ + ID_CLK_SRC)) | ID_DEV_TYPE(TARGET) |\ + ID_DOMAIN(DOM_WKUP)\ + | ID_DEV_BIT_POS(0x9) | ID_CLK_NO(0xA)) + +/* Devices in IVA registers */ +#define PRCM_IVA2 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(INITIATOR)\ + | ID_DOMAIN(DOM_IVA2) | ID_DEV_BIT_POS(0x0)) +#define PRCM_IVA2_CONSTRAINT (ID_OMAP(AT_3430) | \ + OTHER_ID_TYPE(ID_CONSTRAINT_CLK) | \ + ID_DOMAIN(DOM_IVA2)) +/* Devices in DSS registers */ +#define PRCM_DSS (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_DPLL_OP)) |\ + ID_DEV_TYPE(INITIATOR)\ + | ID_DOMAIN(DOM_DSS) | ID_DEV_BIT_POS(0x0) | \ + ID_DPLL_DIV(DPLL_M4X2) | ID_DPLL_NO(DPLL4_PER)) +#define PRCM_DSS2 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(INITIATOR)\ + | ID_DOMAIN(DOM_DSS) | ID_DEV_BIT_POS(0x1)) +#define PRCM_TVOUT (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC)) | \ + ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_DSS) |\ + ID_DEV_BIT_POS(0x2)) +#define PRCM_DISPC (ID_OMAP(AT_3430) | OTHER_ID_TYPE(ID_SYSCONF) |\ + ID_DEV_TYPE(INIT_TAR) \ + | ID_DOMAIN(DOM_DSS) | ID_DEV_BIT_POS(0x1)) +#define PRCM_RFBI (ID_OMAP(AT_3430) | OTHER_ID_TYPE(ID_SYSCONF) |\ + ID_DEV_TYPE(INITIATOR) \ + | ID_DOMAIN(DOM_DSS) | ID_DEV_BIT_POS(0x2)) + +#define PRCM_DSS_CONSTRAINT (ID_OMAP(AT_3430) | \ + OTHER_ID_TYPE(ID_CONSTRAINT_CLK) | \ + ID_DOMAIN(DOM_DSS)) + +/* Devices in CAM Domain */ +#define PRCM_CAM (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_DPLL_OP)) |\ + ID_DEV_TYPE(INITIATOR)\ + | ID_DOMAIN(DOM_CAM) | ID_DEV_BIT_POS(0x0) |\ + ID_DPLL_DIV(DPLL_M5X2) | ID_DPLL_NO(DPLL4_PER)) + +#define PRCM_CSI2 (ID_OMAP(AT_3430_ES2) | ID_TYPE((ID_DEV | ID_DPLL_OP))\ + | ID_DEV_TYPE(INITIATOR)\ + | ID_DOMAIN(DOM_CAM) | ID_DEV_BIT_POS(0x1)) + +#define PRCM_CSIA (ID_OMAP(AT_3430) | OTHER_ID_TYPE(ID_SYSCONF) |\ + ID_DEV_TYPE(INIT_TAR)\ + | ID_DOMAIN(DOM_CAM) | ID_DEV_BIT_POS(0x1)) +#define PRCM_CSIB (ID_OMAP(AT_3430) | OTHER_ID_TYPE(ID_SYSCONF) |\ + ID_DEV_TYPE(INIT_TAR)\ + | ID_DOMAIN(DOM_CAM) | ID_DEV_BIT_POS(0x2)) +#define PRCM_MMU (ID_OMAP(AT_3430) | OTHER_ID_TYPE(ID_SYSCONF) |\ + ID_DEV_TYPE(INIT_TAR)\ + | ID_DOMAIN(DOM_CAM) | ID_DEV_BIT_POS(0x3)) +#define PRCM_ISP_CTRL (ID_OMAP(AT_3430) | OTHER_ID_TYPE(ID_SYSCONF) |\ + ID_DEV_TYPE(INIT_TAR)\ + | ID_DOMAIN(DOM_CAM) | ID_DEV_BIT_POS(0x4)) +#define PRCM_CAM_CONSTRAINT (ID_OMAP(AT_3430) | \ + OTHER_ID_TYPE(ID_CONSTRAINT_CLK) | \ + ID_DOMAIN(DOM_CAM)) + +/* Devices in PER Domain */ +#define PRCM_MCBSP2 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_PER) | \ + ID_CLK_SRC_BIT_POS(0x6) | ID_DEV_BIT_POS(0x0)) +#define PRCM_MCBSP3 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_PER) | \ + ID_CLK_SRC_BIT_POS(0x0) | ID_DEV_BIT_POS(0x1)) +#define PRCM_MCBSP4 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_PER) | \ + ID_CLK_SRC_BIT_POS(0x2) | ID_DEV_BIT_POS(0x2)) +#define PRCM_GPT2 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_PER) | \ + ID_CLK_SRC_BIT_POS(0x0) | ID_DEV_BIT_POS(0x3)) +#define PRCM_GPT3 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_PER) | \ + ID_CLK_SRC_BIT_POS(0x1) | ID_DEV_BIT_POS(0x4)) +#define PRCM_GPT4 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_PER) | \ + ID_CLK_SRC_BIT_POS(0x2) | ID_DEV_BIT_POS(0x5)) +#define PRCM_GPT5 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_PER) | \ + ID_CLK_SRC_BIT_POS(0x3) | ID_DEV_BIT_POS(0x6)) +#define PRCM_GPT6 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_PER) | \ + ID_CLK_SRC_BIT_POS(0x4) | ID_DEV_BIT_POS(0x7)) +#define PRCM_GPT7 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_PER) | \ + ID_CLK_SRC_BIT_POS(0x5) | ID_DEV_BIT_POS(0x8)) +#define PRCM_GPT8 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_PER) | \ + ID_CLK_SRC_BIT_POS(0x6) | ID_DEV_BIT_POS(0x9)) +#define PRCM_GPT9 (ID_OMAP(AT_3430) | ID_TYPE((ID_DEV | ID_CLK_SRC))\ + | ID_DEV_TYPE(TARGET) | ID_DOMAIN(DOM_PER) | \ + ID_CLK_SRC_BIT_POS(0x7) | ID_DEV_BIT_POS(0xA)) +#define PRCM_UART3 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_PER) | ID_DEV_BIT_POS(0xB)) +#define PRCM_WDT3 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_PER) | ID_DEV_BIT_POS(0xC)) +#define PRCM_GPIO2 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_PER) | ID_DEV_BIT_POS(0xD)) +#define PRCM_GPIO3 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_PER) | ID_DEV_BIT_POS(0xE)) +#define PRCM_GPIO4 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_PER) | ID_DEV_BIT_POS(0xF)) +#define PRCM_GPIO5 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_PER) | ID_DEV_BIT_POS(0x10)) +#define PRCM_GPIO6 (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(TARGET)\ + | ID_DOMAIN(DOM_PER) | ID_DEV_BIT_POS(0x11)) +#define PRCM_PER_CONSTRAINT (ID_OMAP(AT_3430) | \ + OTHER_ID_TYPE(ID_CONSTRAINT_CLK) | \ + ID_DOMAIN(DOM_PER)) + +/* Devices in NEON Domain */ +#define PRCM_NEON (ID_OMAP(AT_3430) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(INITIATOR)\ + | ID_DOMAIN(DOM_NEON) | ID_DEV_BIT_POS(0x0)) +#define PRCM_NEON_CONSTRAINT (ID_OMAP(AT_3430) | \ + OTHER_ID_TYPE(ID_CONSTRAINT_CLK) | \ + ID_DOMAIN(DOM_NEON)) + +/* Devices in USBHOST Domain */ +#define PRCM_USBHOST1 (ID_OMAP(AT_3430_ES2) | ID_TYPE(ID_DEV) |\ + ID_DEV_TYPE(INITIATOR)\ + | ID_DOMAIN(DOM_USBHOST) | ID_DEV_BIT_POS(0x0)) +#define PRCM_USBHOST2 (ID_OMAP(AT_3430_ES2) | ID_TYPE((ID_DEV | ID_DPLL_OP))\ + | ID_DEV_TYPE(INITIATOR) |\ + ID_DOMAIN(DOM_USBHOST)\ + | ID_DEV_BIT_POS(0x1)| ID_DPLL_DIV(DPLL_M2)\ + | ID_DPLL_NO(DPLL5_PER2)) +#define PRCM_USBHOST_CONSTRAINT (ID_OMAP(AT_3430) | \ + OTHER_ID_TYPE(ID_CONSTRAINT_CLK) | \ + ID_DOMAIN(DOM_USBHOST)) + +/* DPLL ID's */ +#define PRCM_DPLL1_M2X2_CLK (ID_OMAP(AT_3430) | ID_TYPE(ID_DPLL_OP)\ + | ID_DPLL_DIV(DPLL_M2X2) |\ + ID_DPLL_NO(DPLL1_MPU)) +#define PRCM_DPLL2_M2X2_CLK (ID_OMAP(AT_3430) | ID_TYPE(ID_DPLL_OP)\ + | ID_DPLL_DIV(DPLL_M2X2) |\ + ID_DPLL_NO(DPLL2_IVA2)) +#define PRCM_DPLL3_M2_CLK (ID_OMAP(AT_3430) | ID_TYPE(ID_DPLL_OP)\ + | ID_DPLL_DIV(DPLL_M2) |\ + ID_DPLL_NO(DPLL3_CORE)) +#define PRCM_DPLL3_M2X2_CLK (ID_OMAP(AT_3430) | ID_TYPE(ID_DPLL_OP)\ + | ID_DPLL_DIV(DPLL_M2X2) |\ + ID_DPLL_NO(DPLL3_CORE)) +#define PRCM_DPLL3_M3X2_CLK (ID_OMAP(AT_3430) | ID_TYPE(ID_DPLL_OP)\ + | ID_DPLL_DIV(DPLL_M3X2) |\ + ID_DPLL_NO(DPLL3_CORE)) +#define PRCM_DPLL4_M2X2_CLK (ID_OMAP(AT_3430) | ID_TYPE(ID_DPLL_OP)\ + | ID_DPLL_DIV(DPLL_M2X2) |\ + ID_DPLL_NO(DPLL4_PER)) +#define PRCM_DPLL4_M3X2_CLK (ID_OMAP(AT_3430) | ID_TYPE(ID_DPLL_OP)\ + | ID_DPLL_DIV(DPLL_M3X2) |\ + ID_DPLL_NO(DPLL4_PER)) +#define PRCM_DPLL4_M6X2_CLK (ID_OMAP(AT_3430) | ID_TYPE(ID_DPLL_OP)\ + | ID_DPLL_DIV(DPLL_M6X2) |\ + ID_DPLL_NO(DPLL4_PER)) +#define PRCM_DPLL5_M2_CLK (ID_OMAP(AT_3430_ES2) | ID_TYPE(ID_DPLL_OP)\ + | ID_DPLL_DIV(DPLL_M2) |\ + ID_DPLL_NO(DPLL5_PER2)) + +/* CLK ID's */ +#define PRCM_L3_ICLK (ID_OMAP(AT_3430) | ID_TYPE(ID_CLK_DIV) |\ + ID_CLK_NO(0x1)) +#define PRCM_L4_ICLK (ID_OMAP(AT_3430) | ID_TYPE(ID_CLK_DIV) |\ + ID_CLK_NO(0x2)) +#define PRCM_RM_ICLK (ID_OMAP(AT_3430) | ID_TYPE(ID_CLK_DIV) |\ + ID_CLK_NO(0x3)) +#define PRCM_SYS_CLKOUT2 (ID_OMAP(AT_3430) | ID_TYPE((ID_CLK_DIV |\ + ID_CLK_SRC)) | ID_CLK_NO(0x5)) + +#define PRCM_DPLL1_FCLK (ID_OMAP(AT_3430) | ID_TYPE(ID_CLK_DIV)\ + | ID_CLK_NO(0x8)) +#define PRCM_DPLL2_FCLK (ID_OMAP(AT_3430) | ID_TYPE(ID_CLK_DIV)\ + | ID_CLK_NO(0x9)) +#define PRCM_96M_CLK (ID_OMAP(AT_3430_ES2) | ID_TYPE(ID_CLK_SRC)\ + | ID_CLK_SRC_BIT_POS(0x6)) +#define PRCM_NO_OF_CLKS 0xA +/* func_48m_fclk and func_12m_fclk have dividers */ +/*but they are fixed dividers.*/ +/*So these are not included in the array */ +#define PRCM_48M_FCLK (ID_OMAP(AT_3430) | ID_TYPE((ID_CLK_DIV\ + | ID_CLK_SRC)) | ID_CLK_NO(0xB)) +#define PRCM_12M_FCLK (ID_OMAP(AT_3430) | ID_TYPE(ID_CLK_DIV)\ + | ID_CLK_NO(0xE)) +/* Clock IDs for parent clocks */ +#define PRCM_SYS_ALT_CLK (OMAP(AT_3430)| OTHER_ID_TYPE(ID_CLK_PARENT)\ + | ID_CLK_NO(0xF)) +#define PRCM_SYS_CLK (OMAP(AT_3430)| OTHER_ID_TYPE(ID_CLK_PARENT)\ + | ID_CLK_NO(0x10)) +#define PRCM_SYS_32K_CLK (OMAP(AT_3430)| OTHER_ID_TYPE(ID_CLK_PARENT)\ + | ID_CLK_NO(0x11)) +#define PRCM_EXT_MCBSP_CLK (OMAP(AT_3430)| OTHER_ID_TYPE(ID_CLK_PARENT)\ + | ID_CLK_NO(0x12)) +#define PRCM_SYS_CLKOUT1 (OMAP(AT_3430)| OTHER_ID_TYPE(ID_CLK_PARENT)\ + | ID_CLK_NO(0x13)) +/* VDD1 OPPs */ +#define PRCM_VDD1_OPP1 (OMAP(AT_3430) | OTHER_ID_TYPE(ID_OPP) |\ + ID_VDD(PRCM_VDD1)\ + | ID_OPP_NO(0x1)) +#define PRCM_VDD1_OPP2 (OMAP(AT_3430) | OTHER_ID_TYPE(ID_OPP) |\ + ID_VDD(PRCM_VDD1)\ + | ID_OPP_NO(0x2)) +#define PRCM_VDD1_OPP3 (OMAP(AT_3430) | OTHER_ID_TYPE(ID_OPP) |\ + ID_VDD(PRCM_VDD1)\ + | ID_OPP_NO(0x3)) +#define PRCM_VDD1_OPP4 (OMAP(AT_3430) | OTHER_ID_TYPE(ID_OPP) |\ + ID_VDD(PRCM_VDD1)\ + | ID_OPP_NO(0x4)) +#define PRCM_VDD1_OPP5 (OMAP(AT_3430) | OTHER_ID_TYPE(ID_OPP) |\ + ID_VDD(PRCM_VDD1)\ + | ID_OPP_NO(0x5)) +#define PRCM_NO_VDD1_OPPS 5 + +/* VDD2 OPPs */ +#define PRCM_VDD2_OPP1 (OMAP(AT_3430) | OTHER_ID_TYPE(ID_OPP) |\ + ID_VDD(PRCM_VDD2)\ + | ID_OPP_NO(0x1)) +#define PRCM_VDD2_OPP2 (OMAP(AT_3430) | OTHER_ID_TYPE(ID_OPP) |\ + ID_VDD(PRCM_VDD2)\ + | ID_OPP_NO(0x2)) +#define PRCM_VDD2_OPP3 (OMAP(AT_3430) | OTHER_ID_TYPE(ID_OPP) |\ + ID_VDD(PRCM_VDD2)\ + | ID_OPP_NO(0x3)) +#define PRCM_NO_VDD2_OPPS 3 + +/* VDD1 and VDD2 sleep states */ +#define PRCM_VDD_ACTIVE 1 +#define PRCM_VDD_RET 2 +#define PRCM_VDD_OFF 3 + +/* GPTimer wait delay */ +#define GPTIMER_WAIT_DELAY 50 /* In usec */ + +extern void omap3_configure_core_dpll(u32 tar_m, u32 tar_n, u32 tar_freqsel, + u32 tar_m2); +extern void omap3_clk_prepare_for_reboot(void); + +/* Register Types */ +enum regtype { + REG_FCLKEN, + REG_ICLKEN, + REG_IDLEST, + REG_AUTOIDLE, + REG_WKEN, + REG_WKST, + REG_CLKSTCTRL, + REG_CLKSTST, + REG_PWSTCTRL, + REG_PWSTST, + REG_PREPWSTST, + REG_CLK_SRC, + REG_RSTST, + PRCM_REG_TYPES, +}; + +enum dpll_regtype { + REG_CLKEN_PLL, + REG_AUTOIDLE_PLL, + REG_CLKSEL1_PLL, + REG_IDLEST_PLL, + REG_M2_DIV_PLL, + REG_M2X2_DIV_PLL, + REG_M3_DIV_PLL, + REG_M4_DIV_PLL, + REG_M5_DIV_PLL, + REG_M6_DIV_PLL, + PRCM_DPLL_REG_TYPES, +}; + +struct dpll_param { + u32 dpll_m; + u32 dpll_n; + u32 dpll_freqsel; + u32 dpll_m2; +}; + +/* Offset of MX registers in the pll_register array*/ +#define MX_ARRAY_OFFSET REG_M2_DIV_PLL + +/* Structure to store the attributes of register */ +struct reg_def { + u32 valid_bits; + u32 *reg_addr; +}; + +/* Structure to store attributes of registers in a domain */ +struct domain_registers { + struct reg_def regdef[PRCM_REG_TYPES]; +}; + +/* Structure to store DPLL information */ +struct dpll_registers { + struct reg_def regdef[PRCM_DPLL_REG_TYPES]; +}; + +extern int prcm_clock_control(u32 deviceid, u8 clk_type, u8 control, + u8 checkaccessibility); +extern int prcm_is_device_accessible(u32 deviceid, u8 *result); + +/* DPLL control APIs */ +extern int prcm_enable_dpll(u32 dpll); +extern int prcm_configure_dpll(u32 dpll, u32 mult, u8 div, u8 freq_sel); +extern int prcm_put_dpll_in_bypass(u32 dpll, u32 bypass_mode); +extern int prcm_get_dpll_mn_output(u32 dpll, u32 *mn_output); +extern int prcm_get_dpll_rate(u32 dpll, u32 *rate); +extern int prcm_configure_dpll_divider(u32 dpll, u32 setting); + +/* Other APIs*/ +extern int prcm_get_crystal_rate(void); +extern int prcm_get_system_clock_speed(void); +extern int prcm_select_system_clock_divider(u32 setting); +extern int prcm_control_external_output_clock1(u32 control); +extern int prcm_control_external_output_clock2(u32 control); +extern int prcm_select_external_output_clock2_divider(u32 setting); +extern int prcm_select_external_output_clock2_source(u32 setting); +extern int prcm_clksel_get_divider(u32 clk, u32 *div); +extern int prcm_clksel_set_divider(u32 clk, u32 div); +extern int prcm_get_processor_speed(u32 domainid, u32 *processor_speed); +extern int prcm_clksel_round_rate(u32 clk, u32 parent_rate, u32 target_rate, + u32 *newdiv); +extern int prcm_clk_set_source(u32 clk_id, u32 parent_id); +extern int prcm_clk_get_source(u32 clk_id, u32 *parent_id); +extern int get_dpll_m_n(u32 dpll_id, u32 *mult, u32 *div); +/* Level 2 PRCM APIs */ +extern int prcm_do_frequency_scaling(u32 target_opp, u32 current_opp); +extern void omap_udelay(u32 delay); +void clear_domain_reset_status(void); +u32 omap_prcm_get_reset_sources(void); + +#endif Index: git-latest5/arch/arm/mach-omap2/sram-fn_34xx.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ git-latest5/arch/arm/mach-omap2/sram-fn_34xx.S 2008-03-04 04:44:20.558491901 +0530 @@ -0,0 +1,156 @@ +/* + * linux/arch/arm/mach-omap3/sram.S + * + * Omap3 specific functions that need to be run in internal SRAM + * + * (C) Copyright 2008 + * Texas Instruments Inc. + * Rajendra Nayak <rnayak@xxxxxx> + * + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@xxxxxx> + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/arch/io.h> +#include <asm/hardware.h> + +#include "prcm-regs.h" + +#define CM_CLKSEL1_PLL_V IO_ADDRESS(OMAP3430_CM_BASE + 0xD40) +#define CM_ICLKEN1_CORE_V IO_ADDRESS(OMAP3430_CM_BASE + 0xA10) +#define CM_IDLEST1_CORE_V IO_ADDRESS(OMAP3430_CM_BASE + 0xA20) + +#define SDRC_POWER_V IO_ADDRESS(OMAP343X_SDRC_BASE + 0x070) + + .text + +ENTRY(sram_ddr_init) + stmfd sp!, {r0 - r12, lr} @ save registers on stack + ldmfd sp!, {r0 - r12, pc} @ restore regs and return +ENTRY(sram_ddr_init_sz) + .word . - sram_ddr_init + +ENTRY(sram_reprogram_sdrc) + stmfd sp!, {r0 - r10, lr} @ save registers on stack + ldmfd sp!, {r0 - r10, pc} @ restore regs and return +ENTRY(sram_reprogram_sdrc_sz) + .word . - sram_reprogram_sdrc + +/* + * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. + */ +ENTRY(sram_set_prcm) + stmfd sp!, {r0-r12, lr} @ regs to stack +ENTRY(sram_set_prcm_sz) + .word . - sram_set_prcm + +/* + * Change frequency of core dpll + * r0 = M r1 = N r2 = FreqSel r3 = M2 + */ +ENTRY(sram_configure_core_dpll) + stmfd sp!, {r1-r12, lr} @ store regs to stack + bl sdram_in_selfrefresh @ put the SDRAM in self refresh + bl configure_core_dpll + bl enable_sdrc + mov r0, #0 @ return value + ldmfd sp!, {r1-r12, pc} @ restore regs and return +sdram_in_selfrefresh: + mov r5, #0x0 @ Move 0 to R5 + mcr p15, 0, r5, c7, c10, 5 @ memory barrier + ldr r4, sdrc_power @ read the SDRC_POWER register + ldr r5, [r4] @ read the contents of SDRC_POWER + orr r5, r5, #0x48 @ enable self refresh on idle req + str r5, [r4] @ write back to SDRC_POWER register + ldr r4, cm_iclken1_core @ read the CM_ICLKEN1_CORE reg + ldr r5, [r4] + bic r5, r5, #0x2 @ disable iclk bit for SRDC + str r5, [r4] +wait_sdrc_idle: + ldr r4, cm_idlest1_core + ldr r5, [r4] + and r5, r5, #0x2 @ check for SDRC idle + cmp r5, #2 + bne wait_sdrc_idle + bx lr +configure_core_dpll: + ldr r4, cm_clksel1_pll + ldr r5, [r4] + ldr r6, core_m2_mask_val @ modify m2 for core dpll + and r5, r5, r6 + orr r5, r5, r3, lsl #0x1B @ r3 contains the M2 val + str r5, [r4] + ldr r5, clk_stabilize_delay @ wait for the clock to stabilise +wait_clk_stable: + subs r5, r5, #1 + bne wait_clk_stable + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + bx lr +enable_sdrc: + ldr r4, cm_iclken1_core + ldr r5, [r4] + orr r5, r5, #0x2 @ enable iclk bit for SDRC + str r5, [r4] +wait_sdrc_idle1: + ldr r4, cm_idlest1_core + ldr r5, [r4] + and r5, r5, #0x2 + cmp r5, #0 + bne wait_sdrc_idle1 + ldr r4, sdrc_power + ldr r5, [r4] + bic r5, r5, #0x48 + str r5, [r4] + bx lr + +sdrc_power: + .word SDRC_POWER_V +cm_clksel1_pll: + .word CM_CLKSEL1_PLL_V +cm_idlest1_core: + .word CM_IDLEST1_CORE_V +cm_iclken1_core: + .word CM_ICLKEN1_CORE_V +core_m2_mask_val: + .word 0xE7FFFFFF +clk_stabilize_delay: + .word 0x000002FF + +ENTRY(sram_configure_core_dpll_sz) + .word . - sram_configure_core_dpll + +/* + * Reprogram GPMC + */ +ENTRY(sram_reprogram_gpmc) + stmfd sp!, {r0-r12, lr} @ regs to stack + ldmfd sp!, {r0-r12, pc} @ restore regs and return + +ENTRY(sram_reprogram_gpmc_sz) + .word . - sram_reprogram_gpmc -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html