191 lines
5.1 KiB
C
191 lines
5.1 KiB
C
/*
|
|
* Copyright (c) 2007-2017 Allwinnertech Co., Ltd.
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
/********************************************************************************
|
|
* Allwinner Technology, All Right Reserved. 2006-2010 Copyright (c)
|
|
*
|
|
* File: standby.c
|
|
*
|
|
* Description: This file implements standby for AW1681 DRAM controller
|
|
*
|
|
* History:
|
|
*
|
|
* date author version note
|
|
*
|
|
* 20140926 liuke v0.1 initial
|
|
*
|
|
*
|
|
*
|
|
*
|
|
********************************************************************************/
|
|
#define STANDBY_TEST
|
|
|
|
#ifdef STANDBY_TEST
|
|
#include "dram.h"
|
|
|
|
/* default config */
|
|
__u32 dram_crc_en;
|
|
__u32 dram_crc_start = 0x40000000;
|
|
__u32 dram_crc_len = (1024 * 1024);
|
|
|
|
__s32 standby_set_dram_crc_paras(__u32 en, __u32 start, __u32 len)
|
|
{
|
|
dram_crc_en = en;
|
|
dram_crc_start = start;
|
|
dram_crc_len = len;
|
|
|
|
return 0;
|
|
}
|
|
|
|
__u32 standby_dram_crc(void)
|
|
{
|
|
__u32 *pdata = (__u32 *) (dram_crc_start);
|
|
__u32 crc = 0;
|
|
|
|
printk("crc begin...\n");
|
|
if (0 != dram_crc_en) {
|
|
printk("start:%x len:%x\n", dram_crc_start, dram_crc_len);
|
|
while (pdata < (__u32 *) (dram_crc_start + dram_crc_len)) {
|
|
crc += *pdata;
|
|
pdata++;
|
|
}
|
|
}
|
|
printk("crc finish...\n");
|
|
return crc;
|
|
}
|
|
|
|
unsigned int dram_power_save_process()
|
|
{
|
|
unsigned int reg_val = 0;
|
|
unsigned int i, n = 2;
|
|
|
|
/* disable all master access */
|
|
mctl_write_w(0, MC_MAER); /* close all master */
|
|
|
|
/* DRAM power down. */
|
|
/* 1.enter self refresh */
|
|
reg_val = mctl_read_w(PWRCTL);
|
|
reg_val |= 0x1 << 0;
|
|
reg_val |= (0x1 << 8);
|
|
mctl_write_w(reg_val, PWRCTL);
|
|
/* confirm dram controller has enter selfrefresh */
|
|
while (((mctl_read_w(STATR) & 0x7) != 0x3))
|
|
;
|
|
|
|
/* 2.disable CK and power down pad include AC/DX/ pad,
|
|
* ZQ calibration module power down
|
|
*/
|
|
|
|
for (i = 0; i < n; i++) {
|
|
reg_val = mctl_read_w(DXnGCR0(i));
|
|
reg_val &= ~(0x3U << 22);
|
|
reg_val |= (0x1U << 22); /* DQS receiver off */
|
|
reg_val &= ~(0xfU << 12);
|
|
reg_val |= (0x5U << 12); /* POWER DOWN RECEIVER/DRICER OFF */
|
|
reg_val |= (0x2U << 2); /* OE mode disable */
|
|
reg_val &= ~(0x1U << 0); /* DQ GROUP OFF */
|
|
mctl_write_w(reg_val, DXnGCR0(i));
|
|
}
|
|
reg_val = mctl_read_w(CAIOCR0); /* CA IO POWER DOWN */
|
|
reg_val |= (0x3U << 8); /* CKE ENABLE */
|
|
reg_val &= ~(0x3U << 6); /* CK OUTPUT DISABLE */
|
|
/* reg_val &= ~(0x1U<<3); //CA OE OFF //do not close for 1681/1680 */
|
|
reg_val |= (0x3U << 0); /* CA POWER DOWN RECEIVER/DRIVER ON */
|
|
mctl_write_w(reg_val, CAIOCR0);
|
|
|
|
/* 4.disable global clk and pll-ddr0/pll-ddr1 */
|
|
mctl_write_w(0x0, MC_CLKEN);
|
|
/* disable PLL_DDR1 */
|
|
reg_val = mctl_read_w(_CCM_PLL_DDR1_REG);
|
|
reg_val &= ~(0x1U << 31);
|
|
mctl_write_w(reg_val, _CCM_PLL_DDR1_REG);
|
|
|
|
/* close DRAM AHB gate */
|
|
reg_val = mctl_read_w(BUS_CLK_GATE_REG0);
|
|
reg_val &= ~(0x1U << 14);
|
|
mctl_write_w(reg_val, BUS_CLK_GATE_REG0);
|
|
|
|
/* close MBUS CLK gate */
|
|
reg_val = mctl_read_w(MBUS_CLK_CTL_REG);
|
|
reg_val &= ~(1U << 31);
|
|
mctl_write_w(reg_val, MBUS_CLK_CTL_REG);
|
|
|
|
return DRAM_RET_OK;
|
|
}
|
|
|
|
unsigned int dram_power_up_process(__dram_para_t *para)
|
|
{
|
|
unsigned int reg_val = 0;
|
|
unsigned int i, n = 2;
|
|
|
|
/* Open MBUS CLK gate */
|
|
reg_val = mctl_read_w(MBUS_CLK_CTL_REG);
|
|
reg_val |= (1U << 31);
|
|
mctl_write_w(reg_val, MBUS_CLK_CTL_REG);
|
|
|
|
/* Open DRAM AHB gate */
|
|
reg_val = mctl_read_w(BUS_CLK_GATE_REG0);
|
|
reg_val |= (0x1U << 14);
|
|
mctl_write_w(reg_val, BUS_CLK_GATE_REG0);
|
|
|
|
/* enable PLL_DDR1,and wait it stable */
|
|
reg_val = mctl_read_w(_CCM_PLL_DDR1_REG);
|
|
reg_val |= (0x1U << 31);
|
|
mctl_write_w(reg_val, _CCM_PLL_DDR1_REG);
|
|
while (mctl_read_w(_CCM_PLL_DDR1_REG) == 1)
|
|
;
|
|
|
|
/* enable global clk */
|
|
mctl_write_w(0xC00e, MC_CLKEN);
|
|
|
|
/* controller enter self refresh */
|
|
reg_val = mctl_read_w(PWRCTL);
|
|
reg_val |= 0x1 << 0;
|
|
reg_val |= (0x1 << 8);
|
|
mctl_write_w(reg_val, PWRCTL);
|
|
/* confirm dram controller has enter selfrefresh */
|
|
while (((mctl_read_w(STATR) & 0x7) != 0x3))
|
|
;
|
|
|
|
/* CA Power down dynamic */
|
|
reg_val = mctl_read_w(CAIOCR0);
|
|
reg_val |= (0x3U << 8); /* CKE ENABLE */
|
|
reg_val |= (0x1U << 6); /* CK OUTPUT enable */
|
|
/* reg_val |= (0x1U<<3); //CA OE on //according to standby enter status */
|
|
reg_val &= ~(0x3U << 0); /* CA POWER DOWN RECEIVER/DRIVER off */
|
|
mctl_write_w(reg_val, CAIOCR0);
|
|
|
|
for (i = 0; i < n; i++) {
|
|
reg_val = mctl_read_w(DXnGCR0(i));
|
|
reg_val &= ~(0x3U << 22); /* DQS receiver dynamic */
|
|
reg_val &= ~(0xfU << 12); /* POWER DOWN RECEIVER/DRICER OFF dynamic */
|
|
reg_val &= ~(0x3U << 2); /* OE mode dynamic */
|
|
reg_val |= (0x1U << 0); /* DQ GROUP ON */
|
|
mctl_write_w(reg_val, DXnGCR0(i));
|
|
}
|
|
|
|
reg_val = mctl_read_w(PWRCTL);
|
|
reg_val &= ~(0x1 << 0);
|
|
reg_val &= ~(0x1 << 8);
|
|
mctl_write_w(reg_val, PWRCTL);
|
|
/* confirm dram controller has exit from selfrefresh */
|
|
while (((mctl_read_w(STATR) & 0x7) != 0x1))
|
|
;
|
|
|
|
/* enable all master access */
|
|
mctl_write_w(0xffffffff, MC_MAER);
|
|
|
|
return DRAM_RET_OK;
|
|
}
|
|
#endif
|