From 0b3b9713693567943ed6a41b5cf9fa1b55343bd9 Mon Sep 17 00:00:00 2001 From: jethead71 Date: Wed, 7 Apr 2010 03:43:48 +0000 Subject: [PATCH] Gigabeat S (imx31): Begin voltage and frequency scaling code. For now, to avoid overdrive voltage, just lower core voltage to 1.35V since voltage scaling shouldn't be required for frequencies lower than 399 MHz (according to Freescale BSP, which set all working points to 1.35V for those frequencies). Perhaps battery life will improve as well (cross fingers :). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25506 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 1 + firmware/export/imx31l.h | 203 +++++++++++++++++++++ firmware/export/mc13783.h | 46 +++++ firmware/target/arm/imx31/dvfs_dptc-imx31.c | 48 +++++ firmware/target/arm/imx31/dvfs_dptc-imx31.h | 30 +++ .../target/arm/imx31/gigabeat-s/kernel-imx31.c | 2 + .../target/arm/imx31/gigabeat-s/system-imx31.c | 2 + 7 files changed, 332 insertions(+) create mode 100644 firmware/target/arm/imx31/dvfs_dptc-imx31.c create mode 100644 firmware/target/arm/imx31/dvfs_dptc-imx31.h diff --git a/firmware/SOURCES b/firmware/SOURCES index cfd6db372..dd1575a07 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -872,6 +872,7 @@ target/arm/lcd-as-memframe.S target/arm/mmu-armv6.S target/arm/imx31/ccm-imx31.c target/arm/imx31/debug-imx31.c +target/arm/imx31/dvfs_dptc-imx31.c target/arm/imx31/rolo_restart.S target/arm/imx31/sdma-imx31.c target/arm/imx31/gigabeat-s/adc-imx31.c diff --git a/firmware/export/imx31l.h b/firmware/export/imx31l.h index dea5588e5..6ad50f0a1 100644 --- a/firmware/export/imx31l.h +++ b/firmware/export/imx31l.h @@ -1410,6 +1410,101 @@ #define CCM_PDR1_SSI1_PODF (0x3f << 0) #define CCM_PDR1_SSI1_PODF_POS (0) +/* RCSR */ +#define CCM_RCSR_NF16B (1 << 31) + +#define CCM_RCSR_NFMS (1 << 30) + +#define CCM_RCSR_BTP4 (1 << 27) +#define CCM_RCSR_BTP3 (1 << 26) +#define CCM_RCSR_BTP2 (1 << 25) +#define CCM_RCSR_BTP1 (1 << 24) +#define CCM_RCSR_BTP0 (1 << 23) + +#define CCM_RCSR_OSCNT (0x7f << 16) +#define CCM_RCSR_OSCNT_POS (16) + +#define CCM_RCSR_PERES (1 << 15) + +#define CCM_RCSR_SDM (0x3 << 12) +#define CCM_RCSR_SDM_POS (12) + +#define CCM_RCSR_GPF (0x7 << 5) +#define CCM_RCSR_GPF_POS (5) + +#define CCM_RCSR_WFIS (1 << 4) + +#define CCM_RCSR_REST (0x7 << 0) +#define CCM_RCSR_REST_POS (0) +#define CCM_RCSR_REST_POR_EXT (0x0) +#define CCM_RCSR_REST_QUALIFIED_EXT (0x1) +#define CCM_RCSR_REST_WATCHDOG_TMO (0x2) +/* 0x3 - 0x5: reserved */ +#define CCM_RCSR_REST_JTAG (0x6) +#define CCM_RCSR_REST_ARM11P_GATING (0x7) + +/* MPCTL */ +#define CCM_MPCTL_BRM (1 << 31) +#define CCM_MPCTL_PD (0xf << 26) +#define CCM_MPCTL_PD_POS (26) +#define CCM_MPCTL_MFD (0x3ff << 16) +#define CCM_MPCTL_MFD_POS (16) +#define CCM_MPCTL_MFI (0xf << 10) +#define CCM_MPCTL_MFI_POS (10) +#define CCM_MPCTL_MFN (0x3ff << 0) +#define CCM_MPCTL_MFN_POS (0) + +/* UPCTL */ +#define CCM_UPCTL_BRM (1 << 31) +#define CCM_UPCTL_PD (0xf << 26) +#define CCM_UPCTL_PD_POS (26) +#define CCM_UPCTL_MFD (0x3ff << 16) +#define CCM_UPCTL_MFD_POS (16) +#define CCM_UPCTL_MFI (0xf << 10) +#define CCM_UPCTL_MFI_POS (10) +#define CCM_UPCTL_MFN (0x3ff << 0) +#define CCM_UPCTL_MFN_POS (0) + +/* SPCTL */ +#define CCM_SPCTL_BRM (1 << 31) +#define CCM_SPCTL_PD (0xf << 26) +#define CCM_SPCTL_PD_POS (26) +#define CCM_SPCTL_MFD (0x3ff << 16) +#define CCM_SPCTL_MFD_POS (16) +#define CCM_SPCTL_MFI (0xf << 10) +#define CCM_SPCTL_MFI_POS (10) +#define CCM_SPCTL_MFN (0x3ff << 0) +#define CCM_SPCTL_MFN_POS (0) + +/* COSR */ +#define CCM_COSR_CLKOEN (1 << 9) +#define CCM_COSR_CLKOUTDIV (0x7 << 6) +#define CCM_COSR_CLKOUTDIV_POS (6) +#define CCM_COSR_CLKOSEL (0xf << 0) +#define CCM_COSR_CLKOSEL_POS (0) +#define CCM_COSR_CLKOSEL_MPL_DPDGCK_CLK (0x0) +#define CCM_COSR_CLKOSEL_IPG_CLK_CCM (0x1) +#define CCM_COSR_CLKOSEL_UPL_DPDGCK_CLK (0x2) +#define CCM_COSR_CLKOSEL_PLL_REF_CLK (0x3) +#define CCM_COSR_CLKOSEL_FPM_CKIL512_CLK (0x4) +#define CCM_COSR_CLKOSEL_IPG_CLK_AHB_ARM (0x5) +#define CCM_COSR_CLKOSEL_IPG_CLK_ARM (0x6) +#define CCM_COSR_CLKOSEL_SPL_DPDGCK_CLK (0x7) +#define CCM_COSR_CLKOSEL_CKIH (0x8) +#define CCM_COSR_CLKOSEL_IPG_CLK_AHB_EMI_CLK (0x9) +#define CCM_COSR_CLKOSEL_IPG_CLK_IPU_HSP (0x9) +#define CCM_COSR_CLKOSEL_IPG_CLK_NFC_20M (0xa) +#define CCM_COSR_CLKOSEL_IPG_CLK_PERCLK_UART1 (0xb) +#define CCM_COSR_CLKOSEL_IPG_REF_CIR1 (0xc) /* ref_cir_gateload */ +#define CCM_COSR_CLKOSEL_IPG_REF_CIR2 (0xc) /* ref_cir_intrcload */ +#define CCM_COSR_CLKOSEL_IPG_REF_CIR3 (0xc) /* ref_cir_path */ + +/* CGR0 */ +/* CGR1 */ +/* CGR2 */ +/* Handled in ccm-imx31.h and ccm-imx31.c */ + + #define CCM_WIMR0_GPIO3 (1 << 0) #define CCM_WIMR0_GPIO2 (1 << 1) #define CCM_WIMR0_GPIO1 (1 << 2) @@ -1443,6 +1538,114 @@ #define CCM_WIMR0_RESERVED30 (1 << 30) #define CCM_WIMR0_RESERVED31 (1 << 31) +/* LDC */ +/* 32 bits specify value */ + +/* DCVR0-DCVR3 */ +#define CCM_DCVR_ULV (0x3ff << 22) /* Upper limit */ +#define CCM_DCVR_ULV_POS (22) +#define CCM_DCVR_LLV (0x3ff << 12) /* Lower limit */ +#define CCM_DCVR_LLV_POS (12) +#define CCM_DCVR_ELV (0x3ff << 2) /* Emergency limit */ +#define CCM_DCVR_ELV_POS (2) + +#if 0 +enum DVFS_W_SIGS +{ + DVFS_W_SIGS_M3IF_M0_BUF = 0, /* Hready signal of M3IF's master #0 + (L2 Cache) */ + DVFS_W_SIGS_M3IF_M1 = 1, /* Hready signal of M3IF's master #1 + (L2 Cache) */ + DVFS_W_SIGS_MBX_MBXCLKGATE = 2, /* Hready signal of M3IF's master #2 + (MBX) */ + DVFS_W_SIGS_M3IF_M3 = 3, /* Hready signal of M3IF's master #3 + (MAX) */ + DVFS_W_SIGS_M3IF_M4 = 4, /* Hready signal of M3IF's master #4 + (SDMA) */ + DVFS_W_SIGS_M3IF_M5 = 5, /* Hready signal of M3IF's master #5 + (mpeg4_vga_encoder) */ + DVFS_W_SIGS_M3IF_M6 = 6, /* Hready signal of M3IF's master #6 + (IPU) */ + DVFS_W_SIGS_M3IF_M7 = 7, /* Hready signal of M3IF's master #7 + (IPU) */ + DVFS_W_SIGS_ARM11_P_IRQ_B_RBT_GATE = 8, /* ARM normal interrupt */ + DVFS_W_SIGS_ARM11_P_FIQ_B_RBT_GATE = 9, /* ARM fast interrupt */ + DVFS_W_SIGS_IPI_GPIO1_INT0 = 10, /* Interrupt line from GPIO */ + DVFS_W_SIGS_IPI_INT_IPU_FUNC = 11, /* Interrupt line from IPU */ + DVFS_W_SIGS_DVGP0 = 12, /* Software-controllable general-purpose + bits from the CCM */ + DVFS_W_SIGS_DVGP1 = 13, /* Software-controllable general-purpose + bits from the CCM */ + DVFS_W_SIGS_DVGP2 = 14, /* Software-controllable general-purpose + bits from the CCM */ + DVFS_W_SIGS_DVGP3 = 15, /* Software-controllable general-purpose + bits from the CCM */ +}; +#endif + +/* LTR0 */ +#define CCM_LTR0_UPTHR (0x3f << 22) +#define CCM_LTR0_UPTHR_POS (22) +#define CCM_LTR0_DNTHR (0x3f << 16) +#define CCM_LTR0_DNTHR_POS (16) +/* for div_3_clk */ +#define CCM_LTR0_DIV3CK (0x3 << 1) +#define CCM_LTR0_DIV3CK_POS (1) +#define CCM_LTR0_DIV3CK_2048 (0x0 << 1) /* 1/2048 ARM clock */ +#define CCM_LTR0_DIV3CK_8192 (0x1 << 1) /* 1/8192 ARM clock */ +#define CCM_LTR0_DIV3CK_32768 (0x2 << 1) /* 1/32768 ARM clock */ +#define CCM_LTR0_DIV3CK_131072 (0x3 << 1) /* 1/131072 ARM clock */ + +/* PMCR0 */ +#define CCM_PMCR0_DVSUP_MCUPLL (1 << 31) +#define CCM_PMCR0_DVSUP_POST_DIVIDERS (1 << 30) +#define CCM_PMCR0_DVSUP_DVS (0x3 << 28) +#define CCM_PMCR0_DVS1_0_DVS0_0 (0x0 << 28) /* Highest frequency/voltage */ +#define CCM_PMCR0_DVS1_0_DVS0_1 (0x1 << 28) /* ... */ +#define CCM_PMCR0_DVS1_1_DVS0_0 (0x2 << 28) /* ... */ +#define CCM_PMCR0_DVS1_1_DVS0_1 (0x3 << 28) /* Lowest frequency/voltage */ +#define CCM_PMCR0_DVS_POS (28) +#define CCM_PMCR0_UDSC (1 << 27) +#define CCM_PMCR0_VSCNT (0x7 << 24) +#define CCM_PMCR0_VSCNT_POS (24) +#define CCM_PMCR0_DVFEV (1 << 23) +#define CCM_PMCR0_DVFIS (1 << 22) +#define CCM_PMCR0_LBMI (1 << 21) +#define CCM_PMCR0_LBFL (1 << 20) +#define CCM_PMCR0_LBCF (0x3 << 18) +#define CCM_PMCR0_LBCF_4 (0x0 << 18) +#define CCM_PMCR0_LBCF_8 (0x1 << 18) +#define CCM_PMCR0_LBCF_12 (0x2 << 18) +#define CCM_PMCR0_LBCF_16 (0x3 << 18) +#define CCM_PMCR0_PTVIS (1 << 17) +#define CCM_PMCR0_UPDTEN (1 << 16) +#define CCM_PMCR0_FSVAIM (1 << 15) +#define CCM_PMCR0_FSVAI (0x3 << 13) +#define CCM_PMCR0_FSVAI_NO_INT (0x0 << 13) +#define CCM_PMCR0_FSVAI_INCREASE (0x1 << 13) +#define CCM_PMCR0_FSVAI_DECREASE (0x2 << 13) +#define CCM_PMCR0_FSVAI_INCREASE_NOW (0x3 << 13) +#define CCM_PMCR0_FSVAI_POS (13) +#define CCM_PMCR0_DPVCR (1 << 12) +#define CCM_PMCR0_DPVV (1 << 11) +#define CCM_PMCR0_WFIM (1 << 10) +#define CCM_PMCR0_DRCE3 (1 << 9) +#define CCM_PMCR0_DRCE2 (1 << 8) +#define CCM_PMCR0_DRCE1 (1 << 7) +#define CCM_PMCR0_DRCE0 (1 << 6) +#define CCM_PMCR0_DCR (1 << 5) /* 512 vs 256 count */ +#define CCM_PMCR0_DVFEN (1 << 4) +#define CCM_PMCR0_PTVAIM (1 << 3) +#define CCM_PMCR0_PTVAI (0x3 << 1) +#define CCM_PMCR0_PTVAI_NO_INT (0x0 << 1) +#define CCM_PMCR0_PTVAI_DECREASE (0x1 << 1) +#define CCM_PMCR0_PTVAI_INCREASE (0x2 << 1) +#define CCM_PMCR0_PTVAI_INCREASE_NOW (0x3 << 1) +#define CCM_PMCR0_DPTEN (1 << 0) + + + + /* WEIM - CS0 */ #define CSCRU 0x00 #define CSCRL 0x04 diff --git a/firmware/export/mc13783.h b/firmware/export/mc13783.h index 09fb1f1fc..0a83527c5 100644 --- a/firmware/export/mc13783.h +++ b/firmware/export/mc13783.h @@ -523,6 +523,52 @@ enum mc13783_regs_enum #define MC13783_SW2BSTBY (0x3f << 12) #define MC13783_SW2BSTBY_POS (12) +/* Switcher Voltages (SWITCHERS0-SWITCHERS3) */ +/* Switcher 1 and 2 */ +#define MC13783_SW_0_900 0x00 /* 0.900 V */ +#define MC13783_SW_0_925 0x01 /* 0.925 V */ +#define MC13783_SW_0_950 0x02 /* 0.950 V */ +#define MC13783_SW_0_975 0x03 /* 0.975 V */ +#define MC13783_SW_1_000 0x04 /* 1.000 V */ +#define MC13783_SW_1_025 0x05 /* 1.025 V */ +#define MC13783_SW_1_050 0x06 /* 1.050 V */ +#define MC13783_SW_1_075 0x07 /* 1.075 V */ +#define MC13783_SW_1_100 0x08 /* 1.100 V */ +#define MC13783_SW_1_125 0x09 /* 1.125 V */ +#define MC13783_SW_1_150 0x0a /* 1.150 V */ +#define MC13783_SW_1_175 0x0b /* 1.175 V */ +#define MC13783_SW_1_200 0x0c /* 1.200 V */ +#define MC13783_SW_1_225 0x0d /* 1.225 V */ +#define MC13783_SW_1_250 0x0e /* 1.250 V */ +#define MC13783_SW_1_275 0x0f /* 1.275 V */ +#define MC13783_SW_1_300 0x10 /* 1.300 V */ +#define MC13783_SW_1_325 0x11 /* 1.325 V */ +#define MC13783_SW_1_350 0x12 /* 1.350 V */ +#define MC13783_SW_1_375 0x13 /* 1.375 V */ +#define MC13783_SW_1_400 0x14 /* 1.400 V */ +#define MC13783_SW_1_425 0x15 /* 1.425 V */ +#define MC13783_SW_1_450 0x16 /* 1.450 V */ +#define MC13783_SW_1_475 0x17 /* 1.475 V */ +#define MC13783_SW_1_500 0x18 /* 1.500 V */ +#define MC13783_SW_1_525 0x19 /* 1.525 V */ +#define MC13783_SW_1_550 0x1a /* 1.550 V */ +#define MC13783_SW_1_575 0x1b /* 1.575 V */ +#define MC13783_SW_1_600 0x1c /* 1.600 V */ +#define MC13783_SW_1_625 0x1d /* 1.625 V */ +#define MC13783_SW_1_650 0x1e /* 1.650 V */ +#define MC13783_SW_1_675 0x1f /* 1.675 V */ +#define MC13783_SW_1_700 0x20 /* 0x20 - 0x23 = 1.700V */ +#define MC13783_SW_1_800 0x24 /* 0x24 - 0x27 = 1.800V */ +/* Switcher 1 */ +#define MC13783_SW1_1_850 0x28 /* 0x29 - 0x2b = 1.850V */ +/* Switcher 2 */ +#define MC13783_SW2_1_900 0x28 /* 0x29 - 0x2b = 1.900V */ +/* Switcher 1 and 2 */ +#define MC13783_SW_2_000 0x2c /* 0x2c - 0x2f = 2.000V */ +#define MC13783_SW_2_100 0x30 /* 0x30 - 0x33 = 2.100V */ +#define MC13783_SW_2_200 0x34 /* 0x34 - 0x3f = 2.200V */ + + /* SWITCHERS4 (28) */ #define MC13783_SW1AMODE (0x3 << 0) #define MC13783_SW1AMODE_OFF (0x0 << 0) diff --git a/firmware/target/arm/imx31/dvfs_dptc-imx31.c b/firmware/target/arm/imx31/dvfs_dptc-imx31.c new file mode 100644 index 000000000..8f32fd0fb --- /dev/null +++ b/firmware/target/arm/imx31/dvfs_dptc-imx31.c @@ -0,0 +1,48 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Michael Sevakis + * + * i.MX31 DVFS and DPTC drivers + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include "system.h" +#include "ccm-imx31.h" +#include "mc13783.h" + +/* Most of the code in here is based upon the Linux BSP provided by Freescale + * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. */ + +void dvfs_dptc_start(void) +{ + /* For now, just set the regulator voltage off of overdrive mode */ + /* For 264 MHz, DPTC is not needed and lower V can be used */ + + mc13783_write_masked(MC13783_SWITCHERS0, + MC13783_SW_1_350 << MC13783_SW1A_POS, + MC13783_SW1A); + imx31_regmod32(&CCM_PMCR0, CCM_PMCR0_DVS1_0_DVS0_0, + CCM_PMCR0_DVSUP_DVS); +} + + +void dvfs_dptc_stop(void) +{ + /* Nothing for now */ +} + diff --git a/firmware/target/arm/imx31/dvfs_dptc-imx31.h b/firmware/target/arm/imx31/dvfs_dptc-imx31.h new file mode 100644 index 000000000..8f6f5da98 --- /dev/null +++ b/firmware/target/arm/imx31/dvfs_dptc-imx31.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Michael Sevakis + * + * i.MX31 DVFS and DPTC driver declarations + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef _DVFS_DPTC_IMX31_H_ +#define _DVFS_DPTC_IMX31_H_ + +void dvfs_dptc_start(void); +void dvfs_dptc_stop(void); + +#endif /* _DVFS_DPTC_IMX31_H_ */ diff --git a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c index 775f5cebf..8e81447bd 100644 --- a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c @@ -25,6 +25,7 @@ #include "mc13783.h" #include "ccm-imx31.h" #include "sdma-imx31.h" +#include "dvfs_dptc-imx31.h" #include "kernel.h" #include "thread.h" @@ -69,6 +70,7 @@ void kernel_device_init(void) sdma_init(); spi_init(); mc13783_init(); + dvfs_dptc_start(); } #ifdef BOOTLOADER diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c index 65299cb8d..cd684e77a 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c @@ -31,6 +31,7 @@ #include "debug.h" #include "ccm-imx31.h" #include "mc13783.h" +#include "dvfs_dptc-imx31.h" static unsigned long product_rev; static unsigned long system_rev; @@ -241,6 +242,7 @@ void __attribute__((naked)) imx31_regclr32(volatile uint32_t *reg_p, #ifdef BOOTLOADER void system_prepare_fw_start(void) { + dvfs_dptc_stop(); disable_interrupt(IRQ_FIQ_STATUS); avic_disable_int(INT_ALL); mc13783_close(); -- 2.11.4.GIT