| /* |
| * Copyright (c) 2013 Qualcomm Atheros, Inc. |
| * |
| * See file CREDITS for list of people who contributed to this |
| * project. |
| * |
| * 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 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. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
| * MA 02111-1307 USA |
| */ |
| |
| #include <config.h> |
| #include <version.h> |
| #include <asm/regdef.h> |
| #include <asm/mipsregs.h> |
| #include <asm/addrspace.h> |
| #include <atheros.h> |
| |
| .globl ath_ddr_tap_cal |
| .type ath_ddr_tap_cal, @function |
| .text |
| .align 4 |
| ath_ddr_tap_cal: |
| li a0, 0xbd001f00 |
| sw zero, 0x0(a0) // Place where the tap values are saved and used for SWEEP |
| sw zero, 0x4(a0) // Place where the number of passing taps are saved. |
| sw zero, 0x14(a0) // Place where the last pass tap value is stored |
| li a1, 0xaa55aa55 // Indicates that the First pass tap value is not found |
| sw a1, 0x10(a0) // Place where the First pass tap value is stored |
| nop |
| |
| li a0, 0xb8060000 // RESET_BASE_ADDRESS |
| lw a1, 0x1c(a0) // Reading the RST_RESET_ADDRESS |
| li a2, 0x08000000 // Setting the RST_RESET_RTC_RESET |
| or a1, a1, a2 |
| sw a1, 0x1c(a0) |
| |
| li a3, 0xffffffff |
| xor a2, a2, a3 |
| and a1, a1, a2 |
| sw a1, 0x1c(a0) // Taking the RTC out of RESET |
| nop |
| |
| li a0, 0xb8107000 // RTC_BASE_ADDRESS |
| li a1, 0x1 |
| sw a1, 0x0040(a0) // RTC_SYNC_RESET_ADDRESS |
| |
| li a2, 0x2 |
| |
| _poll_for_RTC_ON: |
| lw a1, 0x0044(a0) // RTC_SYNC_STATUS_ADDRESS |
| and a1, a2, a1 |
| bne a1, a2, _poll_for_RTC_ON |
| |
| |
| _CHANGE_TAPS: |
| |
| li t0, 0xbd001f00 // Read the current value of the TAP for programming |
| lw t1, 0x0(t0) |
| li t2, 0x00000000 |
| or t3, t1, t2 |
| |
| |
| li t0, 0xb8000000 // DDR_BASE_ADDRESS |
| |
| sw t3, 0x1c(t0) // TAP_CONTROL_0_ADDRESS |
| sw t3, 0x20(t0) // TAP_CONTROL_1_ADDRESS |
| sw t3, 0x24(t0) // TAP_CONTROL_2_ADDRESS |
| sw t3, 0x28(t0) // TAP_CONTROL_3_ADDRESS |
| |
| li t1, 0x00000010 // Running the test 8 times |
| sw t1, 0x0068(t0) // PERF_COMP_ADDR_1_ADDRESS |
| |
| li t1, 0xfa5de83f // 4 Row Address Bits, 4 Column Address Bits, 2 BA bits |
| sw t1, 0x002c(t0) // PERF_MASK_ADDR_0_ADDRESS |
| |
| li t1, 0x0000ffff |
| sw t1, 0x0070(t0) // PERF_COMP_AHB_GE0_1_ADDRESS |
| |
| li t1, 0x0000ffff |
| sw t1, 0x0040(t0) // PERF_COMP_AHB_GE1_0_ADDRESS |
| |
| li t1, 0x0000ffff |
| sw t1, 0x0078(t0) // PERF_COMP_AHB_GE1_1_ADDRESS |
| |
| li t1, 0x0000ffff |
| sw t1, 0x0034(t0) // PERF_MASK_AHB_GE0_0_ADDRESS |
| |
| li t1, 0x0000ffff |
| sw t1, 0x006c(t0) // PERF_MASK_AHB_GE0_1_ADDRESS |
| |
| li t1, 0x0000ffff |
| sw t1, 0x003c(t0) // PERF_MASK_AHB_GE1_0_ADDRESS |
| |
| li t1, 0x0000ffff |
| sw t1, 0x0074(t0) // PERF_MASK_AHB_GE1_1_ADDRESS |
| |
| li t1, 0x0000ffff |
| sw t1, 0x0038(t0) // PERF_COMP_AHB_GE0_0_ADDRESS |
| |
| li t1, 0x00000001 |
| sw t1, 0x011c(t0) // DDR_BIST_ADDRESS |
| |
| li t2, 0x1 |
| _bist_done_poll: |
| lw t1, 0x0120(t0) // DDR_BIST_STATUS_ADDRESS |
| and t1, t1, t2 |
| bne t1, t2, _bist_done_poll |
| |
| lw t1, 0x0120(t0) // DDR_BIST_STATUS_ADDRESS |
| li t4, 0x000001fe |
| and t2, t1, t4 |
| srl t2, t2, 0x1 // no. of Pass Runs |
| |
| li t5, 0x00000000 |
| sw t5, 0x011c(t0) //DDR_BIST_ADDRESS - Stop the DDR BIST test |
| |
| li t5, 0x0001fe00 |
| and t5, t5, t1 |
| bnez t5, _iterate_tap // This is a redundant compare but nevertheless - Comparing the FAILS |
| |
| lw t1, 0x0068(t0) // PERF_COMP_ADDR_1_ADDRESS |
| li t3, 0x000001fe |
| and t3, t3, t1 |
| srl t3, t3, 0x1 // No. of runs in the config register. |
| |
| bne t3, t2, _iterate_tap |
| |
| pass_tap: |
| li t0, 0xbd001f00 |
| lw t1, 0x4(t0) |
| addiu t1, t1, 0x1 |
| sw t1, 0x4(t0) |
| |
| li t0, 0xbd001f10 |
| lw t1, 0x0(t0) |
| li t2, 0xaa55aa55 |
| beq t1, t2, _first_pass |
| nop |
| li t0, 0xbd001f00 |
| lw t1, 0x0(t0) |
| li t0, 0xbd001f10 |
| sw t1, 0x4(t0) |
| nop |
| b _iterate_tap |
| nop |
| |
| _first_pass: |
| li t0, 0xbd001f00 |
| lw t1, 0x0(t0) |
| li t0, 0xbd001f10 |
| sw t1, 0x0(t0) |
| sw t1, 0x4(t0) |
| nop |
| |
| _iterate_tap: |
| |
| li t0, 0xbd001f00 |
| lw t1, 0x0(t0) |
| li t2, 0x3f |
| beq t1, t2, _STOP_TEST |
| nop |
| addiu t1, t1, 0x1 |
| sw t1, 0x0(t0) |
| nop |
| b _CHANGE_TAPS |
| |
| _STOP_TEST: |
| li t0, 0xbd001f00 |
| lw t1, 0x4(t0) |
| bnez t1, _load_center_tap |
| nop |
| li t3, 0x8 // Default Tap to be used |
| b _load_tap_into_reg |
| |
| _load_center_tap: |
| li t0, 0xbd001f10 |
| lw t1, 0x0(t0) |
| lw t2, 0x4(t0) |
| add t3, t1, t2 |
| srl t3, t3, 0x1 |
| li t4, 0x3f |
| and t3, t3, t4 |
| _load_tap_into_reg: |
| li t0, 0xb8000000 |
| sw t3, 0x1c(t0) // TAP_CONTROL_0_ADDRESS |
| sw t3, 0x20(t0) // TAP_CONTROL_1_ADDRESS |
| sw t3, 0x24(t0) // TAP_CONTROL_2_ADDRESS |
| sw t3, 0x28(t0) // TAP_CONTROL_3_ADDRESS |
| |
| jr ra |
| nop |
| |