blob: 0a3f55e26e58e8436fa3e4c0e4b52e0ce1fb0a63 [file] [log] [blame]
#include <config.h>
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm-offsets.h>
#include <asm/arch/mx6-ddr.h>
#define MMDC_MDSCR__DATA(x) (((x) & 0xff) << 24)
#define MMDC_MDSCR__ADDR(x) (((x) & 0xff) << 16)
#define MMDC_MDSCR__CON_REQ (1 << 15)
#define MMDC_MDSCR__CON_ACK (1 << 14)
#define MMDC_MDSCR__MRR_ACK (1 << 10)
#define MMDC_MDSCR__CMD(x) (((x) & 0x7) << 4)
.text
.global dram_fixup
.global _dram_fixup_start
.global _dram_fixup_end
.align 3
_dram_fixup_start:
.macro write_and_check
str r1, [r0]
1:
ldr r1, [r0]
ands r1,r2
beq 1b
.endm
ENTRY(dram_fixup)
stmdb sp!, {r11, lr}
ldr r12, .mmdc_mdscr_reg
ldr r11, .mmdc_mdmrr_reg
mov r0, r12
/* Enter Configuration Mode */
ldr r1, =MMDC_MDSCR__CON_REQ
ldr r2, =MMDC_MDSCR__CON_ACK
write_and_check
/* Read Manufacturer ID */
ldr r1, .mfgid_read_cmd
ldr r2, =MMDC_MDSCR__MRR_ACK
write_and_check
/* Check for Winbond */
ldrh r0, .winbond_mfgid
ldrh r1, [r11]
cmp r1, r0
bne 1f
/* Reconfigure */
ldr r1, .precharge_all_cmd
str r1, [r12]
ldr r1, .winbond_ds_cmd
str r1, [r12]
1:
/* Exit Configuration Mode */
ldr r1, =0
str r1, [r12]
ldmia sp!, {r11, pc}
ENDPROC(dram_fixup)
/* Registers */
.mmdc_mdscr_reg:
.word MX6_MMDC_P0_MDSCR
.mmdc_mdmrr_reg:
.word MX6_MMDC_P0_MDMRR
/* Commands */
.mfgid_read_cmd:
.word MMDC_MDSCR__CMD(0x6) | MMDC_MDSCR__CON_REQ | MMDC_MDSCR__ADDR(0x05)
.precharge_all_cmd:
.word MMDC_MDSCR__CMD(0x1) | MMDC_MDSCR__CON_REQ
.winbond_ds_cmd:
.word MMDC_MDSCR__CMD(0x3) | MMDC_MDSCR__CON_REQ | MMDC_MDSCR__ADDR(0x03) | MMDC_MDSCR__DATA(0x06)
/* Constants */
.winbond_mfgid:
/* Actually 0x0808, but need to account for "bit swizzling". */
.hword 0x8002
_dram_fixup_end: