| #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: |