summaryrefslogtreecommitdiff
path: root/drivers/platform/sprd/dmc_freq_ap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/sprd/dmc_freq_ap.c')
-rw-r--r--drivers/platform/sprd/dmc_freq_ap.c838
1 files changed, 838 insertions, 0 deletions
diff --git a/drivers/platform/sprd/dmc_freq_ap.c b/drivers/platform/sprd/dmc_freq_ap.c
new file mode 100644
index 00000000..ac8aff36
--- /dev/null
+++ b/drivers/platform/sprd/dmc_freq_ap.c
@@ -0,0 +1,838 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/input/matrix_keypad.h>
+#include <mach/hardware.h>
+#include <mach/__sc8830_dmc_dfs.h>
+#define REG32(x) (*((volatile uint32 *)(x)))
+#define REG16(x) (*((volatile uint16 *)(x)))
+#define UMCTL2_REG_GET(reg_addr) (*((volatile uint32 *)(reg_addr)))
+#define UMCTL2_REG_SET( reg_addr, value ) *(volatile uint32 *)(reg_addr) = value
+#define UMCTL_REG_BASE (0x30000000)
+#define PUBL_REG_BASE (0x30010000)
+
+#define UMCTL2_REG_(x) (UMCTL_REG_BASE+(x))
+
+#define SPRD_UART1_PHYS (0x70100000)
+/*
+ *uMCTL2 DDRC registers
+*/
+#define UMCTL_MSTR UMCTL2_REG_(0x0000) /*master*/
+#define UMCTL_STAT UMCTL2_REG_(0x0004) /*oeration mode status*/
+#define UMCTL_MRCTRL0 UMCTL2_REG_(0x0010)/*mode register read/werite control*/
+#define UMCTL_MRCTRL1 UMCTL2_REG_(0x0014)
+#define UMCTL_MRSTAT UMCTL2_REG_(0x0018)/*mode register read/weite status*/
+
+#define UMCTL_DERATEEN UMCTL2_REG_(0x0020)/*temperature derate enable*/
+#define UMCTL_DERATEINT UMCTL2_REG_(0x0024)/*temperature derate interval*/
+#define UMCTL_PWRCTL UMCTL2_REG_(0x0030)/*low power control*/
+#define UMCTL_PWRTMG UMCTL2_REG_(0x0034)/*low power timing*/
+
+#define UMCTL_RFSHCTL0 UMCTL2_REG_(0x0050)/*refresh control0*/
+#define UMCTL_RFSHCTL1 UMCTL2_REG_(0x0054)
+#define UMCTL_RFSHCTL2 UMCTL2_REG_(0x0058)
+#define UMCTL_RFSHCTL3 UMCTL2_REG_(0x0060)
+#define UMCTL_RFSHTMG UMCTL2_REG_(0x0064)/*refresh Timing*/
+#define UMCTL_ECCCFG0 UMCTL2_REG_(0x0070)/*ecc configuration*/
+#define UMCTL_ECCCFG1 UMCTL2_REG_(0x0074)
+#define UMCTL_ECCSTAT UMCTL2_REG_(0x0078)/*ecc status*/
+#define UMCTL_ECCCLR UMCTL2_REG_(0x007C)/*ecc clear*/
+#define UMCTL_ECCERRCNT UMCTL2_REG_(0x0080)/*ecc error counter*/
+
+#define UMCTL_ECCADDR0 UMCTL2_REG_(0x0084)/*ecc corrected error address reg0*/
+#define UMCTL_ECCADDR1 UMCTL2_REG_(0x0088)
+#define UMCTL_ECCSYN0 UMCTL2_REG_(0x008C)/*ecc corected syndrome reg0*/
+#define UMCTL_ECCSYN1 UMCTL2_REG_(0x0090)
+#define UMCTL_ECCSYN2 UMCTL2_REG_(0x0094)
+#define UMCTL_ECCBITMASK0 UMCTL2_REG_(0x0098)
+#define UMCTL_ECCBITMASK1 UMCTL2_REG_(0x009C)
+#define UMCTL_ECCBITMASK2 UMCTL2_REG_(0x00A0)
+#define UMCTL_ECCUADDR0 UMCTL2_REG_(0x00A4)/*ecc uncorrected error address reg0*/
+#define UMCTL_ECCUADDR1 UMCTL2_REG_(0x00A8)
+#define UMCTL_ECCUSYN0 UMCTL2_REG_(0x00AC)/*ecc UNcorected syndrome reg0*/
+#define UMCTL_ECCUSYN1 UMCTL2_REG_(0x00B0)
+#define UMCTL_ECCUSYN2 UMCTL2_REG_(0x00B4)
+#define UMCTL_ECCPOISONADDR0 UMCTL2_REG_(0x00B8)/*ecc data poisoning address reg0*/
+#define UMCTL_ECCPOISONADDR1 UMCTL2_REG_(0x00BC)
+
+
+#define UMCTL_PARCTL UMCTL2_REG_(0x00C0)/*parity control register*/
+#define UMCTL_PARSTAT UMCTL2_REG_(0x00C4)/*parity status register*/
+
+#define UMCTL_INIT0 UMCTL2_REG_(0x00D0)/*SDRAM initialization register0*/
+#define UMCTL_INIT1 UMCTL2_REG_(0x00D4)
+#define UMCTL_INIT2 UMCTL2_REG_(0x00D8)
+#define UMCTL_INIT3 UMCTL2_REG_(0x00DC)
+#define UMCTL_INIT4 UMCTL2_REG_(0x00E0)
+#define UMCTL_INIT5 UMCTL2_REG_(0x00E4)
+
+
+#define UMCTL_DIMMCTL UMCTL2_REG_(0x00F0)/*DIMM control register*/
+#define UMCTL_RANKCTL UMCTL2_REG_(0x00F4)
+
+#define UMCTL_DRAMTMG0 UMCTL2_REG_(0x0100)/*SDRAM timing register0*/
+#define UMCTL_DRAMTMG1 UMCTL2_REG_(0x0104)
+#define UMCTL_DRAMTMG2 UMCTL2_REG_(0x0108)
+#define UMCTL_DRAMTMG3 UMCTL2_REG_(0x010C)
+#define UMCTL_DRAMTMG4 UMCTL2_REG_(0x0110)
+#define UMCTL_DRAMTMG5 UMCTL2_REG_(0x0114)
+#define UMCTL_DRAMTMG6 UMCTL2_REG_(0x0118)
+#define UMCTL_DRAMTMG7 UMCTL2_REG_(0x011C)
+#define UMCTL_DRAMTMG8 UMCTL2_REG_(0x0120)
+
+#define UMCTL_ZQCTL0 UMCTL2_REG_(0x0180)/*ZQ control register0*/
+#define UMCTL_ZQCTL1 UMCTL2_REG_(0x0184)
+#define UMCTL_ZQCTL2 UMCTL2_REG_(0x0188)
+#define UMCTL_ZQSTAT UMCTL2_REG_(0x018C)
+
+
+#define UMCTL_DFITMG0 UMCTL2_REG_(0x0190)/*DFI timing register0*/
+#define UMCTL_DFITMG1 UMCTL2_REG_(0x0194)
+
+#define UMCTL_DFILPCFG0 UMCTL2_REG_(0x0198)/*DFI low power configuration*/
+#define UMCTL_DFIUPD0 UMCTL2_REG_(0x01A0)/*DFI update register0*/
+#define UMCTL_DFIUPD1 UMCTL2_REG_(0x01A4)
+#define UMCTL_DFIUPD2 UMCTL2_REG_(0x01A8)
+#define UMCTL_DFIUPD3 UMCTL2_REG_(0x01AC)
+
+#define UMCTL_DFIMISC UMCTL2_REG_(0x01B0)
+
+#define UMCTL_TRAINCTL0 UMCTL2_REG_(0x01D0)/*PHY eval training control reg0*/
+#define UMCTL_TRAINCTL1 UMCTL2_REG_(0x01D4)
+#define UMCTL_TRAINCTL2 UMCTL2_REG_(0x01D8)
+#define UMCTL_TRAINSTAT UMCTL2_REG_(0x01DC)
+
+#define UMCTL_ADDRMAP0 UMCTL2_REG_(0x0200)/*address map register0*/
+#define UMCTL_ADDRMAP1 UMCTL2_REG_(0x0204)
+#define UMCTL_ADDRMAP2 UMCTL2_REG_(0x0208)
+#define UMCTL_ADDRMAP3 UMCTL2_REG_(0x020C)
+#define UMCTL_ADDRMAP4 UMCTL2_REG_(0x0210)
+#define UMCTL_ADDRMAP5 UMCTL2_REG_(0x0214)
+#define UMCTL_ADDRMAP6 UMCTL2_REG_(0x0218)
+
+#define UMCTL_ODTCFG UMCTL2_REG_(0x0240)/*ODT configuration register*/
+#define UMCTL_ODTMAP UMCTL2_REG_(0x0244)
+
+#define UMCTL_SCHED UMCTL2_REG_(0x0250)/*scheduler control register*/
+#define UMCTL_PERFHPR0 UMCTL2_REG_(0x0258)/*high priority read CAM reg0*/
+#define UMCTL_PERFHPR1 UMCTL2_REG_(0x025C)
+#define UMCTL_PERFLPR0 UMCTL2_REG_(0x0260)
+#define UMCTL_PERFLPR1 UMCTL2_REG_(0x0264)
+
+#define UMCTL_PERFWR0 UMCTL2_REG_(0x0268)/*write CAM reg0*/
+#define UMCTL_PERFWR1 UMCTL2_REG_(0x026C)
+#define UMCTL_DBG0 UMCTL2_REG_(0x0300)/*debug register0*/
+#define UMCTL_DBG1 UMCTL2_REG_(0x0304)
+#define UMCTL_DBGCAM UMCTL2_REG_(0x0308)/*cam debug register*/
+
+
+/*
+ *uMCTL2 Multi-Port registers
+*/
+#define UMCTL_PCCFG UMCTL2_REG_(0x0400)/*port common configuration*/
+
+#define UMCTL_PCFGR_0 UMCTL2_REG_(0x0404+(0x00)*0xB0)/*Port n configuration read reg*/
+#define UMCTL_PCFGR_1 UMCTL2_REG_(0x0404+(0x01)*0xB0)
+#define UMCTL_PCFGR_2 UMCTL2_REG_(0x0404+(0x02)*0xB0)
+#define UMCTL_PCFGR_3 UMCTL2_REG_(0x0404+(0x03)*0xB0)
+#define UMCTL_PCFGR_4 UMCTL2_REG_(0x0404+(0x04)*0xB0)
+#define UMCTL_PCFGR_5 UMCTL2_REG_(0x0404+(0x05)*0xB0)
+#define UMCTL_PCFGR_6 UMCTL2_REG_(0x0404+(0x06)*0xB0)
+#define UMCTL_PCFGR_7 UMCTL2_REG_(0x0404+(0x07)*0xB0)
+#define UMCTL_PCFGR_8 UMCTL2_REG_(0x0404+(0x08)*0xB0)
+#define UMCTL_PCFGR_9 UMCTL2_REG_(0x0404+(0x09)*0xB0)
+#define UMCTL_PCFGR_10 UMCTL2_REG_(0x0404+(0x0A)*0xB0)
+#define UMCTL_PCFGR_11 UMCTL2_REG_(0x0404+(0x0B)*0xB0)
+#define UMCTL_PCFGR_12 UMCTL2_REG_(0x0404+(0x0C)*0xB0)
+#define UMCTL_PCFGR_13 UMCTL2_REG_(0x0404+(0x0D)*0xB0)
+#define UMCTL_PCFGR_14 UMCTL2_REG_(0x0404+(0x0E)*0xB0)
+#define UMCTL_PCFGR_15 UMCTL2_REG_(0x0404+(0x0F)*0xB0)
+
+
+#define UMCTL_PCFGW_0 UMCTL2_REG_(0x0408+(0x00)*0xB0)/*Port n configuration write reg*/
+#define UMCTL_PCFGW_1 UMCTL2_REG_(0x0408+(0x01)*0xB0)
+#define UMCTL_PCFGW_2 UMCTL2_REG_(0x0408+(0x02)*0xB0)
+#define UMCTL_PCFGW_3 UMCTL2_REG_(0x0408+(0x03)*0xB0)
+#define UMCTL_PCFGW_4 UMCTL2_REG_(0x0408+(0x04)*0xB0)
+#define UMCTL_PCFGW_5 UMCTL2_REG_(0x0408+(0x05)*0xB0)
+#define UMCTL_PCFGW_6 UMCTL2_REG_(0x0408+(0x06)*0xB0)
+#define UMCTL_PCFGW_7 UMCTL2_REG_(0x0408+(0x07)*0xB0)
+#define UMCTL_PCFGW_8 UMCTL2_REG_(0x0408+(0x08)*0xB0)
+#define UMCTL_PCFGW_9 UMCTL2_REG_(0x0408+(0x09)*0xB0)
+#define UMCTL_PCFGW_10 UMCTL2_REG_(0x0408+(0x0A)*0xB0)
+#define UMCTL_PCFGW_11 UMCTL2_REG_(0x0408+(0x0B)*0xB0)
+#define UMCTL_PCFGW_12 UMCTL2_REG_(0x0408+(0x0C)*0xB0)
+#define UMCTL_PCFGW_13 UMCTL2_REG_(0x0408+(0x0D)*0xB0)
+#define UMCTL_PCFGW_14 UMCTL2_REG_(0x0408+(0x0E)*0xB0)
+#define UMCTL_PCFGW_15 UMCTL2_REG_(0x0408+(0x0F)*0xB0)
+
+
+#define UMCTL_PORT_EN_0 0xFFFF0000//UMCTL2_REG_(0x0490+(0x00)*0xB0)/*Port n enable reg*/
+#define UMCTL_PORT_EN_1 0xFFFF0000//UMCTL2_REG_(0x0490+(0x01)*0xB0)/*Port n enable reg*/
+#define UMCTL_PORT_EN_2 0xFFFF0000//UMCTL2_REG_(0x0490+(0x02)*0xB0)/*Port n enable reg*/
+#define UMCTL_PORT_EN_3 0xFFFF0000//UMCTL2_REG_(0x0490+(0x03)*0xB0)/*Port n enable reg*/
+#define UMCTL_PORT_EN_4 0xFFFF0000//UMCTL2_REG_(0x0490+(0x04)*0xB0)/*Port n enable reg*/
+#define UMCTL_PORT_EN_5 0xFFFF0000//UMCTL2_REG_(0x0490+(0x05)*0xB0)/*Port n enable reg*/
+#define UMCTL_PORT_EN_6 0xFFFF0000//UMCTL2_REG_(0x0490+(0x06)*0xB0)/*Port n enable reg*/
+#define UMCTL_PORT_EN_7 0xFFFF0000//UMCTL2_REG_(0x0490+(0x07)*0xB0)/*Port n enable reg*/
+#define UMCTL_PORT_EN_8 0xFFFF0000//UMCTL2_REG_(0x0490+(0x08)*0xB0)/*Port n enable reg*/
+#define UMCTL_PORT_EN_9 0xFFFF0000//UMCTL2_REG_(0x0490+(0x09)*0xB0)/*Port n enable reg*/
+
+
+/*
+#define UMCTL2_PCFGIDMASKCH_m_N
+#define UMCTL2_PCFGIDVALUECH_m_N
+*/
+
+
+/*
+ *Refer to PUBL databook 1.44a for detail,Chapter3.3 Registers.
+*/
+#define PUBL_RIDR (PUBL_REG_BASE+0x00*4) // R - Revision Identification Register
+#define PUBL_PIR (PUBL_REG_BASE+0x01*4) // R/W - PHY Initialization Register
+#define PUBL_PGCR (PUBL_REG_BASE+0x02*4) // R/W - PHY General Configuration Register
+#define PUBL_PGSR (PUBL_REG_BASE+0x03*4) // R - PHY General Status Register
+#define PUBL_DLLGCR (PUBL_REG_BASE+0x04*4) // R/W - DLL General Control Register
+#define PUBL_ACDLLCR (PUBL_REG_BASE+0x05*4) // R/W - AC DLL Control Register
+#define PUBL_PTR0 (PUBL_REG_BASE+0x06*4) // R/W - PHY Timing Register 0
+#define PUBL_PTR1 (PUBL_REG_BASE+0x07*4) // R/W - PHY Timing Register 1
+#define PUBL_PTR2 (PUBL_REG_BASE+0x08*4) // R/W - PHY Timing Register 2
+#define PUBL_ACIOCR (PUBL_REG_BASE+0x09*4) // R/W - AC I/O Configuration Register
+#define PUBL_DXCCR (PUBL_REG_BASE+0x0A*4) // R/W - DATX8 I/O Configuration Register
+#define PUBL_DSGCR (PUBL_REG_BASE+0x0B*4) // R/W - DFI Configuration Register
+#define PUBL_DCR (PUBL_REG_BASE+0x0C*4) // R/W - DRAM Configuration Register
+#define PUBL_DTPR0 (PUBL_REG_BASE+0x0D*4) // R/W - SDRAM Timing Parameters Register 0
+#define PUBL_DTPR1 (PUBL_REG_BASE+0x0E*4) // R/W - SDRAM Timing Parameters Register 1
+#define PUBL_DTPR2 (PUBL_REG_BASE+0x0F*4) // R/W - SDRAM Timing Parameters Register 2
+#define PUBL_MR0 (PUBL_REG_BASE+0x10*4) // R/W - Mode Register
+#define PUBL_MR1 (PUBL_REG_BASE+0x11*4) // R/W - Ext}ed Mode Register
+#define PUBL_MR2 (PUBL_REG_BASE+0x12*4) // R/W - Ext}ed Mode Register 2
+#define PUBL_MR3 (PUBL_REG_BASE+0x13*4) // R/W - Ext}ed Mode Register 3
+#define PUBL_ODTCR (PUBL_REG_BASE+0x14*4) // R/W - ODT Configuration Register
+#define PUBL_DTAR (PUBL_REG_BASE+0x15*4) // R/W - Data Training Address Register
+#define PUBL_DTDR0 (PUBL_REG_BASE+0x16*4) // R/W - Data Training Data Register 0
+#define PUBL_DTDR1 (PUBL_REG_BASE+0x17*4) // R/W - Data Training Data Register 1
+#define PUBL_DCUAR (PUBL_REG_BASE+0X30*4) // R/W - DCU Address Resiter
+#define PUBL_DCUDR (PUBL_REG_BASE+0x31*4) // R/W - DCU Data Register
+#define PUBL_DCURR (PUBL_REG_BASE+0x32*4) // R/W - DCU Run Register
+#define PUBL_DCULR (PUBL_REG_BASE+0x33*4) // R/W - DCU Loop Register
+#define PUBL_DCUGCR (PUBL_REG_BASE+0x34*4) // R/W - DCU General Configuration Register
+#define PUBL_DCUTPR (PUBL_REG_BASE+0x35*4) // R/W - DCU Timing Parameters Registers
+#define PUBL_DCUSR0 (PUBL_REG_BASE+0x36*4) // R - DCU Status Register 0
+#define PUBL_DCUSR1 (PUBL_REG_BASE+0x37*4) // R - DCU Status Register 1
+#define PUBL_BISTRR (PUBL_REG_BASE+0x40*4) // R/W - BIST Run Register
+#define PUBL_BISTMSKR0 (PUBL_REG_BASE+0x41*4) // R/W - BIST Mask Register 0
+#define PUBL_BISTMSKR1 (PUBL_REG_BASE+0x42*4) // R/W - BIST Mask Register 1
+#define PUBL_BISTWCR (PUBL_REG_BASE+0x43*4) // R/W - BIST Word Count Register
+#define PUBL_BISTLSR (PUBL_REG_BASE+0x44*4) // R/W - BIST LFSR Seed Register
+#define PUBL_BISTAR0 (PUBL_REG_BASE+0x45*4) // R/W - BIST Address Register 0
+#define PUBL_BISTAR1 (PUBL_REG_BASE+0x46*4) // R/W - BIST Address Register 1
+#define PUBL_BISTAR2 (PUBL_REG_BASE+0x47*4) // R/W - BIST Address Register 2
+#define PUBL_BISTUDPR (PUBL_REG_BASE+0x48*4) // R/W - BIST User Data Pattern Register
+#define PUBL_BISTGSR (PUBL_REG_BASE+0x49*4) // R - BIST General Status Register
+#define PUBL_BISTWER (PUBL_REG_BASE+0x4A*4) // R - BIST Word Error Register
+#define PUBL_BISTBER0 (PUBL_REG_BASE+0x4B*4) // R - BIST Bit Error Register 0
+#define PUBL_BISTBER1 (PUBL_REG_BASE+0x4C*4) // R - BIST Bit Error Register 1
+#define PUBL_BISTBER2 (PUBL_REG_BASE+0x4D*4) // R - BIST Bit Error Register 2
+#define PUBL_BISTWCSR (PUBL_REG_BASE+0x4E*4) // R - BIST Word Count Status Register
+#define PUBL_BISTFWR0 (PUBL_REG_BASE+0x4F*4) // R - BIST Fail Word Register 0
+#define PUBL_BISTFWR1 (PUBL_REG_BASE+0x50*4) // R - BIST Fail Word Register 1
+#define PUBL_ZQ0CR0 (PUBL_REG_BASE+0x60*4) // R/W - ZQ 0 Impedance Control Register 0
+#define PUBL_ZQ0CR1 (PUBL_REG_BASE+0x61*4) // R/W - ZQ 0 Impedance Control Register 1
+#define PUBL_ZQ0SR0 (PUBL_REG_BASE+0x62*4) // R - ZQ 0 Impedance Status Register 0
+#define PUBL_ZQ0SR1 (PUBL_REG_BASE+0x63*4) // R - ZQ 0 Impedance Status Register 1
+#define PUBL_ZQ1CR0 (PUBL_REG_BASE+0x64*4) // R/W - ZQ 1 Impedance Control Register 0
+#define PUBL_ZQ1CR1 (PUBL_REG_BASE+0x65*4) // R/W - ZQ 1 Impedance Control Register 1
+#define PUBL_ZQ1SR0 (PUBL_REG_BASE+0x66*4) // R - ZQ 1 Impedance Status Register 0
+#define PUBL_ZQ1SR1 (PUBL_REG_BASE+0x67*4) // R - ZQ 1 Impedance Status Register 1
+#define PUBL_ZQ2CR0 (PUBL_REG_BASE+0x68*4) // R/W - ZQ 2 Impedance Control Register 0
+#define PUBL_ZQ2CR1 (PUBL_REG_BASE+0x69*4) // R/W - ZQ 2 Impedance Control Register 1
+#define PUBL_ZQ2SR0 (PUBL_REG_BASE+0x6A*4) // R - ZQ 2 Impedance Status Register 0
+#define PUBL_ZQ2SR1 (PUBL_REG_BASE+0x6B*4) // R - ZQ 2 Impedance Status Register 1
+#define PUBL_ZQ3CR0 (PUBL_REG_BASE+0x6C*4) // R/W - ZQ 3 Impedance Control Register 0
+#define PUBL_ZQ3CR1 (PUBL_REG_BASE+0x6D*4) // R/W - ZQ 3 Impedance Control Register 1
+#define PUBL_ZQ3SR0 (PUBL_REG_BASE+0x6E*4) // R - ZQ 3 Impedance Status Register 0
+#define PUBL_ZQ3SR1 (PUBL_REG_BASE+0x6F*4) // R - ZQ 3 Impedance Status Register 1
+#define PUBL_DX0GCR (PUBL_REG_BASE+0x70*4) // R/W - DATX8 0 General Configuration Register
+#define PUBL_DX0GSR0 (PUBL_REG_BASE+0x71*4) // R - DATX8 0 General Status Register
+#define PUBL_DX0GSR1 (PUBL_REG_BASE+0x72*4) // R - DATX8 0 General Status Register 1
+#define PUBL_DX0DLLCR (PUBL_REG_BASE+0x73*4) // R - DATX8 0 DLL Control Register
+#define PUBL_DX0DQTR (PUBL_REG_BASE+0x74*4) // R/W - DATX8 0 DQ Timing Register
+#define PUBL_DX0DQSTR (PUBL_REG_BASE+0x75*4) // R/W - DATX8 0 DQS Timing Register
+#define PUBL_DX1GCR (PUBL_REG_BASE+0x80*4) // R - DATX8 1 General Configration Register
+#define PUBL_DX1GSR0 (PUBL_REG_BASE+0x81*4) // R - DATX8 1 General Status Register
+#define PUBL_DX1GSR1 (PUBL_REG_BASE+0x82*4) // R - DATX8 1 General Status Register
+#define PUBL_DX1DLLCR (PUBL_REG_BASE+0x83*4) // R - DATX8 1 DLL Control Register
+#define PUBL_DX1DQTR (PUBL_REG_BASE+0x84*4) // R/W - DATX8 1 DQ Timing Register
+#define PUBL_DX1DQSTR (PUBL_REG_BASE+0x85*4) // R/W - DATX8 1 DQS Timing Register
+#define PUBL_DX2GCR (PUBL_REG_BASE+0x90*4) // R - DATX8 2 General Configration Register
+#define PUBL_DX2GSR0 (PUBL_REG_BASE+0x91*4) // R - DATX8 2 General Status Register
+#define PUBL_DX2GSR1 (PUBL_REG_BASE+0x92*4) // R - DATX8 2 General Status Register
+#define PUBL_DX2DLLCR (PUBL_REG_BASE+0x93*4) // R - DATX8 2 DLL Control Register
+#define PUBL_DX2DQTR (PUBL_REG_BASE+0x94*4) // R/W - DATX8 2 DQ Timing Register
+#define PUBL_DX2DQSTR (PUBL_REG_BASE+0x95*4) // R/W - DATX8 2 DQS Timing Register
+#define PUBL_DX3GCR (PUBL_REG_BASE+0xA0*4) // R - DATX8 3 General Configration Register
+#define PUBL_DX3GSR0 (PUBL_REG_BASE+0xA1*4) // R - DATX8 3 General Status Register
+#define PUBL_DX3GSR1 (PUBL_REG_BASE+0xA2*4) // R - DATX8 3 General Status Register
+#define PUBL_DX3DLLCR (PUBL_REG_BASE+0xA3*4) // R - DATX8 3 DLL Control Register
+#define PUBL_DX3DQTR (PUBL_REG_BASE+0xA4*4) // R/W - DATX8 3 DQ Timing Register
+#define PUBL_DX3DQSTR (PUBL_REG_BASE+0xA5*4) // R/W - DATX8 3 DQS Timing Register
+#define PUBL_DX4GCR (PUBL_REG_BASE+0xB0*4) // R - DATX8 4 General Configration Register
+#define PUBL_DX4GSR0 (PUBL_REG_BASE+0xB1*4) // R - DATX8 4 General Status Register
+#define PUBL_DX4GSR1 (PUBL_REG_BASE+0xB2*4) // R - DATX8 4 General Status Register
+#define PUBL_DX4DLLCR (PUBL_REG_BASE+0xB3*4) // R - DATX8 4 DLL Control Register
+#define PUBL_DX4DQTR (PUBL_REG_BASE+0xB4*4) // R/W - DATX8 4 DQ Timing Register
+#define PUBL_DX4DQSTR (PUBL_REG_BASE+0xB5*4) // R/W - DATX8 4 DQS Timing Register
+#define PUBL_DX5GCR (PUBL_REG_BASE+0xC0*4) // R - DATX8 5 General Configration Register
+#define PUBL_DX5GSR0 (PUBL_REG_BASE+0xC1*4) // R - DATX8 5 General Status Register
+#define PUBL_DX5GSR1 (PUBL_REG_BASE+0xC2*4) // R - DATX8 5 General Status Register
+#define PUBL_DX5DLLCR (PUBL_REG_BASE+0xC3*4) // R - DATX8 5 DLL Control Register
+#define PUBL_DX5DQTR (PUBL_REG_BASE+0xC4*4) // R/W - DATX8 5 DQ Timing Register
+#define PUBL_DX5DQSTR (PUBL_REG_BASE+0xC5*4) // R/W - DATX8 5 DQS Timing Register
+#define PUBL_DX6GCR (PUBL_REG_BASE+0xD0*4) // R - DATX8 6 General Configration Register
+#define PUBL_DX6GSR0 (PUBL_REG_BASE+0xD1*4) // R - DATX8 6 General Status Register
+#define PUBL_DX6GSR1 (PUBL_REG_BASE+0xD2*4) // R - DATX8 6 General Status Register
+#define PUBL_DX6DLLCR (PUBL_REG_BASE+0xD3*4) // R - DATX8 6 DLL Control Register
+#define PUBL_DX6DQTR (PUBL_REG_BASE+0xD4*4) // R/W - DATX8 6 DQ Timing Register
+#define PUBL_DX6DQSTR (PUBL_REG_BASE+0xD5*4) // R/W - DATX8 6 DQS Timing Register
+#define PUBL_DX7GCR (PUBL_REG_BASE+0xE0*4) // R - DATX8 7 General Configration Register
+#define PUBL_DX7GSR0 (PUBL_REG_BASE+0xE1*4) // R - DATX8 7 General Status Register
+#define PUBL_DX7GSR1 (PUBL_REG_BASE+0xE2*4) // R - DATX8 7 General Status Register
+#define PUBL_DX7DLLCR (PUBL_REG_BASE+0xE3*4) // R - DATX8 7 DLL Control Register
+#define PUBL_DX7DQTR (PUBL_REG_BASE+0xE4*4) // R/W - DATX8 7 DQ Timing Register
+#define PUBL_DX7DQSTR (PUBL_REG_BASE+0xE5*4) // R/W - DATX8 7 DQS Timing Register
+#define PUBL_DX8GCR (PUBL_REG_BASE+0xF0*4) // R - DATX8 8 General Configration Register
+#define PUBL_DX8GSR0 (PUBL_REG_BASE+0xF1*4) // R - DATX8 8 General Status Register
+#define PUBL_DX8GSR1 (PUBL_REG_BASE+0xF2*4) // R - DATX8 8 General Status Register
+#define PUBL_DX8DLLCR (PUBL_REG_BASE+0xF3*4) // R - DATX8 8 DLL Control Register
+#define PUBL_DX8DQTR (PUBL_REG_BASE+0xF4*4) // R/W - DATX8 8 DQ Timing Register
+#define PUBL_DX8DQSTR (PUBL_REG_BASE+0xF5*4) // R/W - DATX8 8 DQS Timing Register
+
+typedef unsigned long int uint32;
+
+
+static inline void reg_bits_set(uint32 addr,uint32 start_bitpos,uint32 bit_num,uint32 value)
+{
+ /*create bit mask according to input param*/
+ uint32 bit_mask = (1<<bit_num)-1;
+ uint32 reg_data = *((volatile uint32*)(addr));
+
+ reg_data &= ~(bit_mask<<start_bitpos);
+ reg_data |= ((value&bit_mask)<<start_bitpos);
+
+ *((volatile uint32*)(addr)) = reg_data;
+}__attribute__((always_inline))
+
+
+static inline void assert_reset_dll(void)
+{
+ REG32(PUBL_ACDLLCR) &= ~(0x1<<30);
+ REG32(PUBL_DX0DLLCR) &= ~(0x1<<30);
+ REG32(PUBL_DX1DLLCR) &= ~(0x1<<30);
+ REG32(PUBL_DX2DLLCR) &= ~(0x1<<30);
+ REG32(PUBL_DX3DLLCR) &= ~(0x1<<30);
+}__attribute__((always_inline))
+
+static inline void deassert_reset_dll(void)
+{
+ REG32(PUBL_ACDLLCR) |= (0x1<<30);
+ REG32(PUBL_DX0DLLCR) |= (0x1<<30);
+ REG32(PUBL_DX1DLLCR) |= (0x1<<30);
+ REG32(PUBL_DX2DLLCR) |= (0x1<<30);
+ REG32(PUBL_DX3DLLCR) |= (0x1<<30);
+}__attribute__((always_inline))
+
+static inline void disable_ddrphy_dll(void) {
+ REG32(PUBL_PIR) |= (1 << 17);
+}__attribute__((always_inline))
+
+static inline void enable_ddrphy_dll(void) {
+ REG32(PUBL_PIR) &= ~(1 << 17);
+}__attribute__((always_inline))
+
+static inline void move_upctl_state_to_self_refresh(void)
+{
+ volatile uint32 val;
+
+ REG32(UMCTL_PWRCTL) = 0;
+ val = REG32(UMCTL_STAT);
+ //wait umctl2 core is in self-refresh mode
+ while((val & 0x7) != 1) {
+ val = REG32(UMCTL_STAT);
+ }
+
+ REG32(UMCTL_DFILPCFG0) = 0x0700f000;
+// val = REG32(UMCTL_STAT);
+ //wait umctl2 core is in self-refresh mode
+// while((val & 0x7) != 3) {
+// val = REG32(UMCTL_STAT);
+// }
+ //check self refresh was due to software
+}__attribute__((always_inline))
+static inline void move_upctl_state_exit_self_refresh(u32 dll_enable)
+{
+ if(dll_enable == EMC_DLL_SWITCH_DISABLE_MODE) {
+ REG32(UMCTL_DFILPCFG0) = 0x0700f100;
+ REG32(UMCTL_PWRCTL) = 0x9;
+ }
+ else{
+// REG32(UMCTL_DFILPCFG0) = 0x0700f000;
+ REG32(UMCTL_PWRCTL) = 0xa;
+ }
+
+// val = REG32(UMCTL_STAT);
+ //wait umctl2 core is in self-refresh mode
+// while((val & 0x7) != 1) {
+// val = REG32(UMCTL_STAT);
+// }
+
+}__attribute__((always_inline))
+
+static inline void disable_cam_command_deque(void)
+{
+ REG32(UMCTL_DBG1) |= (1 << 0);
+}__attribute__((always_inline))
+static inline void enable_cam_command_deque(void)
+{
+ REG32(UMCTL_DBG1) &= ~(1 << 0);
+}__attribute__((always_inline))
+static inline void ddr_clk_set(uint32 new_clk, uint32 delay, uint32 sene, ddr_dfs_val_t *timing);
+static inline void ddr_timing_update(ddr_dfs_val_t *timing);
+static inline void manual_issue_autorefresh(void)
+{
+ uint32 val;
+ val = REG32(UMCTL_RFSHCTL3);
+ val |= (1 << 0) ;
+ val ^= (1 << 1);
+ REG32(UMCTL_RFSHCTL3) = val;
+
+ val = REG32(UMCTL_RFSHCTL3);
+ val &= ~(1 << 0) ;
+ val ^= (1 << 1);
+ REG32(UMCTL_RFSHCTL3) = val;
+}__attribute__((always_inline))
+static inline void wait_queue_complete(void)
+{
+ volatile u32 i = 0;
+ volatile u32 value_temp;
+ while(i < 10)
+ {
+ value_temp = REG32(UMCTL_DBG1);
+ if(value_temp == 1) {
+ i++;
+ }
+ }
+}__attribute__((always_inline))
+static inline void dll_bypass_switch(u32 dll_mode, ddr_dfs_val_t *timing)
+{
+ volatile uint32 i;
+ //for(i = 0; i < 0x80000000; i++);
+ move_upctl_state_to_self_refresh();
+ //timing->publ_mr1 = 0x1234556C;
+ disable_cam_command_deque();
+ REG32(UMCTL_DFIMISC) &= ~(1 << 0);
+ wait_queue_complete();
+ //for(i = 0; i < 20; i++);
+
+ //phy clock close
+// REG32(PMU_APB_BASE + 0xc8) &= ~(1 << 2);
+ REG32(SPRD_PMU_PHYS + 0xc8) &= ~(1 << 6);
+// for(i = 0 ; i < 2; i++);
+
+ if(dll_mode == EMC_DLL_SWITCH_DISABLE_MODE) {
+ disable_ddrphy_dll();
+ //phy clock open
+// REG32(PMU_APB_BASE + 0xc8) |= (1 << 2);
+ REG32(SPRD_PMU_PHYS + 0xc8) |= (1 << 6);
+ for(i = 0 ; i < 2; i++);
+// deassert_reset_dll();
+ REG32(PUBL_PIR) |= (1 << 4) | (1 << 0);
+ while((REG32(PUBL_PGSR) & 1) != 1);
+ while((REG32(PUBL_PGSR) & 1) != 1);
+ REG32(PUBL_PIR) |= (1 << 4);
+ }
+ else if(dll_mode == EMC_DLL_SWITCH_ENABLE_MODE){
+ assert_reset_dll();
+ for(i = 0 ; i < 2; i++);
+ enable_ddrphy_dll();
+ //phy clock open
+// REG32(PMU_APB_BASE + 0xc8) |= (1 << 2);
+ REG32(SPRD_PMU_PHYS + 0xc8) |= (1 << 6);
+ for(i = 0 ; i < 2; i++);
+ deassert_reset_dll();
+ for(i = 0 ; i < 40; i++);
+ }
+ REG32(UMCTL_DFIMISC) |= (1 << 0);
+ enable_cam_command_deque();
+ move_upctl_state_exit_self_refresh(dll_mode);
+}__attribute__((always_inline))
+static inline void umctl2_freq_set(uint32 clk, uint32 DDR_TYPE, uint32 dll_mode,uint32 sene,ddr_dfs_val_t *timing)
+{
+ #ifdef CONFIG_SCX35_DMC_FREQ_AP
+ ddr_clk_set(clk,0,sene,timing);
+ #else
+ if(EMC_DLL_SWITCH_ENABLE_MODE == dll_mode) {
+ dll_bypass_switch(dll_mode, timing);
+ ddr_clk_set(clk, 10, sene,timing);
+ }
+ else if(EMC_DLL_SWITCH_DISABLE_MODE == dll_mode) {
+ ddr_clk_set(clk, 10, sene,timing);
+ dll_bypass_switch(dll_mode, timing);
+ }
+ else if(EMC_DLL_NOT_SWITCH_MODE) {
+ ddr_clk_set(clk, 10, sene,timing);
+ }
+ #endif
+}__attribute__((always_inline))
+static inline void ddr_timing_update(ddr_dfs_val_t *timing)
+{
+ disable_cam_command_deque();
+ REG32(UMCTL_RFSHTMG) = timing->umctl2_rfshtmg;
+// REG32(UMCTL_RFSHTMG) = val;
+ REG32(UMCTL_RFSHCTL3) ^= (1 << 1);
+// manual_issue_autorefresh();
+ REG32(UMCTL_DRAMTMG0) = timing->umctl2_dramtmg0;
+ REG32(UMCTL_DRAMTMG1) = timing->umctl2_dramtmg1;
+ REG32(UMCTL_DRAMTMG2) = timing->umctl2_dramtmg2;
+ //REG32(UMCTL_DRAMTMG3) = timing->umctl2_dramtmg3;
+ REG32(UMCTL_DRAMTMG4) = timing->umctl2_dramtmg4;
+ //REG32(UMCTL_DRAMTMG5) = timing->umctl2_dramtmg5;
+ REG32(UMCTL_DRAMTMG6) = timing->umctl2_dramtmg6;
+ //REG32(UMCTL_DRAMTMG7) = timing->umctl2_dramtmg7;
+ //REG32(UMCTL_DRAMTMG8) = timing->umctl2_dramtmg8;
+ //REG32(UMCTL_DRAMTMG8) = 0x2;
+ REG32(PUBL_DX0DQSTR) = timing->publ_dx0dqstr;
+ REG32(PUBL_DX1DQSTR) = timing->publ_dx1dqstr;
+ REG32(PUBL_DX2DQSTR) = timing->publ_dx2dqstr;
+ REG32(PUBL_DX3DQSTR) = timing->publ_dx3dqstr;
+ REG32(PUBL_DX0GCR) = timing->publ_dx0gcr;
+ REG32(PUBL_DX1GCR) = timing->publ_dx1gcr;
+ REG32(PUBL_DX2GCR) = timing->publ_dx2gcr;
+ REG32(PUBL_DX3GCR) = timing->publ_dx3gcr;
+ enable_cam_command_deque();
+}__attribute__((always_inline))
+
+static int get_dpll_refin(void)
+{
+ return ((REG32(SPRD_AONAPB_PHYS + 0X18) >> 24) & 0x3);
+}__attribute__((always_inline))
+
+#ifdef CONFIG_SCX35_DMC_FREQ_AP
+static inline void exit_lowpower_mode(void)
+{
+ uint32 val;
+
+ *(volatile uint32*)(UMCTL_PWRCTL) = 0x8;
+ val = *(volatile uint32*)(UMCTL_STAT);
+ //wait umctl2 core is in self-refresh mode
+ while((val & 0x7) != 1) {
+ val = *(volatile uint32*)(UMCTL_STAT);
+ }
+ *(volatile uint32*)(UMCTL_DFILPCFG0) = 0x0700f000;
+}__attribute__((always_inline))
+
+static inline void ddr_cam_command_dequeue(uint32 isEnable)
+{
+ if(isEnable)
+ {
+ *(volatile uint32*)(UMCTL_DBG1) &= ~(1<<0);
+ }
+ else
+ {
+ *(volatile uint32*)(UMCTL_DBG1) |= (1<<0);
+ }
+}__attribute__((always_inline))
+
+
+static inline void ddr_timing_update_ex(ddr_dfs_val_t *timing_param)
+{
+ //minimum time from refresh to refresh or active
+ //reg_bits_set(UMCTL_RFSHTMG,0,9,timing_param->umctl2_rfshtmg);
+ //toggle this signel indicate refresh register has been update
+ *(volatile uint32*)(UMCTL_RFSHTMG) = timing_param->umctl2_rfshtmg;
+ *(volatile uint32*)(UMCTL_RFSHCTL3) ^= (1<<1);
+ //update umctl & publ timing
+ *(volatile uint32*)UMCTL_DRAMTMG0 = timing_param->umctl2_dramtmg0;
+ *(volatile uint32*)UMCTL_DRAMTMG1 = timing_param->umctl2_dramtmg1;
+ *(volatile uint32*)UMCTL_DRAMTMG2 = timing_param->umctl2_dramtmg2;
+ //*(volatile uint32*)UMCTL_DRAMTMG3 = timing_param->umctl2_dramtmg3;
+ *(volatile uint32*)UMCTL_DRAMTMG4 = timing_param->umctl2_dramtmg4;
+ //*(volatile uint32*)UMCTL_DRAMTMG5 = timing_param->umctl2_dramtmg5;
+ *(volatile uint32*)UMCTL_DRAMTMG6 = timing_param->umctl2_dramtmg6;
+ //*(volatile uint32*)UMCTL_DRAMTMG7 = timing_param->umctl2_dramtmg7;
+ //*(volatile uint32*)UMCTL_DRAMTMG8 = timing_param->umctl2_dramtmg8;
+ //*(volatile uint32*)UMCTL_DRAMTMG8 = 1;
+
+ *(volatile uint32*)PUBL_DX0DQSTR = timing_param->publ_dx0dqstr;
+ *(volatile uint32*)PUBL_DX1DQSTR = timing_param->publ_dx1dqstr;
+ *(volatile uint32*)PUBL_DX2DQSTR = timing_param->publ_dx2dqstr;
+ *(volatile uint32*)PUBL_DX3DQSTR = timing_param->publ_dx3dqstr;
+ *(volatile uint32*)PUBL_DX0GCR = timing_param->publ_dx0gcr;
+ *(volatile uint32*)PUBL_DX1GCR = timing_param->publ_dx1gcr;
+ *(volatile uint32*)PUBL_DX2GCR = timing_param->publ_dx2gcr;
+ *(volatile uint32*)PUBL_DX3GCR = timing_param->publ_dx3gcr;
+}__attribute__((always_inline))
+
+static inline void uart_putch(uint32 c)
+{
+ *(volatile uint32*)SPRD_UART1_PHYS = c;
+}__attribute__((always_inline))
+
+static inline void ddr_clk_set(uint32 new_clk, uint32 delay, uint32 sene,ddr_dfs_val_t *timing)
+{
+ volatile uint32 i;
+ uint32 reg;
+// uint32 time_1,time_2;
+ uart_putch('0');
+ uart_putch('\n');
+ exit_lowpower_mode();
+ uart_putch('1');
+ uart_putch('\n');
+ //hold bus
+ //*(volatile uint32*)(0X40050048) = 0xc0; //open AON AP TIMER2
+ //time_1 = *(volatile uint32*)(0X40050044);
+ ddr_cam_command_dequeue(0);
+ //uart_putch('2');
+ //uart_putch('\n');
+ //confirm hold bus success
+ //hold not trigger sdram initialization
+ *(volatile uint32*)UMCTL_DFIMISC &= ~0x1;
+ wait_queue_complete();
+ //uart_putch('3');
+ //uart_putch('\n');
+ //disable auto refresh
+ REG32(UMCTL_RFSHCTL3) |= (1<<0);
+ for(i=0;i<10;i++);
+ switch(new_clk)
+ {
+ case 192:
+ {
+ if((sene == EMC_FREQ_NORMAL_SWITCH_SENE) || (sene == EMC_FREQ_RESUME_SENE))
+ {
+ //set tdpll clock divider
+ reg_bits_set((SPRD_AONCKG_PHYS+0x0024),0x8,2,0x1);
+
+ for(i=0;i<2;i++);
+
+ //switch to tdpll source 384Mhz
+ reg_bits_set((SPRD_AONCKG_PHYS+0x0024),0x0,2,0x2);
+
+ for(i=0;i<10;i++);
+ }
+ if(sene == EMC_FREQ_DEEP_SLEEP_SENE)
+ {
+ //switch to dpll source
+ reg_bits_set((SPRD_AONCKG_PHYS+0x0024),0x8,2,0x0);
+
+ for(i=0;i<2;i++);
+ reg_bits_set((SPRD_AONCKG_PHYS+0x0024),0x0,2,0x3);
+ for(i=0;i<10;i++);
+ }
+
+ //phy clock close
+ *(volatile uint32*)(SPRD_PMU_PHYS+0x00c8) &= ~(1<<6);
+ for(i=0;i<10;i++);
+ //close dll
+ disable_ddrphy_dll();
+
+ //phy clock open
+ *(volatile uint32*)(SPRD_PMU_PHYS+0x00c8) |= (1<<6);
+// *(volatile uint32*)0x022b00c8 |= (1<<2);
+ for(i=0;i<10;i++);
+ //deassert_reset_dll();
+
+// wait DLL lock in memory side;
+// use MRS to close the DLL in memory side in 192MHz
+ REG32(PUBL_PIR) |= (1 << 4) | (1 << 0);
+ while((REG32(PUBL_PGSR) & 1) != 1);
+ while((REG32(PUBL_PGSR) & 1) != 1);
+// REG32(PUBL_PIR) |= (1 << 4);
+ REG32(UMCTL_PERFLPR1) &= ~0xFFFF;
+ REG32(UMCTL_PERFWR1) &= ~0xFFFF;
+
+ break;
+ }
+
+ case 332:
+ {
+ //config dpll divider
+ reg_bits_set((SPRD_AONCKG_PHYS+0x0024),0x8,2,0x0);
+
+ for(i=0;i<2;i++);
+
+ //switch to dpll source
+ reg_bits_set((SPRD_AONCKG_PHYS+0x0024),0x0,2,0x3);
+
+ for(i=0;i<10;i++);
+ //phy clock close
+ *(volatile uint32*)(SPRD_PMU_PHYS+0x00c8) &= ~(1<<6);
+ for(i=0;i<10;i++);
+
+ assert_reset_dll();
+ for(i=0;i<10;i++);
+ //open dll
+ enable_ddrphy_dll();
+
+ for(i=0;i<10;i++);
+
+ //phy clock open
+ *(volatile uint32*)(SPRD_PMU_PHYS+0x00c8) |= (1<<6);
+// *(volatile uint32*)0x022b00c8 |= (1<<2);
+ for(i=0;i<10;i++);
+ //release dll
+ deassert_reset_dll();
+ for(i=0;i<30;i++);
+
+ REG32(UMCTL_PERFLPR1) |= 0x100;
+ REG32(UMCTL_PERFWR1) |= 0x20;
+ break;
+ }
+ default:
+ break;
+ }
+
+ //enable auto refresh
+ REG32(UMCTL_RFSHCTL3) &= ~(1<<0);
+ //uart_putch('4');
+ //uart_putch('\n');
+ ddr_timing_update_ex(timing);
+ //uart_putch('5');
+ //uart_putch('\n');
+ *(volatile uint32*)UMCTL_DFIMISC |= (1<<0);
+ ddr_cam_command_dequeue(1);
+ //time_2 = *(volatile uint32*)(0X40050044);
+
+ //if(new_clk == 192)
+ //*(volatile uint32*)(0x1dc0) = time_1 - time_2;
+ //else
+ //*(volatile uint32*)(0x1dd0) = time_1 - time_2;
+ uart_putch('6');
+ uart_putch('\n');
+ if(new_clk == 192)
+ {
+ REG32(UMCTL_DFILPCFG0) = 0x0700f100;
+ REG32(UMCTL_PWRCTL) = 0x9;
+ }
+ else
+ {
+ REG32(UMCTL_PWRCTL) = 0xa;
+ }
+}__attribute__((always_inline))
+
+#else
+static inline void ddr_clk_set(uint32 new_clk, uint32 delay, uint32 sene,ddr_dfs_val_t *timing)
+{
+ uint32 reg_val;
+ uint32 old_clk;
+ uint32 steps;
+ uint32 i;
+ uint32 j;
+ reg_val = REG32(SPRD_AONAPB_PHYS + 0X18);
+ old_clk = reg_val & 0xfff;
+ old_clk *= 4;
+ if(old_clk > new_clk) {
+ steps = (old_clk - new_clk) / 4;
+// ddr_autorefresh_timing_update();
+ for(i = 0; i < steps; i++) {
+ REG32(SPRD_AONAPB_PHYS + 0X18) = REG32(SPRD_AONAPB_PHYS + 0X18) - 1;
+ for(j = 0; j < delay; j++);
+ }
+ ddr_timing_update(timing);
+ }
+ else if(old_clk < new_clk){
+ ddr_timing_update(timing);
+ steps = (new_clk - old_clk) / 4;
+ for(i = 0; i < steps; i++) {
+ REG32(SPRD_AONAPB_PHYS + 0X18) = REG32(SPRD_AONAPB_PHYS + 0X18) + 1;
+ for(j = 0; j < delay; j++);
+ }
+// ddr_autorefresh_timing_update();
+ }
+}__attribute__((always_inline))
+#endif
+
+
+#define DFS_PARAM_ADDR (0x1C00)
+#define DFS_AP_REQ_ARRAY_ADDR (SPRD_IRAM0_PHYS + 0x1BF0)
+inline void dev_freq_set(unsigned long req)
+{
+ u32 ddr_type;
+ u32 clk;
+ u32 dll_mode;
+ u32 sene;
+ ddr_dfs_val_t *timing;
+ REG32(PUBL_DSGCR) &= ~(0x10);
+ ddr_type = (req & EMC_DDR_TYPE_MASK) >> EMC_DDR_TYPE_OFFSET;
+ clk = (req & EMC_CLK_FREQ_MASK) >> EMC_CLK_FREQ_OFFSET;
+ dll_mode = (req & EMC_DLL_MODE_MASK);
+ sene = (req & EMC_FREQ_SENE_MASK) >> EMC_FREQ_SENE_OFFSET;
+ timing = (ddr_dfs_val_t *)(DFS_PARAM_ADDR);
+
+ if(clk == 332)
+ {
+ timing += 1;
+ }
+
+ if(timing->ddr_clk != clk)
+ {
+ uart_putch('d');
+ uart_putch('f');
+ uart_putch('s');
+ uart_putch('e');
+ uart_putch('r');
+ uart_putch('r');
+ uart_putch('o');
+ uart_putch('r');
+ uart_putch('\n');
+ while(1);
+ }
+ umctl2_freq_set(clk, ddr_type, dll_mode,sene, timing);
+
+
+} __attribute__((always_inline))
+void emc_dfs_main(unsigned long flag)
+{
+ uint32_t reg, val;
+ /* disable mmu, cache */
+ asm volatile (
+// "ldr %1, =10000 \n"
+// "1: nop \n"
+// "sub %1, %1, #1 \n"
+// "cmp %1, #0 \n"
+// "bne 1b \n"
+ "mrc p15, 0, %0, c1, c0, 0 \n"
+ "ldr %1, =0x1005 \n"
+ "bic %0, %0, %1 \n"
+ "mcr p15, 0, %0, c1, c0, 0\n"
+ "ldr sp, =0x1BF0 \n"
+ "ldr r11, =0x1F00 \n"
+ : "=r"(reg), "=r"(val)
+ );
+ //for(i = 0; i < 0x80000000; i++);
+ dev_freq_set(flag); /* call dfs freq set function */
+ /* "ldr r11, =0x1c00 \n" */
+ /* jump back */
+ asm volatile (
+ "ldr r0, =cpu_resume \n"
+ "sub r0, r0, #0xc0000000 \n"
+ "add r0, r0, #0x80000000 \n"
+ "mov pc, r0 \n"
+ );
+}