fsbl: sync sg200x-dev through 5a80c12

Update the vendored FSBL from Sophgo sg200x-dev commit
426d1e7eccce84b34169e5f21de7d6e7da1804a1 to
5a80c127cf614dea7f534d5b5352886a1c720d37, incorporating 24 upstream
commits. Keep the local plat/sg200x symlink to cv181x.

Import the upstream DDR, clock, storage and boot-image changes together
with their platform support, prebuilt firmware and licensing files.
All 935 upstream files match the target revision.

Validation on LicheeRV Nano (SG2002/C906, SD, DDR3-1866 x16):
- Cross-build BL2 with the existing Xuantie GCC 10.2.0 toolchain.
- Repack FIP while preserving the installed OpenSBI and U-Boot byte
  for byte; verify headers, payload checksums, entry addresses and LZMA.
- Software reboot and power-cycle boot succeed; memtester 16M 1 passes
  all 18 checks.

Validation covers the FSBL update with existing later boot stages.
Full firmware builds, A53 and video/HID acceptance are not covered.
This commit is contained in:
916BGAI
2026-11-06 18:34:01 +08:00
parent d4003f15b3
commit dbbad1938a
81 changed files with 8493 additions and 1608 deletions

24
fsbl/.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# Ignore miscellaneous files
*.py[co]
cscope.*
*.swp
*.patch
*~
.project
.cproject
.vscode/
# Ignore build directory
build/
__pycache__/
# GNU GLOBAL files
GPATH
GRTAGS
GSYMS
GTAGS
#ignore ctags
tags
#ignore vim swap files
*.swo

339
fsbl/LICENSE Normal file
View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -44,6 +44,19 @@ PRINTF_TIMESTAMP := 0
NANDBOOT_V2 := 1
ifeq ($(STORAGE),spinor)
CFLAGS += -DBOOT_SPINOR
endif
ifeq ($(STORAGE),emmc)
CFLAGS += -DBOOT_EMMC
endif
ifeq ($(STORAGE),spinand)
CFLAGS += -DBOOT_SPINAND
endif
# Verbose flag
ifeq (${V},0)
Q:=@
@@ -131,6 +144,15 @@ include lib/cpu/${BOOT_CPU}/cpu.mk
INCLUDES += -Ibuild
INCLUDES += -Iinclude/cpu
ifeq (${STORAGE_TYPE},spinand)
$(eval $(call add_define,BOOT_FROM_NAND))
endif
ifeq (${STORAGE_TYPE},emmc)
$(eval $(call add_define,BOOT_FROM_EMMC))
endif
ifeq (${STORAGE_TYPE},spinor)
$(eval $(call add_define,BOOT_FROM_NOR))
endif
################################################################################
# Build options checks
################################################################################
@@ -176,9 +198,22 @@ ifeq ($(OD_CLK_SEL),y)
$(eval $(call add_define,OD_CLK_SEL))
endif
ifeq ($(ENABLE_BURN_BUTTON),y)
$(eval $(call add_define,ENABLE_BURN_BUTTON))
$(eval $(call add_define_val,GPIO_GRP,${GPIO_GRP}))
$(eval $(call add_define_val,GPIO_PIN,${GPIO_PIN}))
endif
$(eval $(call add_define,FSBL_SECURE_BOOT_SUPPORT))
$(eval $(call add_define, USB_DL_BY_FSBL))
ifeq ($(SUSPEND),y)
$(eval $(call add_define,CONFIG_SUSPEND))
endif
ifeq (${SWITCH_32K_XTAL},y)
$(eval $(call add_define,SWITCH_32K_XTAL))
endif
################################################################################
# Build targets
################################################################################
@@ -187,8 +222,10 @@ $(eval $(call add_define, USB_DL_BY_FSBL))
export BUILD_PLAT NM
all: fip bl2 blmacros
include ${MAKE_HELPERS_DIRECTORY}fip.mk
$(eval $(call MAKE_BL,2))

View File

@@ -3,3 +3,50 @@ FSBL
FSBL is First Stage Boot Loader.
Act as ATF BL2.
License
=======
Project license: GPL-2.0-or-later (SPDX: GPL-2.0-or-later).
Unless stated otherwise at file level, original code authored by Sophgo
Technologies in this repository is licensed under GPL-2.0-or-later
(see LICENSE at repository root).
This project contains code derived from U-Boot (SPDX: GPL-2.0+) which is
compiled into the FSBL image. The project as a whole is therefore
distributed under the GPL; BSD licensing is not applicable.
Third-party components
----------------------
- ARM Trusted Firmware (TF-A) derived code
Copyright (c) 2013-2017, ARM Limited and Contributors
License: BSD-3-Clause (SPDX: BSD-3-Clause)
- U-Boot derived code: Designware DWC2 USB device controller
plat/cv180x/usb/dwc2_udc_otg*.c
plat/cv180x/include/usb/dwc2_udc*.h
Copyright (C) 2008 Samsung Electronics, ported to U-Boot by
Marek Szyprowski and Lukasz Majewski
License: GPL-2.0-or-later (SPDX: GPL-2.0+)
- lib/crc/crc16.c
License: eCos-2.0 (GPL-2.0 with linking exception)
- lib/libtommath/
License: Unlicense (public domain)
- lib/libtomcrypt/
License: public domain
- lib/BigDigits/
License: MPL-2.0 (see lib/BigDigits/LICENSE.txt)
- lib/lz4/
License: BSD-2-Clause
- lib/lzma/
License: public domain
File-level SPDX headers remain authoritative for each individual file.

452
fsbl/include/cv_spi_nand.h Normal file
View File

@@ -0,0 +1,452 @@
/*
* Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __CV_SPI_NAND_H__
#define __CV_SPI_NAND_H__
#include <platform_def.h>
#define SPI_NAND_READ_FROM_CACHE_MODE_X1 0
#define SPI_NAND_READ_FROM_CACHE_MODE_X2 1
#define SPI_NAND_READ_FROM_CACHE_MODE_X4 2
#define SPI_NAND_CMD_WREN 0x06
#define SPI_NAND_CMD_WRDI 0x04
#define SPI_NAND_CMD_GET_FEATURE 0x0F
#define SPI_NAND_CMD_SET_FEATURE 0x1F
#define SPI_NAND_CMD_PAGE_READ_TO_CACHE 0x13
#define SPI_NAND_CMD_READ_FROM_CACHE 0x03
#define SPI_NAND_CMD_READ_FROM_CACHE2 0x0B
#define SPI_NAND_CMD_READ_FROM_CACHEX2 0x3B
#define SPI_NAND_CMD_READ_FROM_CACHEX4 0x6B
#define SPI_NAND_CMD_READ_FROM_DUAL_IO 0xBB
#define SPI_NAND_CMD_READ_FROM_QUAL_IO 0xEB
#define SPI_NAND_CMD_READ_ID 0x9F
#define SPI_NAND_CMD_PROGRAM_LOAD 0x02
#define SPI_NAND_CMD_PROGRAM_LOADX4 0x32
#define SPI_NAND_CMD_PROGRAM_EXECUTE 0x10
#define SPI_NAND_CMD_PROGRAM_LOAD_RANDOM_DATA 0x84
#define SPI_NAND_CMD_PROGRAM_LOAD_RANDOM_DATAX4 0xC4
#define SPI_NAND_CMD_PROGRAM_LOAD_RANDOM_DATA_QUAD_IO 0x72
#define SPI_NAND_CMD_4K_SUBSECTOR_ERASE 0x20
#define SPI_NAND_CMD_32K_SUBSECTOR_ERASE 0x52
#define SPI_NAND_CMD_BLOCK_ERASE 0xD8
#define SPI_NAND_CMD_RESET 0xFF
#define SPI_NAND_FEATURE_PROTECTION (0xA0)
#define FEATURE_PROTECTION_NONE 0
#define SPI_NAND_PROTECTION_CMP (0x01 << 1)
#define SPI_NAND_PROTECTION_INV (0x01 << 2)
#define SPI_NAND_PROTECTION_BP0 (0x01 << 3)
#define SPI_NAND_PROTECTION_BP1 (0x01 << 4)
#define SPI_NAND_PROTECTION_BP2 (0x01 << 5)
#define SPI_NAND_PROTECTION_BRWD (0x01 << 7)
#define SPI_NAND_FEATURE_FEATURE0 (0xB0)
#define SPI_NAND_FEATURE0_QE (0x01 << 0)
#define SPI_NAND_FEATURE0_ECC_EN (0x01 << 4)
#define SPI_NAND_FEATURE0_OTP_EN (0x01 << 6)
#define SPI_NAND_FEATURE0_OTP_PRT (0x01 << 7)
#define SPI_NAND_FEATURE_ECC_CONFIG (0x90)
#define SPI_NAND_FEATURE_CFG_ECC_EN (0x01 << 4)
#define SPI_NAND_FEATURE_STATUS0 (0xC0)
#define SPI_NAND_STATUS0_OIP (0x01 << 0)
#define SPI_NAND_STATUS0_WEL (0x01 << 1)
#define SPI_NAND_STATUS0_E_FAIL (0x01 << 2)
#define SPI_NAND_STATUS0_P_FAIL (0x01 << 3)
#define SPI_NAND_STATUS0_ECCS0 (0x01 << 4)
#define SPI_NAND_STATUS0_ECCS1 (0x01 << 5)
#define SPI_NAND_FEATURE_FEATURE1 (0xD0)
#define SPI_NAND_FEATURE1_DS_S0 (0x01 << 5)
#define SPI_NAND_FEATURE1_DS_S1 (0x01 << 6)
#define SPI_NAND_FEATURE_STATUS1 (0xF0)
#define SPI_NAND_STATUS1_ECCSE0 (0x01 << 4)
#define SPI_NAND_STATUS1_ECCSE1 (0x01 << 5)
#define SPI_NAND_FLASH_BLOCK_SIZE 256
#define SPI_NAND_TRAN_CSR_ADDR_BYTES_SHIFT 8
#define SPI_NAND_MAX_FIFO_DEPTH 8
/*1880V2 spi nand definitions */
#define REG_SPI_NAND_TRX_CTRL0 0x000
#define BIT_REG_TRX_START (0x01 << 0)
#define BIT_REG_TRX_SW_RST (0x01 << 1)
#define BIT_REG_TRX_RST_DONE (0x01 << 16)
#define REG_SPI_NAND_TRX_CTRL1 0x004
#define BIT_REG_TRX_TIME_START (0x01 << 0)
#define BIT_REG_TRX_TIME_TA (0x01 << 4)
#define BIT_REG_TRX_TIME_END (0x01 << 4)
#define BIT_REG_TRX_TIME_WAIT (0x01 << 8)
#define SPI_NAND_SCK_MASK (0x00FF0000)
#define BIT_REG_TRX_SCK_H (0x01 << 16)
#define SPI_NAND_SET_SCK_H(x) (x << 16)
#define BIT_REG_TRX_SCK_L (0x01 << 20)
#define SPI_NAND_SET_SCK_L(x) (x << 20)
#define BIT_REG_IO_CPOL (0x01 << 24)
#define BIT_REG_IO_CPHA (0x01 << 25)
#define REG_SPI_NAND_TRX_CTRL2 0x008
#define BIT_REG_TRX_CMD_CONT_SIZE (0x01 << 0)
#define BIT_REG_TRX_DUMMY_SIZE (0x01 << 4)
#define BIT_REG_TRX_DATA_SIZE (0x01 << 16)
#define TRX_CMD_CONT_SIZE_SHIFT (0)
#define TRX_DUMMY_SIZE_SHIFT (4)
#define TRX_DATA_SIZE_SHIFT (16)
#define REG_SPI_NAND_TRX_CTRL3 0x00C
#define BIT_REG_IO_SIZE_MODE (0x01 << 0)
#define SPI_NAND_CTRL3_IO_TYPE_X1_MODE 0
#define SPI_NAND_CTRL3_IO_TYPE_X2_MODE 2
#define SPI_NAND_CTRL3_IO_TYPE_X4_MODE 3
#define SPI_NAND_CTRL3_IO_TYPE_DUAL_MODE 6
#define SPI_NAND_CTRL3_IO_TYPE_QUAD_MODE 7
#define BIT_REG_TRX_RW (0x01 << 16) // 1 for write, 0 for read
#define BIT_REG_TRX_DUMMY_HIZ (0x01 << 17)
#define BIT_REG_TRX_DMA_EN (0x01 << 18)
#define BIT_REG_RSP_CHK_EN (0x01 << 19)
#define REG_SPI_NAND_INT_EN 0x010
#define BIT_REG_TRX_DONE_INT_EN (0x01 << 0)
#define BIT_REG_TRX_EXCEPTION_INT_EN (0x01 << 1)
#define BIT_REG_TX_PUSH_ERR_INT_EN (0x01 << 4)
#define BIT_REG_TX_POP_ERR_INT_EN (0x01 << 5)
#define BIT_REG_RX_PUSH_ERR_INT_EN (0x01 << 6)
#define BIT_REG_RX_POP_ERR_INT_EN (0x01 << 7)
#define BIT_REG_DMA_DONE_INT_EN (0x01 << 8)
#define BIT_REG_DMA_E_TERM_INT_EN (0x01 << 9)
#define BITS_SPI_NAND_INT_EN_ALL (BIT_REG_TRX_DONE_INT_EN | BIT_REG_TRX_EXCEPTION_INT_EN \
| BIT_REG_TX_PUSH_ERR_INT_EN | BIT_REG_TX_POP_ERR_INT_EN \
| BIT_REG_RX_PUSH_ERR_INT_EN | BIT_REG_RX_POP_ERR_INT_EN \
| BIT_REG_DMA_DONE_INT_EN | BIT_REG_DMA_E_TERM_INT_EN)
#define REG_SPI_NAND_INT_CLR 0x014
#define BIT_REG_TRX_DONE_INT_CLR (0x01 << 0)
#define BIT_REG_TRX_EXCEPTION_INT_CLR (0x01 << 1)
#define BIT_REG_TX_PUSH_ERR_INT_CLR (0x01 << 4)
#define BIT_REG_TX_POP_ERR_INT_CLR (0x01 << 5)
#define BIT_REG_RX_PUSH_ERR_INT_CLR (0x01 << 6)
#define BIT_REG_RX_POP_ERR_INT_CLR (0x01 << 7)
#define BIT_REG_DMA_DONE_INT_CLR (0x01 << 8)
#define BIT_REG_DMA_E_TERM_INT_CLR (0x01 << 9)
#define BITS_SPI_NAND_INT_CLR_ALL (BIT_REG_TRX_DONE_INT_CLR | BIT_REG_TRX_EXCEPTION_INT_CLR \
| BIT_REG_TX_PUSH_ERR_INT_CLR | BIT_REG_TX_POP_ERR_INT_CLR \
| BIT_REG_RX_PUSH_ERR_INT_CLR | BIT_REG_RX_POP_ERR_INT_CLR \
| BIT_REG_DMA_DONE_INT_CLR | BIT_REG_DMA_E_TERM_INT_CLR)
#define REG_SPI_NAND_INT_MASK 0x018
#define BIT_REG_TRX_DONE_INT_MSK (0x01 << 0)
#define BIT_REG_TRX_EXCEPTION_INT_MSK (0x01 << 1)
#define BIT_REG_TX_PUSH_ERR_INT_MSK (0x01 << 4)
#define BIT_REG_TX_POP_ERR_INT_MSK (0x01 << 5)
#define BIT_REG_RX_PUSH_ERR_INT_MSK (0x01 << 6)
#define BIT_REG_RX_POP_ERR_INT_MSK (0x01 << 7)
#define BIT_REG_DMA_DONE_INT_MSK (0x01 << 8)
#define BIT_REG_DMA_E_TERM_INT_MSK (0x01 << 9)
#define BITS_SPI_NAND_INT_MASK_ALL (BIT_REG_TRX_DONE_INT_MSK | BIT_REG_TRX_EXCEPTION_INT_MSK \
| BIT_REG_TX_PUSH_ERR_INT_MSK | BIT_REG_TX_POP_ERR_INT_MSK \
| BIT_REG_RX_PUSH_ERR_INT_MSK | BIT_REG_RX_POP_ERR_INT_MSK \
| BIT_REG_DMA_DONE_INT_MSK | BIT_REG_DMA_E_TERM_INT_MSK)
#define REG_SPI_NAND_INT 0x01C
#define BIT_REG_TRX_DONE_INT (0x01 << 0)
#define BIT_REG_TRX_EXCEPTION_INT (0x01 << 1)
#define BIT_REG_TX_PUSH_ERR_INT (0x01 << 4)
#define BIT_REG_TX_POP_ERR_INT (0x01 << 5)
#define BIT_REG_RX_PUSH_ERR_INT (0x01 << 6)
#define BIT_REG_RX_POP_ERR_INT (0x01 << 7)
#define BIT_REG_DMA_DONE_INT (0x01 << 8)
#define BIT_REG_DMA_E_TERM_INT (0x01 << 9)
#define BITS_REG_TRX_DMA_DONE_INT (BIT_REG_TRX_DONE_INT | BIT_REG_DMA_DONE_INT)
#define REG_SPI_NAND_INT_RAW 0x020
#define BIT_REG_TRX_DONE_INT_RAW (0x01 << 0)
#define BIT_REG_TRX_EXCEPTION_INT_RAW (0x01 << 1)
#define BIT_REG_TX_PUSH_ERR_INT_RAW (0x01 << 4)
#define BIT_REG_TX_POP_ERR_INT_RAW (0x01 << 5)
#define BIT_REG_RX_PUSH_ERR_INT_RAW (0x01 << 6)
#define BIT_REG_RX_POP_ERR_INT_RAW (0x01 << 7)
#define BIT_REG_DMA_DONE_INT_RAW (0x01 << 8)
#define BIT_REG_DMA_E_TERM_INT_RAW (0x01 << 9)
#define REG_SPI_NAND_BOOT_CTRL 0x024
#define BIT_REG_BOOT_PRD (0x01 << 0)
#define SPI_NAND_BOOT_SAMPLE_MASK (0xFFFFFFFE)
#define BIT_REG_RSP_DLY_SEL (0x01 << 8)
#define BIT_REG_RSP_NEG_SEL (0x01 << 12)
#define REG_SPI_NAND_IO_CTRL 0x028
#define BIT_REG_CSN0_OUT_OW_EN (0x01 << 0)
#define BIT_REG_CSN1_OUT_OW_EN (0x01 << 1)
#define BIT_REG_SCK_OUT_OW_EN (0x01 << 3)
#define BIT_REG_MOSI_OUT_OW_EN (0x01 << 4)
#define BIT_REG_MISO_OUT_OW_EN (0x01 << 5)
#define BIT_REG_WPN_OUT_OW_EN (0x01 << 6)
#define BIT_REG_HOLDN_OUT_OW_EN (0x01 << 7)
#define BIT_REG_CSN0_OUT_OW_VAL (0x01 << 8)
#define BIT_REG_CSN1_OUT_OW_VAL (0x01 << 9)
#define BIT_REG_SCK_OUT_OW_VAL (0x01 << 11)
#define BIT_REG_MOSI_OUT_OW_VAL (0x01 << 12)
#define BIT_REG_MISO_OUT_OW_VAL (0x01 << 13)
#define BIT_REG_WPN_OUT_OW_VAL (0x01 << 14)
#define BIT_REG_HOLDN_OUT_OW_VAL (0x01 << 15)
#define BIT_REG_CSN0_OEN_OW_EN (0x01 << 16)
#define BIT_REG_CSN1_OEN_OW_EN (0x01 << 17)
#define BIT_REG_SCK_OEN_OW_EN (0x01 << 19)
#define BIT_REG_MOSI_OEN_OW_EN (0x01 << 20)
#define BIT_REG_MISO_OEN_OW_EN (0x01 << 21)
#define BIT_REG_WPN_OEN_OW_EN (0x01 << 22)
#define BIT_REG_HOLDN_OEN_OW_EN (0x01 << 23)
#define BIT_REG_CSN0_OEN_OW_VAL (0x01 << 24)
#define BIT_REG_CSN1_OEN_OW_VAL (0x01 << 25)
#define BIT_REG_SCK_OEN_OW_VAL (0x01 << 27)
#define BIT_REG_MOSI_OEN_OW_VAL (0x01 << 28)
#define BIT_REG_MISO_OEN_OW_VAL (0x01 << 29)
#define BIT_REG_WPN_OEN_OW_VAL (0x01 << 30)
#define BIT_REG_HOLDN_OEN_OW_VAL (0x01 << 31)
#define REG_SPI_NAND_IO_STATUS 0x02C
#define BIT_REG_CSN0_VAL (0x01 << 0)
#define BIT_REG_CSN1_VAL (0x01 << 1)
#define BIT_REG_SCK_VAL (0x01 << 3)
#define BIT_REG_MOSI_VAL (0x01 << 4)
#define BIT_REG_MISO_VAL (0x01 << 5)
#define BIT_REG_WPN_VAL (0x01 << 6)
#define BIT_REG_HOLDN_VAL (0x01 << 7)
#define REG_SPI_NAND_TRX_CMD0 0x30
#define BIT_REG_TRX_CMD_IDX (0x01 << 0)
#define BIT_REG_TRX_CMD_CONT0 (0x01 << 8)
#define TRX_CMD_CONT0_SHIFT (8)
#define REG_SPI_NAND_TRX_CMD1 0x034
//#define BIT_REG_TRX_CMD_CONT1 (0x01 << 0)
#define REG_SPI_NAND_TRX_CS 0x3C
#define BIT_REG_TRX_CS_SEL (0x01 << 0)
#define REG_SPI_NAND_TRX_DMA_CTRL 0x40
#define BIT_REG_DMA_WT_TH (0x01 << 0)
#define BIT_REG_DMA_RD_TH (0x01 << 8)
#define BIT_REG_DMA_REQ_SIZE (0x01 << 16)
#define BIT_REG_DMA_TX_EMPTY_SEL (0x01 << 24)
#define BIT_REG_DMA_RX_FULL_SEL (0x01 << 25)
#define REG_SPI_NAND_TRX_DMA_STATUS 0x44
#define BIT_REG_DMA_REQ (0x01 << 0)
#define BIT_REG_DMA_SINGLE (0x01 << 1)
#define BIT_REG_DMA_LAST (0x01 << 2)
#define BIT_REG_DMA_ACK (0x01 << 3)
#define BIT_REG_DMA_FINISH (0x01 << 4)
#define REG_SPI_NAND_TRX_DMA_SW 0x48
#define BIT_REG_DMA_SW_MODE (0x01 << 0)
#define BIT_REG_DMA_SW_ACK (0x01 << 8)
#define BIT_REG_DMA_SW_FINISH (0x01 << 9)
#define REG_SPI_NAND_TX_FIFO_STATUS 0x50
#define BIT_REG_TX_PUSH_EMPTY (0x01 << 0)
#define BIT_REG_TX_PUSH_AE (0x01 << 1)
#define BIT_REG_TX_PUSH_HF (0x01 << 2)
#define BIT_REG_TX_PUSH_AF (0x01 << 3)
#define BIT_REG_TX_PUSH_FULL (0x01 << 4)
#define BIT_REG_TX_PUSH_ERROR (0x01 << 5)
#define BIT_REG_TX_PUSH_WORD_COUNT (0x01 << 8)
#define BIT_REG_TX_POP_EMPTY (0x01 << 16)
#define BIT_REG_TX_POP_AE (0x01 << 17)
#define BIT_REG_TX_POP_HF (0x01 << 18)
#define BIT_REG_TX_POP_AF (0x01 << 19)
#define BIT_REG_TX_POP_FULL (0x01 << 20)
#define BIT_REG_TX_POP_ERROR (0x01 << 21)
#define BIT_REG_TX_POP_WORD_COUNT (0x01 << 24)
#define REG_SPI_NAND_RX_FIFO_STATUS 0x54
#define BIT_REG_RX_PUSH_EMPTY (0x01 << 0)
#define BIT_REG_RX_PUSH_AE (0x01 << 1)
#define BIT_REG_RX_PUSH_HF (0x01 << 2)
#define BIT_REG_RX_PUSH_AF (0x01 << 3)
#define BIT_REG_RX_PUSH_FULL (0x01 << 4)
#define BIT_REG_RX_PUSH_ERROR (0x01 << 5)
#define BIT_REG_RX_PUSH_WORD_COUNT (0x01 << 8)
#define BIT_REG_RX_POP_EMPTY (0x01 << 16)
#define BIT_REG_RX_POP_AE (0x01 << 17)
#define BIT_REG_RX_POP_HF (0x01 << 18)
#define BIT_REG_RX_POP_AF (0x01 << 19)
#define BIT_REG_RX_POP_FULL (0x01 << 20)
#define BIT_REG_RX_POP_ERROR (0x01 << 21)
#define BIT_REG_RX_POP_WORD_COUNT (0x01 << 24)
#define REG_SPI_NAND_CMPLT_BYTE_CNT 0x58
#define BIT_REG_CMPLT_CNT (0x01 << 0)
#define REG_SPI_NAND_TX_DATA 0x60
#define BIT_REG_TX_DATA (0x01 << 0)
#define REG_SPI_NAND_RX_DATA 0x64
#define BIT_REG_RX_DATA (0x01 << 0)
#define REG_SPI_NAND_RSP_POLLING 0x68
#define BIT_REG_RSP_EXP_MSK (0x01 << 0)
#define BIT_REG_RSP_EXP_VAL (0x01 << 8)
#define BIT_REG_RSP_WAIT_TIME_OFFSET (16)
#define REG_SPI_NAND_SPARE0 0x70
#define BIT_REG_SPARE0 (0x01 << 0)
#define REG_SPI_NAND_SPARE1 0x74
#define BIT_REG_SPARE1 (0x01 << 0)
#define REG_SPI_NAND_SPARE_RO 0x78
#define BIT_REG_SPARE_RO (0x01 << 0)
#define REG_SPI_NAND_TX_FIFO 0x800
#define BIT_REG_TX_FIFO (0x01 << 0)
#define REG_SPI_NAND_RX_FIFO 0xC00
#define BIT_REG_RX_FIFO (0x01 << 0)
#define SPI_NAND_ID_GD5F1GQ4U 0xD1C8 // SPI NAND 1Gbit 3.3V
#define SPI_NAND_ID_GD5F1GQ4R 0xC1C8 // SPI NAND 1Gbit 1.8V
#define SPI_NAND_BLOCK_RA_SHIFT (6) // RA<15:6>
#define SPI_NAND_BLOCK_RA_NUM (10) // RA<15:6>
#define SPI_NAND_PAGE_RA_NUM (6) // RA<5:0>
#define SPI_NAND_PAGE_SIZE (2048)
/*
* P_FAIL : Program Fail
* This bit indicates that a program failure has occurred (P_FAIL set to 1). It will also be
* set if the user attempts to program an invalid address or a protected region, including
* the OTP area. This bit is cleared during the PROGRAM EXECUTE command
* sequence or a RESET command (P_FAIL = 0).
*
* E_FAIL : Erase Fail
* This bit indicates that an erase failure has occurred (E_FAIL set to 1). It will also be
* set if the user attempts to erase a locked region. This bit is cleared (E_FAIL = 0) at the
* start of the BLOCK ERASE command sequence or the RESET command.
*
* WEL : Write Enable Latch
* This bit indicates the current status of the write enable latch (WEL) and must be set
* (WEL = 1), prior to issuing a PROGRAM EXECUTE or BLOCK ERASE command. It
* is set by issuing the WRITE ENABLE command. WEL can also be disabled (WEL =
* 0), by issuing the WRITE DISABLE command.
*
* OIP : Operation In Progress
* This bit is set (OIP = 1 ) when a PROGRAM EXECUTE, PAGE READ, BLOCK
* ERASE, or RESET command is executing, indicating the device is busy. When the bit
* is 0, the interface is in the ready state
*
* Register Addr. 7 6 5 4 3 2 1 0
* Status C0H Reserved Reserved ECCS1 ECCS0 P_FAIL E_FAIL WEL OIP
* Status F0H Reserved Reserved ECCSE1 ECCSE0 Reserved Reserved Reserved Reserved
*
* ECCS1 ECCS0 ECCSE1 ECCSE0 Description
* 0 0 x x No bit errors were detected during the previous read algorithm.
* 0 1 0 0 Bit errors(<4) were detected and corrected.
* 0 1 0 1 Bit errors(=5) were detected and corrected.
* 0 1 1 0 Bit errors(=6) were detected and corrected.
* 0 1 1 1 Bit errors(=7) were detected and corrected.
* 1 0 x x Bit errors greater than ECC capability(8 bits) and not corrected
* 1 1 x x Bit errors reach ECC capability( 8 bits) and corrected
*/
#define ECC_NOERR 0
#define ECC_CORR 1
#define ECC_UNCORR 2
#define BBP_LAST_PAGE 0x01
#define BBP_FIRST_PAGE 0x02
#define BBP_FIRST_2_PAGE 0x03
struct spinand_cmd {
uint8_t cmd;
uint32_t n_cmd_cont; /* Number of command content */
uint8_t content[3]; /* Command content */
uint32_t n_dummy; /* Dummy use */
uint32_t n_tx; /* Number of tx bytes */
uint32_t *tx_buf; /* Tx buf */
uint32_t n_rx; /* Number of rx bytes */
uint32_t *rx_buf; /* Rx buf */
uint32_t flags; /* Flags */
};
#define FLAGS_SET_PLANE_BIT (BIT(0))
#define FLAGS_SET_QE_BIT (BIT(1))
#define FLAGS_ENABLE_X2_BIT (BIT(2))
#define FLAGS_ENABLE_X4_BIT (BIT(3))
#define FLAGS_OW_SETTING_BIT (BIT(4)) // overwrite setting from sysvec
#define FIP_IMAGE_HEAD "FIPH" /* FIP Image Header 1 */
#define FIP_IMAGE_BODY "FIPB" /* FIP Image body */
#define FIP_MAGIC_NUMBER "CVBL01\n\0"
#define FIP_BK_TAG_SIZE 4
struct block_header_t {
uint8_t tag[FIP_BK_TAG_SIZE];
uint32_t bk_cnt_or_seq; /* for first block, it is page count. Otherwise, it is sequence number */
uint32_t checknum; /* the check number to make sure all fip header and body are consistent */
uint32_t dummy;
};
struct block_info_t {
uint8_t used;
uint8_t blk_idx;
uint16_t dummy;
uint32_t checknum;
};
uint16_t cv_spi_nand_read_id(void);
uint8_t cv_spi_nand_query_ecc_en_status(void);
uint32_t cv_spi_nand_read_page_non_ecc(uint32_t blk_id, uint32_t pg_nr, void *buf, uint32_t len);
void cv_spi_nand_dump_reg(void);
void cv_spi_nand_flash_read_sector(uint32_t addr, uint8_t *buf);
struct spi_nand_info_t *spi_nand_get_nand_info(void);
uint32_t cv_spi_nand_reset(void);
uint32_t cv_spi_nand_init(uint32_t base);
uint32_t cv_spi_nand_read_page_by_row_addr(uint32_t row_addr, void *buf, uint32_t len);
uint32_t cv_spi_nand_read_oob(uint32_t row_addr, void *buf);
void cv_spi_nand_set_qe(uint32_t enable);
void cv_spi_nand_set_default_info(void);
void cv_spi_nand_set_device(struct spi_nand_info_t *info);
struct spi_nand_info_t *cv_spi_nand_get_info(void);
void cv_spi_nand_dump_dma_reg(void);
void cv_spi_nand_current_freq(void);
void cv_spi_nand_phy_init(void);
extern void cv_spi_nand_g_param_init(void);
void spi_nand_downgrade_read_mode(void);
void spi_nand_downgrade_freq(void);
void cv_spi_nand_set_freq(struct spi_nand_info_t nand_info);
int get_nand_info(void);
int cv_spi_nand_read_data(void * buffer, uint32_t offset, uint32_t size);
#endif /* __CV_SPI_NAND_H__ */

View File

@@ -36,6 +36,13 @@ int putchar_l(int c, int level);
#define MSG_INFO MSG_SOH "3"
#define MSG_VERBOSE MSG_SOH "4"
#ifdef FSBL_FASTBOOT
#define ERROR(...)
#define WARN(...)
#define NOTICE(...)
#define INFO(...)
#define VERBOSE(...)
#else
#define ERROR(...) tf_printf(MSG_ERROR " E:" __VA_ARGS__)
#define WARN(...) tf_printf(MSG_WARN " W:" __VA_ARGS__)
#define NOTICE(...) tf_printf(MSG_NOTICE __VA_ARGS__)
@@ -46,6 +53,7 @@ int putchar_l(int c, int level);
#else
#define VERBOSE(...)
#endif
#endif
void __dead2 do_panic(void);
#define panic() do_panic()

View File

@@ -104,7 +104,7 @@ call_with_eret:
eret
b .
.global disable_mmu_el3
func disable_mmu_el3
mov x1, #(SCTLR_M_BIT | SCTLR_C_BIT)
do_disable_mmu:
@@ -116,6 +116,7 @@ do_disable_mmu:
ret
endfunc disable_mmu_el3
.global disable_mmu_icache_el3
func disable_mmu_icache_el3
mov x1, #(SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_I_BIT)
b do_disable_mmu

View File

@@ -5,6 +5,51 @@
#include <aarch64/bl2_helper.h>
#include <bl2.h>
#include <delay_timer.h>
#include <mmio.h>
#define GICD_BASE 0x01F01000U
#define GICC_BASE 0x01F02000U
/*
* Hand the GIC over to a non-secure single-OS image (RT-Thread et al).
*
* Scope: AArch64 only — this file is compiled solely for BOOT_CPU=aarch64
* (Makefile includes lib/cpu/${BOOT_CPU}/cpu.mk), and the only caller is
* jump_to_loader_2nd() below, i.e. the direct-jump path taken when the fip
* carries no monitor (load_monitor() leaves monitor_entry at 0). Monitor
* flows (dual-OS / BL31) go jump_to_monitor() -> jump_bl31() and never reach
* this code, since the monitor reconfigures the GIC itself.
*
* Why it must happen here, at EL3: GICD_IGROUPR and GICD_NSACR for SGI/PPI
* are banked-secure registers. GIC reset state puts every interrupt in
* Group0 (secure, FIQ-only), and the NS-side driver (e.g. RT-Thread's
* libcpu/aarch64 gic.c, running at EL1) cannot move them to Group1 — its
* IGROUPR writes are ignored. Only secure EL3 can do the hand-off, so if it
* is skipped the NS image boots with no interrupts at all (no tick).
*/
static void gic_secure_init_for_ns_el1(void)
{
unsigned int i;
mmio_write_32(GICD_BASE + 0x000, 0x0);
/* Make all SGI/PPI/SPI Group1 so NS EL1 can receive them as IRQ. */
for (i = 0; i < 5; i++) {
mmio_write_32(GICD_BASE + 0x080 + i * 4, 0xffffffff);
}
/* Let NS access SGI/PPI control where GICv2 security extension enforces it. */
mmio_write_32(GICD_BASE + 0x0e00, 0xffffffff); /* NSACR0 */
mmio_write_32(GICD_BASE + 0x000, 0x3);
mmio_write_32(GICC_BASE + 0x004, 0xff);
mmio_write_32(GICC_BASE + 0x008, 0x7);
mmio_write_32(GICC_BASE + 0x000, 0x3);
__asm__ volatile ("dsb sy; isb" ::: "memory");
}
void switch_el3_to_el2_ns(uintptr_t bl2_entry)
{
@@ -161,6 +206,8 @@ void switch_el3_to_el2_ns(uintptr_t bl2_entry)
ATF_STATE = ATF_STATE_BL2_MAIN + 1;
time_records->fsbl_exit = read_time_ms();
gic_secure_init_for_ns_el1();
call_with_eret(bl2_entry);
ATF_STATE = ATF_STATE_BL2_MAIN + 2;

0
fsbl/lib/lzma/lzma.c Normal file
View File

View File

@@ -107,6 +107,10 @@ void tf_printf(const char *fmt, ...)
int level = LOG_LEVEL;
#ifdef FSBL_FASTBOOT
return;
#endif
#if PRINTF_TIMESTAMP
const uint32_t ts = read_count_tick();
#endif

View File

@@ -118,7 +118,9 @@ int decompress_lz4(void *dst, size_t *dst_size, const void *src, size_t src_size
ERROR("LZ4F_decompress=%lu\n", ret);
return -1;
}
#ifdef FSBL_FASTBOOT
(void)(ret);
#endif
// No need to free.
// LZ4F_freeDecompressionContext(dctx);

View File

@@ -273,7 +273,7 @@ $(DUMP): $(ELF)
$(BIN): $(ELF)
@echo " BIN $$@"
$$(Q)$$(OC) -O binary $$< $$@
$$(Q)$$(OC) -O binary -R .suspend_sect $$< $$@
@${ECHO_BLANK_LINE}
@echo "Built $$@ successfully"
@${ECHO_BLANK_LINE}

View File

@@ -12,17 +12,39 @@ else ifeq (${BOOT_CPU},riscv)
MONITOR_PATH = ../opensbi/build/platform/generic/firmware/fw_dynamic.bin
endif
ifeq (${ENABLE_BURN_BUTTON},y)
LOADER_2ND_PATH_B=${UBOOT_PATH}/${UBOOT_OUTPUT_FOLDER}/u-boot-raw.bin
else
LOADER_2ND_PATH_B=
endif
fip%: export BLCP_IMG_RUNADDR=0x05200200
fip%: export BLCP_PARAM_LOADADDR=0
fip%: export NAND_INFO=00000000
ifeq (${FSBL_FASTBOOT},y)
$(eval $(call add_define,FSBL_FASTBOOT))
fip%: export NOR_INFO=01C0080000430000A93B060000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
else ifeq (${BUILD_FASTBOOT0},y)
$(eval $(call add_define,ENABLE_FASTBOOT0))
fip%: export NOR_INFO=01C0080000430000A93B060000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
else
fip%: export NOR_INFO=$(shell printf '%72s' | tr ' ' 'FF')
endif
fip%: export DDR_PARAM_TEST_PATH = test/cv181x/ddr_param.bin
# Defaults for keys dir and fipsign script
FIPSIGN_SCRIPT ?= ./plat/${CHIP_ARCH}/fipsign.py
FSBL_KEYS_DIR ?= ./plat/keys
ifeq (${CONFIG_ENABLE_EMMC_HW_RESET_QFN},y)
$(eval $(call add_define,CONFIG_ENABLE_EMMC_HW_RESET_QFN))
endif
${BUILD_PLAT}:
@mkdir -p '${BUILD_PLAT}'
gen-chip-conf:
$(print_target)
${Q}mkdir -p '${BUILD_PLAT}'
${Q}./plat/${CHIP_ARCH}/chip_conf.py ${CHIP_CONF_PATH}
macro_to_env = ${NM} '${BLMACROS_ELF}' | awk '/DEF_${1}/ { rc = 1; print "${1}=0x" $$1 } END { exit !rc }' >> ${BUILD_PLAT}/blmacros.env
@@ -32,11 +54,32 @@ blmacros-env: blmacros
${Q}> ${BUILD_PLAT}/blmacros.env # clear .env first
${Q}$(call macro_to_env,MONITOR_RUNADDR)
${Q}$(call macro_to_env,BLCP_2ND_RUNADDR)
ifeq (${BUILD_BOOT0},y)
$(eval $(call add_define,ENABLE_BOOT0))
fip: fip_boot0
else
fip: fip-all
endif
fip-dep: bl2 blmacros-env gen-chip-conf
fip_boot0: fip-dep
$(print_target)
${Q}echo " [GEN] boot0"
${Q}. ${BUILD_PLAT}/blmacros.env && \
${FIPTOOL} -v genfip \
'${BUILD_PLAT}/boot0' \
--MONITOR_RUNADDR="$${MONITOR_RUNADDR}" \
--BLCP_2ND_RUNADDR="$${BLCP_2ND_RUNADDR}" \
--CHIP_CONF='${CHIP_CONF_PATH}' \
--NOR_INFO='${NOR_INFO}' \
--NAND_INFO='${NAND_INFO}'\
--BL2='${BUILD_PLAT}/bl2.bin'\
--LOADER_2ND_B='${LOADER_2ND_PATH_B}'
${Q}echo " [LS] " $$(ls -l '${BUILD_PLAT}/boot0')
${Q}cp ${BUILD_PLAT}/boot0 ${OUTPUT_DIR}
fip-simple: fip-dep
$(print_target)
${Q}echo " [GEN] fip.bin"
@@ -63,9 +106,61 @@ fip-all: fip-dep
--BLCP_IMG_RUNADDR=${BLCP_IMG_RUNADDR} \
--BLCP_PARAM_LOADADDR=${BLCP_PARAM_LOADADDR} \
--BLCP=${BLCP_PATH} \
--DDR_PARAM='${DDR_PARAM_TEST_PATH}' \
--BLCP_2ND='${BLCP_2ND_PATH}' \
--MONITOR='${MONITOR_PATH}' \
--LOADER_2ND='${LOADER_2ND_PATH}' \
--compress='${FIP_COMPRESS}'\
--LOADER_2ND_B='${LOADER_2ND_PATH_B}'
${Q}echo " [LS] " $$(ls -l '${BUILD_PLAT}/fip.bin')
--compress='${FIP_COMPRESS}'
${Q}echo " [LS] " $$(ls -l '${BUILD_PLAT}/fip.bin')
ifeq (${FSBL_SECURE_BOOT_SUPPORT},1)
.PHONY: fip-sign fip-sign-enc boot0-sign boot0-sign-enc
ifeq (${BUILD_BOOT0},y)
fip:boot0-sign boot0-sign-enc
boot0-sign: fip_boot0
$(print_target)
${Q}echo " [SIGN] boot0 -> boot0_signed"
${Q}python3 ${FIPSIGN_SCRIPT} sign \
--root-priv='${FSBL_KEYS_DIR}/rsa_hash0.pem' \
--bl-priv='${FSBL_KEYS_DIR}/bl_priv.pem' \
'${BUILD_PLAT}/boot0' \
'${BUILD_PLAT}/boot0_signed'
${Q}echo " [LS] " $$(ls -l '${BUILD_PLAT}/boot0_signed')
boot0-sign-enc: fip_boot0
$(print_target)
${Q}echo " [SIGN-ENC] boot0 -> boot0_signed_enc"
${Q}python3 ${FIPSIGN_SCRIPT} sign-enc \
--root-priv='${FSBL_KEYS_DIR}/rsa_hash0.pem' \
--bl-priv='${FSBL_KEYS_DIR}/bl_priv.pem' \
--ldr-ek='${FSBL_KEYS_DIR}/root_ek.key' \
--bl-ek='${FSBL_KEYS_DIR}/bl_ek.key' \
'${BUILD_PLAT}/boot0' \
'${BUILD_PLAT}/boot0_signed_enc'
${Q}echo " [LS] " $$(ls -l '${BUILD_PLAT}/boot0_signed')
else
fip:fip-sign fip-sign-enc
fip-sign: fip-all
$(print_target)
${Q}echo " [SIGN] fip.bin -> fip_signed.bin"
${Q}python3 ${FIPSIGN_SCRIPT} sign \
--root-priv='${FSBL_KEYS_DIR}/rsa_hash0.pem' \
--bl-priv='${FSBL_KEYS_DIR}/bl_priv.pem' \
'${BUILD_PLAT}/fip.bin' \
'${BUILD_PLAT}/fip_signed.bin'
${Q}echo " [LS] " $$(ls -l '${BUILD_PLAT}/fip_signed.bin')
fip-sign-enc: fip-all
$(print_target)
${Q}echo " [SIGN-ENC] fip.bin -> fip_signed_enc.bin"
${Q}python3 ${FIPSIGN_SCRIPT} sign-enc \
--root-priv='${FSBL_KEYS_DIR}/rsa_hash0.pem' \
--bl-priv='${FSBL_KEYS_DIR}/bl_priv.pem' \
--ldr-ek='${FSBL_KEYS_DIR}/root_ek.key' \
--bl-ek='${FSBL_KEYS_DIR}/bl_ek.key' \
'${BUILD_PLAT}/fip.bin' \
'${BUILD_PLAT}/fip_signed_enc.bin'
${Q}echo " [LS] " $$(ls -l '${BUILD_PLAT}/fip_signed_enc.bin')
endif
endif

View File

@@ -17,6 +17,8 @@ ENTRY(bl2_entrypoint)
MEMORY {
RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_SIZE
SRAM (rwx): ORIGIN = TPU_SRAM_BASE, LENGTH = TPU_SRAM_SIZE
}
SECTIONS
@@ -80,5 +82,17 @@ SECTIONS
ASSERT(. <= (BL2_BASE + BL2_SIZE), "BL2 image has exceeded its limit.")
.suspend_sect :
{
. = ALIGN(8);
__suspend_sect_start = .;
KEEP(*(.suspend_entry))
KEEP(*(.suspend_func))
. = ALIGN(8);
__suspend_data_start = .;
KEEP(*(.suspend_data))
. = ALIGN(8);
__suspend_sect_end = .;
} > SRAM
#include <rom_api_refer.h>
}

View File

@@ -5,6 +5,8 @@
#include <string.h>
#include <delay_timer.h>
enum CHIP_CLK_MODE chip_clk_mode = CLK_ND;
#ifdef RTOS_ENABLE_FREERTOS
int init_comm_info(int ret)
{
@@ -64,16 +66,29 @@ void bl2_main(void)
setup_dl_flag();
#ifdef SWITCH_32K_XTAL
switch_rtc_mode_1st_stage();
#endif
set_rtc_en_registers();
load_ddr();
#ifdef OD_CLK_SEL
load_rest_od_sel();
chip_clk_mode = CLK_OD;
#else
load_rest();
#ifdef VC_CLK_OVERDRIVE
chip_clk_mode = CLK_VC_OD;
#endif
#endif
#ifdef CONFIG_SUSPEND
#ifndef NO_DDR_CFG //for fpga
jump_to_warmboot_entry();
#endif
#endif
load_ddr();
load_rest();
NOTICE("BL2 end.\n");

View File

@@ -11,11 +11,18 @@
#include <rom_api.h>
#include <bl2.h>
#include <ddr.h>
#include <ddr_sys.h>
#include <rtc.h>
#include <string.h>
#include <decompress.h>
#include <delay_timer.h>
#include <security/security.h>
#include <cv_usb.h>
#include <cv_spi_nand.h>
uint64_t load_addr = 0x0c000;
uint64_t run_addr = 0x8000C000;
uint64_t reading_size = 0x020000;
struct _time_records *time_records = (void *)TIME_RECORDS_ADDR;
struct fip_param1 *fip_param1 = (void *)PARAM1_BASE;
@@ -132,53 +139,17 @@ int load_param2(int retry)
return 0;
}
int load_ddr_param(int retry)
{
uint32_t crc;
int ret = -1;
NOTICE("DPS/0x%x/0x%x.\n", fip_param2.ddr_param_loadaddr, fip_param2.ddr_param_size);
if (fip_param2.ddr_param_size >= sizeof(sram_union_buf.ddr_param))
fip_param2.ddr_param_size = sizeof(sram_union_buf.ddr_param);
#ifdef USB_DL_BY_FSBL
if (p_rom_api_get_boot_src() == BOOT_SRC_USB)
ret = load_image_by_usb(&sram_union_buf.ddr_param, fip_param2.ddr_param_loadaddr,
fip_param2.ddr_param_size, retry);
else
#endif
ret = p_rom_api_load_image(&sram_union_buf.ddr_param, fip_param2.ddr_param_loadaddr,
fip_param2.ddr_param_size, retry);
if (ret < 0) {
return ret;
}
crc = p_rom_api_image_crc(&sram_union_buf.ddr_param, fip_param2.ddr_param_size);
if (crc != fip_param2.ddr_param_cksum) {
ERROR("ddr_param_cksum (0x%x/0x%x)\n", crc, fip_param2.ddr_param_cksum);
return -1;
}
NOTICE("DPE.\n");
return 0;
}
int load_ddr(void)
{
#ifndef ENABLE_BOOT0
int retry = 0;
retry_from_flash:
for (retry = 0; retry < p_rom_api_get_number_of_retries(); retry++) {
if (load_param2(retry) < 0)
continue;
if (load_ddr_param(retry) < 0)
continue;
break;
}
if (retry >= p_rom_api_get_number_of_retries()) {
switch (p_rom_api_get_boot_src()) {
case BOOT_SRC_UART:
@@ -189,11 +160,11 @@ retry_from_flash:
p_rom_api_flash_init();
goto retry_from_flash;
default:
ERROR("Failed to load DDR param (%d).\n", retry);
ERROR("Failed to load param2 (%d).\n", retry);
panic_handler();
}
}
#endif
time_records->ddr_init_start = read_time_ms();
ddr_init(&sram_union_buf.ddr_param);
time_records->ddr_init_end = read_time_ms();
@@ -256,12 +227,20 @@ int load_blcp_2nd(int retry)
rtos_base = mmio_read_32(AXI_SRAM_RTOS_BASE);
init_comm_info(0);
switch (p_rom_api_get_boot_src()) {
case BOOT_SRC_UART:
// case BOOT_SRC_SD:
// case BOOT_SRC_USB:
break;
default:
time_records->release_blcp_2nd = read_time_ms();
if (rtos_base == CVI_RTOS_MAGIC_CODE) {
mmio_write_32(AXI_SRAM_RTOS_BASE, fip_param2.blcp_2nd_runaddr);
} else {
reset_c906l(fip_param2.blcp_2nd_runaddr);
}
}
NOTICE("C2E.\n");
@@ -427,6 +406,130 @@ int load_loader_2nd(int retry, uint64_t *loader_2nd_entry)
return 0;
}
#ifndef NO_DDR_CFG //for fpga
static void *get_warmboot_entry(void)
{
/*
* "FSM state change to ST_ON from the state
* 4'h0 = state changed from ST_OFF to ST_ON
* 4'h3 = state changed to ST_PWR_CYC or ST_WARM_RESET then back to ST_ON
* 4'h9 = state changed from ST_SUSP to ST_ON
*/
#define WANTED_STATE SYS_RESUME
NOTICE("\nREG_RTC_ST_ON_REASON=0x%x\n", mmio_read_32(REG_RTC_ST_ON_REASON));
NOTICE("\nRTC_SRAM_FLAG_ADDR%x=0x%x\n", RTC_SRAM_FLAG_ADDR, mmio_read_32(RTC_SRAM_FLAG_ADDR));
/* Check if RTC state changed from ST_SUSP */
if ((mmio_read_32(REG_RTC_ST_ON_REASON) & 0xF) == WANTED_STATE)
return (void *)(uintptr_t)mmio_read_32(RTC_SRAM_FLAG_ADDR);
return 0;
}
#endif
int load_loader_2nd_alios(int retry, uint64_t *loader_2nd_entry)
{
void *image_buf;
int ret = -1;
#ifdef BOOT_SPINOR
load_addr = 0x0c000;
#endif
#ifdef BOOT_EMMC
load_addr = 0x00000;
#endif
#ifdef BOOT_SPINAND
load_addr = 0x280000;
#endif
uint64_t loadaddr_alios = load_addr;
uint64_t runaddr_alios = run_addr;
uint64_t size_alios = reading_size;
image_buf = (void *)runaddr_alios;
NOTICE("loadaddr_alios:0x%lx runaddr_alios:0x%lx.\n", loadaddr_alios, runaddr_alios);
#ifdef BOOT_SPINAND
/* SPI-NAND uses the in-tree raw-read driver: read linearly by physical
* page, bypassing the ROM API FIP (FIPH/fip_vector) scan. The single-image
* RTT boot partition is not in the NAND-FIP layout, so the ROM API returns
* FIP0NC. get_nand_info() self-calibrates the geometry on the first read.
* cv180x has no load_data_from_storage aggregator, so branch here by the
* compile-time medium macro. */
{
static int nand_info_ready;
if (!nand_info_ready) {
get_nand_info();
nand_info_ready = 1;
}
ret = cv_spi_nand_read_data(image_buf, loadaddr_alios, size_alios);
}
#else
ret = p_rom_api_load_image(image_buf, loadaddr_alios, size_alios, retry);
#endif
/* Must check the return value: the original code ignored ret and jumped to
* run_addr executing garbage on a failed load, causing a panic. */
if (ret < 0) {
ERROR("load loader_2nd_alios failed (%d)\n", ret);
return ret;
}
NOTICE("image_buf:0x%lx.\n", *((uint64_t *)runaddr_alios));
if (security_is_tee_enabled()) {
ret = dec_verify_image(image_buf, fip_param2.alios_boot_size, 0, fip_param1);
if (ret < 0) {
ERROR("verify alios boot0 failed (%d)\n", ret);
return ret;
}
}
sys_switch_all_to_pll();
*loader_2nd_entry = run_addr;
return 0;
}
void rtc_set_ddr_pwrok(void)
{
mmio_setbits_32(REG_RTC_BASE + RTC_PG_REG, 0x00000001);
}
void rtc_set_rmio_pwrok(void)
{
mmio_setbits_32(REG_RTC_BASE + RTC_PG_REG, 0x00000002);
}
#ifndef NO_DDR_CFG //for fpga
static void ddr_resume(void)
{
rtc_set_ddr_pwrok();
rtc_set_rmio_pwrok();
ddr_sys_resume();
}
void jump_to_warmboot_entry(void)
{
void (*warmboot_entry)() = get_warmboot_entry();
// treat next reset as normal boot
mmio_write_64(RTC_SRAM_FLAG_ADDR, 0);
if (warmboot_entry) {
INFO("WE=0x%lx\n", (uintptr_t)warmboot_entry);
NOTICE("ddr resume...\n");
ddr_resume();
NOTICE("ddr resume end\n");
sys_pll_init();
sys_switch_all_to_pll();
warmboot_entry();
}
}
#endif
int load_rest(void)
{
int retry = 0;
@@ -435,7 +538,10 @@ int load_rest(void)
// Init sys PLL and switch clocks to PLL
sys_pll_init();
#ifndef ENABLE_BOOT0
#ifdef FSBL_FASTBOOT
mmio_write_32(0x030020B8, 0x00030009); // improve axi clock from 300m to 500m
#endif
retry_from_flash:
for (retry = 0; retry < p_rom_api_get_number_of_retries(); retry++) {
if (load_blcp_2nd(retry) < 0)
@@ -465,65 +571,27 @@ retry_from_flash:
}
}
#ifdef FSBL_FASTBOOT
mmio_write_32(0x030020B8, 0x00050009); // restore axi clock from 500m to 300m
#endif
sync_cache();
console_flush();
switch_rtc_mode_2nd_stage();
if (monitor_entry) {
NOTICE("Jump to monitor at 0x%lx.\n", monitor_entry);
jump_to_monitor(monitor_entry, loader_2nd_entry);
} else {
NOTICE("Jump to loader_2nd at 0x%lx.\n", loader_2nd_entry);
jump_to_loader_2nd(loader_2nd_entry);
}
return 0;
}
int load_rest_od_sel(void)
{
int retry = 0;
uint64_t monitor_entry = 0;
uint64_t loader_2nd_entry = 0;
// Init sys PLL and switch clocks to PLL
sys_pll_init_od_sel();
retry_from_flash:
for (retry = 0; retry < p_rom_api_get_number_of_retries(); retry++) {
if (load_blcp_2nd(retry) < 0)
continue;
if (load_monitor(retry, &monitor_entry) < 0)
continue;
if (load_loader_2nd(retry, &loader_2nd_entry) < 0)
continue;
break;
}
if (retry >= p_rom_api_get_number_of_retries()) {
switch (p_rom_api_get_boot_src()) {
case BOOT_SRC_UART:
case BOOT_SRC_SD:
case BOOT_SRC_USB:
WARN("DL cancelled. Load flash. (%d).\n", retry);
// Continue to boot from flash if boot from external source
p_rom_api_flash_init();
goto retry_from_flash;
default:
ERROR("Failed to load rest (%d).\n", retry);
panic_handler();
}
}
sync_cache();
console_flush();
switch_rtc_mode_2nd_stage();
// switch_rtc_mode_2nd_stage();
#else
#ifdef ENABLE_FASTBOOT0
mmio_write_32(0x030020B8, 0x00030009);
#endif
if (load_loader_2nd_alios(retry, &loader_2nd_entry) < 0)
return -1;
#ifdef ENABLE_FASTBOOT0
mmio_write_32(0x030020B8, 0x00050009);
#endif
sync_cache();
// switch_rtc_mode_2nd_stage();
monitor_entry = run_addr;
#endif
if (monitor_entry) {
NOTICE("Jump to monitor at 0x%lx.\n", monitor_entry);
jump_to_monitor(monitor_entry, loader_2nd_entry);

View File

@@ -0,0 +1,380 @@
#include "cv_spi_nand.h"
#include "mmio.h"
#include <cpu.h>
#include <assert.h>
#include <delay_timer.h>
#include <errno.h>
#include <mmio.h>
#include <platform.h>
#include <string.h>
#include <platform.h>
#include <security/security.h>
static unsigned long spi_nand_ctrl_base = SPINAND_BASE;
/* default value */
static struct spi_nand_info_t spinand_info;
static uint8_t ecc_en_status = 0xff;
#define BASE_SYSDMAC 0x04330000
#define SPI_NAND_INTERRUPT_UDELAY_TIME 10
#define SPI_NAND_INTERRUPT_UDELAY_COUNT (100000000 / SPI_NAND_INTERRUPT_UDELAY_TIME)
#define SPI_NAND_PLANE_BIT_OFFSET BIT(12)
static int spi_nand_set_feature(uint8_t fe, uint8_t val)
{
uint32_t fe_set = fe | (val << 8);
uint32_t retry = 0;
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL2, 2 << TRX_CMD_CONT_SIZE_SHIFT);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL3, BIT_REG_TRX_RW);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CMD0,
(fe_set << TRX_CMD_CONT0_SHIFT) | SPI_NAND_CMD_SET_FEATURE);
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL0, BIT_REG_TRX_START);
while(((mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_INT) & BIT_REG_TRX_DONE_INT) == 0)
&& (retry++ < SPI_NAND_INTERRUPT_UDELAY_COUNT))
udelay(1);
if (retry > SPI_NAND_INTERRUPT_UDELAY_COUNT) {
ERROR("SPINAND command error, no interrupt, %d %s\n", retry, __func__);
//assert(0);
}
// clr trx done intr
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_CLR, BIT_REG_TRX_DONE_INT);
return 0;
}
static void spi_nand_setup_intr(void)
{
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_EN, 3);
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_CLR, BITS_SPI_NAND_INT_CLR_ALL);
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_MASK, 0x00000f00);
}
static uint8_t spi_nand_get_feature(uint32_t fe)
{
uint32_t val = 0;
uint32_t retry = 0;
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL2,
1 << TRX_DATA_SIZE_SHIFT | 1 << TRX_CMD_CONT_SIZE_SHIFT);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL3, 0);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CMD0, fe << 8 | SPI_NAND_CMD_GET_FEATURE);
spi_nand_setup_intr();
// Trigger communication start
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL0, BIT_REG_TRX_START);
while(((mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_INT) & BIT_REG_TRX_DONE_INT) == 0)
&& (retry++ < SPI_NAND_INTERRUPT_UDELAY_COUNT))
udelay(1);
if (retry > SPI_NAND_INTERRUPT_UDELAY_COUNT) {
ERROR("SPINAND command error, no interrupt, %d %s\n", retry, __func__);
}
val = mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_RX_DATA);
uint32_t intr = mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_INT);
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_CLR, intr);
return (val & 0xff);
}
void spi_nand_rw_dma_setup(void *buf, uint32_t len, uint32_t rw)
{
uint32_t ch = 0;
VERBOSE("%s: buf %p, len %d\n", __func__, buf, len);
mmio_write_32(BASE_SYSDMAC + 0x010, 0x00000003);
mmio_write_32(BASE_SYSDMAC + 0x018, 0x00000f00);
mmio_write_32(BASE_SYSDMAC + 0x110 + ch * (0x100), (len / 4) - 1);
mmio_write_32(BASE_SYSDMAC + 0x11C + ch * (0x100), 0x000f0792);
buf = (void *)phys_to_dma((uintptr_t) buf);
if (rw) {
// for dma write
mmio_write_64(BASE_SYSDMAC + 0x100 + ch * (0x100), (uint64_t) buf);
mmio_write_64(BASE_SYSDMAC + 0x108 + ch * (0x100), spi_nand_ctrl_base + 0x800);
mmio_write_32(BASE_SYSDMAC + 0x118 + ch * (0x100), 0x00045441);
// [0:2] = 1 : MEM_TO_PER_DMAC, PER dst = 0
mmio_write_32(BASE_SYSDMAC + 0x124 + ch * (0x100), 0x00000001);
mmio_write_32(0x03000154, 0x26); //PER dst = 0 => remap ch0
mmio_setbits_32(0x03000154, BIT(31)); // set sdma remap update bit
VERBOSE("0x100: 0x%lx\n", mmio_read_64(BASE_SYSDMAC + 0x100 + ch * (0x100)));
VERBOSE("0x108: 0x%lx\n", mmio_read_64(BASE_SYSDMAC + 0x108 + ch * (0x100)));
} else {
mmio_write_64(BASE_SYSDMAC + 0x100 + ch * (0x100), spi_nand_ctrl_base + 0xC00);
mmio_write_64(BASE_SYSDMAC + 0x108 + ch * (0x100), (uint64_t)buf);
mmio_write_32(BASE_SYSDMAC + 0x118 + ch * (0x100), 0x00046214);
// [0:2] = 2 : PER_TO_MEM_DMAC, PER src = 0
mmio_write_32(BASE_SYSDMAC + 0x124 + ch * (0x100), 0x00000002);
mmio_write_32(0x03000154, 0x26); //PER src = 0 => remap ch0
mmio_setbits_32(0x03000154, BIT(31)); // set sdma remap update bit
VERBOSE("0x100: 0x%lx\n", mmio_read_64(BASE_SYSDMAC + 0x100 + ch * (0x100)));
VERBOSE("0x108: 0x%lx\n", mmio_read_64(BASE_SYSDMAC + 0x108 + ch * (0x100)));
}
mmio_write_32(BASE_SYSDMAC + 0x120 + ch * (0x100), 0x0);
mmio_write_32(BASE_SYSDMAC + 0x018, 0x00000f0f);
}
static void spi_nand_polling_oip(void)
{
uint32_t status = 0xff;
uint32_t retry = 0;
while ((status & SPI_NAND_STATUS0_OIP) && (retry++ < (SPI_NAND_INTERRUPT_UDELAY_COUNT * 10))) {
status = spi_nand_get_feature(spinand_info.ecc_status_offset);
udelay(1);
}
if (retry > (SPI_NAND_INTERRUPT_UDELAY_COUNT * 10)) {
ERROR("SPINAND is still busy over 10 sec after reseting spinand %d %s\n", retry, __func__);
//assert(0);
}
}
static void spi_nand_ctrl_ecc(uint8_t enable)
{
uint8_t status;
if ((ecc_en_status == 1) && (enable == 1)) {
VERBOSE("NAND_DEBUG: ecc is already enabled\n");
return;
} else if ((ecc_en_status == 0) && (enable == 0)) {
VERBOSE("NAND_DEBUG: ecc is already disabled\n");
return;
}
status = spi_nand_get_feature(spinand_info.ecc_en_feature_offset);
if (enable) {
spi_nand_set_feature(spinand_info.ecc_en_feature_offset,
status | spinand_info.ecc_en_mask); // set ECC_EN to enable
ecc_en_status = 1;
} else {
spi_nand_set_feature(spinand_info.ecc_en_feature_offset,
status & (~spinand_info.ecc_en_mask)); // set ECC_EN to disable
ecc_en_status = 0;
}
}
static int spi_nand_read_page_by_row_addr(uint32_t row_addr, void *buf, uint32_t len)
{
uint32_t retry = 0;
uint32_t r_row_addr = ((row_addr & 0xff0000) >> 16) | (row_addr & 0xff00) | ((row_addr & 0xff) << 16);
VERBOSE("%s r_row_addr 0x%x\n", __func__, r_row_addr);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL2,
0 << TRX_DATA_SIZE_SHIFT | 3 << TRX_CMD_CONT_SIZE_SHIFT); // 0x8
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL3, 0);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CMD0,
r_row_addr << TRX_CMD_CONT0_SHIFT | SPI_NAND_CMD_PAGE_READ_TO_CACHE);
// Trigger communication start
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL0, BIT_REG_TRX_START);
while(((mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_INT) & BIT_REG_TRX_DONE_INT) == 0)
&& (retry++ < SPI_NAND_INTERRUPT_UDELAY_COUNT))
udelay(1);
if (retry > SPI_NAND_INTERRUPT_UDELAY_COUNT) {
ERROR("SPINAND command error, no interrupt, %d %s\n", retry, __func__);
//assert(0);
}
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_CLR, BIT_REG_TRX_DONE_INT);
spi_nand_polling_oip();
return 0;
}
static void spi_nand_set_read_from_cache_mode(uint32_t col_addr)
{
/*if (spinand_info.flags & FLAGS_ENABLE_X4_BIT) {
VERBOSE("NAND_DEBUG: Read by 4 bit mode\n");
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL3,
BIT_REG_TRX_DMA_EN | SPI_NAND_CTRL3_IO_TYPE_X4_MODE | BIT_REG_TRX_DUMMY_HIZ);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CMD0,
col_addr << TRX_CMD_CONT0_SHIFT | SPI_NAND_CMD_READ_FROM_CACHEX4);
} else if (spinand_info.flags & FLAGS_ENABLE_X2_BIT) {
VERBOSE("NAND_DEBUG: Read by 2 bit mode\n");
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL3,
BIT_REG_TRX_DMA_EN | SPI_NAND_CTRL3_IO_TYPE_X2_MODE | BIT_REG_TRX_DUMMY_HIZ);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CMD0,
col_addr << TRX_CMD_CONT0_SHIFT | SPI_NAND_CMD_READ_FROM_CACHEX2);
} else*/ {
VERBOSE("NAND_DEBUG: Read by 1 bit mode\n");
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL3,
BIT_REG_TRX_DMA_EN | BIT_REG_TRX_DUMMY_HIZ);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CMD0,
col_addr << TRX_CMD_CONT0_SHIFT | SPI_NAND_CMD_READ_FROM_CACHE);
}
return;
}
static int spi_nand_read_from_cache(uint32_t blk_id, uint32_t page_nr, uint32_t col_addr,
uint32_t len, void *buf)
{
uint32_t r_col_addr = ((col_addr & 0xff00) >> 8) | ((col_addr & 0xff) << 8);
VERBOSE("%s col_addr 0x%x, r_col_addr 0x%x\n", __func__, col_addr, r_col_addr);
spi_nand_rw_dma_setup(buf, len, 0);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL2,
len << TRX_DATA_SIZE_SHIFT | 3 << TRX_CMD_CONT_SIZE_SHIFT);
spi_nand_set_read_from_cache_mode(r_col_addr);
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL0, BIT_REG_TRX_START);
while ((mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_INT) & BITS_REG_TRX_DMA_DONE_INT) == 0);
uint32_t intr = mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_INT);
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_CLR, intr);
return 0;
}
#define ECC_NOERR 0
#define ECC_CORR 1
#define ECC_UNCORR 2
uint32_t spi_nand_parsing_ecc_info(uint32_t page)
{
uint32_t statusc0 = spi_nand_get_feature(spinand_info.ecc_status_offset);
uint8_t ecc_sts = (statusc0 & spinand_info.ecc_status_mask) >> spinand_info.ecc_status_shift;
if (ecc_sts) {
VERBOSE("statusc0 0x%x\n", statusc0);
INFO("block %d, page %d, ecc sts : %d!!\n",
page >> spinand_info.pages_per_block_shift, page % spinand_info.pages_per_block, ecc_sts);
}
if (ecc_sts == spinand_info.ecc_status_uncorr_val) {
INFO("ECC UNCORR\n");
return ECC_UNCORR;
}
return ECC_NOERR;
}
static void dump_nand_info(void)
{
INFO("NAND_DEBUG: NAND version=0x%x, id=0x%x\n", spinand_info.version, spinand_info.id);
INFO("NAND_DEBUG: page size=%d, block size=%d, page per block=%d, badblock_pos=%d\n",
spinand_info.page_size, spinand_info.block_size,
spinand_info.pages_per_block, spinand_info.badblock_pos);
VERBOSE("NAND_DEBUG: fip block count=%d, page per block shift=%d, flags=0x%x\n", spinand_info.fip_block_cnt,
spinand_info.pages_per_block_shift, spinand_info.flags);
VERBOSE("NAND_DEBUG: ECC feature offset=0x%x, en mask=0x%x, status offset=0x%x, status mask=0x%x\n",
spinand_info.ecc_en_feature_offset, spinand_info.ecc_en_mask,
spinand_info.ecc_status_offset, spinand_info.ecc_status_mask);
VERBOSE("NAND_DEBUG: ECC status shift=%d, uncorr_val=0x%x, erase count=%d\n", spinand_info.ecc_status_shift,
spinand_info.ecc_status_uncorr_val, spinand_info.erase_count);
VERBOSE("NAND_DEBUG: sck_l=%d, sck_h=0x%x, max_freq=%d\n", spinand_info.sck_l,
spinand_info.sck_h, spinand_info.max_freq);
VERBOSE("NAND_DEBUG: xtal_switch=%d\n", spinand_info.xtal_switch);
}
int get_nand_info(void)
{
uint32_t ret;
uint8_t page_buff[2048] = {0};
struct fip_param1 *fip_param;
spinand_info.id = 0x0;
spinand_info.page_size = 2048;
spinand_info.spare_size = 64;
spinand_info.block_size = 0x20000;
spinand_info.pages_per_block = 64;
spinand_info.fip_block_cnt = 1024;
spinand_info.pages_per_block_shift = 6;
spinand_info.flags = 0;
spinand_info.badblock_pos = BBP_FIRST_PAGE;
spinand_info.ecc_en_feature_offset = SPI_NAND_FEATURE_FEATURE0;
spinand_info.ecc_en_mask = SPI_NAND_FEATURE0_ECC_EN;
spinand_info.ecc_status_offset = SPI_NAND_FEATURE_STATUS0;
spinand_info.ecc_status_mask = 0x30;
spinand_info.ecc_status_shift = 4;
spinand_info.ecc_status_uncorr_val = 0x2;
spinand_info.erase_count = 1;
spinand_info.sck_l = 2;
spinand_info.sck_h = 2;
spinand_info.max_freq = 0;
spinand_info.sample_param = 0x100;
spinand_info.xtal_switch = 0;
ret = cv_spi_nand_read_page_by_row_addr(0, page_buff, 2048);
if (ret) {
ERROR("Scan fip_header fialed!\n");
}
fip_param = (void *)(page_buff + sizeof(struct block_header_t));
/* update spinand info */
memcpy(&spinand_info, &fip_param->nand_info, sizeof(struct spi_nand_info_t));
dump_nand_info();
return 0;
}
uint32_t cv_spi_nand_read_page_by_row_addr(uint32_t row_addr, void *buf, uint32_t len)
{
uint32_t col_addr = 0;
uint32_t blk_id = row_addr >> 6;
VERBOSE("%s, row_addr 0x%x, buf %p, len %d, spinand_info.flags 0x%x\n", __func__, row_addr, buf, len,
spinand_info.flags);
spi_nand_ctrl_ecc(1);
spi_nand_read_page_by_row_addr(row_addr, buf, len);
if ((spinand_info.flags & FLAGS_SET_PLANE_BIT) && (blk_id % 2 == 1))
col_addr |= SPI_NAND_PLANE_BIT_OFFSET;
flush_dcache_range((uintptr_t)buf, len);
spi_nand_read_from_cache(0, 0, col_addr, len, buf);
return spi_nand_parsing_ecc_info(row_addr);
}
int cv_spi_nand_read_data(void * buffer, uint32_t offset, uint32_t size)
{
uint32_t i;
offset = offset / spinand_info.page_size;
int ret = 0;
if (size & (spinand_info.page_size - 1)) {
size = (size + spinand_info.page_size - 1) &~(spinand_info.page_size - 1);
}
for (i = 0; i < size / spinand_info.page_size; i++) {
ret = (int)cv_spi_nand_read_page_by_row_addr(offset, buffer, spinand_info.page_size);
if (ret) {
ERROR("read page %u failed\n", offset);
return ret;
}
offset++;
buffer += spinand_info.page_size;
}
return ret;
}

View File

@@ -132,6 +132,112 @@ void cvx16_pinmux(void)
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x76012345);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000008);
break;
case DDR_VENDOR_NY_N20_1G:
// NY_N20_DDR3_1G
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x08060F0B);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x07040109);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x1405020C);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x15030F00);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x0A0F1213);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00111016);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x82315764);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x67513208);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000004);
break;
case DDR_VENDOR_UNILC_N25_1G:
// UnilC_DDR3_1G
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x08020B07);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x00030905);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x04010006);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x1300150C);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x16111214);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00000A10);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x08137564);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000002);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x76513820);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000004);
break;
case DDR_VENDOR_UNILC_N21_2G:
// UnilC_DDR3_2G
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x08070D09);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x0605020B);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x14040100);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x1503000C);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x0A120013);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00111016);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x82135764);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x76513208);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000004);
break;
case DDR_VENDOR_ESMT_N21_2G:
// ESMT_N21_DDR3_2G
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x08070D09);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x0605020B);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x14040100);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x1503000C);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x16001213);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x0011100A);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x82315746);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x67513208);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000004);
break;
case DDR_VENDOR_ESMT_N19_4G:
// ESMT_DDR3_4G_19nm
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x09050D07);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x00080E02);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x0C060B01);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x12031104);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x15001310);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x000A1614);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x31756024);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000008);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x45172380);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000006);
break;
case DDR_VENDOR_UNILC_N25_512M_DDR2:
// UniIC_DDR2_512M
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x00040608);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x02090B0C);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x0E01070D);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x0A031605);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x10110F14);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00121513);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x61437025);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000008);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x63410725);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000008);
break;
case DDR_VENDOR_ETRON_N20_2G:
// Etron_N20_DDR3_2G (ERD3CBA20-HA2133, GELMV QFN88 SIP)
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x08070D09);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x06010B02);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x0C000405);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x13151403);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x0A001612);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00110010);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x20317546);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000008);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x67512308);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000004);
break;
}
#endif //ndef DDR_SIM

View File

@@ -27,6 +27,7 @@ BL2_SOURCES += \
plat/${CHIP_ARCH}/ddr/ddr_pkg_info.c \
plat/${CHIP_ARCH}/ddr/ddr_sys_bring_up.c \
plat/${CHIP_ARCH}/ddr/ddr_sys.c \
plat/${CHIP_ARCH}/ddr/ddr_suspend.c \
plat/${CHIP_ARCH}/ddr/phy_pll_init.c \
plat/${CHIP_ARCH}/ddr/cvx16_pinmux.c \
plat/${CHIP_ARCH}/ddr/cvx16_dram_cap_check.c \
@@ -70,11 +71,6 @@ $(eval $(call add_define,X16_MODE))
# $(eval $(call add_define,FULL_MEM_BIST))
# $(eval $(call add_define,FULL_MEM_BIST_FOREVER))
# overdrive clock setting
ifeq ($(OD_CLK_SEL),y)
$(eval $(call add_define,OD_CLK_SEL))
endif
# # for ddr simulation
# $(eval $(call add_define,DDR_SIM))

View File

@@ -6,6 +6,7 @@
#include <ddr_sys.h>
#include <ddr_init.h>
#include <bitwise_ops.h>
#include <ddr_pkg_info.h>
uint32_t ddr_data_rate = 1333;
@@ -38,7 +39,11 @@ void ddrc_init(void)
mmio_wr32(0x08004000 + 0x6c, 0x00000003);
// PATCH5.vpr_fix:0:1:=0x1
// PATCH5.vpw_fix:1:1:=0x1
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2)
mmio_wr32(0x08004000 + 0x148, 0x989D0000);
else
mmio_wr32(0x08004000 + 0x148, 0x979C0000);
// PATCH4.t_phyd_rden:16:6=0x0
// PATCH4.phyd_rd_clk_stop:23:1=0x0
// PATCH4.t_phyd_wren:24:6=0x0
@@ -50,7 +55,11 @@ void ddrc_init(void)
mmio_wr32(0x08004000 + 0x38, 0x00020000);
mmio_wr32(0x08004000 + 0x50, 0x00201070);
mmio_wr32(0x08004000 + 0x60, 0x00000000);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2)
mmio_wr32(0x08004000 + 0x64, 0x00510023);
else
mmio_wr32(0x08004000 + 0x64, 0x0051002C);
#ifdef DDR_INIT_SPEED_UP
mmio_wr32(0x08004000 + 0xd0, 0x00010002);
mmio_wr32(0x08004000 + 0xd4, 0x00000000);
@@ -58,6 +67,17 @@ void ddrc_init(void)
mmio_wr32(0x08004000 + 0xd0, 0x00010043);
mmio_wr32(0x08004000 + 0xd4, 0x00000000);
#endif
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2) {
mmio_wr32(0x08004000 + 0xdc, 0x03030040);
mmio_wr32(0x08004000 + 0xe0, 0x00800000);
mmio_wr32(0x08004000 + 0x100, 0x0B01160F);
mmio_wr32(0x08004000 + 0x104, 0x00020414);
mmio_wr32(0x08004000 + 0x108, 0x04050409);
mmio_wr32(0x08004000 + 0x10c, 0x00001004);
mmio_wr32(0x08004000 + 0x110, 0x05020405);
mmio_wr32(0x08004000 + 0x114, 0x01010202);
mmio_wr32(0x08004000 + 0x120, 0x00000503);
} else {
mmio_wr32(0x08004000 + 0xdc, 0x03730040);
mmio_wr32(0x08004000 + 0xe0, 0x00800000);
mmio_wr32(0x08004000 + 0x100, 0x0A011610);
@@ -67,8 +87,13 @@ void ddrc_init(void)
mmio_wr32(0x08004000 + 0x110, 0x05020406);
mmio_wr32(0x08004000 + 0x114, 0x01010303);
mmio_wr32(0x08004000 + 0x120, 0x00000503);
}
// phyd related
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2)
mmio_wr32(0x08004000 + 0x190, 0x04878304);
else
mmio_wr32(0x08004000 + 0x190, 0x04858302);
// DFITMG0.dfi_t_ctrl_delay:24:5:=0x4
// DFITMG0.dfi_rddata_use_dfi_phy_clk:23:1:=0x1
// DFITMG0.dfi_t_rddata_en:16:7:=0xa
@@ -102,6 +127,20 @@ void ddrc_init(void)
// address map, auto gen.
// support from 0.5Gb to 4Gb
// R[17:13]B[2]R[12:0]B[1:0]C[9:0]
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2) {
mmio_wr32(0x08004000 + 0x200, 0x00001F1F);
mmio_wr32(0x08004000 + 0x204, 0x00141414);
mmio_wr32(0x08004000 + 0x208, 0x00000000);
mmio_wr32(0x08004000 + 0x20c, 0x1F000000);
mmio_wr32(0x08004000 + 0x210, 0x00001F1F);
mmio_wr32(0x08004000 + 0x214, 0x030F0303);
mmio_wr32(0x08004000 + 0x218, 0x06060603);
mmio_wr32(0x08004000 + 0x21c, 0x00000606);
mmio_wr32(0x08004000 + 0x220, 0x00003F3F);
mmio_wr32(0x08004000 + 0x224, 0x03030303);
mmio_wr32(0x08004000 + 0x228, 0x03030303);
mmio_wr32(0x08004000 + 0x22c, 0x001F1F03);
} else {
mmio_wr32(0x08004000 + 0x200, 0x00001F1F);
mmio_wr32(0x08004000 + 0x204, 0x00140707);
mmio_wr32(0x08004000 + 0x208, 0x00000000);
@@ -114,8 +153,13 @@ void ddrc_init(void)
mmio_wr32(0x08004000 + 0x224, 0x05050505);
mmio_wr32(0x08004000 + 0x228, 0x05050505);
mmio_wr32(0x08004000 + 0x22c, 0x001F1F05);
}
// auto gen.
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2)
mmio_wr32(0x08004000 + 0x240, 0x07030710);
else
mmio_wr32(0x08004000 + 0x240, 0x07010708); //TBD
mmio_wr32(0x08004000 + 0x244, 0x00000000);
mmio_wr32(0x08004000 + 0x250, 0x00003F85);
// SCHED.opt_vprw_sch:31:1:=0x0
@@ -305,6 +349,36 @@ void ctrl_init_update_by_dram_size(uint8_t dram_cap_in_mbyte)
dram_cap_in_mbyte_per_dev = dram_cap_in_mbyte;
dram_cap_in_mbyte_per_dev >>= (1 - get_bits_from_value(rddata, 13, 12)); // change sys cap to x16 cap
dram_cap_in_mbyte_per_dev >>= (2 - get_bits_from_value(rddata, 31, 30)); // change x16 cap to device cap
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2) {
switch (dram_cap_in_mbyte_per_dev) {
case 5:
mmio_wr32(0x08004000 + 0x64, 0x00510019);
mmio_wr32(0x08004000 + 0x100, 0x0B01160F);
mmio_wr32(0x08004000 + 0x120, 0x00000502);
break;
case 6:
mmio_wr32(0x08004000 + 0x64, 0x00510023);
mmio_wr32(0x08004000 + 0x100, 0x0B01160F);
mmio_wr32(0x08004000 + 0x120, 0x00000503);
break;
case 7:
mmio_wr32(0x08004000 + 0x64, 0x0051002B);
mmio_wr32(0x08004000 + 0x100, 0x0B0F160F);
mmio_wr32(0x08004000 + 0x120, 0x00000503);
break;
case 8:
mmio_wr32(0x08004000 + 0x64, 0x00510041);
mmio_wr32(0x08004000 + 0x100, 0x0B0F160F);
mmio_wr32(0x08004000 + 0x120, 0x00000504);
break;
case 9:
mmio_wr32(0x08004000 + 0x64, 0x0051006E);
mmio_wr32(0x08004000 + 0x100, 0x0B0F160F);
mmio_wr32(0x08004000 + 0x120, 0x00000505);
break;
}
} else {
switch (dram_cap_in_mbyte_per_dev) {
case 5:
mmio_wr32(0x08004000 + 0x64, 0x00510019);
@@ -332,6 +406,7 @@ void ctrl_init_update_by_dram_size(uint8_t dram_cap_in_mbyte)
mmio_wr32(0x08004000 + 0x120, 0x00000505);
break;
}
}
switch (dram_cap_in_mbyte_per_dev) {
case 5:

View File

@@ -86,13 +86,13 @@ struct regpatch ddr_patch_regs[] = {
{0x08000b00, 0xFFFFFFFF, 0x05030703},
{0x08000b04, 0xFFFFFFFF, 0x03030403},
// BYTE0 DQ8 deskew [6:0] neg DQS [15:8] ; pos DQS [23:16]
{0x08000b08, 0xFFFFFFFF, 0x002e3b03},
{0x08000b08, 0xFFFFFFFF, 0x00323603},
// BYTE1 RX DQ deskew
{0x08000b30, 0xFFFFFFFF, 0x07030204},
{0x08000b34, 0xFFFFFFFF, 0x03030403},
// BYTE1 DQ8 deskew [6:0] neg DQS [15:8] ; pos DQS [23:16]
{0x08000b38, 0xFFFFFFFF, 0x002e3d04},
{0x08000b38, 0xFFFFFFFF, 0x00323604},
#if 0
//Read gate TX dline + shift
// BYTE0

View File

@@ -4,6 +4,7 @@
#include <ddr_sys.h>
#include <ddr_init.h>
#include <bitwise_ops.h>
#include <ddr_pkg_info.h>
uint32_t ddr_data_rate = 1866;
@@ -66,6 +67,8 @@ void ddrc_init(void)
#endif
mmio_wr32(0x08004000 + 0xe4, 0x000B03BF);
mmio_wr32(0x08004000 + 0x100, 0x0E111F10);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x100, mmio_rd32(0x08004000 + 0x100) + 0x3000000);
mmio_wr32(0x08004000 + 0x104, 0x00030417);
mmio_wr32(0x08004000 + 0x108, 0x0507060A);
mmio_wr32(0x08004000 + 0x10c, 0x00002007);
@@ -142,6 +145,8 @@ void ddrc_init(void)
// SCHED.prefer_write:1:1:=0x0
// SCHED.dis_opt_wrecc_collision_flush:0:1:=0x1
mmio_wr32(0x08004000 + 0x254, 0x00000000);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x254, 0x40);
// SCHED1.page_hit_limit_rd:28:3:=0x0
// SCHED1.page_hit_limit_wr:24:3:=0x0
// SCHED1.visible_window_limit_rd:20:3:=0x0

View File

@@ -4,6 +4,7 @@
#include <ddr_sys.h>
#include <ddr_init.h>
#include <bitwise_ops.h>
#include <ddr_pkg_info.h>
uint32_t ddr_data_rate = 2133;
@@ -65,6 +66,8 @@ void ddrc_init(void)
#endif
mmio_wr32(0x08004000 + 0xe4, 0x000C03BF);
mmio_wr32(0x08004000 + 0x100, 0x0F132412);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x100, mmio_rd32(0x08004000 + 0x100) + 0x3000000);
mmio_wr32(0x08004000 + 0x104, 0x00040419);
mmio_wr32(0x08004000 + 0x108, 0x0507060B);
mmio_wr32(0x08004000 + 0x10c, 0x00002008);
@@ -146,6 +149,8 @@ void ddrc_init(void)
// SCHED.dis_opt_wrecc_collision_flush:0:1:=0x1
mmio_wr32(0x08004000 + 0x254, 0x00000000);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x254, 0x40);
// SCHED1.page_hit_limit_rd:28:3:=0x0
// SCHED1.page_hit_limit_wr:24:3:=0x0
// SCHED1.visible_window_limit_rd:20:3:=0x0

View File

@@ -86,13 +86,13 @@ struct regpatch ddr3_1866_patch_regs[] = {
{0x08000b00, 0xFFFFFFFF, 0x05030703},
{0x08000b04, 0xFFFFFFFF, 0x03030403},
// BYTE0 DQ8 deskew [6:0] neg DQS [15:8] ; pos DQS [23:16]
{0x08000b08, 0xFFFFFFFF, 0x002e3b03},
{0x08000b08, 0xFFFFFFFF, 0x00323603},
// BYTE1 RX DQ deskew
{0x08000b30, 0xFFFFFFFF, 0x07030204},
{0x08000b34, 0xFFFFFFFF, 0x03030403},
// BYTE1 DQ8 deskew [6:0] neg DQS [15:8] ; pos DQS [23:16]
{0x08000b38, 0xFFFFFFFF, 0x002e3d04},
{0x08000b38, 0xFFFFFFFF, 0x00323604},
#if 0
//Read gate TX dline + shift
// BYTE0

View File

@@ -74,6 +74,8 @@ void ddrc_init(void)
#endif
mmio_wr32(0x08004000 + 0xe4, 0x000B03BF);
mmio_wr32(0x08004000 + 0x100, 0x0E111F10);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x100, mmio_rd32(0x08004000 + 0x100) + 0x3000000);
mmio_wr32(0x08004000 + 0x104, 0x00030417);
mmio_wr32(0x08004000 + 0x108, 0x0507060A);
mmio_wr32(0x08004000 + 0x10c, 0x00002007);
@@ -150,6 +152,8 @@ void ddrc_init(void)
// SCHED.prefer_write:1:1:=0x0
// SCHED.dis_opt_wrecc_collision_flush:0:1:=0x1
mmio_wr32(0x08004000 + 0x254, 0x00000000);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x254, 0x40);
// SCHED1.page_hit_limit_rd:28:3:=0x0
// SCHED1.page_hit_limit_wr:24:3:=0x0
// SCHED1.visible_window_limit_rd:20:3:=0x0
@@ -316,7 +320,11 @@ void ddrc_init(void)
mmio_wr32(0x08004000 + 0x6c, 0x00000003);
// PATCH5.vpr_fix:0:1:=0x1
// PATCH5.vpw_fix:1:1:=0x1
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2)
mmio_wr32(0x08004000 + 0x148, 0x989D0000);
else
mmio_wr32(0x08004000 + 0x148, 0x979C0000);
// PATCH4.t_phyd_rden:16:6=0x0
// PATCH4.phyd_rd_clk_stop:23:1=0x0
// PATCH4.t_phyd_wren:24:6=0x0
@@ -328,7 +336,11 @@ void ddrc_init(void)
mmio_wr32(0x08004000 + 0x38, 0x00020000);
mmio_wr32(0x08004000 + 0x50, 0x00201070);
mmio_wr32(0x08004000 + 0x60, 0x00000000);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2)
mmio_wr32(0x08004000 + 0x64, 0x00510023);
else
mmio_wr32(0x08004000 + 0x64, 0x0051002C);
#ifdef DDR_INIT_SPEED_UP
mmio_wr32(0x08004000 + 0xd0, 0x00010002);
mmio_wr32(0x08004000 + 0xd4, 0x00000000);
@@ -336,6 +348,17 @@ void ddrc_init(void)
mmio_wr32(0x08004000 + 0xd0, 0x00010043);
mmio_wr32(0x08004000 + 0xd4, 0x00000000);
#endif
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2) {
mmio_wr32(0x08004000 + 0xdc, 0x03030040);
mmio_wr32(0x08004000 + 0xe0, 0x00800000);
mmio_wr32(0x08004000 + 0x100, 0x0B01160F);
mmio_wr32(0x08004000 + 0x104, 0x00020414);
mmio_wr32(0x08004000 + 0x108, 0x04050409);
mmio_wr32(0x08004000 + 0x10c, 0x00001004);
mmio_wr32(0x08004000 + 0x110, 0x05020405);
mmio_wr32(0x08004000 + 0x114, 0x01010202);
mmio_wr32(0x08004000 + 0x120, 0x00000503);
} else {
mmio_wr32(0x08004000 + 0xdc, 0x03730040);
mmio_wr32(0x08004000 + 0xe0, 0x00800000);
mmio_wr32(0x08004000 + 0x100, 0x0A011610);
@@ -345,8 +368,13 @@ void ddrc_init(void)
mmio_wr32(0x08004000 + 0x110, 0x05020406);
mmio_wr32(0x08004000 + 0x114, 0x01010303);
mmio_wr32(0x08004000 + 0x120, 0x00000503);
}
// phyd related
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2)
mmio_wr32(0x08004000 + 0x190, 0x04878304);
else
mmio_wr32(0x08004000 + 0x190, 0x04858302);
// DFITMG0.dfi_t_ctrl_delay:24:5:=0x4
// DFITMG0.dfi_rddata_use_dfi_phy_clk:23:1:=0x1
// DFITMG0.dfi_t_rddata_en:16:7:=0xa
@@ -380,6 +408,20 @@ void ddrc_init(void)
// address map, auto gen.
// support from 0.5Gb to 4Gb
// R[17:13]B[2]R[12:0]B[1:0]C[9:0]
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2) {
mmio_wr32(0x08004000 + 0x200, 0x00001F1F);
mmio_wr32(0x08004000 + 0x204, 0x00141414);
mmio_wr32(0x08004000 + 0x208, 0x00000000);
mmio_wr32(0x08004000 + 0x20c, 0x1F000000);
mmio_wr32(0x08004000 + 0x210, 0x00001F1F);
mmio_wr32(0x08004000 + 0x214, 0x030F0303);
mmio_wr32(0x08004000 + 0x218, 0x06060603);
mmio_wr32(0x08004000 + 0x21c, 0x00000606);
mmio_wr32(0x08004000 + 0x220, 0x00003F3F);
mmio_wr32(0x08004000 + 0x224, 0x03030303);
mmio_wr32(0x08004000 + 0x228, 0x03030303);
mmio_wr32(0x08004000 + 0x22c, 0x001F1F03);
} else {
mmio_wr32(0x08004000 + 0x200, 0x00001F1F);
mmio_wr32(0x08004000 + 0x204, 0x00140707);
mmio_wr32(0x08004000 + 0x208, 0x00000000);
@@ -392,8 +434,13 @@ void ddrc_init(void)
mmio_wr32(0x08004000 + 0x224, 0x05050505);
mmio_wr32(0x08004000 + 0x228, 0x05050505);
mmio_wr32(0x08004000 + 0x22c, 0x001F1F05);
}
// auto gen.
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2)
mmio_wr32(0x08004000 + 0x240, 0x07030710);
else
mmio_wr32(0x08004000 + 0x240, 0x07010708); //TBD
mmio_wr32(0x08004000 + 0x244, 0x00000000);
mmio_wr32(0x08004000 + 0x250, 0x00003F85);
// SCHED.opt_vprw_sch:31:1:=0x0
@@ -639,6 +686,35 @@ void ctrl_init_update_by_dram_size(uint8_t dram_cap_in_mbyte)
dram_cap_in_mbyte_per_dev = dram_cap_in_mbyte;
dram_cap_in_mbyte_per_dev >>= (1 - get_bits_from_value(rddata, 13, 12)); // change sys cap to x16 cap
dram_cap_in_mbyte_per_dev >>= (2 - get_bits_from_value(rddata, 31, 30)); // change x16 cap to device cap
if (get_ddr_vendor() == DDR_VENDOR_ETRON_512M_DDR2) {
switch (dram_cap_in_mbyte_per_dev) {
case 5:
mmio_wr32(0x08004000 + 0x64, 0x00510019);
mmio_wr32(0x08004000 + 0x100, 0x0B01160F);
mmio_wr32(0x08004000 + 0x120, 0x00000502);
break;
case 6:
mmio_wr32(0x08004000 + 0x64, 0x00510023);
mmio_wr32(0x08004000 + 0x100, 0x0B01160F);
mmio_wr32(0x08004000 + 0x120, 0x00000503);
break;
case 7:
mmio_wr32(0x08004000 + 0x64, 0x0051002B);
mmio_wr32(0x08004000 + 0x100, 0x0B0F160F);
mmio_wr32(0x08004000 + 0x120, 0x00000503);
break;
case 8:
mmio_wr32(0x08004000 + 0x64, 0x00510041);
mmio_wr32(0x08004000 + 0x100, 0x0B0F160F);
mmio_wr32(0x08004000 + 0x120, 0x00000504);
break;
case 9:
mmio_wr32(0x08004000 + 0x64, 0x0051006E);
mmio_wr32(0x08004000 + 0x100, 0x0B0F160F);
mmio_wr32(0x08004000 + 0x120, 0x00000505);
break;
}
} else {
switch (dram_cap_in_mbyte_per_dev) {
case 5:
mmio_wr32(0x08004000 + 0x64, 0x00510019);
@@ -666,6 +742,7 @@ void ctrl_init_update_by_dram_size(uint8_t dram_cap_in_mbyte)
mmio_wr32(0x08004000 + 0x120, 0x00000505);
break;
}
}
switch (dram_cap_in_mbyte_per_dev) {
case 5:

View File

@@ -85,18 +85,48 @@ void read_ddr_pkg_info(void)
ddr_type = DDR_TYPE_DDR2;
ddr_data_rate = 1333;
break;
case DDR_VENDOR_UNILC_N25_512M_DDR2:
NOTICE("DDR2");
ddr_type = DDR_TYPE_DDR2;
ddr_data_rate = 1333;
break;
case DDR_VENDOR_NY_4G:
case DDR_VENDOR_NY_2G:
case DDR_VENDOR_ESMT_1G:
case DDR_VENDOR_ETRON_1G:
case DDR_VENDOR_ESMT_2G:
case DDR_VENDOR_PM_2G:
case DDR_VENDOR_PM_1G:
case DDR_VENDOR_ETRON_N20_2G:
case DDR_VENDOR_ESMT_N25_1G:
NOTICE("DDR3");
ddr_type = DDR_TYPE_DDR3;
ddr_data_rate = 1866;
break;
case DDR_VENDOR_NY_N20_1G:
NOTICE("DDR3");
ddr_type = DDR_TYPE_DDR3;
ddr_data_rate = 1866;
break;
case DDR_VENDOR_UNILC_N25_1G:
NOTICE("DDR3");
ddr_type = DDR_TYPE_DDR3;
ddr_data_rate = 1866;
break;
case DDR_VENDOR_UNILC_N21_2G:
NOTICE("DDR3");
ddr_type = DDR_TYPE_DDR3;
ddr_data_rate = 1866;
break;
case DDR_VENDOR_ESMT_N21_2G:
NOTICE("DDR3");
ddr_type = DDR_TYPE_DDR3;
ddr_data_rate = 1866;
break;
case DDR_VENDOR_ESMT_N19_4G:
NOTICE("DDR3");
ddr_type = DDR_TYPE_DDR3;
ddr_data_rate = 1866;
break;
default:
NOTICE("unknown vendor=%d", ddr_vendor);
ddr_type = DDR_TYPE_UNKNOWN;

View File

@@ -0,0 +1,404 @@
// SPDX-License-Identifier: BSD-3-Clause
#include <stddef.h>
#include <string.h>
#include <stdint.h>
#include <delay_timer.h>
#include "mmio.h"
#include "reg_soc.h"
#include "phy_pll_init.h"
#include "ddr_sys.h"
#include "ddr_suspend.h"
#include "bitwise_ops.h"
// #include "regconfig.h"
#include "rtc.h"
#include "cvx16_dram_cap_check.h"
#include <platform_def.h>
#ifdef DDR2_3
#include <ddr3_1866_init.h>
#include <ddr2_1333_init.h>
#else
#include <ddr_init.h>
#endif
#define susp_read_csr(reg) ({ unsigned long __tmp; \
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
SUSPEND_DATA uint32_t start, delta, total_delta;
void susp_udelay(uint32_t delay)
{
start = (uint32_t)(~susp_read_csr(time));
total_delta = (delay * 25);
mmio_write_32(REG_GP_REG2, total_delta);
do {
/*
* If the timer value wraps around, the subtraction will
* overflow and it will still give the correct result.
*/
delta = start - (uint32_t)(~susp_read_csr(time)); /* Decreasing counter */
} while (delta < total_delta);
}
void ddr_suspend_entry(void)
{
ddr_sys_suspend_sus_res();
rtc_clr_ddr_pwrok();
rtc_clr_rmio_pwrok();
#ifndef SUSPEND_USE_WDG_RST
rtc_req_suspend();
#else
rtc_req_wdg_rst();
#endif
}
void ddr_sys_suspend_sus_res(void)
{
cvx16_ddrc_suspend_sus_res();
cvx16_ddr_phyd_save_sus_res(0x05026800);
cvx16_ddr_phya_pd_sus_res();
}
void cvx16_ddrc_suspend_sus_res(void)
{
uint32_t rddata;
// Write 0 to PCTRL_n.port_en
for (int i = 0; i < 4; i++)
mmio_wr32(cfg_base + 0x490 + 0xb0 * i, 0x0);
while (1) {
rddata = mmio_rd32(cfg_base + 0x3fc);
if (rddata == 0)
break;
}
//Write 1 to PWRCTL.selfref_sw
rddata = mmio_rd32(cfg_base + 0x30);
rddata = FIELD_SET(rddata, 1, 5, 5);
mmio_wr32(cfg_base + 0x30, rddata);
//Poll STAT.selfref_type= 2'b10
//Poll STAT.selfref_state = 0b10 (LPDDR4 only)
while (1) {
rddata = mmio_rd32(cfg_base + 0x4);
if (FIELD_GET(rddata, 5, 4) == 0x2)
break;
}
}
void cvx16_ddr_phya_pd_sus_res(void)
{
uint32_t rddata;
// ----------- PHY oen/pd reset ----------------
//OEN
//param_phyd_tx_ca_oenz 0
//param_phyd_tx_ca_clk0_oenz 8
//param_phyd_tx_ca_clk1_oenz 16
rddata = 0x00010101;
mmio_wr32(0x0130 + PHYD_BASE_ADDR, rddata);
//PD
//TOP_REG_TX_CA_PD_CA 22 0
//TOP_REG_TX_CA_PD_CKE0 24 24
//TOP_REG_TX_CLK_PD_CLK0 26 26
//TOP_REG_TX_CA_PD_CSB0 28 28
//TOP_REG_TX_CA_PD_RESETZ 30 30
//TOP_REG_TX_ZQ_PD 31 31
//rddata[31:0] = 0x947f_ffff;
rddata = 0x947fffff;
mmio_wr32(0x40 + CV_DDR_PHYD_APB, rddata);
//TOP_REG_TX_BYTE0_PD 0
//TOP_REG_TX_BYTE1_PD 1
rddata = 0x00000003;
mmio_wr32(0x00 + CV_DDR_PHYD_APB, rddata);
//OEN
//param_phyd_sel_cke_oenz <= `PI_SD int_regin[0];
rddata = mmio_rd32(0x0154 + PHYD_BASE_ADDR);
//rddata[0] = 0b1;
rddata = FIELD_SET(rddata, 1, 0, 0);
mmio_wr32(0x0154 + PHYD_BASE_ADDR, rddata);
//PD
//All PHYA PD=0
rddata = 0xffffffff;
mmio_wr32(0x40 + CV_DDR_PHYD_APB, rddata);
//PLL PD
rddata = mmio_rd32(0x0C + CV_DDR_PHYD_APB);
//rddata[15] = 1; //TOP_REG_DDRPLL_PD
rddata = FIELD_SET(rddata, 1, 15, 15);
mmio_wr32(0x0C + CV_DDR_PHYD_APB, rddata);
// ----------- PHY oen/pd reset ----------------
//reg_ddr_ssc_syn_src_en =0
rddata = mmio_rd32(0x40 + 0x03002900);
rddata = FIELD_SET(rddata, 0, 1, 1); //reg_ddr_ssc_syn_src_en
mmio_wr32(0x40 + 0x03002900, rddata);
}
SUSPEND_DATA struct reg save_phy_regs[] = {
{0x0 + PHYD_BASE_ADDR, 0x0},
{0x4 + PHYD_BASE_ADDR, 0x0},
{0x8 + PHYD_BASE_ADDR, 0x0},
{0xc + PHYD_BASE_ADDR, 0x0},
{0x10 + PHYD_BASE_ADDR, 0x0},
{0x14 + PHYD_BASE_ADDR, 0x0},
{0x18 + PHYD_BASE_ADDR, 0x0},
{0x1c + PHYD_BASE_ADDR, 0x0},
{0x20 + PHYD_BASE_ADDR, 0x0},
{0x24 + PHYD_BASE_ADDR, 0x0},
{0x28 + PHYD_BASE_ADDR, 0x0},
{0x2c + PHYD_BASE_ADDR, 0x0},
{0x40 + PHYD_BASE_ADDR, 0x0},
{0x44 + PHYD_BASE_ADDR, 0x0},
{0x48 + PHYD_BASE_ADDR, 0x0},
{0x4c + PHYD_BASE_ADDR, 0x0},
{0x50 + PHYD_BASE_ADDR, 0x0},
{0x54 + PHYD_BASE_ADDR, 0x0},
{0x58 + PHYD_BASE_ADDR, 0x0},
{0x5c + PHYD_BASE_ADDR, 0x0},
{0x60 + PHYD_BASE_ADDR, 0x0},
{0x64 + PHYD_BASE_ADDR, 0x0},
{0x68 + PHYD_BASE_ADDR, 0x0},
{0x70 + PHYD_BASE_ADDR, 0x0},
{0x74 + PHYD_BASE_ADDR, 0x0},
{0x80 + PHYD_BASE_ADDR, 0x0},
{0x84 + PHYD_BASE_ADDR, 0x0},
{0x88 + PHYD_BASE_ADDR, 0x0},
{0x8c + PHYD_BASE_ADDR, 0x0},
{0x90 + PHYD_BASE_ADDR, 0x0},
{0x94 + PHYD_BASE_ADDR, 0x0},
{0xa0 + PHYD_BASE_ADDR, 0x0},
{0xa4 + PHYD_BASE_ADDR, 0x0},
{0xa8 + PHYD_BASE_ADDR, 0x0},
{0xac + PHYD_BASE_ADDR, 0x0},
{0xb0 + PHYD_BASE_ADDR, 0x0},
{0xb4 + PHYD_BASE_ADDR, 0x0},
{0xb8 + PHYD_BASE_ADDR, 0x0},
{0xbc + PHYD_BASE_ADDR, 0x0},
{0xf8 + PHYD_BASE_ADDR, 0x0},
{0xfc + PHYD_BASE_ADDR, 0x0},
{0x100 + PHYD_BASE_ADDR, 0x0},
{0x104 + PHYD_BASE_ADDR, 0x0},
{0x10c + PHYD_BASE_ADDR, 0x0},
{0x110 + PHYD_BASE_ADDR, 0x0},
{0x114 + PHYD_BASE_ADDR, 0x0},
{0x118 + PHYD_BASE_ADDR, 0x0},
{0x11c + PHYD_BASE_ADDR, 0x0},
{0x120 + PHYD_BASE_ADDR, 0x0},
{0x124 + PHYD_BASE_ADDR, 0x0},
{0x128 + PHYD_BASE_ADDR, 0x0},
{0x12c + PHYD_BASE_ADDR, 0x0},
{0x130 + PHYD_BASE_ADDR, 0x0},
{0x134 + PHYD_BASE_ADDR, 0x0},
{0x138 + PHYD_BASE_ADDR, 0x0},
{0x140 + PHYD_BASE_ADDR, 0x0},
{0x144 + PHYD_BASE_ADDR, 0x0},
{0x148 + PHYD_BASE_ADDR, 0x0},
{0x14c + PHYD_BASE_ADDR, 0x0},
{0x150 + PHYD_BASE_ADDR, 0x0},
{0x154 + PHYD_BASE_ADDR, 0x0},
{0x158 + PHYD_BASE_ADDR, 0x0},
{0x15c + PHYD_BASE_ADDR, 0x0},
{0x164 + PHYD_BASE_ADDR, 0x0},
{0x168 + PHYD_BASE_ADDR, 0x0},
{0x16c + PHYD_BASE_ADDR, 0x0},
{0x170 + PHYD_BASE_ADDR, 0x0},
{0x174 + PHYD_BASE_ADDR, 0x0},
{0x180 + PHYD_BASE_ADDR, 0x0},
{0x184 + PHYD_BASE_ADDR, 0x0},
{0x188 + PHYD_BASE_ADDR, 0x0},
{0x18c + PHYD_BASE_ADDR, 0x0},
{0x190 + PHYD_BASE_ADDR, 0x0},
{0x200 + PHYD_BASE_ADDR, 0x0},
{0x204 + PHYD_BASE_ADDR, 0x0},
{0x208 + PHYD_BASE_ADDR, 0x0},
{0x220 + PHYD_BASE_ADDR, 0x0},
{0x224 + PHYD_BASE_ADDR, 0x0},
{0x228 + PHYD_BASE_ADDR, 0x0},
{0x400 + PHYD_BASE_ADDR, 0x0},
{0x404 + PHYD_BASE_ADDR, 0x0},
{0x408 + PHYD_BASE_ADDR, 0x0},
{0x40c + PHYD_BASE_ADDR, 0x0},
{0x410 + PHYD_BASE_ADDR, 0x0},
{0x414 + PHYD_BASE_ADDR, 0x0},
{0x418 + PHYD_BASE_ADDR, 0x0},
{0x41c + PHYD_BASE_ADDR, 0x0},
{0x500 + PHYD_BASE_ADDR, 0x0},
{0x504 + PHYD_BASE_ADDR, 0x0},
{0x508 + PHYD_BASE_ADDR, 0x0},
{0x50c + PHYD_BASE_ADDR, 0x0},
{0x510 + PHYD_BASE_ADDR, 0x0},
{0x514 + PHYD_BASE_ADDR, 0x0},
{0x518 + PHYD_BASE_ADDR, 0x0},
{0x51c + PHYD_BASE_ADDR, 0x0},
{0x520 + PHYD_BASE_ADDR, 0x0},
{0x540 + PHYD_BASE_ADDR, 0x0},
{0x544 + PHYD_BASE_ADDR, 0x0},
{0x548 + PHYD_BASE_ADDR, 0x0},
{0x54c + PHYD_BASE_ADDR, 0x0},
{0x550 + PHYD_BASE_ADDR, 0x0},
{0x554 + PHYD_BASE_ADDR, 0x0},
{0x558 + PHYD_BASE_ADDR, 0x0},
{0x55c + PHYD_BASE_ADDR, 0x0},
{0x560 + PHYD_BASE_ADDR, 0x0},
{0x900 + PHYD_BASE_ADDR, 0x0},
{0x904 + PHYD_BASE_ADDR, 0x0},
{0x908 + PHYD_BASE_ADDR, 0x0},
{0x90c + PHYD_BASE_ADDR, 0x0},
{0x910 + PHYD_BASE_ADDR, 0x0},
{0x914 + PHYD_BASE_ADDR, 0x0},
{0x918 + PHYD_BASE_ADDR, 0x0},
{0x91c + PHYD_BASE_ADDR, 0x0},
{0x920 + PHYD_BASE_ADDR, 0x0},
{0x924 + PHYD_BASE_ADDR, 0x0},
{0x928 + PHYD_BASE_ADDR, 0x0},
{0x92c + PHYD_BASE_ADDR, 0x0},
{0x930 + PHYD_BASE_ADDR, 0x0},
{0x934 + PHYD_BASE_ADDR, 0x0},
{0x938 + PHYD_BASE_ADDR, 0x0},
{0x940 + PHYD_BASE_ADDR, 0x0},
{0x944 + PHYD_BASE_ADDR, 0x0},
{0x948 + PHYD_BASE_ADDR, 0x0},
{0x94c + PHYD_BASE_ADDR, 0x0},
{0x950 + PHYD_BASE_ADDR, 0x0},
{0x954 + PHYD_BASE_ADDR, 0x0},
{0x958 + PHYD_BASE_ADDR, 0x0},
{0x95c + PHYD_BASE_ADDR, 0x0},
{0x960 + PHYD_BASE_ADDR, 0x0},
{0x964 + PHYD_BASE_ADDR, 0x0},
{0x968 + PHYD_BASE_ADDR, 0x0},
{0x96c + PHYD_BASE_ADDR, 0x0},
{0x970 + PHYD_BASE_ADDR, 0x0},
{0x974 + PHYD_BASE_ADDR, 0x0},
{0x978 + PHYD_BASE_ADDR, 0x0},
{0x97c + PHYD_BASE_ADDR, 0x0},
{0x980 + PHYD_BASE_ADDR, 0x0},
{0xa00 + PHYD_BASE_ADDR, 0x0},
{0xa04 + PHYD_BASE_ADDR, 0x0},
{0xa08 + PHYD_BASE_ADDR, 0x0},
{0xa0c + PHYD_BASE_ADDR, 0x0},
{0xa10 + PHYD_BASE_ADDR, 0x0},
{0xa14 + PHYD_BASE_ADDR, 0x0},
{0xa18 + PHYD_BASE_ADDR, 0x0},
{0xa1c + PHYD_BASE_ADDR, 0x0},
{0xa20 + PHYD_BASE_ADDR, 0x0},
{0xa24 + PHYD_BASE_ADDR, 0x0},
{0xa28 + PHYD_BASE_ADDR, 0x0},
{0xa2c + PHYD_BASE_ADDR, 0x0},
{0xa30 + PHYD_BASE_ADDR, 0x0},
{0xa34 + PHYD_BASE_ADDR, 0x0},
{0xa38 + PHYD_BASE_ADDR, 0x0},
{0xa3c + PHYD_BASE_ADDR, 0x0},
{0xa40 + PHYD_BASE_ADDR, 0x0},
{0xa44 + PHYD_BASE_ADDR, 0x0},
{0xa48 + PHYD_BASE_ADDR, 0x0},
{0xa4c + PHYD_BASE_ADDR, 0x0},
{0xa50 + PHYD_BASE_ADDR, 0x0},
{0xa54 + PHYD_BASE_ADDR, 0x0},
{0xa58 + PHYD_BASE_ADDR, 0x0},
{0xa5c + PHYD_BASE_ADDR, 0x0},
{0xa60 + PHYD_BASE_ADDR, 0x0},
{0xa64 + PHYD_BASE_ADDR, 0x0},
{0xa68 + PHYD_BASE_ADDR, 0x0},
{0xa6c + PHYD_BASE_ADDR, 0x0},
{0xa70 + PHYD_BASE_ADDR, 0x0},
{0xa74 + PHYD_BASE_ADDR, 0x0},
{0xa78 + PHYD_BASE_ADDR, 0x0},
{0xa7c + PHYD_BASE_ADDR, 0x0},
{0xb00 + PHYD_BASE_ADDR, 0x0},
{0xb04 + PHYD_BASE_ADDR, 0x0},
{0xb08 + PHYD_BASE_ADDR, 0x0},
{0xb0c + PHYD_BASE_ADDR, 0x0},
{0xb10 + PHYD_BASE_ADDR, 0x0},
{0xb14 + PHYD_BASE_ADDR, 0x0},
{0xb18 + PHYD_BASE_ADDR, 0x0},
{0xb1c + PHYD_BASE_ADDR, 0x0},
{0xb20 + PHYD_BASE_ADDR, 0x0},
{0xb24 + PHYD_BASE_ADDR, 0x0},
{0xb30 + PHYD_BASE_ADDR, 0x0},
{0xb34 + PHYD_BASE_ADDR, 0x0},
{0xb38 + PHYD_BASE_ADDR, 0x0},
{0xb3c + PHYD_BASE_ADDR, 0x0},
{0xb40 + PHYD_BASE_ADDR, 0x0},
{0xb44 + PHYD_BASE_ADDR, 0x0},
{0xb48 + PHYD_BASE_ADDR, 0x0},
{0xb4c + PHYD_BASE_ADDR, 0x0},
{0xb50 + PHYD_BASE_ADDR, 0x0},
{0xb54 + PHYD_BASE_ADDR, 0x0},
{REG_GP_REG3, 0x0}, //reserve for chipid suspend resume
{0xDEADBEEF, 0xDEADBEEF},
};
void cvx16_ddr_phyd_save_sus_res(uint32_t rtc_sram_base)
{
// struct reg *psave_phy_regs = (struct reg *)rtc_sram_base;
uintptr_t temp = rtc_sram_base;
struct reg *psave_phy_regs = (struct reg *)temp;
int i;
for (i = 0; i < ARRAY_SIZE(save_phy_regs) - 1; i++) {
psave_phy_regs[i].addr = save_phy_regs[i].addr;
psave_phy_regs[i].val = mmio_rd32(save_phy_regs[i].addr);
}
}
void rtc_clr_ddr_pwrok(void)
{
mmio_clrbits_32(REG_RTC_BASE + RTC_PG_REG, 0x00000001);
}
void rtc_clr_rmio_pwrok(void)
{
mmio_clrbits_32(REG_RTC_BASE + RTC_PG_REG, 0x00000002);
}
#ifndef SUSPEND_USE_WDG_RST
void rtc_req_suspend(void)
{
//info("Send suspend request\n");
/* Enable power suspend wakeup source mask */
mmio_write_32(REG_RTC_BASE + 0x3C, 0x1); // 1 = select prdata from 32K domain
mmio_write_32(REG_RTC_CTRL_BASE + RTC_CTRL0_UNLOCKKEY, 0xAB18);
mmio_write_32(REG_RTC_BASE + RTC_EN_SUSPEND_REQ, 0x01);
while (mmio_read_32(REG_RTC_BASE + RTC_EN_SUSPEND_REQ) != 0x01)
;
while (1) {
/* Send suspend request to RTC*/
susp_udelay(1000);
mmio_write_32(REG_RTC_CTRL_BASE + RTC_CTRL0, 0x00800080);
}
}
#else
void rtc_req_wdg_rst(void)
{
uint32_t write_data = 0;
write_data = mmio_rd32(REG_RTC_CTRL_BASE + 0x18); //rtcsys_rst_ctrl
write_data = write_data | (0x01 << 24); //reg_rtcsys_reset_en
mmio_wr32(REG_RTC_CTRL_BASE + 0x18, write_data); //
mmio_wr32(REG_RTC_BASE + 0xE8, 0x04); // RTC_DB_REQ_WARM_RST
mmio_wr32(REG_RTC_BASE + 0xE0, 0x01); // RTC_EN_WDG_RST_REQ
mmio_wr32(REG_RTC_CTRL_BASE + 0x60, 0xA5); // write dummy register
mmio_wr32(REG_RTC_CTRL_BASE + 0x04, 0xAB18); // rtc_ctrl0_unlockkey
write_data = mmio_rd32(REG_RTC_CTRL_BASE + 0x08); // rtc_ctrl0
//req_shdn = rtc_ctrl0[0];
//req_sw_thm_shdn = rtc_ctrl0[1];
//hw_thm_shdn_en = rtc_ctrl0[2];
//req_pwr_cyc = rtc_ctrl0[3];
//req_warm_rst = rtc_ctrl0[4];
//req_sw_wdg_rst = rtc_ctrl0[5];
//hw_wdg_rst_en = rtc_ctrl0[6];
//req_suspend = rtc_ctrl0[7];
write_data = 0xffff0000 | write_data | (0x01 << 5);
// printf("[RTC] ----> Set req_sw_wdg_rst to 1 by register setting\n");
mmio_wr32(REG_RTC_CTRL_BASE + 0x08, write_data); //rtc_ctrl0
}
#endif

View File

@@ -13,6 +13,8 @@
#include <cvx16_pinmux.h>
#include <ddr_pkg_info.h>
#include <regconfig.h>
#include <phy_pll_init.h>
#include <platform_def.h>
#define opdelay(_x) udelay((_x)/1000)
@@ -164,13 +166,17 @@ void ddr_sys_resume(void)
// KC_MSG("ddr_sub_resume1\n");
// pll_init
cvx16_pll_init();
pll_init();
KC_MSG("pll_init_h finish\n");
// ctrl_init
ddrc_init();
KC_MSG("2nd ctrl_init_h finish\n");
// set axi QOS
mmio_wr32(0x030001D8, 0x008899aa);
mmio_wr32(0x030001DC, 0x00002244);
// ddr_sub_resume2
cvx16_ddr_sub_resume2();
KC_MSG("ddr_sub_resume2\n");
@@ -765,20 +771,37 @@ void cvx16_bist_wdqlvl_init(uint32_t mode)
cmd[4] = 0; // NOP
cmd[5] = 0; // NOP
#else
#ifdef ENABLE_FASTBOOT0
// cmd queue
// op_code start stop pattern dq_inv dm_inv dq_rotate
// repeat
cmd[0] = (1 << 30) | (sram_st << 21) | (511 << 12) | (5 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(2 << 0); // W 1~17 prbs repeat0
(0 << 0); // W 1~17 prbs repeat0
cmd[1] = (2 << 30) | (sram_st << 21) | (511 << 12) | (5 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(2 << 0); // R 1~17 prbs repeat0
(0 << 0); // R 1~17 prbs repeat0
cmd[2] = (1 << 30) | (sram_st << 21) | (sram_sp << 12) | (6 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(2 << 0); // W 1~17 sram repeat0
(0 << 0); // W 1~17 sram repeat0
cmd[3] = (2 << 30) | (sram_st << 21) | (sram_sp << 12) | (6 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(2 << 0); // R 1~17 sram repeat0
(0 << 0); // R 1~17 sram repeat0
// GOTO addr_not_reset loop_cnt
cmd[4] = (3 << 30) | (0 << 20) | (1 << 0); // GOTO
cmd[4] = 0; // GOTO
cmd[5] = 0; // NOP
#else
// cmd queue
// op_code start stop pattern dq_inv dm_inv dq_rotate
// repeat
cmd[0] = (1 << 30) | (sram_st << 21) | (511 << 12) | (5 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(0 << 0); // W 1~17 prbs repeat0
cmd[1] = (2 << 30) | (sram_st << 21) | (511 << 12) | (5 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(0 << 0); // R 1~17 prbs repeat0
cmd[2] = (1 << 30) | (sram_st << 21) | (sram_sp << 12) | (6 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(0 << 0); // W 1~17 sram repeat0
cmd[3] = (2 << 30) | (sram_st << 21) | (sram_sp << 12) | (6 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(0 << 0); // R 1~17 sram repeat0
// GOTO addr_not_reset loop_cnt
cmd[4] = 0; // GOTO
cmd[5] = 0; // NOP
#endif
#endif
} else if (mode == 0x11) { // bist write/read
//----for Error enject simulation only
@@ -6232,590 +6255,41 @@ void cvx16_ddr_phyd_save(uint32_t sram_base_addr)
void cvx16_ddr_phyd_restore(uint32_t sram_base_addr)
{
int sram_offset = 0x0;
{
uartlog("cvx16_ddr_phyd_restore\n");
ddr_debug_wr32(0x47);
ddr_debug_num_write();
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x0 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x4 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x8 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xc + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x10 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x14 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x18 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x1c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x20 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x24 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x28 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x2c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x40 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x44 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x48 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x4c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x50 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x54 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x58 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x5c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x60 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x64 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x68 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x70 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x74 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x80 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x84 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x88 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x8c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x90 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x94 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa0 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa4 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa8 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xac + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb0 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb4 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb8 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xbc + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xf0 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xf4 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xf8 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xfc + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x100 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x104 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x10c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x110 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x114 + PHYD_BASE_ADDR, rddata);
uintptr_t temp = sram_base_addr;
struct regconf *psave_phy_regs = (struct regconf *)temp;
int i = 0;
uint32_t addr;
uint32_t val;
while (1) {
addr = psave_phy_regs[i].addr;
val = psave_phy_regs[i].val;
i++;
if (addr != REG_GP_REG3) {
if ((addr < (0x0 + PHYD_BASE_ADDR)) || (addr > (0xb54 + PHYD_BASE_ADDR)))
break;
}
switch (addr) {
case (0x118 + PHYD_BASE_ADDR):
//reset param_phyd_clkctrl_init_complete
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x118 + PHYD_BASE_ADDR, rddata & 0x00000000);
//------------------------------------------------------------
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x11c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x120 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x124 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x128 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x12c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
// mmio_wr32 ( 0x130 + PHYD_BASE_ADDR, rddata );
val &= 0x00000000;
break;
case (0x130 + PHYD_BASE_ADDR):
//ca oenz set by c-code
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x134 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x138 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x140 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x144 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x148 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x14c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x150 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
// param_phyd_sel_cke_oenz=1
mmio_wr32(0x154 + PHYD_BASE_ADDR, (rddata | 0x00000001));
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x158 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x15c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x164 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x168 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x16c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x170 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x174 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x180 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x184 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x188 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x18c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x190 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x200 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
// param_phya_reg_tx_byte0_en_extend_oenz_gated_dline =0
mmio_wr32(0x204 + PHYD_BASE_ADDR, (rddata & 0xFFFBFFFF));
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x208 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x220 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
// param_phya_reg_tx_byte1_en_extend_oenz_gated_dline =0
mmio_wr32(0x224 + PHYD_BASE_ADDR, (rddata & 0xFFFBFFFF));
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x228 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x400 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x404 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x408 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x40c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x410 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x414 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x418 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x41c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x500 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x504 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x508 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x50c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x510 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x514 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x518 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x51c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x520 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x540 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x544 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x548 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x54c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x550 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x554 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x558 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x55c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x560 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x900 + PHYD_BASE_ADDR, rddata);
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x904 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x908 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x90c + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x910 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x914 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x918 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x91c + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x920 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x924 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x928 + PHYD_BASE_ADDR, rddata );
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x92c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x930 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x934 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x938 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x940 + PHYD_BASE_ADDR, rddata);
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x944 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x948 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x94c + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x950 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x954 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x958 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x95c + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x960 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x964 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x968 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x96c + PHYD_BASE_ADDR, rddata );
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x970 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x974 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x978 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x97c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x980 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa00 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa04 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa08 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa0c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa10 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa14 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa18 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa1c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa20 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa24 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa28 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa2c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa30 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa34 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa38 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa3c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa40 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa44 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa48 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa4c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa50 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa54 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa58 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa5c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa60 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa64 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa68 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa6c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa70 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa74 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa78 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa7c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb00 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb04 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb08 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb0c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb10 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb14 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb18 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb1c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb20 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb24 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb30 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb34 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb38 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb3c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb40 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb44 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb48 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb4c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb50 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb54 + PHYD_BASE_ADDR, rddata);
continue;
case (0x154 + PHYD_BASE_ADDR):
val |= 0x00000001;
break;
case (0x204 + PHYD_BASE_ADDR):
val &= 0xFFFBFFFF;
break;
case (0x224 + PHYD_BASE_ADDR):
val &= 0xFFFBFFFF;
break;
}
mmio_write_32(addr, val);
}
}

View File

@@ -170,6 +170,7 @@ void ddr_sys_bring_up(void)
uartlog("phy_init !\n");
phy_init();
#endif
mmio_wr32(0x080000a4, 0x02620504);
cvx16_setting_check();
KC_MSG("cvx16_setting_check finish\n");

View File

@@ -7,5 +7,4 @@ struct ddr_param {
int ddr_init(const struct ddr_param *ddr_param);
#endif /* __DDR_H__ */

View File

@@ -457,7 +457,7 @@ extern uint32_t ddr_data_rate;
// f0_param_phya_reg_rx_byte0_sel_odt_reg_mode:[6:6]=0b1
// f0_param_phya_reg_rx_byte1_odt_reg:[12:8]=0b00000
// f0_param_phya_reg_rx_byte1_sel_odt_reg_mode:[14:14]=0b1
#define DDR_PHY_REG_64_F0_DATA 0b00000000000001000001000000000001
#define DDR_PHY_REG_64_F0_DATA 0b00000000000001000000000000000001
// f0_param_phya_reg_rx_byte0_en_lsmode:[0:0]=0b1
// f0_param_phya_reg_rx_byte0_hystr:[5:4]=0b00
// f0_param_phya_reg_rx_byte0_sel_dqs_rec_vref_mode:[8:8]=0b0
@@ -467,7 +467,7 @@ extern uint32_t ddr_data_rate;
// f0_param_phya_reg_rx_byte0_force_en_lvstl_odt:[16:16]=0b0
// f0_param_phya_reg_rx_byte0_en_trig_lvl_rangex2:[18:18]=0b1
// f0_param_phya_reg_rx_byte0_trig_lvl_en_free_offset:[20:20]=0b0
#define DDR_PHY_REG_65_F0_DATA 0b00000000000100000000000000000000
#define DDR_PHY_REG_65_F0_DATA 0b00000000000000000000000000000000
// f0_param_phya_reg_tx_byte0_drvn_de_dq:[1:0]=0b00
// f0_param_phya_reg_tx_byte0_drvp_de_dq:[5:4]=0b00
// f0_param_phya_reg_tx_byte0_drvn_de_dqs:[9:8]=0b00
@@ -501,7 +501,7 @@ extern uint32_t ddr_data_rate;
// f0_param_phyd_reg_byte0_dqsp_offset:[27:24]=0b0000
#define DDR_PHY_REG_72_F0_DATA 0b00000000000000000000000000000011
// f0_param_phyd_tx_byte0_tx_oenz_extend:[2:0]=0b011
#define DDR_PHY_REG_80_F0_DATA 0b00000000000001000001000000000001
#define DDR_PHY_REG_80_F0_DATA 0b00000000000001000000000000000001
// f0_param_phya_reg_rx_byte1_en_lsmode:[0:0]=0b1
// f0_param_phya_reg_rx_byte1_hystr:[5:4]=0b00
// f0_param_phya_reg_rx_byte1_sel_dqs_rec_vref_mode:[8:8]=0b0
@@ -511,7 +511,7 @@ extern uint32_t ddr_data_rate;
// f0_param_phya_reg_rx_byte1_force_en_lvstl_odt:[16:16]=0b0
// f0_param_phya_reg_rx_byte1_en_trig_lvl_rangex2:[18:18]=0b1
// f0_param_phya_reg_rx_byte1_trig_lvl_en_free_offset:[20:20]=0b0
#define DDR_PHY_REG_81_F0_DATA 0b00000000000100000000000000000000
#define DDR_PHY_REG_81_F0_DATA 0b00000000000000000000000000000000
// f0_param_phya_reg_tx_byte1_drvn_de_dq:[1:0]=0b00
// f0_param_phya_reg_tx_byte1_drvp_de_dq:[5:4]=0b00
// f0_param_phya_reg_tx_byte1_drvn_de_dqs:[9:8]=0b00

View File

@@ -457,7 +457,7 @@ extern uint32_t ddr_data_rate;
// f0_param_phya_reg_rx_byte0_sel_odt_reg_mode:[6:6]=0b1
// f0_param_phya_reg_rx_byte1_odt_reg:[12:8]=0b00000
// f0_param_phya_reg_rx_byte1_sel_odt_reg_mode:[14:14]=0b1
#define DDR_PHY_REG_64_F0_DATA 0b00000000000001000001000000000001
#define DDR_PHY_REG_64_F0_DATA 0b00000000000001000000000000000001
// f0_param_phya_reg_rx_byte0_en_lsmode:[0:0]=0b1
// f0_param_phya_reg_rx_byte0_hystr:[5:4]=0b00
// f0_param_phya_reg_rx_byte0_sel_dqs_rec_vref_mode:[8:8]=0b0
@@ -467,7 +467,7 @@ extern uint32_t ddr_data_rate;
// f0_param_phya_reg_rx_byte0_force_en_lvstl_odt:[16:16]=0b0
// f0_param_phya_reg_rx_byte0_en_trig_lvl_rangex2:[18:18]=0b1
// f0_param_phya_reg_rx_byte0_trig_lvl_en_free_offset:[20:20]=0b0
#define DDR_PHY_REG_65_F0_DATA 0b00000000000100000000000000000000
#define DDR_PHY_REG_65_F0_DATA 0b00000000000000000000000000000000
// f0_param_phya_reg_tx_byte0_drvn_de_dq:[1:0]=0b00
// f0_param_phya_reg_tx_byte0_drvp_de_dq:[5:4]=0b00
// f0_param_phya_reg_tx_byte0_drvn_de_dqs:[9:8]=0b00
@@ -501,7 +501,7 @@ extern uint32_t ddr_data_rate;
// f0_param_phyd_reg_byte0_dqsp_offset:[27:24]=0b0000
#define DDR_PHY_REG_72_F0_DATA 0b00000000000000000000000000000011
// f0_param_phyd_tx_byte0_tx_oenz_extend:[2:0]=0b011
#define DDR_PHY_REG_80_F0_DATA 0b00000000000001000001000000000001
#define DDR_PHY_REG_80_F0_DATA 0b00000000000001000000000000000001
// f0_param_phya_reg_rx_byte1_en_lsmode:[0:0]=0b1
// f0_param_phya_reg_rx_byte1_hystr:[5:4]=0b00
// f0_param_phya_reg_rx_byte1_sel_dqs_rec_vref_mode:[8:8]=0b0
@@ -511,7 +511,7 @@ extern uint32_t ddr_data_rate;
// f0_param_phya_reg_rx_byte1_force_en_lvstl_odt:[16:16]=0b0
// f0_param_phya_reg_rx_byte1_en_trig_lvl_rangex2:[18:18]=0b1
// f0_param_phya_reg_rx_byte1_trig_lvl_en_free_offset:[20:20]=0b0
#define DDR_PHY_REG_81_F0_DATA 0b00000000000100000000000000000000
#define DDR_PHY_REG_81_F0_DATA 0b00000000000000000000000000000000
// f0_param_phya_reg_tx_byte1_drvn_de_dq:[1:0]=0b00
// f0_param_phya_reg_tx_byte1_drvp_de_dq:[5:4]=0b00
// f0_param_phya_reg_tx_byte1_drvn_de_dqs:[9:8]=0b00

View File

@@ -10,9 +10,15 @@
#define DDR_VENDOR_ETRON_1G 0b00101
#define DDR_VENDOR_ESMT_2G 0b00110
#define DDR_VENDOR_PM_2G 0b00111
#define DDR_VENDOR_PM_1G 0b01000
#define DDR_VENDOR_ETRON_N20_2G 0b01000
#define DDR_VENDOR_ETRON_512M_DDR2 0b01001
#define DDR_VENDOR_ESMT_N25_1G 0b01010
#define DDR_VENDOR_NY_N20_1G 0b01011
#define DDR_VENDOR_ESMT_N21_2G 0b01100
#define DDR_VENDOR_ESMT_N19_4G 0b01101
#define DDR_VENDOR_UNILC_N25_512M_DDR2 0b01110
#define DDR_VENDOR_UNILC_N25_1G 0b01111
#define DDR_VENDOR_UNILC_N21_2G 0b10000
#define DDR_CAPACITY_UNKNOWN 0b000
#define DDR_CAPACITY_512M 0b001

View File

@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#define SUSPEND_ENTRY __section(".suspend_entry")
#define SUSPEND_FUNC __section(".suspend_func")
#define SUSPEND_DATA __section(".suspend_data")
SUSPEND_ENTRY void ddr_suspend_entry(void);
static SUSPEND_FUNC void susp_udelay(uint32_t delay);
static SUSPEND_FUNC void ddr_sys_suspend_sus_res(void);
static SUSPEND_FUNC void cvx16_ddr_phya_pd_sus_res(void);
static SUSPEND_FUNC void cvx16_ddrc_suspend_sus_res(void);
static SUSPEND_FUNC void cvx16_ddr_phyd_save_sus_res(uint32_t);
static SUSPEND_FUNC void rtc_clr_ddr_pwrok(void);
static SUSPEND_FUNC void rtc_clr_rmio_pwrok(void);
// #define SUSPEND_USE_WDG_RST
#ifndef SUSPEND_USE_WDG_RST
static SUSPEND_FUNC void rtc_req_suspend(void);
#else
static SUSPEND_FUNC void rtc_req_wdg_rst(void);
#endif
struct reg {
uint32_t addr;
uint32_t val;
};

View File

@@ -51,6 +51,12 @@ enum CHIP_CONF_CMD {
CHIP_CONF_CMD_DELAY_MS = 0xFFFFFFFD
};
enum CHIP_CLK_MODE {
CLK_ND = 0,
CLK_OD,
CLK_VC_OD
};
void apply_chip_conf(const struct chip_conf chip_conf[], uint32_t size, enum CHIP_CONF_CMD scan_start,
enum CHIP_CONF_CMD scan_end);
@@ -125,7 +131,7 @@ void sys_switch_all_to_pll(void);
void lock_efuse_chipsn(void);
int load_ddr(void);
int load_rest(void);
int load_rest_od_sel(void);
void jump_to_warmboot_entry(void);
#endif /* __ASSEMBLY__ */

View File

@@ -309,6 +309,7 @@ extern struct _time_records *time_records;
#define BOOT_SOURCE_FLAG_SIZE 4
#define MAGIC_NUM_USB_DL 0x4D474E31 // MGN1
#define MAGIC_NUM_SD_DL 0x4D474E32 // MGN2
#define MAGIC_NUM_UART_DL 0x4D474E33 // MGN3
#define BOOT_LOG_LEN_ADDR (BOOT_SOURCE_FLAG_ADDR + BOOT_SOURCE_FLAG_SIZE) // 0x0E000008
#define BOOT_LOG_LEN_SIZE 4

View File

@@ -13,6 +13,8 @@
#include "ddr_pkg_info.h"
#include "rtc.h"
extern enum CHIP_CLK_MODE chip_clk_mode;
void panic_handler(void)
{
void *ra;
@@ -96,6 +98,9 @@ void setup_dl_flag(void)
uint32_t v = p_rom_api_get_boot_src();
switch (v) {
case BOOT_SRC_UART:
mmio_write_32(BOOT_SOURCE_FLAG_ADDR, MAGIC_NUM_UART_DL);
break;
case BOOT_SRC_SD:
mmio_write_32(BOOT_SOURCE_FLAG_ADDR, MAGIC_NUM_SD_DL);
break;
@@ -110,6 +115,9 @@ void setup_dl_flag(void)
void config_core_power(uint32_t low_period)
{
if (PKG_QFN68 == get_pkg())
return;
/*
* low_period = 0x42; // 0.90V
* low_period = 0x48; // 0.93V
@@ -134,7 +142,6 @@ void sys_switch_all_to_pll(void)
mmio_write_32(0x03002034, 0x0); // REG_CLK_BYPASS_SEL1_REG
}
// #ifdef OD_CLK_SEL
void sys_pll_od(void)
{
// OD clk setting
@@ -142,7 +149,7 @@ void sys_pll_od(void)
uint32_t byp0_value;
uint32_t pll_syn_set[] = {
614400000, // set apll synthesizer 98.304 M
614440960, // set apll synthesizer 98.304 M
610080582, // set disp synthesizer 99 M
610080582, // set cam0 synthesizer 99 M
//586388132, // set cam1 synthesizer 103 M
@@ -197,10 +204,6 @@ void sys_pll_od(void)
// set mpll = 1050MHz
mmio_write_32(0x03002908, 0x05548101);
// set clk_sel_23: [23] clk_sel for clk_c906_0 = 1 (DIV_IN0_SRC_MUX)
// set clk_sel_24: [24] clk_sel for clk_c906_1 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x01800000);
// set div, src_mux of clk_c906_0: [20:16]div_factor=1, [9:8]clk_src = 3 (mpll), 1050/1 = 1050MHz
mmio_write_32(0x03002130, 0x00010309);
@@ -210,9 +213,6 @@ void sys_pll_od(void)
// set mpll = 1000MHz
mmio_write_32(0x03002908, 0x05508101);
// set clk_sel_0: [0] clk_sel for clk_a53 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x00000001);
// set div, src_mux of clk_a53: [20:16]div_factor=1, [9:8]clk_src = 3 (mpll)
mmio_write_32(0x03002040, 0x00010309);
#endif
@@ -222,7 +222,7 @@ void sys_pll_od(void)
mmio_write_32(0x03002048, 0x00020109); //clk_cpu_axi0 = DISPPLL(1188) / 2
mmio_write_32(0x03002054, 0x00020009); //clk_tpu = TPLL(1400) / 2 = 700MHz
mmio_write_32(0x03002064, 0x00080009); //clk_emmc = FPLL(1500) / 8 = 187.5MHz
mmio_write_32(0x03002064, 0x00040009); //clk_emmc = FPLL(1500) / 4 = 375MHz
mmio_write_32(0x03002088, 0x00080009); //clk_spi_nand = FPLL(1500) / 8 = 187.5MHz
mmio_write_32(0x03002098, 0x00200009); //clk_sdma_aud0 = APLL(786.432) / 32 = 24.576MHz
mmio_write_32(0x03002120, 0x000F0009); //clk_pwm_src = FPLL(1500) / 15 = 100MHz
@@ -251,6 +251,15 @@ void sys_pll_od(void)
//wait for pll stable
udelay(200);
#ifdef __riscv
// set clk_sel_23: [23] clk_sel for clk_c906_0 = 1 (DIV_IN0_SRC_MUX)
// set clk_sel_24: [24] clk_sel for clk_c906_1 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x01800000);
#else
// set clk_sel_0: [0] clk_sel for clk_a53 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x00000001);
#endif
// switch clock to PLL from xtal except clk_axi4 & clk_spi_nand
byp0_value &= (1 << 8 | //clk_spi_nand
1 << 19 //clk_axi4
@@ -258,16 +267,15 @@ void sys_pll_od(void)
mmio_write_32(0x03002030, byp0_value); // REG_CLK_BYPASS_SEL0_REG
mmio_write_32(0x03002034, 0x0); // REG_CLK_BYPASS_SEL1_REG
}
// #endif
void sys_pll_nd(void)
void sys_pll_nd(int vc_overdrive)
{
// ND clk setting
uint32_t value;
uint32_t byp0_value;
uint32_t pll_syn_set[] = {
614400000, // set apll synthesizer 98.304 M
614440960, // set apll synthesizer 98.304 M
610080582, // set disp synthesizer 99 M
610080582, // set cam0 synthesizer 99 M
615164587, // set cam1 synthesizer 98.18181818 M
@@ -283,6 +291,11 @@ void sys_pll_nd(void)
NOTICE("PLLS.\n");
if (vc_overdrive) {
// set vddc for OD clock
config_core_power(0x58); //1.00V
}
// store byp0 value
byp0_value = mmio_read_32(0x03002030);
@@ -317,10 +330,6 @@ void sys_pll_nd(void)
// set mpll = 850MHz
mmio_write_32(0x03002908, 0x00448101);
// set clk_sel_23: [23] clk_sel for clk_c906_0 = 1 (DIV_IN0_SRC_MUX)
// set clk_sel_24: [24] clk_sel for clk_c906_1 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x01800000);
// set div, src_mux of clk_c906_0: [20:16]div_factor=1, [9:8]clk_src = 3 (mpll), 850/1 = 850MHz
mmio_write_32(0x03002130, 0x00010309);
@@ -330,9 +339,6 @@ void sys_pll_nd(void)
// set mpll = 800MHz
mmio_write_32(0x03002908, 0x00408101);
// set clk_sel_0: [0] clk_sel for clk_a53 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x00000001);
// set div, src_mux of clk_a53: [20:16]div_factor=1, [9:8]clk_src = 3 (mpll)
mmio_write_32(0x03002040, 0x00010309);
#endif
@@ -342,20 +348,31 @@ void sys_pll_nd(void)
mmio_write_32(0x03002048, 0x00030009); //clk_cpu_axi0 = FPLL(1500) / 3
mmio_write_32(0x03002054, 0x00030309); //clk_tpu = FPLL(1500) / 3 = 500MHz
mmio_write_32(0x03002064, 0x00080009); //clk_emmc = FPLL(1500) / 8 = 187.5MHz
mmio_write_32(0x03002064, 0x00040009); //clk_emmc = FPLL(1500) / 4 = 375MHz
mmio_write_32(0x03002088, 0x00080009); //clk_spi_nand = FPLL(1500) / 8 = 187.5MHz
mmio_write_32(0x03002098, 0x00120009); //clk_sdma_aud0 = APLL(442.368) / 18 = 24.576MHz
mmio_write_32(0x03002120, 0x000F0009); //clk_pwm_src = FPLL(1500) / 15 = 100MHz
mmio_write_32(0x030020A8, 0x00010009); //clk_uart -> clk_cam0_200 = XTAL(25) / 1 = 25MHz
mmio_write_32(0x030020C8, 0x00030009); //clk_axi_vip = MIPIPLL(900) / 3 = 300MHz
mmio_write_32(0x03002110, 0x00020209); //clk_src_vip_sys_2 = DISPPLL(1188) / 2 = 594MHz
if (vc_overdrive) {
mmio_write_32(0x030020E4, 0x00030209); //clk_axi_video_codec = CAM1PLL(1080) / 3 = 360MHz
mmio_write_32(0x030020EC, 0x00020109); //clk_vc_src0 = MIPIPLL(900) / 2 = 450MHz
mmio_write_32(0x030020D0, 0x00060309); //clk_src_vip_sys_0 = FPLL(1500) / 6 = 250MHz
mmio_write_32(0x030020D8, 0x00040209); //clk_src_vip_sys_1 = DISPPLL(1188)/ 4 = 297MHz
//mmio_write_32(0x03002140, 0x00020009); //clk_src_vip_sys_3 = MIPIPLL(900) / 2 = 450MHz
mmio_write_32(0x03002144, 0x00030309); //clk_src_vip_sys_4 = FPLL(1500) / 3 = 500MHz
} else {
mmio_write_32(0x030020E4, 0x00030109); //clk_axi_video_codec = MIPIPLL(900) / 3 = 300MHz
mmio_write_32(0x030020EC, 0x00040309); //clk_vc_src0 = FPLL(1500) / 4 = 375MHz
mmio_write_32(0x030020C8, 0x00030009); //clk_axi_vip = MIPIPLL(900) / 3 = 300MHz
mmio_write_32(0x030020D0, 0x00060209); //clk_src_vip_sys_0 = DISPPLL(1188) / 6 = 198MHz
mmio_write_32(0x030020D8, 0x00060209); //clk_src_vip_sys_1 = DISPPLL(1188) / 6 = 198MHz
mmio_write_32(0x03002110, 0x00020209); //clk_src_vip_sys_2 = DISPPLL(1188) / 2 = 594MHz
//mmio_write_32(0x03002140, 0x00030009); //clk_src_vip_sys_3 = MIPIPLL(900) / 3 = 300MHz
mmio_write_32(0x03002144, 0x00030209); //clk_src_vip_sys_4 = DISPPLL(1188) / 3 = 396MHz
}
// set hsperi clock to PLL (FPLL) div by 5 = 300MHz
mmio_write_32(0x030020B8, 0x00050009); //--> CLK_AXI4
@@ -371,6 +388,15 @@ void sys_pll_nd(void)
//wait for pll stable
udelay(200);
#ifdef __riscv
// set clk_sel_23: [23] clk_sel for clk_c906_0 = 1 (DIV_IN0_SRC_MUX)
// set clk_sel_24: [24] clk_sel for clk_c906_1 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x01800000);
#else
// set clk_sel_0: [0] clk_sel for clk_a53 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x00000001);
#endif
// switch clock to PLL from xtal except clk_axi4 & clk_spi_nand
byp0_value &= (1 << 8 | //clk_spi_nand
1 << 19 //clk_axi4
@@ -381,26 +407,17 @@ void sys_pll_nd(void)
void sys_pll_init(void)
{
sys_pll_nd();
NOTICE("PLLE.\n");
}
void sys_pll_init_od_sel(void)
{
uint8_t pkg = get_pkg();
switch (pkg) {
case PKG_QFN88:
NOTICE("pkg QFN88\n");
switch (chip_clk_mode) {
case CLK_VC_OD:
sys_pll_nd(1);
break;
case CLK_OD:
sys_pll_od();
break;
case PKG_QFN68:
NOTICE("QFN68: OD UNSUPPORTED!\n");
sys_pll_nd();
break;
case CLK_ND:
default:
NOTICE("unknown pkg=%d\n", pkg);
sys_pll_od();
sys_pll_nd(0);
break;
}
NOTICE("PLLE.\n");
}
@@ -435,12 +452,14 @@ void switch_rtc_mode_2nd_stage(void)
void set_rtc_en_registers(void)
{
uint32_t write_data;
#ifndef FSBL_FASTBOOT
uint32_t read_data;
read_data = mmio_read_32(REG_RTC_BASE + RTC_ST_ON_REASON);
NOTICE("st_on_reason=%x\n", read_data);
read_data = mmio_read_32(REG_RTC_BASE + RTC_ST_OFF_REASON);
NOTICE("st_off_reason=%x\n", read_data);
#endif
mmio_write_32(REG_RTC_BASE + RTC_EN_SHDN_REQ, 0x01);
while (mmio_read_32(REG_RTC_BASE + RTC_EN_SHDN_REQ) != 0x01)
@@ -454,7 +473,12 @@ void set_rtc_en_registers(void)
mmio_write_32(REG_RTC_BASE + RTC_EN_WDT_RST_REQ, 0x01);
while (mmio_read_32(REG_RTC_BASE + RTC_EN_WDT_RST_REQ) != 0x01)
;
mmio_setbits_32(REG_RTC_CTRL_BASE + RTC_POR_RST_CTRL, 0X1);
#ifdef CONFIG_SUSPEND
// Set rtcsys_rst_ctrl[24] = 1; bit 24 is reg_rtcsys_reset_en
mmio_write_32(REG_RTC_CTRL_BASE + RTC_POR_RST_CTRL, 0X2);
#else
mmio_write_32(REG_RTC_CTRL_BASE + RTC_POR_RST_CTRL, 0X1);
#endif
mmio_write_32(REG_RTC_CTRL_BASE + RTC_CTRL0_UNLOCKKEY, 0xAB18);
write_data = mmio_read_32(REG_RTC_CTRL_BASE + RTC_CTRL0);
write_data = 0xffff0000 | write_data | (0x1 << 11) | (0x01 << 6);

View File

@@ -14,6 +14,13 @@ TEST_FROM_SPINOR1 := 0
DEFINES += -DLZ4_USER_MEMORY_FUNCTIONS=1
# overdrive clock setting
ifeq ($(OD_CLK_SEL),y)
$(eval $(call add_define,OD_CLK_SEL))
else ifeq ($(VC_CLK_OVERDRIVE),y)
$(eval $(call add_define,VC_CLK_OVERDRIVE))
endif
# ifeq ($(FSBL_SECURE_BOOT_SUPPORT),1)
DEFINES += \
-DNO_ALLOCS \
@@ -65,6 +72,7 @@ BL2_SRCS = \
${BL_COMMON_SOURCES} \
plat/${CHIP_ARCH}/platform_device.c \
plat/${CHIP_ARCH}/bl2/bl2_opt.c \
plat/${CHIP_ARCH}/bl2/cvi_spinand.c \
lib/utils/decompress.c \
plat/${CHIP_ARCH}/usb/cps_cvi.c \
plat/${CHIP_ARCH}/usb/usb_tty.c \

View File

@@ -1135,6 +1135,7 @@ static int dwc2_udc_get_status(struct dwc2_udc *dev,
// DWC2_CacheFlush((unsigned long) dev->usb_ctrl, ROUND(sizeof(g_status), CONFIG_SYS_CACHELINE_SIZE));
// flush_dcache_range((unsigned long)dev->usb_ctrl, ROUND(sizeof(g_status), CONFIG_SYS_CACHELINE_SIZE));
#ifdef DWC2_DMA_EN
DWC2_UncachedWrite32(dev->usb_ctrl_dma_addr, &reg->in_endp[EP0_CON].diepdma);
DWC2_UncachedWrite32(DIEPT_SIZ_PKT_CNT(1) | DIEPT_SIZ_XFER_SIZE(2),
&reg->in_endp[EP0_CON].dieptsiz);
@@ -1143,6 +1144,17 @@ static int dwc2_udc_get_status(struct dwc2_udc *dev,
ep_ctrl &= ~(1 << 30);
DWC2_UncachedWrite32(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK,
&reg->in_endp[EP0_CON].diepctl);
#else
DWC2_UncachedWrite32(DIEPT_SIZ_PKT_CNT(1) | DIEPT_SIZ_XFER_SIZE(2),
&reg->in_endp[EP0_CON].dieptsiz);
ep_ctrl = DWC2_UncachedRead32(&reg->in_endp[EP0_CON].diepctl);
ep_ctrl |= (DEPCTL_EPENA|DEPCTL_CNAK);
DWC2_UncachedWrite32(ep_ctrl, &reg->in_endp[EP0_CON].diepctl);
dwc2_ep_fifo_write(dev, ep_num, (uint8_t *)dev->usb_ctrl, sizeof(g_status));
DWC2_UncachedWrite32(1UL << (ep_num & 0x0f), &reg->diepempmsk);
#endif
dev->ep0state = WAIT_FOR_NULL_COMPLETE;
return 0;

View File

@@ -17,6 +17,8 @@ ENTRY(bl2_entrypoint)
MEMORY {
RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_SIZE
SRAM (rwx): ORIGIN = 0x000000000C030000, LENGTH = 0x10000
}
SECTIONS
@@ -80,5 +82,17 @@ SECTIONS
ASSERT(. <= (BL2_BASE + BL2_SIZE), "BL2 image has exceeded its limit.")
.suspend_sect :
{
. = ALIGN(8);
__suspend_sect_start = .;
KEEP(*(.suspend_entry))
KEEP(*(.suspend_func))
. = ALIGN(8);
__suspend_data_start = .;
KEEP(*(.suspend_data))
. = ALIGN(8);
__suspend_sect_end = .;
} > SRAM
#include <rom_api_refer.h>
}

View File

@@ -5,7 +5,8 @@
#include <string.h>
#include <delay_timer.h>
#include <rom_api.h>
#include <cpu.h>
enum CHIP_CLK_MODE chip_clk_mode = CLK_ND;
#ifdef RTOS_ENABLE_FREERTOS
int init_comm_info(int ret)
{
@@ -48,7 +49,6 @@ int dec_verify_image(const void *image, size_t size, size_t dec_skip, struct fip
void bl2_main(void)
{
enum CHIP_CLK_MODE mode;
uint32_t v = p_rom_api_get_boot_src();
if (v == BOOT_SRC_UART) {
@@ -71,22 +71,28 @@ void bl2_main(void)
setup_dl_flag();
#ifdef SWITCH_32K_XTAL
switch_rtc_mode_1st_stage();
#endif
set_rtc_en_registers();
load_ddr();
#ifdef OD_CLK_SEL
mode = CLK_OD;
chip_clk_mode = CLK_OD;
#else
#ifdef VC_CLK_OVERDRIVE
mode = CLK_VC_OD;
#else
mode = CLK_ND;
chip_clk_mode = CLK_VC_OD;
#endif
#endif
load_rest(mode);
#ifdef CONFIG_SUSPEND
#ifndef NO_DDR_CFG //for fpga
jump_to_warmboot_entry();
#endif
#endif
load_ddr();
load_rest();
NOTICE("BL2 end.\n");
while (1)

View File

@@ -11,10 +11,18 @@
#include <rom_api.h>
#include <bl2.h>
#include <ddr.h>
#include <ddr_sys.h>
#include <rtc.h>
#include <string.h>
#include <decompress.h>
#include <delay_timer.h>
#include <security/security.h>
#include <emmc/emmc.h>
#include <cv_spi_nand.h>
uint64_t load_addr = 0x0c000;
uint64_t run_addr = 0x8000C000;
uint64_t reading_size = 0x020000;
struct _time_records *time_records = (void *)TIME_RECORDS_ADDR;
struct fip_param1 *fip_param1 = (void *)PARAM1_BASE;
@@ -108,48 +116,17 @@ int load_param2(int retry)
return 0;
}
int load_ddr_param(int retry)
{
uint32_t crc;
int ret = -1;
NOTICE("DPS/0x%x/0x%x.\n", fip_param2.ddr_param_loadaddr, fip_param2.ddr_param_size);
if (fip_param2.ddr_param_size >= sizeof(sram_union_buf.ddr_param))
fip_param2.ddr_param_size = sizeof(sram_union_buf.ddr_param);
ret = p_rom_api_load_image(&sram_union_buf.ddr_param, fip_param2.ddr_param_loadaddr, fip_param2.ddr_param_size,
retry);
if (ret < 0) {
return ret;
}
crc = p_rom_api_image_crc(&sram_union_buf.ddr_param, fip_param2.ddr_param_size);
if (crc != fip_param2.ddr_param_cksum) {
ERROR("ddr_param_cksum (0x%x/0x%x)\n", crc, fip_param2.ddr_param_cksum);
return -1;
}
NOTICE("DPE.\n");
return 0;
}
int load_ddr(void)
{
#ifndef ENABLE_BOOT0
int retry = 0;
retry_from_flash:
for (retry = 0; retry < p_rom_api_get_number_of_retries(); retry++) {
if (load_param2(retry) < 0)
continue;
if (load_ddr_param(retry) < 0)
continue;
break;
}
if (retry >= p_rom_api_get_number_of_retries()) {
switch (p_rom_api_get_boot_src()) {
case BOOT_SRC_UART:
@@ -160,11 +137,11 @@ retry_from_flash:
p_rom_api_flash_init();
goto retry_from_flash;
default:
ERROR("Failed to load DDR param (%d).\n", retry);
ERROR("Failed to load param2 (%d).\n", retry);
panic_handler();
}
}
#endif
time_records->ddr_init_start = read_time_ms();
ddr_init(&sram_union_buf.ddr_param);
time_records->ddr_init_end = read_time_ms();
@@ -172,6 +149,45 @@ retry_from_flash:
return 0;
}
static int emmc_read_fip_bl2(uint32_t offset, uint32_t size, uintptr_t buf)
{
int lba = 0;
if (((offset & EMMC_BLOCK_MASK) != 0) || ((buf & EMMC_BLOCK_MASK) != 0) || ((size & EMMC_BLOCK_MASK) != 0))
return -22;
lba = offset / EMMC_BLOCK_SIZE;
// INFO("%s offset %x,lba %d, size %d, dst buf 0x%lx\n", __func__, offset, lba, size, buf);
if (size != emmc_partition_read_blocks(EMMC_PARTITION_BOOT1, lba, buf, size))
return -5;
return 0;
}
static int load_data_from_storage(void *buffer, uint32_t offset, uint32_t size, int retry)
{
static int is_get_boot_src;
static int boot_src;
if (!is_get_boot_src) {
boot_src = p_rom_api_get_boot_src();
is_get_boot_src = 1;
/* reinit eMMC */
if (boot_src == BOOT_SRC_EMMC)
bm_emmc_init();
}
//use BL2 eMMC driver to load image
if (boot_src == BOOT_SRC_EMMC) {
return emmc_read_fip_bl2(offset, size, (uintptr_t)buffer);
} else {
return p_rom_api_load_image(buffer, offset, size, retry);
}
}
int load_blcp_2nd(int retry)
{
uint32_t crc, rtos_base;
@@ -198,7 +214,7 @@ int load_blcp_2nd(int retry)
panic_handler();
}
ret = p_rom_api_load_image((void *)(uintptr_t)fip_param2.blcp_2nd_runaddr, fip_param2.blcp_2nd_loadaddr,
ret = load_data_from_storage((void *)(uintptr_t)fip_param2.blcp_2nd_runaddr, fip_param2.blcp_2nd_loadaddr,
fip_param2.blcp_2nd_size, retry);
if (ret < 0) {
return ret;
@@ -221,12 +237,20 @@ int load_blcp_2nd(int retry)
rtos_base = mmio_read_32(AXI_SRAM_RTOS_BASE);
init_comm_info(0);
switch (p_rom_api_get_boot_src()) {
case BOOT_SRC_UART:
// case BOOT_SRC_SD:
// case BOOT_SRC_USB:
break;
default:
time_records->release_blcp_2nd = read_time_ms();
if (rtos_base == CVI_RTOS_MAGIC_CODE) {
mmio_write_32(AXI_SRAM_RTOS_BASE, fip_param2.blcp_2nd_runaddr);
} else {
reset_c906l(fip_param2.blcp_2nd_runaddr);
}
}
NOTICE("C2E.\n");
@@ -256,7 +280,7 @@ int load_monitor(int retry, uint64_t *monitor_entry)
panic_handler();
}
ret = p_rom_api_load_image((void *)(uintptr_t)fip_param2.monitor_runaddr, fip_param2.monitor_loadaddr,
ret = load_data_from_storage((void *)(uintptr_t)fip_param2.monitor_runaddr, fip_param2.monitor_loadaddr,
fip_param2.monitor_size, retry);
if (ret < 0) {
return ret;
@@ -282,6 +306,58 @@ int load_monitor(int retry, uint64_t *monitor_entry)
return 0;
}
#ifdef ENABLE_BURN_BUTTON
int button_usb_down_pressed(void)
{
// Modify the GPIO configuration as needed!!!!!!!!!
uint8_t gpio_grp = GPIO_GRP, gpio_pin = GPIO_PIN; // XGPIOB[3];
NOTICE("gpio_grp = %d gpio_pin = %d\n", gpio_grp, gpio_pin);
// gpio base addr: gpioa, gpiob, gpioc, gpiod, pwr_gpio;
uint32_t gpio_base[5] = { 0x03020000, 0x03021000, 0x03022000, 0x03023000, 0x05021000 };
uint32_t gpio_direction_addr = gpio_base[gpio_grp] + 0x4;
uint32_t gpio_value_addr = gpio_base[gpio_grp] + 0x50;
uint32_t val = 0x1;
/* pinmux config */
// mmio_write_32(0x03001098, 0x3);
/* open internel pull up */
// mmio_write_32(0x05027020, 0x44);
/* gpio input mode */
val = mmio_read_32(gpio_direction_addr) & (~(1 << gpio_pin));
mmio_write_32(gpio_direction_addr, val);
/* gpio debouncing */
val = (mmio_read_32(gpio_value_addr) >> gpio_pin) & 0x1;
NOTICE("key value = %u (key down should be 0)\n", val);
if (!val) {
mdelay(10);
val = (mmio_read_32(gpio_value_addr) >> gpio_pin) & 0x1;
NOTICE("repeat key value = %u (key down should be 0)\n", val);
return !val;
}
return 0; // pressed:1 unpressed:0
}
int load_uboot(void *image_buf, int retry)
{
int ret = -1;
int reading_size = 0;
reading_size = ROUND_UP(fip_param2.loader_2nd_b_size, BLOCK_SIZE);
NOTICE("reading_size:%x, addr:=0x%x\n", reading_size, fip_param2.loader_2nd_b_loadaddr);
ret = load_data_from_storage(image_buf, fip_param2.loader_2nd_b_loadaddr, reading_size, retry);
if (ret < 0) {
return -1;
}
return 0;
}
#endif
int load_loader_2nd(int retry, uint64_t *loader_2nd_entry)
{
struct loader_2nd_header *loader_2nd_header = &sram_union_buf.loader_2nd_header;
@@ -296,7 +372,7 @@ int load_loader_2nd(int retry, uint64_t *loader_2nd_entry)
NOTICE("L2/0x%x.\n", fip_param2.loader_2nd_loadaddr);
ret = p_rom_api_load_image(loader_2nd_header, fip_param2.loader_2nd_loadaddr, BLOCK_SIZE, retry);
ret = load_data_from_storage(loader_2nd_header, fip_param2.loader_2nd_loadaddr, BLOCK_SIZE, retry);
if (ret < 0) {
return -1;
}
@@ -306,6 +382,18 @@ int load_loader_2nd(int retry, uint64_t *loader_2nd_entry)
NOTICE("L2/0x%x/0x%x/0x%lx/0x%x/0x%x\n", loader_2nd_header->magic, loader_2nd_header->cksum,
loader_2nd_header->runaddr, loader_2nd_header->size, reading_size);
#ifdef ENABLE_BURN_BUTTON
if (button_usb_down_pressed()) {
NOTICE("usb_down button pressed.\n");
mmio_write_32(BOOT_SOURCE_FLAG_ADDR, MAGIC_NUM_USB_DL);
loader_2nd_header->runaddr = CONFIG_SYS_TEXT_BASE;
ret = load_uboot((void *)loader_2nd_header->runaddr, retry);
if (ret < 0) {
return -1;
}
goto done;
}
#endif
switch (loader_2nd_header->magic) {
case LOADER_2ND_MAGIC_LZMA:
comp_type = COMP_LZMA;
@@ -366,7 +454,9 @@ int load_loader_2nd(int retry, uint64_t *loader_2nd_entry)
reading_size = dst_size;
}
#ifdef ENABLE_BURN_BUTTON
done:
#endif
flush_dcache_range(loader_2nd_header->runaddr, reading_size);
time_records->fsbl_decomp_end = read_time_ms();
NOTICE("Loader_2nd loaded.\n");
@@ -376,15 +466,81 @@ int load_loader_2nd(int retry, uint64_t *loader_2nd_entry)
return 0;
}
int load_rest(enum CHIP_CLK_MODE mode)
int load_loader_2nd_alios(int retry, uint64_t *loader_2nd_entry)
{
void *image_buf;
int ret = -1;
#ifdef BOOT_SPINOR
load_addr = 0x0c000;
#endif
#ifdef BOOT_EMMC
load_addr = 0x00000;
#endif
#ifdef BOOT_SPINAND
load_addr = 0x280000;
#endif
uint64_t loadaddr_alios = load_addr;
uint64_t runaddr_alios = run_addr;
uint64_t size_alios = reading_size;
image_buf = (void *)runaddr_alios;
NOTICE("loadaddr_alios:0x%lx runaddr_alios:0x%lx.\n", loadaddr_alios, runaddr_alios);
#ifdef BOOT_SPINAND
/* SPI-NAND uses the in-tree raw-read driver: read linearly by physical
* page, bypassing the ROM API FIP (FIPH/fip_vector) scan. The single-image
* RTT boot partition is not in the NAND-FIP layout, so the ROM API returns
* FIP0NC. get_nand_info() self-calibrates the geometry on the first read.
* Compiled only into spinand boot0 images; the full-FIP paths are untouched,
* symmetric with cv180x. */
{
static int nand_info_ready;
if (!nand_info_ready) {
get_nand_info();
nand_info_ready = 1;
}
ret = cv_spi_nand_read_data(image_buf, loadaddr_alios, size_alios);
}
#else
ret = p_rom_api_load_image(image_buf, loadaddr_alios, size_alios, retry);
#endif
/* Must check the return value: the original code ignored ret and jumped to
* run_addr executing garbage on a failed load, causing a panic. */
if (ret < 0) {
ERROR("load loader_2nd_alios failed (%d)\n", ret);
return ret;
}
NOTICE("image_buf:0x%lx.\n", *((uint64_t *)runaddr_alios));
if (security_is_tee_enabled()) {
ret = dec_verify_image(image_buf,size_alios, 0, fip_param1);
if (ret < 0) {
ERROR("verify alios boot0 failed (%d)\n", ret);
return ret;
}
}
sys_switch_all_to_pll();
*loader_2nd_entry = run_addr;
return 0;
}
int load_rest(void)
{
int retry = 0;
uint64_t monitor_entry = 0;
uint64_t loader_2nd_entry = 0;
// Init sys PLL and switch clocks to PLL
sys_pll_init(mode);
sys_pll_init();
#ifndef ENABLE_BOOT0
#ifdef FSBL_FASTBOOT
mmio_write_32(0x030020B8, 0x00030009); // improve axi clock from 300m to 500m
#endif
retry_from_flash:
for (retry = 0; retry < p_rom_api_get_number_of_retries(); retry++) {
if (load_blcp_2nd(retry) < 0)
@@ -414,10 +570,36 @@ retry_from_flash:
}
}
#ifdef FSBL_FASTBOOT
mmio_write_32(0x030020B8, 0x00050009); // restore axi clock from 500m to 300m
#endif
sync_cache();
console_flush();
switch_rtc_mode_2nd_stage();
// switch_rtc_mode_2nd_stage();
#else
#ifdef ENABLE_FASTBOOT0
mmio_write_32(0x030020B8, 0x00030009);
#endif
if (load_loader_2nd_alios(retry, &loader_2nd_entry) < 0)
return -1;
#ifdef ENABLE_FASTBOOT0
mmio_write_32(0x030020B8, 0x00050009);
#endif
sync_cache();
// switch_rtc_mode_2nd_stage();
#ifdef __riscv
/*
* RISC-V: jump_to_loader_2nd() is empty; jump_to_monitor() calls the
* image directly in M-mode, which is how the loaded image is started.
* AArch64: leave monitor_entry at 0 so jump_to_loader_2nd() drops to
* EL2-NS. jump_to_monitor() would enter the image at secure EL3 with
* BL31 params, and the image loaded here is not a BL31 monitor.
*/
monitor_entry = run_addr;
#endif
#endif
if (monitor_entry) {
NOTICE("Jump to monitor at 0x%lx.\n", monitor_entry);

View File

@@ -0,0 +1,400 @@
#include "cv_spi_nand.h"
#include "mmio.h"
#include <cpu.h>
#include <assert.h>
#include <delay_timer.h>
#include <errno.h>
#include <mmio.h>
#include <platform.h>
#include <string.h>
#include <platform.h>
#include <security/security.h>
static unsigned long spi_nand_ctrl_base = SPINAND_BASE;
/* default value */
static struct spi_nand_info_t spinand_info;
static uint8_t ecc_en_status = 0xff;
#define BASE_SYSDMAC 0x04330000
#define SPI_NAND_INTERRUPT_UDELAY_TIME 10
#define SPI_NAND_INTERRUPT_UDELAY_COUNT (100000000 / SPI_NAND_INTERRUPT_UDELAY_TIME)
#define SPI_NAND_PLANE_BIT_OFFSET BIT(12)
static int spi_nand_set_feature(uint8_t fe, uint8_t val)
{
uint32_t fe_set = fe | (val << 8);
uint32_t retry = 0;
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL2, 2 << TRX_CMD_CONT_SIZE_SHIFT);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL3, BIT_REG_TRX_RW);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CMD0,
(fe_set << TRX_CMD_CONT0_SHIFT) | SPI_NAND_CMD_SET_FEATURE);
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL0, BIT_REG_TRX_START);
while(((mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_INT) & BIT_REG_TRX_DONE_INT) == 0)
&& (retry++ < SPI_NAND_INTERRUPT_UDELAY_COUNT))
udelay(1);
if (retry > SPI_NAND_INTERRUPT_UDELAY_COUNT) {
ERROR("SPINAND command error, no interrupt, %d %s\n", retry, __func__);
//assert(0);
}
// clr trx done intr
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_CLR, BIT_REG_TRX_DONE_INT);
return 0;
}
static void spi_nand_setup_intr(void)
{
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_EN, 3);
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_CLR, BITS_SPI_NAND_INT_CLR_ALL);
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_MASK, 0x00000f00);
}
static uint8_t spi_nand_get_feature(uint32_t fe)
{
uint32_t val = 0;
uint32_t retry = 0;
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL2,
1 << TRX_DATA_SIZE_SHIFT | 1 << TRX_CMD_CONT_SIZE_SHIFT);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL3, 0);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CMD0, fe << 8 | SPI_NAND_CMD_GET_FEATURE);
spi_nand_setup_intr();
// Trigger communication start
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL0, BIT_REG_TRX_START);
while(((mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_INT) & BIT_REG_TRX_DONE_INT) == 0)
&& (retry++ < SPI_NAND_INTERRUPT_UDELAY_COUNT))
udelay(1);
if (retry > SPI_NAND_INTERRUPT_UDELAY_COUNT) {
ERROR("SPINAND command error, no interrupt, %d %s\n", retry, __func__);
}
val = mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_RX_DATA);
uint32_t intr = mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_INT);
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_CLR, intr);
return (val & 0xff);
}
void spi_nand_rw_dma_setup(void *buf, uint32_t len, uint32_t rw)
{
uint32_t ch = 0;
VERBOSE("%s: buf %p, len %d\n", __func__, buf, len);
mmio_write_32(BASE_SYSDMAC + 0x010, 0x00000003);
mmio_write_32(BASE_SYSDMAC + 0x018, 0x00000f00);
mmio_write_32(BASE_SYSDMAC + 0x110 + ch * (0x100), (len / 4) - 1);
mmio_write_32(BASE_SYSDMAC + 0x11C + ch * (0x100), 0x000f0792);
buf = (void *)phys_to_dma((uintptr_t) buf);
if (rw) {
// for dma write
mmio_write_64(BASE_SYSDMAC + 0x100 + ch * (0x100), (uint64_t) buf);
mmio_write_64(BASE_SYSDMAC + 0x108 + ch * (0x100), spi_nand_ctrl_base + 0x800);
mmio_write_32(BASE_SYSDMAC + 0x118 + ch * (0x100), 0x00045441);
// [0:2] = 1 : MEM_TO_PER_DMAC, PER dst = 0
mmio_write_32(BASE_SYSDMAC + 0x124 + ch * (0x100), 0x00000001);
mmio_write_32(0x03000154, 0x26); //PER dst = 0 => remap ch0
mmio_setbits_32(0x03000154, BIT(31)); // set sdma remap update bit
VERBOSE("0x100: 0x%lx\n", mmio_read_64(BASE_SYSDMAC + 0x100 + ch * (0x100)));
VERBOSE("0x108: 0x%lx\n", mmio_read_64(BASE_SYSDMAC + 0x108 + ch * (0x100)));
} else {
mmio_write_64(BASE_SYSDMAC + 0x100 + ch * (0x100), spi_nand_ctrl_base + 0xC00);
mmio_write_64(BASE_SYSDMAC + 0x108 + ch * (0x100), (uint64_t)buf);
mmio_write_32(BASE_SYSDMAC + 0x118 + ch * (0x100), 0x00046214);
// [0:2] = 2 : PER_TO_MEM_DMAC, PER src = 0
mmio_write_32(BASE_SYSDMAC + 0x124 + ch * (0x100), 0x00000002);
mmio_write_32(0x03000154, 0x26); //PER src = 0 => remap ch0
mmio_setbits_32(0x03000154, BIT(31)); // set sdma remap update bit
VERBOSE("0x100: 0x%lx\n", mmio_read_64(BASE_SYSDMAC + 0x100 + ch * (0x100)));
VERBOSE("0x108: 0x%lx\n", mmio_read_64(BASE_SYSDMAC + 0x108 + ch * (0x100)));
}
mmio_write_32(BASE_SYSDMAC + 0x120 + ch * (0x100), 0x0);
mmio_write_32(BASE_SYSDMAC + 0x018, 0x00000f0f);
}
static void spi_nand_polling_oip(void)
{
uint32_t status = 0xff;
uint32_t retry = 0;
while ((status & SPI_NAND_STATUS0_OIP) && (retry++ < (SPI_NAND_INTERRUPT_UDELAY_COUNT * 10))) {
status = spi_nand_get_feature(spinand_info.ecc_status_offset);
udelay(1);
}
if (retry > (SPI_NAND_INTERRUPT_UDELAY_COUNT * 10)) {
ERROR("SPINAND is still busy over 10 sec after reseting spinand %d %s\n", retry, __func__);
//assert(0);
}
}
static void spi_nand_ctrl_ecc(uint8_t enable)
{
uint8_t status;
if ((ecc_en_status == 1) && (enable == 1)) {
VERBOSE("NAND_DEBUG: ecc is already enabled\n");
return;
} else if ((ecc_en_status == 0) && (enable == 0)) {
VERBOSE("NAND_DEBUG: ecc is already disabled\n");
return;
}
status = spi_nand_get_feature(spinand_info.ecc_en_feature_offset);
if (enable) {
spi_nand_set_feature(spinand_info.ecc_en_feature_offset,
status | spinand_info.ecc_en_mask); // set ECC_EN to enable
ecc_en_status = 1;
} else {
spi_nand_set_feature(spinand_info.ecc_en_feature_offset,
status & (~spinand_info.ecc_en_mask)); // set ECC_EN to disable
ecc_en_status = 0;
}
}
static void spi_nand_qe_enable(void)
{
uint8_t status;
status = spi_nand_get_feature(0xB0);
spi_nand_set_feature(0xB0, status | 0x1);
}
static int spi_nand_read_page_by_row_addr(uint32_t row_addr, void *buf, uint32_t len)
{
uint32_t retry = 0;
uint32_t r_row_addr = ((row_addr & 0xff0000) >> 16) | (row_addr & 0xff00) | ((row_addr & 0xff) << 16);
VERBOSE("%s r_row_addr 0x%x\n", __func__, r_row_addr);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL2,
0 << TRX_DATA_SIZE_SHIFT | 3 << TRX_CMD_CONT_SIZE_SHIFT); // 0x8
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL3, 0);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CMD0,
r_row_addr << TRX_CMD_CONT0_SHIFT | SPI_NAND_CMD_PAGE_READ_TO_CACHE);
// Trigger communication start
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL0, BIT_REG_TRX_START);
while(((mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_INT) & BIT_REG_TRX_DONE_INT) == 0)
&& (retry++ < SPI_NAND_INTERRUPT_UDELAY_COUNT))
udelay(1);
if (retry > SPI_NAND_INTERRUPT_UDELAY_COUNT) {
ERROR("SPINAND command error, no interrupt, %d %s\n", retry, __func__);
//assert(0);
}
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_CLR, BIT_REG_TRX_DONE_INT);
spi_nand_polling_oip();
return 0;
}
static void spi_nand_set_read_from_cache_mode(uint32_t col_addr)
{
if (spinand_info.flags & FLAGS_ENABLE_X4_BIT) {
VERBOSE("NAND_DEBUG: Read by 4 bit mode\n");
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL3,
BIT_REG_TRX_DMA_EN | SPI_NAND_CTRL3_IO_TYPE_X4_MODE | BIT_REG_TRX_DUMMY_HIZ);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CMD0,
col_addr << TRX_CMD_CONT0_SHIFT | SPI_NAND_CMD_READ_FROM_CACHEX4);
} else if (spinand_info.flags & FLAGS_ENABLE_X2_BIT) {
VERBOSE("NAND_DEBUG: Read by 2 bit mode\n");
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL3,
BIT_REG_TRX_DMA_EN | SPI_NAND_CTRL3_IO_TYPE_X2_MODE | BIT_REG_TRX_DUMMY_HIZ);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CMD0,
col_addr << TRX_CMD_CONT0_SHIFT | SPI_NAND_CMD_READ_FROM_CACHEX2);
} else {
VERBOSE("NAND_DEBUG: Read by 1 bit mode\n");
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL3,
BIT_REG_TRX_DMA_EN | BIT_REG_TRX_DUMMY_HIZ);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CMD0,
col_addr << TRX_CMD_CONT0_SHIFT | SPI_NAND_CMD_READ_FROM_CACHE);
}
return;
}
static int spi_nand_read_from_cache(uint32_t blk_id, uint32_t page_nr, uint32_t col_addr,
uint32_t len, void *buf)
{
uint32_t r_col_addr = ((col_addr & 0xff00) >> 8) | ((col_addr & 0xff) << 8);
VERBOSE("%s col_addr 0x%x, r_col_addr 0x%x\n", __func__, col_addr, r_col_addr);
spi_nand_rw_dma_setup(buf, len, 0);
mmio_write_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL2,
len << TRX_DATA_SIZE_SHIFT | 3 << TRX_CMD_CONT_SIZE_SHIFT);
spi_nand_set_read_from_cache_mode(r_col_addr);
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_TRX_CTRL0, BIT_REG_TRX_START);
while ((mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_INT) & BITS_REG_TRX_DMA_DONE_INT) == 0);
uint32_t intr = mmio_read_32(spi_nand_ctrl_base + REG_SPI_NAND_INT);
mmio_setbits_32(spi_nand_ctrl_base + REG_SPI_NAND_INT_CLR, intr);
return 0;
}
#define ECC_NOERR 0
#define ECC_CORR 1
#define ECC_UNCORR 2
uint32_t spi_nand_parsing_ecc_info(uint32_t page)
{
uint32_t statusc0 = spi_nand_get_feature(spinand_info.ecc_status_offset);
uint8_t ecc_sts = (statusc0 & spinand_info.ecc_status_mask) >> spinand_info.ecc_status_shift;
if (ecc_sts) {
VERBOSE("statusc0 0x%x\n", statusc0);
INFO("block %d, page %d, ecc sts : %d!!\n",
page >> spinand_info.pages_per_block_shift, page % spinand_info.pages_per_block, ecc_sts);
}
if (ecc_sts == spinand_info.ecc_status_uncorr_val) {
INFO("ECC UNCORR\n");
return ECC_UNCORR;
}
return ECC_NOERR;
}
static void dump_nand_info(void)
{
INFO("NAND_DEBUG: NAND version=0x%x, id=0x%x\n", spinand_info.version, spinand_info.id);
INFO("NAND_DEBUG: page size=%d, block size=%d, page per block=%d, badblock_pos=%d\n",
spinand_info.page_size, spinand_info.block_size,
spinand_info.pages_per_block, spinand_info.badblock_pos);
VERBOSE("NAND_DEBUG: fip block count=%d, page per block shift=%d, flags=0x%x\n", spinand_info.fip_block_cnt,
spinand_info.pages_per_block_shift, spinand_info.flags);
VERBOSE("NAND_DEBUG: ECC feature offset=0x%x, en mask=0x%x, status offset=0x%x, status mask=0x%x\n",
spinand_info.ecc_en_feature_offset, spinand_info.ecc_en_mask,
spinand_info.ecc_status_offset, spinand_info.ecc_status_mask);
VERBOSE("NAND_DEBUG: ECC status shift=%d, uncorr_val=0x%x, erase count=%d\n", spinand_info.ecc_status_shift,
spinand_info.ecc_status_uncorr_val, spinand_info.erase_count);
VERBOSE("NAND_DEBUG: sck_l=%d, sck_h=0x%x, max_freq=%d\n", spinand_info.sck_l,
spinand_info.sck_h, spinand_info.max_freq);
VERBOSE("NAND_DEBUG: xtal_switch=%d\n", spinand_info.xtal_switch);
}
int get_nand_info(void)
{
uint32_t ret;
uint8_t page_buff[4096] = {0};
struct fip_param1 *fip_param;
spinand_info.id = 0x0;
spinand_info.page_size = 2048;
spinand_info.spare_size = 64;
spinand_info.block_size = 0x20000;
spinand_info.pages_per_block = 64;
spinand_info.fip_block_cnt = 1024;
spinand_info.pages_per_block_shift = 6;
spinand_info.flags = 0;
spinand_info.badblock_pos = BBP_FIRST_PAGE;
spinand_info.ecc_en_feature_offset = SPI_NAND_FEATURE_FEATURE0;
spinand_info.ecc_en_mask = SPI_NAND_FEATURE0_ECC_EN;
spinand_info.ecc_status_offset = SPI_NAND_FEATURE_STATUS0;
spinand_info.ecc_status_mask = 0x30;
spinand_info.ecc_status_shift = 4;
spinand_info.ecc_status_uncorr_val = 0x2;
spinand_info.erase_count = 1;
spinand_info.sck_l = 2;
spinand_info.sck_h = 2;
spinand_info.max_freq = 0;
spinand_info.sample_param = 0x100;
spinand_info.xtal_switch = 0;
ret = cv_spi_nand_read_page_by_row_addr(0, page_buff, 2048);
if (ret)
ERROR("Scan fip_header fialed!\n");
fip_param = (void *)(page_buff + sizeof(struct block_header_t));
/* update spinand info */
memcpy(&spinand_info, &fip_param->nand_info, sizeof(struct spi_nand_info_t));
if (spinand_info.flags & FLAGS_ENABLE_X4_BIT) {
if (spinand_info.flags & (FLAGS_ENABLE_X4_BIT | FLAGS_SET_QE_BIT))
spi_nand_qe_enable();
ret = cv_spi_nand_read_page_by_row_addr(0, page_buff + 2048, 2048);
if (ret)
ERROR("Scan fip_header fialed!\n");
if (memcmp(page_buff, page_buff + 2048, 2048))
spinand_info.flags &= ~(FLAGS_ENABLE_X4_BIT | FLAGS_ENABLE_X2_BIT);
}
dump_nand_info();
return 0;
}
uint32_t cv_spi_nand_read_page_by_row_addr(uint32_t row_addr, void *buf, uint32_t len)
{
uint32_t col_addr = 0;
uint32_t blk_id = row_addr >> 6;
VERBOSE("%s, row_addr 0x%x, buf %p, len %d, spinand_info.flags 0x%x\n", __func__, row_addr, buf, len,
spinand_info.flags);
spi_nand_ctrl_ecc(1);
spi_nand_read_page_by_row_addr(row_addr, buf, len);
if ((spinand_info.flags & FLAGS_SET_PLANE_BIT) && (blk_id % 2 == 1))
col_addr |= SPI_NAND_PLANE_BIT_OFFSET;
flush_dcache_range((uintptr_t)buf, len);
spi_nand_read_from_cache(0, 0, col_addr, len, buf);
return spi_nand_parsing_ecc_info(row_addr);
}
int cv_spi_nand_read_data(void * buffer, uint32_t offset, uint32_t size)
{
uint32_t i;
offset = offset / spinand_info.page_size;
int ret = 0;
if (size & (spinand_info.page_size - 1)) {
size = (size + spinand_info.page_size - 1) &~(spinand_info.page_size - 1);
}
for (i = 0; i < size / spinand_info.page_size; i++) {
ret = (int)cv_spi_nand_read_page_by_row_addr(offset, buffer, spinand_info.page_size);
if (ret) {
ERROR("read page %u failed\n", offset);
return ret;
}
offset++;
buffer += spinand_info.page_size;
}
return ret;
}

View File

@@ -3,6 +3,40 @@
#include <ddr_sys.h>
#include <ddr_pkg_info.h>
static void cvx16_pinmux_esmt_n21_2g_qfn(void)
{
// ESMT_N21_DDR3_2G_QFN88
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x08070D09);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x0605020B);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x14040100);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x1503000C);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x0A001213);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00111016);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x82315764);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x67513208);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000004);
}
static void cvx16_pinmux_esmt_n21_2g_bga(void)
{
// ESMT_N21_DDR3_2G_BGA
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x08070D09);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x0605020B);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x14040100);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x1503000C);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x16001213);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x0011100A);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x82315746);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x67513208);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000004);
}
void cvx16_pinmux(void)
{
uartlog("%s\n", __func__);
@@ -129,6 +163,169 @@ void cvx16_pinmux(void)
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x76012345);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000008);
break;
case DDR_VENDOR_NY_N20_1G:
// NY_N20_DDR3_1G
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x08060F0B);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x07040109);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x1405020C);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x15030F00);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x0A0F1213);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00111016);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x82315764);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x67513208);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000004);
break;
case DDR_VENDOR_UNILC_N25_1G:
// UnilC_DDR3_1G
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x08020B07);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x00030905);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x04010006);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x1300150C);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x16111214);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00000A10);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x08137564);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000002);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x76513820);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000004);
break;
case DDR_VENDOR_UNILC_N21_2G:
// UnilC_DDR3_2G
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x08070D09);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x0605020B);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x14040100);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x1503000C);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x0A120013);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00111016);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x82135764);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x76513208);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000004);
break;
case DDR_VENDOR_ESMT_N21_2G:
/* Select by package; unknown packages default to BGA. */
if (get_pkg() == PKG_QFN)
cvx16_pinmux_esmt_n21_2g_qfn();
else if (get_pkg() == PKG_BGA)
cvx16_pinmux_esmt_n21_2g_bga();
else
/* Sample pkg fallback; production should not hit. */
cvx16_pinmux_esmt_n21_2g_bga();
break;
case DDR_VENDOR_ESMT_N19_4G:
// ESMT_DDR3_4G_19nm
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x09050D07);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x00080E02);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x0C060B01);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x12031104);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x15001310);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x000A1614);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x31756024);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000008);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x45172380);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000006);
break;
case DDR_VENDOR_UNILC_N25_512M_DDR2:
// UniIC_DDR2_512M
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x00040608);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x02090B0C);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x0E01070D);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x0A031605);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x10110F14);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00121513);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x61437025);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000008);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x63410725);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000008);
break;
case DDR_VENDOR_ETRON_N20_2G:
// Etron_N20_DDR3_2G (ERD3CBA20-HA2133, GELMV QFN88 SIP)
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x08070D09);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x06010B02);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x0C000405);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x13151403);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x0A001612);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00110010);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x20317546);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000008);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x67512308);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000004);
break;
case DDR_VENDOR_ETRON_N25_2G:
// Etron_N25_DDR3_2G (ERD3CBA25-HA1866, WX2012D QFN96 SIP)
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x08090D07);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x00020506);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x0C010B03);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x13001504);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x0A120014);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00101116);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x82316547);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x76358120);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000004);
break;
case DDR_VENDOR_EXTERN_DDR2_1815J:
// external ddr2
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x0C060B08);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x03000709);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x11040A02);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x01160005);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x00101314);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x00000012);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x68502143);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000007);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x02768143);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000005);
break;
case DDR_VENDOR_EXTERN_DDR3_1815J:
// external ddr3
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x0D080212);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x00040709);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x0E0B1506);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x030A0C05);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x14101613);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x000F1101);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x38754062);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000001);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x62475103);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000008);
break;
case DDR_VENDOR_EXTERN_DDR3_1815K:
/* external ddr3, CV1848K EVB bonding table (CA + DQ
* domains). CV1815K uses the same K package (BGA320)
* as CV1848K, so the DDR pinout is identical.
*/
mmio_write_32(0x0000 + PHYD_BASE_ADDR, 0x0E0D0902);
mmio_write_32(0x0004 + PHYD_BASE_ADDR, 0x12081500);
mmio_write_32(0x0008 + PHYD_BASE_ADDR, 0x0B040706);
mmio_write_32(0x000C + PHYD_BASE_ADDR, 0x13031405);
mmio_write_32(0x0010 + PHYD_BASE_ADDR, 0x0110160C);
mmio_write_32(0x0014 + PHYD_BASE_ADDR, 0x000F110A);
mmio_write_32(0x0018 + PHYD_BASE_ADDR, 0x00000000);
mmio_write_32(0x001C + PHYD_BASE_ADDR, 0x00000100);
mmio_write_32(0x0020 + PHYD_BASE_ADDR, 0x28375064);
mmio_write_32(0x0024 + PHYD_BASE_ADDR, 0x00000001);
mmio_write_32(0x0028 + PHYD_BASE_ADDR, 0x42807135);
mmio_write_32(0x002C + PHYD_BASE_ADDR, 0x00000006);
break;
}
#ifdef ETRON_DDR2_512

View File

@@ -2,6 +2,7 @@
#include <ddr.h>
#include <ddr_sys_bring_up.h>
#include <ddr_pkg_info.h>
#include "regconfig.h"
int ddr_init(const struct ddr_param *ddr_param)
@@ -13,6 +14,9 @@ int ddr_init(const struct ddr_param *ddr_param)
// bldp_init((void *)ddr_param);
#ifndef NO_DDR_CFG
read_ddr_pkg_info();
#ifndef DDR2_3
ddr_patch_regs_init();
#endif
ddr_sys_bring_up();
#endif //NO_DDR_CFG

View File

@@ -27,6 +27,7 @@ BL2_SOURCES += \
plat/${CHIP_ARCH}/ddr/ddr_pkg_info.c \
plat/${CHIP_ARCH}/ddr/ddr_sys_bring_up.c \
plat/${CHIP_ARCH}/ddr/ddr_sys.c \
plat/${CHIP_ARCH}/ddr/ddr_suspend.c \
plat/${CHIP_ARCH}/ddr/phy_pll_init.c \
plat/${CHIP_ARCH}/ddr/cvx16_pinmux.c \
plat/${CHIP_ARCH}/ddr/cvx16_dram_cap_check.c \
@@ -46,6 +47,8 @@ ifneq ($(findstring 2133, ${DDR_CFG}),)
$(eval $(call add_define,_mem_freq_2133))
else ifneq ($(findstring 1866, ${DDR_CFG}),)
$(eval $(call add_define,_mem_freq_1866))
else ifneq ($(findstring 1600, ${DDR_CFG}),)
$(eval $(call add_define,_mem_freq_1600))
else ifneq ($(findstring 1333, ${DDR_CFG}),)
$(eval $(call add_define,_mem_freq_1333))
endif

View File

@@ -7,7 +7,7 @@
//regpatch_ddr2_1333_x16_qfn.c
struct regpatch ddr_patch_regs[] = {
static struct regpatch _ddr_patch_regs_sip[] = {
// tune damp //////
{0x08000150, 0xFFFFFFFF, 0x00000005},
@@ -106,4 +106,11 @@ struct regpatch ddr_patch_regs[] = {
{0x08000934, 0xFFFFFFFF, 0x04000400},
};
uint32_t ddr_patch_regs_count = ARRAY_SIZE(ddr_patch_regs);
struct regpatch *ddr_patch_regs;
uint32_t ddr_patch_regs_count;
void ddr_patch_regs_init(void)
{
ddr_patch_regs = _ddr_patch_regs_sip;
ddr_patch_regs_count = ARRAY_SIZE(_ddr_patch_regs_sip);
}

View File

@@ -4,6 +4,7 @@
#include <ddr_sys.h>
#include <ddr_init.h>
#include <bitwise_ops.h>
#include <ddr_pkg_info.h>
uint32_t ddr_data_rate = 1333;
@@ -292,6 +293,28 @@ void ctrl_init_update_by_dram_size(uint8_t dram_cap_in_mbyte)
{
uint8_t dram_cap_in_mbyte_per_dev;
// Print capacity for external DDR after training
if (get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR2_1815J ||
get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815J ||
get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815K) {
switch (dram_cap_in_mbyte) {
case 6:
NOTICE("External DDR capacity: 512M\n");
break;
case 7:
NOTICE("External DDR capacity: 1G\n");
break;
case 8:
NOTICE("External DDR capacity: 2G\n");
break;
case 9:
NOTICE("External DDR capacity: 4G\n");
break;
default:
NOTICE("External DDR capacity: Unknown, %u\n", dram_cap_in_mbyte);
}
}
rddata = mmio_rd32(0x08004000 + 0x0);
dram_cap_in_mbyte_per_dev = dram_cap_in_mbyte;
dram_cap_in_mbyte_per_dev >>= (1 - get_bits_from_value(rddata, 13, 12)); // change sys cap to x16 cap

View File

@@ -0,0 +1,224 @@
#include <stddef.h>
#include <utils_def.h>
#include <mmio.h>
#include <reg_soc.h>
#include <ddr_sys.h>
#include <ddr_pkg_info.h>
#include "regconfig.h"
//regpatch_ddr3_x16_bga.c for 1600
static struct regpatch _ddr_patch_regs_sip[] = {
// tune damp //////
{0x08000150, 0xFFFFFFFF, 0x00000005},
// CSB & CA driving
{0x0800097c, 0xFFFFFFFF, 0x08080404},
// CLK driving
{0x08000980, 0xFFFFFFFF, 0x08080808},
// DQ driving // BYTE0
{0x08000a38, 0xFFFFFFFF, 0x00000606},
// DQS driving // BYTE0
{0x08000a3c, 0xFFFFFFFF, 0x06060606},
// DQ driving // BYTE1
{0x08000a78, 0xFFFFFFFF, 0x00000606},
// DQS driving // BYTE1
{0x08000a7c, 0xFFFFFFFF, 0x06060606},
//trigger level //////
// BYTE0
{0x08000b24, 0xFFFFFFFF, 0x00100010},
// BYTE1
{0x08000b54, 0xFFFFFFFF, 0x00100010},
//APHY TX VREFDQ rangex2 [1]
//VREF DQ //
{0x08000410, 0xFFFFFFFF, 0x00120002},
//APHY TX VREFCA rangex2 [1]
//VREF CA //
{0x08000414, 0xFFFFFFFF, 0x00100002},
// tx dline code
// BYTE0 DQ
{0x08000a00, 0xFFFFFFFF, 0x06430643},
{0x08000a04, 0xFFFFFFFF, 0x06430643},
{0x08000a08, 0xFFFFFFFF, 0x06430643},
{0x08000a0c, 0xFFFFFFFF, 0x06430643},
{0x08000a10, 0xFFFFFFFF, 0x00000643},
{0x08000a14, 0xFFFFFFFF, 0x0a7e007e},
// BYTE1 DQ
{0x08000a40, 0xFFFFFFFF, 0x06480648},
{0x08000a44, 0xFFFFFFFF, 0x06480648},
{0x08000a48, 0xFFFFFFFF, 0x06480648},
{0x08000a4c, 0xFFFFFFFF, 0x06480648},
{0x08000a50, 0xFFFFFFFF, 0x00000648},
{0x08000a54, 0xFFFFFFFF, 0x0a7e007e},
//APHY RX TRIG rangex2[18] & disable lsmode[0]
//f0_param_phya_reg_rx_byte0_en_lsmode[0]
//f0_param_phya_reg_byte0_en_rec_vol_mode[12]
//f0_param_phya_reg_rx_byte0_force_en_lvstl_odt[16]
//f0_param_phya_reg_rx_byte0_sel_dqs_rec_vref_mode[8]
//param_phya_reg_rx_byte0_en_trig_lvl_rangex2[18]
// BYTE0 [0]
{0x08000500, 0xFFFFFFFF, 0x00041001},
//f0_param_phya_reg_rx_byte1_en_lsmode[0]
//f0_param_phya_reg_byte1_en_rec_vol_mode[12]
//f0_param_phya_reg_rx_byte0_force_en_lvstl_odt[16]
//f0_param_phya_reg_rx_byte0_sel_dqs_rec_vref_mode[8]
//param_phya_reg_rx_byte0_en_trig_lvl_rangex2[18]
// BYTE1 [0]
{0x08000540, 0xFFFFFFFF, 0x00041001},
//////// FOR U02 ///////
/////////// U02 enable DQS voltage mode receiver
// f0_param_phya_reg_tx_byte0_en_tx_de_dqs[20]
{0x08000504, 0xFFFFFFFF, 0x00100000},
// f0_param_phya_reg_tx_byte1_en_tx_de_dqs[20]
{0x08000544, 0xFFFFFFFF, 0x00100000},
/////////// U02 enable MASK voltage mode receiver
// param_phya_reg_rx_sel_dqs_wo_pream_mode[2]
{0x08000138, 0xFFFFFFFF, 0x00000014},
// BYTE0 RX DQ deskew
{0x08000b00, 0xFFFFFFFF, 0x00020402},
{0x08000b04, 0xFFFFFFFF, 0x05020401},
// BYTE0 DQ8 deskew [6:0] neg DQS [15:8] ; pos DQS [23:16]
{0x08000b08, 0xFFFFFFFF, 0x00313902},
// BYTE1 RX DQ deskew
{0x08000b30, 0xFFFFFFFF, 0x06000100},
{0x08000b34, 0xFFFFFFFF, 0x02010303},
// BYTE1 DQ8 deskew [6:0] neg DQS [15:8] ; pos DQS [23:16]
{0x08000b38, 0xFFFFFFFF, 0x00323900},
//Read gate TX dline + shift
// BYTE0
{0x08000b0c, 0xFFFFFFFF, 0x00000a14},
// BYTE1
{0x08000b3c, 0xFFFFFFFF, 0x00000a14},
// CKE dline + shift CKE0 [6:0]+[13:8] ; CKE1 [22:16]+[29:24]
{0x08000930, 0xFFFFFFFF, 0x04000400},
// CSB dline + shift CSB0 [6:0]+[13:8] ; CSB1 [22:16]+[29:24]
{0x08000934, 0xFFFFFFFF, 0x04000400},
};
/* External DDR3: same as SIP but disable DQS voltage mode RX */
static struct regpatch _ddr_patch_regs_ext[] = {
// tune damp //////
{0x08000150, 0xFFFFFFFF, 0x00000005},
// CSB & CA driving
{0x0800097c, 0xFFFFFFFF, 0x08080404},
// CLK driving
{0x08000980, 0xFFFFFFFF, 0x08080808},
// DQ driving // BYTE0
{0x08000a38, 0xFFFFFFFF, 0x00000606},
// DQS driving // BYTE0
{0x08000a3c, 0xFFFFFFFF, 0x06060606},
// DQ driving // BYTE1
{0x08000a78, 0xFFFFFFFF, 0x00000606},
// DQS driving // BYTE1
{0x08000a7c, 0xFFFFFFFF, 0x06060606},
//trigger level //////
// BYTE0
{0x08000b24, 0xFFFFFFFF, 0x00100010},
// BYTE1
{0x08000b54, 0xFFFFFFFF, 0x00100010},
//APHY TX VREFDQ rangex2 [1]
//VREF DQ //
{0x08000410, 0xFFFFFFFF, 0x00120002},
//APHY TX VREFCA rangex2 [1]
//VREF CA //
{0x08000414, 0xFFFFFFFF, 0x00100002},
// tx dline code
// BYTE0 DQ
{0x08000a00, 0xFFFFFFFF, 0x06430643},
{0x08000a04, 0xFFFFFFFF, 0x06430643},
{0x08000a08, 0xFFFFFFFF, 0x06430643},
{0x08000a0c, 0xFFFFFFFF, 0x06430643},
{0x08000a10, 0xFFFFFFFF, 0x00000643},
{0x08000a14, 0xFFFFFFFF, 0x0a7e007e},
// BYTE1 DQ
{0x08000a40, 0xFFFFFFFF, 0x06480648},
{0x08000a44, 0xFFFFFFFF, 0x06480648},
{0x08000a48, 0xFFFFFFFF, 0x06480648},
{0x08000a4c, 0xFFFFFFFF, 0x06480648},
{0x08000a50, 0xFFFFFFFF, 0x00000648},
{0x08000a54, 0xFFFFFFFF, 0x0a7e007e},
//APHY RX TRIG rangex2[18] & disable lsmode[0]
//f0_param_phya_reg_rx_byte0_en_lsmode[0]
//f0_param_phya_reg_byte0_en_rec_vol_mode[12]
//f0_param_phya_reg_rx_byte0_force_en_lvstl_odt[16]
//f0_param_phya_reg_rx_byte0_sel_dqs_rec_vref_mode[8]
//param_phya_reg_rx_byte0_en_trig_lvl_rangex2[18]
// BYTE0 [0]
{0x08000500, 0xFFFFFFFF, 0x00040001},
//f0_param_phya_reg_rx_byte1_en_lsmode[0]
//f0_param_phya_reg_byte1_en_rec_vol_mode[12]
//f0_param_phya_reg_rx_byte0_force_en_lvstl_odt[16]
//f0_param_phya_reg_rx_byte0_sel_dqs_rec_vref_mode[8]
//param_phya_reg_rx_byte0_en_trig_lvl_rangex2[18]
// BYTE1 [0]
{0x08000540, 0xFFFFFFFF, 0x00040001},
//////// FOR U02 ///////
/////////// U02 DQS voltage mode receiver -- disabled for external DDR
// f0_param_phya_reg_tx_byte0_en_tx_de_dqs[20]
{0x08000504, 0xFFFFFFFF, 0x00000000},
// f0_param_phya_reg_tx_byte1_en_tx_de_dqs[20]
{0x08000544, 0xFFFFFFFF, 0x00000000},
/////////// U02 enable MASK voltage mode receiver
// param_phya_reg_rx_sel_dqs_wo_pream_mode[2]
{0x08000138, 0xFFFFFFFF, 0x00000014},
// RX ODT 120ohm for external DDR3 (override ddr_init.h default 240ohm)
{0x0800041c, 0xFFFFFFFF, 0x00004242},
// BYTE0 RX DQ deskew
{0x08000b00, 0xFFFFFFFF, 0x00020402},
{0x08000b04, 0xFFFFFFFF, 0x05020401},
// BYTE0 DQ8 deskew [6:0] neg DQS [15:8] ; pos DQS [23:16]
{0x08000b08, 0xFFFFFFFF, 0x00313902},
// BYTE1 RX DQ deskew
{0x08000b30, 0xFFFFFFFF, 0x06000100},
{0x08000b34, 0xFFFFFFFF, 0x02010303},
// BYTE1 DQ8 deskew [6:0] neg DQS [15:8] ; pos DQS [23:16]
{0x08000b38, 0xFFFFFFFF, 0x00323900},
//Read gate TX dline + shift
// BYTE0
{0x08000b0c, 0xFFFFFFFF, 0x00000a14},
// BYTE1
{0x08000b3c, 0xFFFFFFFF, 0x00000a14},
// CKE dline + shift CKE0 [6:0]+[13:8] ; CKE1 [22:16]+[29:24]
{0x08000930, 0xFFFFFFFF, 0x04000400},
// CSB dline + shift CSB0 [6:0]+[13:8] ; CSB1 [22:16]+[29:24]
{0x08000934, 0xFFFFFFFF, 0x04000400},
};
struct regpatch *ddr_patch_regs;
uint32_t ddr_patch_regs_count;
void ddr_patch_regs_init(void)
{
if (get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815J ||
get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815K) {
ddr_patch_regs = _ddr_patch_regs_ext;
ddr_patch_regs_count = ARRAY_SIZE(_ddr_patch_regs_ext);
} else {
ddr_patch_regs = _ddr_patch_regs_sip;
ddr_patch_regs_count = ARRAY_SIZE(_ddr_patch_regs_sip);
}
}

View File

@@ -0,0 +1,363 @@
#include <mmio.h>
// #include <soc.h>
#include <reg_soc.h>
#include <ddr_sys.h>
#include <ddr_init.h>
#include <bitwise_ops.h>
#include <ddr_pkg_info.h>
uint32_t ddr_data_rate = 1600;
void ddrc_init(void)
{
mmio_wr32(0x08004000 + 0xc, 0x63746371);
// PATCH0.use_blk_ext}:0:2:=0x1
// PATCH0.dis_auto_ref_cnt_fix:2:1:=0x0
// PATCH0.dis_auto_ref_algn_to_8:3:1:=0x0
// PATCH0.starve_stall_at_dfi_ctrlupd:4:1:=0x1
// PATCH0.starve_stall_at_abr:5:1:=0x1
// PATCH0.dis_rdwr_switch_at_abr:6:1:=0x1
// PATCH0.dfi_wdata_same_to_axi:7:1:=0x0
// PATCH0.pagematch_limit_threshold:8:3=0x3
// PATCH0.qos_sel:12:2:=0x2
// PATCH0.burst_rdwr_xpi:16:4:=0x4
// PATCH0.always_critical_when_urgent_hpr:20:1:=0x1
// PATCH0.always_critical_when_urgent_lpr:21:1:=0x1
// PATCH0.always_critical_when_urgent_wr:22:1:=0x1
// PATCH0.disable_hif_rcmd_stall_path:24:1:=0x1
// PATCH0.disable_hif_wcmd_stall_path:25:1:=0x1
// PATCH0.derate_sys_en:29:1:=0x1
// PATCH0.ref_4x_sys_high_temp:30:1:=0x1
mmio_wr32(0x08004000 + 0x44, 0x00000000);
// PATCH1.ref_adv_stop_threshold:0:7:=0x0
// PATCH1.ref_adv_dec_threshold:8:7:=0x0
// PATCH1.ref_adv_max:16:7:=0x0
mmio_wr32(0x08004000 + 0x148, 0x989E0000);
// PATCH4.t_phyd_rden:16:6=0x0
// PATCH4.phyd_rd_clk_stop:23:1=0x0
// PATCH4.t_phyd_wren:24:6=0x0
// PATCH4.phyd_wr_clk_stop:31:1=0x0
// auto gen.
mmio_wr32(0x08004000 + 0x0, 0x81041401);
mmio_wr32(0x08004000 + 0x30, 0x00000000);
mmio_wr32(0x08004000 + 0x34, 0x00930001);
mmio_wr32(0x08004000 + 0x38, 0x00020000);
mmio_wr32(0x08004000 + 0x50, 0x00201070);
mmio_wr32(0x08004000 + 0x60, 0x00000000);
mmio_wr32(0x08004000 + 0x64, 0x0061008C);
mmio_wr32(0x08004000 + 0xc0, 0x00000000);
mmio_wr32(0x08004000 + 0xc4, 0x00000000);
#ifdef DDR_INIT_SPEED_UP
mmio_wr32(0x08004000 + 0xd0, 0x00010002);
mmio_wr32(0x08004000 + 0xd4, 0x00020000);
#else
mmio_wr32(0x08004000 + 0xd0, 0x000100C5);
mmio_wr32(0x08004000 + 0xd4, 0x005B0000);
#endif
mmio_wr32(0x08004000 + 0xdc, 0x1F140040);
#ifdef DDR_DODT
mmio_wr32(0x08004000 + 0xe0, 0x04600000);
#else
mmio_wr32(0x08004000 + 0xe0, 0x00600000);
#endif
mmio_wr32(0x08004000 + 0xe4, 0x000903BF);
mmio_wr32(0x08004000 + 0x100, 0x0C101A0E);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x100, mmio_rd32(0x08004000 + 0x100) + 0x3000000);
mmio_wr32(0x08004000 + 0x104, 0x00030314);
mmio_wr32(0x08004000 + 0x108, 0x04060509);
mmio_wr32(0x08004000 + 0x10c, 0x00002006);
mmio_wr32(0x08004000 + 0x110, 0x06020306);
mmio_wr32(0x08004000 + 0x114, 0x04040302);
mmio_wr32(0x08004000 + 0x120, 0x00000906);
mmio_wr32(0x08004000 + 0x13c, 0x00000000);
mmio_wr32(0x08004000 + 0x180, 0xC0800020);
mmio_wr32(0x08004000 + 0x184, 0x00000001);
// phyd related
mmio_wr32(0x08004000 + 0x190, 0x048a8305);
// DFITMG0.dfi_t_ctrl_delay:24:5:=0x4
// DFITMG0.dfi_rddata_use_dfi_phy_clk:23:1:=0x1
// DFITMG0.dfi_t_rddata_en:16:7:=0xa
// DFITMG0.dfi_wrdata_use_dfi_phy_clk:15:1:=0x1
// DFITMG0.dfi_tphy_wrdata:8:6:=0x3
// DFITMG0.dfi_tphy_wrlat:0:6:=0x5
mmio_wr32(0x08004000 + 0x194, 0x00070202);
// DFITMG1.dfi_t_cmd_lat:28:4:=0x0
// DFITMG1.dfi_t_parin_lat:24:2:=0x0
// DFITMG1.dfi_t_wrdata_delay:16:5:=0x7
// DFITMG1.dfi_t_dram_clk_disable:8:5:=0x2
// DFITMG1.dfi_t_dram_clk_enable:0:5:=0x2
mmio_wr32(0x08004000 + 0x198, 0x07c13121);
// DFILPCFG0.dfi_tlp_resp:24:5:=0x7
// DFILPCFG0.dfi_lp_wakeup_dpd:20:4:=0xc
// DFILPCFG0.dfi_lp_en_dpd:16:1:=0x1
// DFILPCFG0.dfi_lp_wakeup_sr:12:4:=0x3
// DFILPCFG0.dfi_lp_en_sr:8:1:=0x1
// DFILPCFG0.dfi_lp_wakeup_pd:4:4:=0x2
// DFILPCFG0.dfi_lp_en_pd:0:1:=0x1
mmio_wr32(0x08004000 + 0x19c, 0x00000021);
// DFILPCFG1.dfi_lp_wakeup_mpsm:4:4:=0x2
// DFILPCFG1.dfi_lp_en_mpsm:0:1:=0x1
// auto gen.
mmio_wr32(0x08004000 + 0x1a0, 0xC0400018);
mmio_wr32(0x08004000 + 0x1a4, 0x00B100FF);
mmio_wr32(0x08004000 + 0x1a8, 0x80000000);
mmio_wr32(0x08004000 + 0x1b0, 0x000002C1);
mmio_wr32(0x08004000 + 0x1c0, 0x00000001);
mmio_wr32(0x08004000 + 0x1c4, 0x00000001);
// address map, auto gen.
mmio_wr32(0x08004000 + 0x200, 0x00001F1F);
mmio_wr32(0x08004000 + 0x204, 0x00070707);
mmio_wr32(0x08004000 + 0x208, 0x00000000);
mmio_wr32(0x08004000 + 0x20c, 0x1F000000);
mmio_wr32(0x08004000 + 0x210, 0x00001F1F);
mmio_wr32(0x08004000 + 0x214, 0x060F0606);
mmio_wr32(0x08004000 + 0x218, 0x06060606);
mmio_wr32(0x08004000 + 0x21c, 0x00000606);
mmio_wr32(0x08004000 + 0x220, 0x00003F3F);
mmio_wr32(0x08004000 + 0x224, 0x06060606);
mmio_wr32(0x08004000 + 0x228, 0x06060606);
mmio_wr32(0x08004000 + 0x22c, 0x001F1F06);
// auto gen.
mmio_wr32(0x08004000 + 0x240, 0x0800060C);
#ifdef DDR_DODT
mmio_wr32(0x08004000 + 0x244, 0x00000001);
#else
mmio_wr32(0x08004000 + 0x244, 0x00000000);
#endif
mmio_wr32(0x08004000 + 0x250, 0x00003F85);
// SCHED.opt_vprw_sch:31:1:=0x0
// SCHED.rdwr_idle_gap:24:7:=0x0
// SCHED.go2critical_hysteresis:16:8:=0x0
// SCHED.lpddr4_opt_act_timing:15:1:=0x0
// SCHED.lpr_num_entries:8:7:=0x1f
// SCHED.autopre_rmw:7:1:=0x1
// SCHED.dis_opt_ntt_by_pre:6:1:=0x0
// SCHED.dis_opt_ntt_by_act:5:1:=0x0
// SCHED.opt_wrcam_fill_level:4:1:=0x0
// SCHED.rdwr_switch_policy_sel:3:1:=0x0
// SCHED.pageclose:2:1:=0x1
// SCHED.prefer_write:1:1:=0x0
// SCHED.dis_opt_wrecc_collision_flush:0:1:=0x1
mmio_wr32(0x08004000 + 0x254, 0x00000000);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x254, 0x40);
// SCHED1.page_hit_limit_rd:28:3:=0x0
// SCHED1.page_hit_limit_wr:24:3:=0x0
// SCHED1.visible_window_limit_rd:20:3:=0x0
// SCHED1.visible_window_limit_wr:16:3:=0x0
// SCHED1.delay_switch_write:12:4:=0x0
// SCHED1.pageclose_timer:0:8:=0x0
// auto gen.
mmio_wr32(0x08004000 + 0x25c, 0x100000C8);
// PERFHPR1.hpr_xact_run_length:24:8:=0x20
// PERFHPR1.hpr_max_starve:0:16:=0x6a
mmio_wr32(0x08004000 + 0x264, 0x100000C8);
// PERFLPR1.lpr_xact_run_length:24:8:=0x20
// PERFLPR1.lpr_max_starve:0:16:=0x6a
mmio_wr32(0x08004000 + 0x26c, 0x100000C8);
// PERFWR1.w_xact_run_length:24:8:=0x20
// PERFWR1.w_max_starve:0:16:=0x1a8
mmio_wr32(0x08004000 + 0x300, 0x00000000);
// DBG0.dis_max_rank_wr_opt:7:1:=0x0
// DBG0.dis_max_rank_rd_opt:6:1:=0x0
// DBG0.dis_collision_page_opt:4:1:=0x0
// DBG0.dis_act_bypass:2:1:=0x0
// DBG0.dis_rd_bypass:1:1:=0x0
// DBG0.dis_wc:0:1:=0x0
mmio_wr32(0x08004000 + 0x304, 0x00000000);
// DBG1.dis_hif:1:1:=0x0
// DBG1.dis_dq:0:1:=0x0
mmio_wr32(0x08004000 + 0x30c, 0x00000000);
mmio_wr32(0x08004000 + 0x320, 0x00000001);
// SWCTL.sw_done:0:1:=0x1
mmio_wr32(0x08004000 + 0x36c, 0x00000000);
// POISONCFG.rd_poison_intr_clr:24:1:=0x0
// POISONCFG.rd_poison_intr_en:20:1:=0x0
// POISONCFG.rd_poison_slverr_en:16:1:=0x0
// POISONCFG.wr_poison_intr_clr:8:1:=0x0
// POISONCFG.wr_poison_intr_en:4:1:=0x0
// POISONCFG.wr_poison_slverr_en:0:1:=0x0
mmio_wr32(0x08004000 + 0x400, 0x00000011);
// PCCFG.dch_density_ratio:12:2:=0x0
// PCCFG.bl_exp_mode:8:1:=0x0
// PCCFG.pagematch_limit:4:1:=0x1
// PCCFG.go2critical_en:0:1:=0x1
mmio_wr32(0x08004000 + 0x404, 0x00006000);
// PCFGR_0.rdwr_ordered_en:16:1:=0x0
// PCFGR_0.rd_port_pagematch_en:14:1:=0x1
// PCFGR_0.rd_port_urgent_en:13:1:=0x1
// PCFGR_0.rd_port_aging_en:12:1:=0x0
// PCFGR_0.read_reorder_bypass_en:11:1:=0x0
// PCFGR_0.rd_port_priority:0:10:=0x0
mmio_wr32(0x08004000 + 0x408, 0x00006000);
// PCFGW_0.wr_port_pagematch_en:14:1:=0x1
// PCFGW_0.wr_port_urgent_en:13:1:=0x1
// PCFGW_0.wr_port_aging_en:12:1:=0x0
// PCFGW_0.wr_port_priority:0:10:=0x0
mmio_wr32(0x08004000 + 0x490, 0x00000001);
// PCTRL_0.port_en:0:1:=0x1
mmio_wr32(0x08004000 + 0x494, 0x00000007);
// PCFGQOS0_0.rqos_map_region2:24:8:=0x0
// PCFGQOS0_0.rqos_map_region1:20:4:=0x0
// PCFGQOS0_0.rqos_map_region0:16:4:=0x0
// PCFGQOS0_0.rqos_map_level2:8:8:=0x0
// PCFGQOS0_0.rqos_map_level1:0:8:=0x7
mmio_wr32(0x08004000 + 0x498, 0x0000006a);
// PCFGQOS1_0.rqos_map_timeoutr:16:16:=0x0
// PCFGQOS1_0.rqos_map_timeoutb:0:16:=0x6a
mmio_wr32(0x08004000 + 0x49c, 0x00000e07);
// PCFGWQOS0_0.wqos_map_region2:24:8:=0x0
// PCFGWQOS0_0.wqos_map_region1:20:4:=0x0
// PCFGWQOS0_0.wqos_map_region0:16:4:=0x0
// PCFGWQOS0_0.wqos_map_level2:8:8:=0xe
// PCFGWQOS0_0.wqos_map_level1:0:8:=0x7
mmio_wr32(0x08004000 + 0x4a0, 0x01a801a8);
// PCFGWQOS1_0.wqos_map_timeout2:16:16:=0x1a8
// PCFGWQOS1_0.wqos_map_timeout1:0:16:=0x1a8
mmio_wr32(0x08004000 + 0x4b4, 0x00006000);
// PCFGR_1.rdwr_ordered_en:16:1:=0x0
// PCFGR_1.rd_port_pagematch_en:14:1:=0x1
// PCFGR_1.rd_port_urgent_en:13:1:=0x1
// PCFGR_1.rd_port_aging_en:12:1:=0x0
// PCFGR_1.read_reorder_bypass_en:11:1:=0x0
// PCFGR_1.rd_port_priority:0:10:=0x0
mmio_wr32(0x08004000 + 0x4b8, 0x00006000);
// PCFGW_1.wr_port_pagematch_en:14:1:=0x1
// PCFGW_1.wr_port_urgent_en:13:1:=0x1
// PCFGW_1.wr_port_aging_en:12:1:=0x0
// PCFGW_1.wr_port_priority:0:10:=0x0
mmio_wr32(0x08004000 + 0x540, 0x00000001);
// PCTRL_1.port_en:0:1:=0x1
mmio_wr32(0x08004000 + 0x544, 0x00000007);
// PCFGQOS0_1.rqos_map_region2:24:8:=0x0
// PCFGQOS0_1.rqos_map_region1:20:4:=0x0
// PCFGQOS0_1.rqos_map_region0:16:4:=0x0
// PCFGQOS0_1.rqos_map_level2:8:8:=0x0
// PCFGQOS0_1.rqos_map_level1:0:8:=0x7
mmio_wr32(0x08004000 + 0x548, 0x0000006a);
// PCFGQOS1_1.rqos_map_timeoutr:16:16:=0x0
// PCFGQOS1_1.rqos_map_timeoutb:0:16:=0x6a
mmio_wr32(0x08004000 + 0x54c, 0x00000e07);
// PCFGWQOS0_1.wqos_map_region2:24:8:=0x0
// PCFGWQOS0_1.wqos_map_region1:20:4:=0x0
// PCFGWQOS0_1.wqos_map_region0:16:4:=0x0
// PCFGWQOS0_1.wqos_map_level2:8:8:=0xe
// PCFGWQOS0_1.wqos_map_level1:0:8:=0x7
mmio_wr32(0x08004000 + 0x550, 0x01a801a8);
// PCFGWQOS1_1.wqos_map_timeout2:16:16:=0x1a8
// PCFGWQOS1_1.wqos_map_timeout1:0:16:=0x1a8
mmio_wr32(0x08004000 + 0x564, 0x00006000);
// PCFGR_2.rdwr_ordered_en:16:1:=0x0
// PCFGR_2.rd_port_pagematch_en:14:1:=0x1
// PCFGR_2.rd_port_urgent_en:13:1:=0x1
// PCFGR_2.rd_port_aging_en:12:1:=0x0
// PCFGR_2.read_reorder_bypass_en:11:1:=0x0
// PCFGR_2.rd_port_priority:0:10:=0x0
mmio_wr32(0x08004000 + 0x568, 0x00006000);
// PCFGW_2.wr_port_pagematch_en:14:1:=0x1
// PCFGW_2.wr_port_urgent_en:13:1:=0x1
// PCFGW_2.wr_port_aging_en:12:1:=0x0
// PCFGW_2.wr_port_priority:0:10:=0x0
mmio_wr32(0x08004000 + 0x5f0, 0x00000001);
// PCTRL_2.port_en:0:1:=0x1
mmio_wr32(0x08004000 + 0x5f4, 0x00000007);
// PCFGQOS0_2.rqos_map_region2:24:8:=0x0
// PCFGQOS0_2.rqos_map_region1:20:4:=0x0
// PCFGQOS0_2.rqos_map_region0:16:4:=0x0
// PCFGQOS0_2.rqos_map_level2:8:8:=0x0
// PCFGQOS0_2.rqos_map_level1:0:8:=0x7
mmio_wr32(0x08004000 + 0x5f8, 0x0000006a);
// PCFGQOS1_2.rqos_map_timeoutr:16:16:=0x0
// PCFGQOS1_2.rqos_map_timeoutb:0:16:=0x6a
mmio_wr32(0x08004000 + 0x5fc, 0x00000e07);
// PCFGWQOS0_2.wqos_map_region2:24:8:=0x0
// PCFGWQOS0_2.wqos_map_region1:20:4:=0x0
// PCFGWQOS0_2.wqos_map_region0:16:4:=0x0
// PCFGWQOS0_2.wqos_map_level2:8:8:=0xe
// PCFGWQOS0_2.wqos_map_level1:0:8:=0x7
mmio_wr32(0x08004000 + 0x600, 0x01a801a8);
// PCFGWQOS1_2.wqos_map_timeout2:16:16:=0x1a8
// PCFGWQOS1_2.wqos_map_timeout1:0:16:=0x1a8
}
void ctrl_init_high_patch(void)
{
// enable auto PD/SR
mmio_wr32(0x08004000 + 0x30, 0x00000002);
// enable auto ctrl_upd
mmio_wr32(0x08004000 + 0x1a0, 0x00400018);
// enable clock gating
mmio_wr32(0x0800a000 + 0x14, 0x00000000);
// change xpi to multi DDR burst
//mmio_wr32(0x08004000 + 0xc, 0x63786370);
}
void ctrl_init_low_patch(void)
{
// disable auto PD/SR
mmio_wr32(0x08004000 + 0x30, 0x00000000);
// disable auto ctrl_upd
mmio_wr32(0x08004000 + 0x1a0, 0xC0400018);
// disable clock gating
mmio_wr32(0x0800a000 + 0x14, 0x00000fff);
// change xpi to single DDR burst
//mmio_wr32(0x08004000 + 0xc, 0x63746371);
}
void ctrl_init_update_by_dram_size(uint8_t dram_cap_in_mbyte)
{
uint8_t dram_cap_in_mbyte_per_dev;
// Print capacity for external DDR after training
if (get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR2_1815J ||
get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815J ||
get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815K) {
switch (dram_cap_in_mbyte) {
case 6:
NOTICE("External DDR capacity: 512M\n");
break;
case 7:
NOTICE("External DDR capacity: 1G\n");
break;
case 8:
NOTICE("External DDR capacity: 2G\n");
break;
case 9:
NOTICE("External DDR capacity: 4G\n");
break;
default:
NOTICE("External DDR capacity: Unknown, %u\n",dram_cap_in_mbyte);
}
}
rddata = mmio_rd32(0x08004000 + 0x0);
dram_cap_in_mbyte_per_dev = dram_cap_in_mbyte;
dram_cap_in_mbyte_per_dev >>= (1 - get_bits_from_value(rddata, 13, 12)); // change sys cap to x16 cap
dram_cap_in_mbyte_per_dev >>= (2 - get_bits_from_value(rddata, 31, 30)); // change x16 cap to device cap
switch (dram_cap_in_mbyte_per_dev) {
case 6:
mmio_wr32(0x08004000 + 0x64, 0x00610024);
mmio_wr32(0x08004000 + 0x120, 0x00000903);
break;
case 7:
mmio_wr32(0x08004000 + 0x64, 0x0061002C);
mmio_wr32(0x08004000 + 0x120, 0x00000903);
break;
case 8:
mmio_wr32(0x08004000 + 0x64, 0x00610040);
mmio_wr32(0x08004000 + 0x120, 0x00000904);
break;
case 9:
mmio_wr32(0x08004000 + 0x64, 0x00610068);
mmio_wr32(0x08004000 + 0x120, 0x00000905);
break;
case 10:
mmio_wr32(0x08004000 + 0x64, 0x0061008C);
mmio_wr32(0x08004000 + 0x120, 0x00000906);
break;
}
// toggle refresh_update_level
mmio_wr32(0x08004000 + 0x60, 0x00000002);
mmio_wr32(0x08004000 + 0x60, 0x00000000);
}

View File

@@ -0,0 +1,271 @@
#include <mmio.h>
// #include <soc.h>
#include <reg_soc.h>
#include <ddr_sys.h>
#include <ddr_init.h>
// #include <printf.h>
void phy_init(void)
{
mmio_wr32(0x0 + PHYD_BASE_ADDR, DDR_PHY_REG_0_DATA);
mmio_wr32(0x4 + PHYD_BASE_ADDR, DDR_PHY_REG_1_DATA);
mmio_wr32(0x8 + PHYD_BASE_ADDR, DDR_PHY_REG_2_DATA);
mmio_wr32(0xc + PHYD_BASE_ADDR, DDR_PHY_REG_3_DATA);
mmio_wr32(0x10 + PHYD_BASE_ADDR, DDR_PHY_REG_4_DATA);
mmio_wr32(0x14 + PHYD_BASE_ADDR, DDR_PHY_REG_5_DATA);
mmio_wr32(0x18 + PHYD_BASE_ADDR, DDR_PHY_REG_6_DATA);
mmio_wr32(0x1c + PHYD_BASE_ADDR, DDR_PHY_REG_7_DATA);
mmio_wr32(0x20 + PHYD_BASE_ADDR, DDR_PHY_REG_8_DATA);
mmio_wr32(0x24 + PHYD_BASE_ADDR, DDR_PHY_REG_9_DATA);
mmio_wr32(0x28 + PHYD_BASE_ADDR, DDR_PHY_REG_10_DATA);
mmio_wr32(0x2c + PHYD_BASE_ADDR, DDR_PHY_REG_11_DATA);
mmio_wr32(0x40 + PHYD_BASE_ADDR, DDR_PHY_REG_16_DATA);
mmio_wr32(0x44 + PHYD_BASE_ADDR, DDR_PHY_REG_17_DATA);
mmio_wr32(0x48 + PHYD_BASE_ADDR, DDR_PHY_REG_18_DATA);
mmio_wr32(0x4c + PHYD_BASE_ADDR, DDR_PHY_REG_19_DATA);
mmio_wr32(0x50 + PHYD_BASE_ADDR, DDR_PHY_REG_20_DATA);
mmio_wr32(0x54 + PHYD_BASE_ADDR, DDR_PHY_REG_21_DATA);
mmio_wr32(0x58 + PHYD_BASE_ADDR, DDR_PHY_REG_22_DATA);
mmio_wr32(0x5c + PHYD_BASE_ADDR, DDR_PHY_REG_23_DATA);
mmio_wr32(0x60 + PHYD_BASE_ADDR, DDR_PHY_REG_24_DATA);
mmio_wr32(0x64 + PHYD_BASE_ADDR, DDR_PHY_REG_25_DATA);
mmio_wr32(0x68 + PHYD_BASE_ADDR, DDR_PHY_REG_26_DATA);
mmio_wr32(0x70 + PHYD_BASE_ADDR, DDR_PHY_REG_28_DATA);
mmio_wr32(0x74 + PHYD_BASE_ADDR, DDR_PHY_REG_29_DATA);
mmio_wr32(0x80 + PHYD_BASE_ADDR, DDR_PHY_REG_32_DATA);
mmio_wr32(0x84 + PHYD_BASE_ADDR, DDR_PHY_REG_33_DATA);
mmio_wr32(0x88 + PHYD_BASE_ADDR, DDR_PHY_REG_34_DATA);
mmio_wr32(0x8c + PHYD_BASE_ADDR, DDR_PHY_REG_35_DATA);
mmio_wr32(0x90 + PHYD_BASE_ADDR, DDR_PHY_REG_36_DATA);
mmio_wr32(0x94 + PHYD_BASE_ADDR, DDR_PHY_REG_37_DATA);
mmio_wr32(0xa0 + PHYD_BASE_ADDR, DDR_PHY_REG_40_DATA);
mmio_wr32(0xa4 + PHYD_BASE_ADDR, DDR_PHY_REG_41_DATA);
mmio_wr32(0xa8 + PHYD_BASE_ADDR, DDR_PHY_REG_42_DATA);
mmio_wr32(0xac + PHYD_BASE_ADDR, DDR_PHY_REG_43_DATA);
mmio_wr32(0xb0 + PHYD_BASE_ADDR, DDR_PHY_REG_44_DATA);
mmio_wr32(0xb4 + PHYD_BASE_ADDR, DDR_PHY_REG_45_DATA);
mmio_wr32(0xb8 + PHYD_BASE_ADDR, DDR_PHY_REG_46_DATA);
mmio_wr32(0xbc + PHYD_BASE_ADDR, DDR_PHY_REG_47_DATA);
mmio_wr32(0xf0 + PHYD_BASE_ADDR, DDR_PHY_REG_60_DATA);
mmio_wr32(0xf4 + PHYD_BASE_ADDR, DDR_PHY_REG_61_DATA);
mmio_wr32(0xf8 + PHYD_BASE_ADDR, DDR_PHY_REG_62_DATA);
mmio_wr32(0xfc + PHYD_BASE_ADDR, DDR_PHY_REG_63_DATA);
mmio_wr32(0x100 + PHYD_BASE_ADDR, DDR_PHY_REG_64_DATA);
mmio_wr32(0x104 + PHYD_BASE_ADDR, DDR_PHY_REG_65_DATA);
mmio_wr32(0x10c + PHYD_BASE_ADDR, DDR_PHY_REG_67_DATA);
mmio_wr32(0x110 + PHYD_BASE_ADDR, DDR_PHY_REG_68_DATA);
mmio_wr32(0x114 + PHYD_BASE_ADDR, DDR_PHY_REG_69_DATA);
mmio_wr32(0x118 + PHYD_BASE_ADDR, DDR_PHY_REG_70_DATA);
mmio_wr32(0x11c + PHYD_BASE_ADDR, DDR_PHY_REG_71_DATA);
mmio_wr32(0x120 + PHYD_BASE_ADDR, DDR_PHY_REG_72_DATA);
mmio_wr32(0x124 + PHYD_BASE_ADDR, DDR_PHY_REG_73_DATA);
mmio_wr32(0x128 + PHYD_BASE_ADDR, DDR_PHY_REG_74_DATA);
mmio_wr32(0x12c + PHYD_BASE_ADDR, DDR_PHY_REG_75_DATA);
mmio_wr32(0x130 + PHYD_BASE_ADDR, DDR_PHY_REG_76_DATA);
mmio_wr32(0x134 + PHYD_BASE_ADDR, DDR_PHY_REG_77_DATA);
mmio_wr32(0x138 + PHYD_BASE_ADDR, DDR_PHY_REG_78_DATA);
mmio_wr32(0x140 + PHYD_BASE_ADDR, DDR_PHY_REG_80_DATA);
mmio_wr32(0x144 + PHYD_BASE_ADDR, DDR_PHY_REG_81_DATA);
mmio_wr32(0x148 + PHYD_BASE_ADDR, DDR_PHY_REG_82_DATA);
mmio_wr32(0x14c + PHYD_BASE_ADDR, DDR_PHY_REG_83_DATA);
mmio_wr32(0x150 + PHYD_BASE_ADDR, DDR_PHY_REG_84_DATA);
mmio_wr32(0x154 + PHYD_BASE_ADDR, DDR_PHY_REG_85_DATA);
mmio_wr32(0x158 + PHYD_BASE_ADDR, DDR_PHY_REG_86_DATA);
mmio_wr32(0x15c + PHYD_BASE_ADDR, DDR_PHY_REG_87_DATA);
mmio_wr32(0x164 + PHYD_BASE_ADDR, DDR_PHY_REG_89_DATA);
mmio_wr32(0x168 + PHYD_BASE_ADDR, DDR_PHY_REG_90_DATA);
mmio_wr32(0x16c + PHYD_BASE_ADDR, DDR_PHY_REG_91_DATA);
mmio_wr32(0x170 + PHYD_BASE_ADDR, DDR_PHY_REG_92_DATA);
mmio_wr32(0x174 + PHYD_BASE_ADDR, DDR_PHY_REG_93_DATA);
mmio_wr32(0x180 + PHYD_BASE_ADDR, DDR_PHY_REG_96_DATA);
mmio_wr32(0x184 + PHYD_BASE_ADDR, DDR_PHY_REG_97_DATA);
mmio_wr32(0x188 + PHYD_BASE_ADDR, DDR_PHY_REG_98_DATA);
mmio_wr32(0x18c + PHYD_BASE_ADDR, DDR_PHY_REG_99_DATA);
mmio_wr32(0x190 + PHYD_BASE_ADDR, DDR_PHY_REG_100_DATA);
mmio_wr32(0x200 + PHYD_BASE_ADDR, DDR_PHY_REG_128_DATA);
mmio_wr32(0x204 + PHYD_BASE_ADDR, DDR_PHY_REG_129_DATA);
mmio_wr32(0x208 + PHYD_BASE_ADDR, DDR_PHY_REG_130_DATA);
mmio_wr32(0x220 + PHYD_BASE_ADDR, DDR_PHY_REG_136_DATA);
mmio_wr32(0x224 + PHYD_BASE_ADDR, DDR_PHY_REG_137_DATA);
mmio_wr32(0x228 + PHYD_BASE_ADDR, DDR_PHY_REG_138_DATA);
mmio_wr32(0x400 + PHYD_BASE_ADDR, DDR_PHY_REG_0_F0_DATA);
mmio_wr32(0x404 + PHYD_BASE_ADDR, DDR_PHY_REG_1_F0_DATA);
mmio_wr32(0x408 + PHYD_BASE_ADDR, DDR_PHY_REG_2_F0_DATA);
mmio_wr32(0x40c + PHYD_BASE_ADDR, DDR_PHY_REG_3_F0_DATA);
mmio_wr32(0x410 + PHYD_BASE_ADDR, DDR_PHY_REG_4_F0_DATA);
mmio_wr32(0x414 + PHYD_BASE_ADDR, DDR_PHY_REG_5_F0_DATA);
mmio_wr32(0x418 + PHYD_BASE_ADDR, DDR_PHY_REG_6_F0_DATA);
mmio_wr32(0x41c + PHYD_BASE_ADDR, DDR_PHY_REG_7_F0_DATA);
mmio_wr32(0x500 + PHYD_BASE_ADDR, DDR_PHY_REG_64_F0_DATA);
mmio_wr32(0x504 + PHYD_BASE_ADDR, DDR_PHY_REG_65_F0_DATA);
mmio_wr32(0x508 + PHYD_BASE_ADDR, DDR_PHY_REG_66_F0_DATA);
mmio_wr32(0x50c + PHYD_BASE_ADDR, DDR_PHY_REG_67_F0_DATA);
mmio_wr32(0x510 + PHYD_BASE_ADDR, DDR_PHY_REG_68_F0_DATA);
mmio_wr32(0x514 + PHYD_BASE_ADDR, DDR_PHY_REG_69_F0_DATA);
mmio_wr32(0x518 + PHYD_BASE_ADDR, DDR_PHY_REG_70_F0_DATA);
mmio_wr32(0x51c + PHYD_BASE_ADDR, DDR_PHY_REG_71_F0_DATA);
mmio_wr32(0x520 + PHYD_BASE_ADDR, DDR_PHY_REG_72_F0_DATA);
mmio_wr32(0x540 + PHYD_BASE_ADDR, DDR_PHY_REG_80_F0_DATA);
mmio_wr32(0x544 + PHYD_BASE_ADDR, DDR_PHY_REG_81_F0_DATA);
mmio_wr32(0x548 + PHYD_BASE_ADDR, DDR_PHY_REG_82_F0_DATA);
mmio_wr32(0x54c + PHYD_BASE_ADDR, DDR_PHY_REG_83_F0_DATA);
mmio_wr32(0x550 + PHYD_BASE_ADDR, DDR_PHY_REG_84_F0_DATA);
mmio_wr32(0x554 + PHYD_BASE_ADDR, DDR_PHY_REG_85_F0_DATA);
mmio_wr32(0x558 + PHYD_BASE_ADDR, DDR_PHY_REG_86_F0_DATA);
mmio_wr32(0x55c + PHYD_BASE_ADDR, DDR_PHY_REG_87_F0_DATA);
mmio_wr32(0x560 + PHYD_BASE_ADDR, DDR_PHY_REG_88_F0_DATA);
mmio_wr32(0x900 + PHYD_BASE_ADDR, DDR_PHY_REG_320_F0_DATA);
mmio_wr32(0x92c + PHYD_BASE_ADDR, DDR_PHY_REG_331_F0_DATA);
mmio_wr32(0x930 + PHYD_BASE_ADDR, DDR_PHY_REG_332_F0_DATA);
mmio_wr32(0x934 + PHYD_BASE_ADDR, DDR_PHY_REG_333_F0_DATA);
mmio_wr32(0x938 + PHYD_BASE_ADDR, DDR_PHY_REG_334_F0_DATA);
mmio_wr32(0x940 + PHYD_BASE_ADDR, DDR_PHY_REG_336_F0_DATA);
mmio_wr32(0x970 + PHYD_BASE_ADDR, DDR_PHY_REG_348_F0_DATA);
mmio_wr32(0x974 + PHYD_BASE_ADDR, DDR_PHY_REG_349_F0_DATA);
mmio_wr32(0x978 + PHYD_BASE_ADDR, DDR_PHY_REG_350_F0_DATA);
mmio_wr32(0x97c + PHYD_BASE_ADDR, DDR_PHY_REG_351_F0_DATA);
mmio_wr32(0x980 + PHYD_BASE_ADDR, DDR_PHY_REG_352_F0_DATA);
mmio_wr32(0xa00 + PHYD_BASE_ADDR, DDR_PHY_REG_384_F0_DATA);
mmio_wr32(0xa04 + PHYD_BASE_ADDR, DDR_PHY_REG_385_F0_DATA);
mmio_wr32(0xa08 + PHYD_BASE_ADDR, DDR_PHY_REG_386_F0_DATA);
mmio_wr32(0xa0c + PHYD_BASE_ADDR, DDR_PHY_REG_387_F0_DATA);
mmio_wr32(0xa10 + PHYD_BASE_ADDR, DDR_PHY_REG_388_F0_DATA);
mmio_wr32(0xa14 + PHYD_BASE_ADDR, DDR_PHY_REG_389_F0_DATA);
mmio_wr32(0xa18 + PHYD_BASE_ADDR, DDR_PHY_REG_390_F0_DATA);
mmio_wr32(0xa1c + PHYD_BASE_ADDR, DDR_PHY_REG_391_F0_DATA);
mmio_wr32(0xa20 + PHYD_BASE_ADDR, DDR_PHY_REG_392_F0_DATA);
mmio_wr32(0xa24 + PHYD_BASE_ADDR, DDR_PHY_REG_393_F0_DATA);
mmio_wr32(0xa28 + PHYD_BASE_ADDR, DDR_PHY_REG_394_F0_DATA);
mmio_wr32(0xa2c + PHYD_BASE_ADDR, DDR_PHY_REG_395_F0_DATA);
mmio_wr32(0xa30 + PHYD_BASE_ADDR, DDR_PHY_REG_396_F0_DATA);
mmio_wr32(0xa34 + PHYD_BASE_ADDR, DDR_PHY_REG_397_F0_DATA);
mmio_wr32(0xa38 + PHYD_BASE_ADDR, DDR_PHY_REG_398_F0_DATA);
mmio_wr32(0xa3c + PHYD_BASE_ADDR, DDR_PHY_REG_399_F0_DATA);
mmio_wr32(0xa40 + PHYD_BASE_ADDR, DDR_PHY_REG_400_F0_DATA);
mmio_wr32(0xa44 + PHYD_BASE_ADDR, DDR_PHY_REG_401_F0_DATA);
mmio_wr32(0xa48 + PHYD_BASE_ADDR, DDR_PHY_REG_402_F0_DATA);
mmio_wr32(0xa4c + PHYD_BASE_ADDR, DDR_PHY_REG_403_F0_DATA);
mmio_wr32(0xa50 + PHYD_BASE_ADDR, DDR_PHY_REG_404_F0_DATA);
mmio_wr32(0xa54 + PHYD_BASE_ADDR, DDR_PHY_REG_405_F0_DATA);
mmio_wr32(0xa58 + PHYD_BASE_ADDR, DDR_PHY_REG_406_F0_DATA);
mmio_wr32(0xa5c + PHYD_BASE_ADDR, DDR_PHY_REG_407_F0_DATA);
mmio_wr32(0xa60 + PHYD_BASE_ADDR, DDR_PHY_REG_408_F0_DATA);
mmio_wr32(0xa64 + PHYD_BASE_ADDR, DDR_PHY_REG_409_F0_DATA);
mmio_wr32(0xa68 + PHYD_BASE_ADDR, DDR_PHY_REG_410_F0_DATA);
mmio_wr32(0xa6c + PHYD_BASE_ADDR, DDR_PHY_REG_411_F0_DATA);
mmio_wr32(0xa70 + PHYD_BASE_ADDR, DDR_PHY_REG_412_F0_DATA);
mmio_wr32(0xa74 + PHYD_BASE_ADDR, DDR_PHY_REG_413_F0_DATA);
mmio_wr32(0xa78 + PHYD_BASE_ADDR, DDR_PHY_REG_414_F0_DATA);
mmio_wr32(0xa7c + PHYD_BASE_ADDR, DDR_PHY_REG_415_F0_DATA);
mmio_wr32(0xb00 + PHYD_BASE_ADDR, DDR_PHY_REG_448_F0_DATA);
mmio_wr32(0xb04 + PHYD_BASE_ADDR, DDR_PHY_REG_449_F0_DATA);
mmio_wr32(0xb08 + PHYD_BASE_ADDR, DDR_PHY_REG_450_F0_DATA);
mmio_wr32(0xb0c + PHYD_BASE_ADDR, DDR_PHY_REG_451_F0_DATA);
mmio_wr32(0xb10 + PHYD_BASE_ADDR, DDR_PHY_REG_452_F0_DATA);
mmio_wr32(0xb14 + PHYD_BASE_ADDR, DDR_PHY_REG_453_F0_DATA);
mmio_wr32(0xb18 + PHYD_BASE_ADDR, DDR_PHY_REG_454_F0_DATA);
mmio_wr32(0xb1c + PHYD_BASE_ADDR, DDR_PHY_REG_455_F0_DATA);
mmio_wr32(0xb20 + PHYD_BASE_ADDR, DDR_PHY_REG_456_F0_DATA);
mmio_wr32(0xb24 + PHYD_BASE_ADDR, DDR_PHY_REG_457_F0_DATA);
mmio_wr32(0xb30 + PHYD_BASE_ADDR, DDR_PHY_REG_460_F0_DATA);
mmio_wr32(0xb34 + PHYD_BASE_ADDR, DDR_PHY_REG_461_F0_DATA);
mmio_wr32(0xb38 + PHYD_BASE_ADDR, DDR_PHY_REG_462_F0_DATA);
mmio_wr32(0xb3c + PHYD_BASE_ADDR, DDR_PHY_REG_463_F0_DATA);
mmio_wr32(0xb40 + PHYD_BASE_ADDR, DDR_PHY_REG_464_F0_DATA);
mmio_wr32(0xb44 + PHYD_BASE_ADDR, DDR_PHY_REG_465_F0_DATA);
mmio_wr32(0xb48 + PHYD_BASE_ADDR, DDR_PHY_REG_466_F0_DATA);
mmio_wr32(0xb4c + PHYD_BASE_ADDR, DDR_PHY_REG_467_F0_DATA);
mmio_wr32(0xb50 + PHYD_BASE_ADDR, DDR_PHY_REG_468_F0_DATA);
mmio_wr32(0xb54 + PHYD_BASE_ADDR, DDR_PHY_REG_469_F0_DATA);
#ifdef F1_TEST
mmio_wr32(0x1400 + PHYD_BASE_ADDR, DDR_PHY_REG_0_F1_DATA);
mmio_wr32(0x1404 + PHYD_BASE_ADDR, DDR_PHY_REG_1_F1_DATA);
mmio_wr32(0x1408 + PHYD_BASE_ADDR, DDR_PHY_REG_2_F1_DATA);
mmio_wr32(0x140c + PHYD_BASE_ADDR, DDR_PHY_REG_3_F1_DATA);
mmio_wr32(0x1410 + PHYD_BASE_ADDR, DDR_PHY_REG_4_F1_DATA);
mmio_wr32(0x1414 + PHYD_BASE_ADDR, DDR_PHY_REG_5_F1_DATA);
mmio_wr32(0x1418 + PHYD_BASE_ADDR, DDR_PHY_REG_6_F1_DATA);
mmio_wr32(0x141c + PHYD_BASE_ADDR, DDR_PHY_REG_7_F1_DATA);
mmio_wr32(0x1500 + PHYD_BASE_ADDR, DDR_PHY_REG_64_F1_DATA);
mmio_wr32(0x1504 + PHYD_BASE_ADDR, DDR_PHY_REG_65_F1_DATA);
mmio_wr32(0x1508 + PHYD_BASE_ADDR, DDR_PHY_REG_66_F1_DATA);
mmio_wr32(0x150c + PHYD_BASE_ADDR, DDR_PHY_REG_67_F1_DATA);
mmio_wr32(0x1510 + PHYD_BASE_ADDR, DDR_PHY_REG_68_F1_DATA);
mmio_wr32(0x1514 + PHYD_BASE_ADDR, DDR_PHY_REG_69_F1_DATA);
mmio_wr32(0x1518 + PHYD_BASE_ADDR, DDR_PHY_REG_70_F1_DATA);
mmio_wr32(0x151c + PHYD_BASE_ADDR, DDR_PHY_REG_71_F1_DATA);
mmio_wr32(0x1520 + PHYD_BASE_ADDR, DDR_PHY_REG_72_F1_DATA);
mmio_wr32(0x1540 + PHYD_BASE_ADDR, DDR_PHY_REG_80_F1_DATA);
mmio_wr32(0x1544 + PHYD_BASE_ADDR, DDR_PHY_REG_81_F1_DATA);
mmio_wr32(0x1548 + PHYD_BASE_ADDR, DDR_PHY_REG_82_F1_DATA);
mmio_wr32(0x154c + PHYD_BASE_ADDR, DDR_PHY_REG_83_F1_DATA);
mmio_wr32(0x1550 + PHYD_BASE_ADDR, DDR_PHY_REG_84_F1_DATA);
mmio_wr32(0x1554 + PHYD_BASE_ADDR, DDR_PHY_REG_85_F1_DATA);
mmio_wr32(0x1558 + PHYD_BASE_ADDR, DDR_PHY_REG_86_F1_DATA);
mmio_wr32(0x155c + PHYD_BASE_ADDR, DDR_PHY_REG_87_F1_DATA);
mmio_wr32(0x1560 + PHYD_BASE_ADDR, DDR_PHY_REG_88_F1_DATA);
mmio_wr32(0x1900 + PHYD_BASE_ADDR, DDR_PHY_REG_320_F1_DATA);
mmio_wr32(0x192c + PHYD_BASE_ADDR, DDR_PHY_REG_331_F1_DATA);
mmio_wr32(0x1930 + PHYD_BASE_ADDR, DDR_PHY_REG_332_F1_DATA);
mmio_wr32(0x1934 + PHYD_BASE_ADDR, DDR_PHY_REG_333_F1_DATA);
mmio_wr32(0x1938 + PHYD_BASE_ADDR, DDR_PHY_REG_334_F1_DATA);
mmio_wr32(0x1940 + PHYD_BASE_ADDR, DDR_PHY_REG_336_F1_DATA);
mmio_wr32(0x1970 + PHYD_BASE_ADDR, DDR_PHY_REG_348_F1_DATA);
mmio_wr32(0x1974 + PHYD_BASE_ADDR, DDR_PHY_REG_349_F1_DATA);
mmio_wr32(0x1978 + PHYD_BASE_ADDR, DDR_PHY_REG_350_F1_DATA);
mmio_wr32(0x197c + PHYD_BASE_ADDR, DDR_PHY_REG_351_F1_DATA);
mmio_wr32(0x1980 + PHYD_BASE_ADDR, DDR_PHY_REG_352_F1_DATA);
mmio_wr32(0x1a00 + PHYD_BASE_ADDR, DDR_PHY_REG_384_F1_DATA);
mmio_wr32(0x1a04 + PHYD_BASE_ADDR, DDR_PHY_REG_385_F1_DATA);
mmio_wr32(0x1a08 + PHYD_BASE_ADDR, DDR_PHY_REG_386_F1_DATA);
mmio_wr32(0x1a0c + PHYD_BASE_ADDR, DDR_PHY_REG_387_F1_DATA);
mmio_wr32(0x1a10 + PHYD_BASE_ADDR, DDR_PHY_REG_388_F1_DATA);
mmio_wr32(0x1a14 + PHYD_BASE_ADDR, DDR_PHY_REG_389_F1_DATA);
mmio_wr32(0x1a18 + PHYD_BASE_ADDR, DDR_PHY_REG_390_F1_DATA);
mmio_wr32(0x1a1c + PHYD_BASE_ADDR, DDR_PHY_REG_391_F1_DATA);
mmio_wr32(0x1a20 + PHYD_BASE_ADDR, DDR_PHY_REG_392_F1_DATA);
mmio_wr32(0x1a24 + PHYD_BASE_ADDR, DDR_PHY_REG_393_F1_DATA);
mmio_wr32(0x1a28 + PHYD_BASE_ADDR, DDR_PHY_REG_394_F1_DATA);
mmio_wr32(0x1a2c + PHYD_BASE_ADDR, DDR_PHY_REG_395_F1_DATA);
mmio_wr32(0x1a30 + PHYD_BASE_ADDR, DDR_PHY_REG_396_F1_DATA);
mmio_wr32(0x1a34 + PHYD_BASE_ADDR, DDR_PHY_REG_397_F1_DATA);
mmio_wr32(0x1a38 + PHYD_BASE_ADDR, DDR_PHY_REG_398_F1_DATA);
mmio_wr32(0x1a3c + PHYD_BASE_ADDR, DDR_PHY_REG_399_F1_DATA);
mmio_wr32(0x1a40 + PHYD_BASE_ADDR, DDR_PHY_REG_400_F1_DATA);
mmio_wr32(0x1a44 + PHYD_BASE_ADDR, DDR_PHY_REG_401_F1_DATA);
mmio_wr32(0x1a48 + PHYD_BASE_ADDR, DDR_PHY_REG_402_F1_DATA);
mmio_wr32(0x1a4c + PHYD_BASE_ADDR, DDR_PHY_REG_403_F1_DATA);
mmio_wr32(0x1a50 + PHYD_BASE_ADDR, DDR_PHY_REG_404_F1_DATA);
mmio_wr32(0x1a54 + PHYD_BASE_ADDR, DDR_PHY_REG_405_F1_DATA);
mmio_wr32(0x1a58 + PHYD_BASE_ADDR, DDR_PHY_REG_406_F1_DATA);
mmio_wr32(0x1a5c + PHYD_BASE_ADDR, DDR_PHY_REG_407_F1_DATA);
mmio_wr32(0x1a60 + PHYD_BASE_ADDR, DDR_PHY_REG_408_F1_DATA);
mmio_wr32(0x1a64 + PHYD_BASE_ADDR, DDR_PHY_REG_409_F1_DATA);
mmio_wr32(0x1a68 + PHYD_BASE_ADDR, DDR_PHY_REG_410_F1_DATA);
mmio_wr32(0x1a6c + PHYD_BASE_ADDR, DDR_PHY_REG_411_F1_DATA);
mmio_wr32(0x1a70 + PHYD_BASE_ADDR, DDR_PHY_REG_412_F1_DATA);
mmio_wr32(0x1a74 + PHYD_BASE_ADDR, DDR_PHY_REG_413_F1_DATA);
mmio_wr32(0x1a78 + PHYD_BASE_ADDR, DDR_PHY_REG_414_F1_DATA);
mmio_wr32(0x1a7c + PHYD_BASE_ADDR, DDR_PHY_REG_415_F1_DATA);
mmio_wr32(0x1b00 + PHYD_BASE_ADDR, DDR_PHY_REG_448_F1_DATA);
mmio_wr32(0x1b04 + PHYD_BASE_ADDR, DDR_PHY_REG_449_F1_DATA);
mmio_wr32(0x1b08 + PHYD_BASE_ADDR, DDR_PHY_REG_450_F1_DATA);
mmio_wr32(0x1b0c + PHYD_BASE_ADDR, DDR_PHY_REG_451_F1_DATA);
mmio_wr32(0x1b10 + PHYD_BASE_ADDR, DDR_PHY_REG_452_F1_DATA);
mmio_wr32(0x1b14 + PHYD_BASE_ADDR, DDR_PHY_REG_453_F1_DATA);
mmio_wr32(0x1b18 + PHYD_BASE_ADDR, DDR_PHY_REG_454_F1_DATA);
mmio_wr32(0x1b1c + PHYD_BASE_ADDR, DDR_PHY_REG_455_F1_DATA);
mmio_wr32(0x1b20 + PHYD_BASE_ADDR, DDR_PHY_REG_456_F1_DATA);
mmio_wr32(0x1b24 + PHYD_BASE_ADDR, DDR_PHY_REG_457_F1_DATA);
mmio_wr32(0x1b30 + PHYD_BASE_ADDR, DDR_PHY_REG_460_F1_DATA);
mmio_wr32(0x1b34 + PHYD_BASE_ADDR, DDR_PHY_REG_461_F1_DATA);
mmio_wr32(0x1b38 + PHYD_BASE_ADDR, DDR_PHY_REG_462_F1_DATA);
mmio_wr32(0x1b3c + PHYD_BASE_ADDR, DDR_PHY_REG_463_F1_DATA);
mmio_wr32(0x1b40 + PHYD_BASE_ADDR, DDR_PHY_REG_464_F1_DATA);
mmio_wr32(0x1b44 + PHYD_BASE_ADDR, DDR_PHY_REG_465_F1_DATA);
mmio_wr32(0x1b48 + PHYD_BASE_ADDR, DDR_PHY_REG_466_F1_DATA);
mmio_wr32(0x1b4c + PHYD_BASE_ADDR, DDR_PHY_REG_467_F1_DATA);
mmio_wr32(0x1b50 + PHYD_BASE_ADDR, DDR_PHY_REG_468_F1_DATA);
mmio_wr32(0x1b54 + PHYD_BASE_ADDR, DDR_PHY_REG_469_F1_DATA);
#endif
}

View File

@@ -3,11 +3,12 @@
#include <mmio.h>
#include <reg_soc.h>
#include <ddr_sys.h>
#include <ddr_pkg_info.h>
#include "regconfig.h"
//regpatch_ddr3_x16_bga.c for 1866
struct regpatch ddr_patch_regs[] = {
static struct regpatch _ddr_patch_regs_sip[] = {
// tune damp //////
{0x08000150, 0xFFFFFFFF, 0x00000005},
@@ -105,4 +106,119 @@ struct regpatch ddr_patch_regs[] = {
{0x08000934, 0xFFFFFFFF, 0x04000400},
};
uint32_t ddr_patch_regs_count = ARRAY_SIZE(ddr_patch_regs);
/* External DDR3: same as SIP but disable DQS voltage mode RX */
static struct regpatch _ddr_patch_regs_ext[] = {
// tune damp //////
{0x08000150, 0xFFFFFFFF, 0x00000005},
// CSB & CA driving
{0x0800097c, 0xFFFFFFFF, 0x08080404},
// CLK driving
{0x08000980, 0xFFFFFFFF, 0x08080808},
// DQ driving // BYTE0
{0x08000a38, 0xFFFFFFFF, 0x00000606},
// DQS driving // BYTE0
{0x08000a3c, 0xFFFFFFFF, 0x06060606},
// DQ driving // BYTE1
{0x08000a78, 0xFFFFFFFF, 0x00000606},
// DQS driving // BYTE1
{0x08000a7c, 0xFFFFFFFF, 0x06060606},
//trigger level //////
// BYTE0
{0x08000b24, 0xFFFFFFFF, 0x00100010},
// BYTE1
{0x08000b54, 0xFFFFFFFF, 0x00100010},
//APHY TX VREFDQ rangex2 [1]
//VREF DQ //
{0x08000410, 0xFFFFFFFF, 0x00120002},
//APHY TX VREFCA rangex2 [1]
//VREF CA //
{0x08000414, 0xFFFFFFFF, 0x00100002},
// tx dline code
// BYTE0 DQ
{0x08000a00, 0xFFFFFFFF, 0x06430643},
{0x08000a04, 0xFFFFFFFF, 0x06430643},
{0x08000a08, 0xFFFFFFFF, 0x06430643},
{0x08000a0c, 0xFFFFFFFF, 0x06430643},
{0x08000a10, 0xFFFFFFFF, 0x00000643},
{0x08000a14, 0xFFFFFFFF, 0x0a7e007e},
// BYTE1 DQ
{0x08000a40, 0xFFFFFFFF, 0x06480648},
{0x08000a44, 0xFFFFFFFF, 0x06480648},
{0x08000a48, 0xFFFFFFFF, 0x06480648},
{0x08000a4c, 0xFFFFFFFF, 0x06480648},
{0x08000a50, 0xFFFFFFFF, 0x00000648},
{0x08000a54, 0xFFFFFFFF, 0x0a7e007e},
//APHY RX TRIG rangex2[18] & disable lsmode[0]
//f0_param_phya_reg_rx_byte0_en_lsmode[0]
//f0_param_phya_reg_byte0_en_rec_vol_mode[12]
//f0_param_phya_reg_rx_byte0_force_en_lvstl_odt[16]
//f0_param_phya_reg_rx_byte0_sel_dqs_rec_vref_mode[8]
//param_phya_reg_rx_byte0_en_trig_lvl_rangex2[18]
// BYTE0 [0]
{0x08000500, 0xFFFFFFFF, 0x00040001},
//f0_param_phya_reg_rx_byte1_en_lsmode[0]
//f0_param_phya_reg_byte1_en_rec_vol_mode[12]
//f0_param_phya_reg_rx_byte0_force_en_lvstl_odt[16]
//f0_param_phya_reg_rx_byte0_sel_dqs_rec_vref_mode[8]
//param_phya_reg_rx_byte0_en_trig_lvl_rangex2[18]
// BYTE1 [0]
{0x08000540, 0xFFFFFFFF, 0x00040001},
//////// FOR U02 ///////
/////////// U02 DQS voltage mode receiver -- disabled for external DDR
// f0_param_phya_reg_tx_byte0_en_tx_de_dqs[20]
{0x08000504, 0xFFFFFFFF, 0x00000000},
// f0_param_phya_reg_tx_byte1_en_tx_de_dqs[20]
{0x08000544, 0xFFFFFFFF, 0x00000000},
/////////// U02 enable MASK voltage mode receiver
// param_phya_reg_rx_sel_dqs_wo_pream_mode[2]
{0x08000138, 0xFFFFFFFF, 0x00000014},
// RX ODT 120ohm for external DDR3 (override ddr_init.h default 240ohm)
{0x0800041c, 0xFFFFFFFF, 0x00004242},
// BYTE0 RX DQ deskew
{0x08000b00, 0xFFFFFFFF, 0x00020402},
{0x08000b04, 0xFFFFFFFF, 0x05020401},
// BYTE0 DQ8 deskew [6:0] neg DQS [15:8] ; pos DQS [23:16]
{0x08000b08, 0xFFFFFFFF, 0x00313902},
// BYTE1 RX DQ deskew
{0x08000b30, 0xFFFFFFFF, 0x06000100},
{0x08000b34, 0xFFFFFFFF, 0x02010303},
// BYTE1 DQ8 deskew [6:0] neg DQS [15:8] ; pos DQS [23:16]
{0x08000b38, 0xFFFFFFFF, 0x00323900},
//Read gate TX dline + shift
// BYTE0
{0x08000b0c, 0xFFFFFFFF, 0x00000a14},
// BYTE1
{0x08000b3c, 0xFFFFFFFF, 0x00000a14},
// CKE dline + shift CKE0 [6:0]+[13:8] ; CKE1 [22:16]+[29:24]
{0x08000930, 0xFFFFFFFF, 0x04000400},
// CSB dline + shift CSB0 [6:0]+[13:8] ; CSB1 [22:16]+[29:24]
{0x08000934, 0xFFFFFFFF, 0x04000400},
};
struct regpatch *ddr_patch_regs;
uint32_t ddr_patch_regs_count;
void ddr_patch_regs_init(void)
{
if (get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815J ||
get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815K) {
ddr_patch_regs = _ddr_patch_regs_ext;
ddr_patch_regs_count = ARRAY_SIZE(_ddr_patch_regs_ext);
} else {
ddr_patch_regs = _ddr_patch_regs_sip;
ddr_patch_regs_count = ARRAY_SIZE(_ddr_patch_regs_sip);
}
}

View File

@@ -4,6 +4,7 @@
#include <ddr_sys.h>
#include <ddr_init.h>
#include <bitwise_ops.h>
#include <ddr_pkg_info.h>
uint32_t ddr_data_rate = 1866;
@@ -61,6 +62,8 @@ void ddrc_init(void)
#endif
mmio_wr32(0x08004000 + 0xe4, 0x000B03BF);
mmio_wr32(0x08004000 + 0x100, 0x0E111F10);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x100, mmio_rd32(0x08004000 + 0x100) + 0x3000000);
mmio_wr32(0x08004000 + 0x104, 0x00030417);
mmio_wr32(0x08004000 + 0x108, 0x0507060A);
mmio_wr32(0x08004000 + 0x10c, 0x00002007);
@@ -137,6 +140,8 @@ void ddrc_init(void)
// SCHED.prefer_write:1:1:=0x0
// SCHED.dis_opt_wrecc_collision_flush:0:1:=0x1
mmio_wr32(0x08004000 + 0x254, 0x00000000);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x254, 0x40);
// SCHED1.page_hit_limit_rd:28:3:=0x0
// SCHED1.page_hit_limit_wr:24:3:=0x0
// SCHED1.visible_window_limit_rd:20:3:=0x0
@@ -304,6 +309,28 @@ void ctrl_init_update_by_dram_size(uint8_t dram_cap_in_mbyte)
{
uint8_t dram_cap_in_mbyte_per_dev;
// Print capacity for external DDR after training
if (get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR2_1815J ||
get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815J ||
get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815K) {
switch (dram_cap_in_mbyte) {
case 6:
NOTICE("External DDR capacity: 512M\n");
break;
case 7:
NOTICE("External DDR capacity: 1G\n");
break;
case 8:
NOTICE("External DDR capacity: 2G\n");
break;
case 9:
NOTICE("External DDR capacity: 4G\n");
break;
default:
NOTICE("External DDR capacity: Unknown, %u\n",dram_cap_in_mbyte);
}
}
rddata = mmio_rd32(0x08004000 + 0x0);
dram_cap_in_mbyte_per_dev = dram_cap_in_mbyte;
dram_cap_in_mbyte_per_dev >>= (1 - get_bits_from_value(rddata, 13, 12)); // change sys cap to x16 cap

View File

@@ -3,11 +3,12 @@
#include <mmio.h>
#include <reg_soc.h>
#include <ddr_sys.h>
#include <ddr_pkg_info.h>
#include "regconfig.h"
//regpatch_ddr3_x16_bga.c for 2133
struct regpatch ddr_patch_regs[] = {
static struct regpatch _ddr_patch_regs_sip[] = {
// tune damp //////
{0x08000150, 0xFFFFFFFF, 0x00000005},
@@ -105,4 +106,119 @@ struct regpatch ddr_patch_regs[] = {
{0x08000934, 0xFFFFFFFF, 0x04000400},
};
uint32_t ddr_patch_regs_count = ARRAY_SIZE(ddr_patch_regs);
/* External DDR3: same as SIP but disable DQS voltage mode RX */
static struct regpatch _ddr_patch_regs_ext[] = {
// tune damp //////
{0x08000150, 0xFFFFFFFF, 0x00000005},
// CSB & CA driving
{0x0800097c, 0xFFFFFFFF, 0x08080404},
// CLK driving
{0x08000980, 0xFFFFFFFF, 0x08080808},
// DQ driving // BYTE0
{0x08000a38, 0xFFFFFFFF, 0x00000606},
// DQS driving // BYTE0
{0x08000a3c, 0xFFFFFFFF, 0x06060606},
// DQ driving // BYTE1
{0x08000a78, 0xFFFFFFFF, 0x00000606},
// DQS driving // BYTE1
{0x08000a7c, 0xFFFFFFFF, 0x06060606},
//trigger level //////
// BYTE0
{0x08000b24, 0xFFFFFFFF, 0x00100010},
// BYTE1
{0x08000b54, 0xFFFFFFFF, 0x00100010},
//APHY TX VREFDQ rangex2 [1]
//VREF DQ //
{0x08000410, 0xFFFFFFFF, 0x00120002},
//APHY TX VREFCA rangex2 [1]
//VREF CA //
{0x08000414, 0xFFFFFFFF, 0x00100002},
// tx dline code
// BYTE0 DQ
{0x08000a00, 0xFFFFFFFF, 0x06430643},
{0x08000a04, 0xFFFFFFFF, 0x06430643},
{0x08000a08, 0xFFFFFFFF, 0x06430643},
{0x08000a0c, 0xFFFFFFFF, 0x06430643},
{0x08000a10, 0xFFFFFFFF, 0x00000643},
{0x08000a14, 0xFFFFFFFF, 0x0a7e007e},
// BYTE1 DQ
{0x08000a40, 0xFFFFFFFF, 0x06480648},
{0x08000a44, 0xFFFFFFFF, 0x06480648},
{0x08000a48, 0xFFFFFFFF, 0x06480648},
{0x08000a4c, 0xFFFFFFFF, 0x06480648},
{0x08000a50, 0xFFFFFFFF, 0x00000648},
{0x08000a54, 0xFFFFFFFF, 0x0a7e007e},
//APHY RX TRIG rangex2[18] & disable lsmode[0]
//f0_param_phya_reg_rx_byte0_en_lsmode[0]
//f0_param_phya_reg_byte0_en_rec_vol_mode[12]
//f0_param_phya_reg_rx_byte0_force_en_lvstl_odt[16]
//f0_param_phya_reg_rx_byte0_sel_dqs_rec_vref_mode[8]
//param_phya_reg_rx_byte0_en_trig_lvl_rangex2[18]
// BYTE0 [0]
{0x08000500, 0xFFFFFFFF, 0x00040001},
//f0_param_phya_reg_rx_byte1_en_lsmode[0]
//f0_param_phya_reg_byte1_en_rec_vol_mode[12]
//f0_param_phya_reg_rx_byte0_force_en_lvstl_odt[16]
//f0_param_phya_reg_rx_byte0_sel_dqs_rec_vref_mode[8]
//param_phya_reg_rx_byte0_en_trig_lvl_rangex2[18]
// BYTE1 [0]
{0x08000540, 0xFFFFFFFF, 0x00040001},
//////// FOR U02 ///////
/////////// U02 DQS voltage mode receiver -- disabled for external DDR
// f0_param_phya_reg_tx_byte0_en_tx_de_dqs[20]
{0x08000504, 0xFFFFFFFF, 0x00000000},
// f0_param_phya_reg_tx_byte1_en_tx_de_dqs[20]
{0x08000544, 0xFFFFFFFF, 0x00000000},
/////////// U02 enable MASK voltage mode receiver
// param_phya_reg_rx_sel_dqs_wo_pream_mode[2]
{0x08000138, 0xFFFFFFFF, 0x00000014},
// RX ODT 120ohm for external DDR3 (override ddr_init.h default 240ohm)
{0x0800041c, 0xFFFFFFFF, 0x00004242},
// BYTE0 RX DQ deskew
{0x08000b00, 0xFFFFFFFF, 0x00020402},
{0x08000b04, 0xFFFFFFFF, 0x05020401},
// BYTE0 DQ8 deskew [6:0] neg DQS [15:8] ; pos DQS [23:16]
{0x08000b08, 0xFFFFFFFF, 0x00313902},
// BYTE1 RX DQ deskew
{0x08000b30, 0xFFFFFFFF, 0x06000100},
{0x08000b34, 0xFFFFFFFF, 0x02010303},
// BYTE1 DQ8 deskew [6:0] neg DQS [15:8] ; pos DQS [23:16]
{0x08000b38, 0xFFFFFFFF, 0x00323900},
//Read gate TX dline + shift
// BYTE0
{0x08000b0c, 0xFFFFFFFF, 0x00000c28},
// BYTE1
{0x08000b3c, 0xFFFFFFFF, 0x00000c2a},
// CKE dline + shift CKE0 [6:0]+[13:8] ; CKE1 [22:16]+[29:24]
{0x08000930, 0xFFFFFFFF, 0x04000400},
// CSB dline + shift CSB0 [6:0]+[13:8] ; CSB1 [22:16]+[29:24]
{0x08000934, 0xFFFFFFFF, 0x04000400},
};
struct regpatch *ddr_patch_regs;
uint32_t ddr_patch_regs_count;
void ddr_patch_regs_init(void)
{
if (get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815J ||
get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815K) {
ddr_patch_regs = _ddr_patch_regs_ext;
ddr_patch_regs_count = ARRAY_SIZE(_ddr_patch_regs_ext);
} else {
ddr_patch_regs = _ddr_patch_regs_sip;
ddr_patch_regs_count = ARRAY_SIZE(_ddr_patch_regs_sip);
}
}

View File

@@ -4,6 +4,7 @@
#include <ddr_sys.h>
#include <ddr_init.h>
#include <bitwise_ops.h>
#include <ddr_pkg_info.h>
uint32_t ddr_data_rate = 2133;
@@ -61,6 +62,8 @@ void ddrc_init(void)
#endif
mmio_wr32(0x08004000 + 0xe4, 0x000C03BF);
mmio_wr32(0x08004000 + 0x100, 0x0F132412);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x100, mmio_rd32(0x08004000 + 0x100) + 0x3000000);
mmio_wr32(0x08004000 + 0x104, 0x00040419);
mmio_wr32(0x08004000 + 0x108, 0x0507060B);
mmio_wr32(0x08004000 + 0x10c, 0x00002008);
@@ -137,6 +140,8 @@ void ddrc_init(void)
// SCHED.prefer_write:1:1:=0x0
// SCHED.dis_opt_wrecc_collision_flush:0:1:=0x1
mmio_wr32(0x08004000 + 0x254, 0x00000000);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x254, 0x40);
// SCHED1.page_hit_limit_rd:28:3:=0x0
// SCHED1.page_hit_limit_wr:24:3:=0x0
// SCHED1.visible_window_limit_rd:20:3:=0x0
@@ -304,6 +309,28 @@ void ctrl_init_update_by_dram_size(uint8_t dram_cap_in_mbyte)
{
uint8_t dram_cap_in_mbyte_per_dev;
// Print capacity for external DDR after training
if (get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR2_1815J ||
get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815J ||
get_ddr_vendor() == DDR_VENDOR_EXTERN_DDR3_1815K) {
switch (dram_cap_in_mbyte) {
case 6:
NOTICE("External DDR capacity: 512M\n");
break;
case 7:
NOTICE("External DDR capacity: 1G\n");
break;
case 8:
NOTICE("External DDR capacity: 2G\n");
break;
case 9:
NOTICE("External DDR capacity: 4G\n");
break;
default:
NOTICE("External DDR capacity: Unknown, %u\n", dram_cap_in_mbyte);
}
}
rddata = mmio_rd32(0x08004000 + 0x0);
dram_cap_in_mbyte_per_dev = dram_cap_in_mbyte;
dram_cap_in_mbyte_per_dev >>= (1 - get_bits_from_value(rddata, 13, 12)); // change sys cap to x16 cap

View File

@@ -69,6 +69,8 @@ void ddrc_init(void)
#endif
mmio_wr32(0x08004000 + 0xe4, 0x000B03BF);
mmio_wr32(0x08004000 + 0x100, 0x0E111F10);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x100, mmio_rd32(0x08004000 + 0x100) + 0x3000000);
mmio_wr32(0x08004000 + 0x104, 0x00030417);
mmio_wr32(0x08004000 + 0x108, 0x0507060A);
mmio_wr32(0x08004000 + 0x10c, 0x00002007);
@@ -145,6 +147,8 @@ void ddrc_init(void)
// SCHED.prefer_write:1:1:=0x0
// SCHED.dis_opt_wrecc_collision_flush:0:1:=0x1
mmio_wr32(0x08004000 + 0x254, 0x00000000);
if (get_ddr_vendor() == DDR_VENDOR_ETRON_1G)
mmio_wr32(0x08004000 + 0x254, 0x40);
// SCHED1.page_hit_limit_rd:28:3:=0x0
// SCHED1.page_hit_limit_wr:24:3:=0x0
// SCHED1.visible_window_limit_rd:20:3:=0x0

View File

@@ -23,6 +23,34 @@ void read_ddr_pkg_info(void)
NOTICE("FTSN4=0x%08x\n", mmio_read_32(0x03050110));
#endif // DBG_SHMOO || DBG_SHMOO_CA || DBG_SHMOO_CS
/* External DDR is identified by the package field alone:
* pkg (efuse_leakage[31:29]) = 5 (BGA285, CV1815J) or
* 6 (BGA320, CV1815K/CV1848K). The package is a better
* external-DDR indicator than the efuse capacity field, so
* capacity is not consulted here. Encoding: 1=QFN88, 2=BGA205,
* 3=QFN68, 4=QFN96, 5=BGA285, 6=BGA320, 7=BGA169(CV1904G).
*/
pkg = FIELD_GET(efuse_leakage, 31, 29);
NOTICE("pkg=%x\n", pkg);
if (pkg == 0x5 || pkg == 0x6) {
NOTICE("External DDR detected\n");
ddr_capacity = DDR_CAPACITY_UNKNOWN;
if (pkg == 0x6) {
ddr_vendor = DDR_VENDOR_EXTERN_DDR3_1815K;
} else {
/* DDR2/DDR3 is a build-time choice: ddr.mk injects
* DDR2/DDR3 from the DDR_CFG directory name, there
* is no runtime DDR2/DDR3 auto-detection.
*/
#if defined(DDR2)
ddr_vendor = DDR_VENDOR_EXTERN_DDR2_1815J;
#else
ddr_vendor = DDR_VENDOR_EXTERN_DDR3_1815J;
#endif
}
} else {
pkg_type = FIELD_GET(conf_info, 30, 28);
NOTICE("pkg_type=%x\n", pkg_type);
@@ -63,9 +91,30 @@ void read_ddr_pkg_info(void)
ddr_capacity = DDR_CAPACITY_512M;
pkg = PKG_QFN;
break;
case 0x8: //QFN9x9, SIP 1Gb DDR3
ddr_vendor = DDR_VENDOR_UNILC_N25_1G;
ddr_capacity = DDR_CAPACITY_1G;
pkg = PKG_QFN;
break;
case 0x9: //QFN9x9, SIP 2Gb DDR3
ddr_vendor = DDR_VENDOR_UNILC_N21_2G;
ddr_capacity = DDR_CAPACITY_2G;
pkg = PKG_QFN;
break;
case 0xA: //QFN9x9, SIP 2Gb DDR3
ddr_vendor = DDR_VENDOR_ESMT_N21_2G;
ddr_capacity = DDR_CAPACITY_2G;
pkg = PKG_QFN;
break;
case 0xB:
ddr_vendor = DDR_VENDOR_ESMT_2G;
ddr_capacity = DDR_CAPACITY_2G;
pkg = PKG_BGA;
break;
default:
NOTICE("unknown pkg_type=0x%x\n", pkg_type);
}
}
NOTICE("D%x_%x_%x\n", pkg, ddr_capacity, ddr_vendor);
@@ -73,6 +122,8 @@ void read_ddr_pkg_info(void)
switch (ddr_vendor) {
case DDR_VENDOR_ESMT_512M_DDR2:
case DDR_VENDOR_ETRON_512M_DDR2:
case DDR_VENDOR_UNILC_N25_512M_DDR2:
case DDR_VENDOR_EXTERN_DDR2_1815J:
NOTICE("DDR2");
ddr_type = DDR_TYPE_DDR2;
ddr_data_rate = 1333;
@@ -83,17 +134,26 @@ void read_ddr_pkg_info(void)
case DDR_VENDOR_ETRON_1G:
case DDR_VENDOR_ESMT_2G:
case DDR_VENDOR_PM_2G:
case DDR_VENDOR_PM_1G:
case DDR_VENDOR_ETRON_N20_2G:
case DDR_VENDOR_ESMT_N25_1G:
case DDR_VENDOR_NY_N20_1G:
case DDR_VENDOR_UNILC_N25_1G:
case DDR_VENDOR_UNILC_N21_2G:
case DDR_VENDOR_ESMT_N21_2G:
case DDR_VENDOR_ESMT_N19_4G:
case DDR_VENDOR_ETRON_N25_2G:
case DDR_VENDOR_EXTERN_DDR3_1815J:
case DDR_VENDOR_EXTERN_DDR3_1815K:
NOTICE("DDR3");
ddr_type = DDR_TYPE_DDR3;
ddr_data_rate = 1866;
// ddr_data_rate = 1866;
break;
default:
NOTICE("unknown vendor=%d", ddr_vendor);
ddr_type = DDR_TYPE_UNKNOWN;
}
chip_id = 0x0;
switch (ddr_capacity) {
case DDR_CAPACITY_512M:
NOTICE("-512M");
@@ -112,9 +172,16 @@ void read_ddr_pkg_info(void)
chip_id = 0x1813f;
break;
default:
if (ddr_vendor == DDR_VENDOR_EXTERN_DDR2_1815J ||
ddr_vendor == DDR_VENDOR_EXTERN_DDR3_1815J ||
ddr_vendor == DDR_VENDOR_EXTERN_DDR3_1815K) {
/* external DDR, no SIP DDR: identify as CV1815J */
chip_id = 0x1815;
} else {
NOTICE("-unknown capacity=%d", ddr_capacity);
chip_id = 0x0;
}
}
mmio_write_32(REG_GP_REG3, chip_id);
switch (pkg) {
@@ -125,7 +192,7 @@ void read_ddr_pkg_info(void)
NOTICE("-BGA\n");
break;
default:
NOTICE("-unknown pkg=%d", pkg);
NOTICE("-unknown pkg=%d\n", pkg);
}
}

View File

@@ -0,0 +1,430 @@
// SPDX-License-Identifier: BSD-3-Clause
#include <stddef.h>
#include <string.h>
#include <stdint.h>
#include <delay_timer.h>
#include "mmio.h"
#include "reg_soc.h"
#include "phy_pll_init.h"
#include "ddr_sys.h"
#include "ddr_suspend.h"
#include "bitwise_ops.h"
// #include "regconfig.h"
#include "rtc.h"
#include "cvx16_dram_cap_check.h"
#include <platform_def.h>
#ifdef DDR2_3
#include <ddr3_1866_init.h>
#include <ddr2_1333_init.h>
#else
#include <ddr_init.h>
#endif
#ifdef AARCH64
SUSPEND_DATA uint32_t start, delta, total_delta;
//arm use CNTPCT_EL0 to get tick
void susp_udelay(uint32_t delay)
{
start = (uint32_t)~read_cntpct_el0();
total_delta = (delay * 25);
// Trig simulation bench to increse cntpct_el0
mmio_write_32(REG_GP_REG2, total_delta);
do {
/*
* If the timer value wraps around, the subtraction will
* overflow and it will still give the correct result.
*/
delta = start - (uint32_t)~read_cntpct_el0(); /* Decreasing counter */
} while (delta < total_delta);
}
#else //RISCV
#define susp_read_csr(reg) ({ unsigned long __tmp; \
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
SUSPEND_DATA uint32_t start, delta, total_delta;
void susp_udelay(uint32_t delay)
{
start = (uint32_t)(~susp_read_csr(time));
total_delta = (delay * 25);
mmio_write_32(REG_GP_REG2, total_delta);
do {
/*
* If the timer value wraps around, the subtraction will
* overflow and it will still give the correct result.
*/
delta = start - (uint32_t)(~susp_read_csr(time)); /* Decreasing counter */
} while (delta < total_delta);
}
#endif //end AARCH64
void ddr_suspend_entry(void)
{
ddr_sys_suspend_sus_res();
rtc_clr_ddr_pwrok();
rtc_clr_rmio_pwrok();
/*Warning: DO NOT use any functions or varibales beyond SUSPEND section
* after DDR enter self refresh.*/
#ifndef SUSPEND_USE_WDG_RST
rtc_req_suspend();
#else
rtc_req_wdg_rst();
#endif
}
void ddr_sys_suspend_sus_res(void)
{
cvx16_ddrc_suspend_sus_res();
cvx16_ddr_phyd_save_sus_res(0x05026800);
cvx16_ddr_phya_pd_sus_res();
}
void cvx16_ddrc_suspend_sus_res(void)
{
uint32_t rddata;
// Write 0 to PCTRL_n.port_en
for (int i = 0; i < 4; i++)
mmio_wr32(cfg_base + 0x490 + 0xb0 * i, 0x0);
while (1) {
rddata = mmio_rd32(cfg_base + 0x3fc);
if (rddata == 0)
break;
}
//Write 1 to PWRCTL.selfref_sw
rddata = mmio_rd32(cfg_base + 0x30);
rddata = FIELD_SET(rddata, 1, 5, 5);
mmio_wr32(cfg_base + 0x30, rddata);
//Poll STAT.selfref_type= 2'b10
//Poll STAT.selfref_state = 0b10 (LPDDR4 only)
while (1) {
rddata = mmio_rd32(cfg_base + 0x4);
if (FIELD_GET(rddata, 5, 4) == 0x2)
break;
}
}
void cvx16_ddr_phya_pd_sus_res(void)
{
uint32_t rddata;
// ----------- PHY oen/pd reset ----------------
//OEN
//param_phyd_tx_ca_oenz 0
//param_phyd_tx_ca_clk0_oenz 8
//param_phyd_tx_ca_clk1_oenz 16
rddata = 0x00010101;
mmio_wr32(0x0130 + PHYD_BASE_ADDR, rddata);
//PD
//TOP_REG_TX_CA_PD_CA 22 0
//TOP_REG_TX_CA_PD_CKE0 24 24
//TOP_REG_TX_CLK_PD_CLK0 26 26
//TOP_REG_TX_CA_PD_CSB0 28 28
//TOP_REG_TX_CA_PD_RESETZ 30 30
//TOP_REG_TX_ZQ_PD 31 31
//rddata[31:0] = 0x947f_ffff;
rddata = 0x947fffff;
mmio_wr32(0x40 + CV_DDR_PHYD_APB, rddata);
//TOP_REG_TX_BYTE0_PD 0
//TOP_REG_TX_BYTE1_PD 1
rddata = 0x00000003;
mmio_wr32(0x00 + CV_DDR_PHYD_APB, rddata);
//OEN
//param_phyd_sel_cke_oenz <= `PI_SD int_regin[0];
rddata = mmio_rd32(0x0154 + PHYD_BASE_ADDR);
//rddata[0] = 0b1;
rddata = FIELD_SET(rddata, 1, 0, 0);
mmio_wr32(0x0154 + PHYD_BASE_ADDR, rddata);
//PD
//All PHYA PD=0
rddata = 0xffffffff;
mmio_wr32(0x40 + CV_DDR_PHYD_APB, rddata);
//PLL PD
rddata = mmio_rd32(0x0C + CV_DDR_PHYD_APB);
//rddata[15] = 1; //TOP_REG_DDRPLL_PD
rddata = FIELD_SET(rddata, 1, 15, 15);
mmio_wr32(0x0C + CV_DDR_PHYD_APB, rddata);
// ----------- PHY oen/pd reset ----------------
//reg_ddr_ssc_syn_src_en =0
rddata = mmio_rd32(0x40 + 0x03002900);
rddata = FIELD_SET(rddata, 0, 1, 1); //reg_ddr_ssc_syn_src_en
mmio_wr32(0x40 + 0x03002900, rddata);
}
SUSPEND_DATA struct reg save_phy_regs[] = {
{0x0 + PHYD_BASE_ADDR, 0x0},
{0x4 + PHYD_BASE_ADDR, 0x0},
{0x8 + PHYD_BASE_ADDR, 0x0},
{0xc + PHYD_BASE_ADDR, 0x0},
{0x10 + PHYD_BASE_ADDR, 0x0},
{0x14 + PHYD_BASE_ADDR, 0x0},
{0x18 + PHYD_BASE_ADDR, 0x0},
{0x1c + PHYD_BASE_ADDR, 0x0},
{0x20 + PHYD_BASE_ADDR, 0x0},
{0x24 + PHYD_BASE_ADDR, 0x0},
{0x28 + PHYD_BASE_ADDR, 0x0},
{0x2c + PHYD_BASE_ADDR, 0x0},
{0x40 + PHYD_BASE_ADDR, 0x0},
{0x44 + PHYD_BASE_ADDR, 0x0},
{0x48 + PHYD_BASE_ADDR, 0x0},
{0x4c + PHYD_BASE_ADDR, 0x0},
{0x50 + PHYD_BASE_ADDR, 0x0},
{0x54 + PHYD_BASE_ADDR, 0x0},
{0x58 + PHYD_BASE_ADDR, 0x0},
{0x5c + PHYD_BASE_ADDR, 0x0},
{0x60 + PHYD_BASE_ADDR, 0x0},
{0x64 + PHYD_BASE_ADDR, 0x0},
{0x68 + PHYD_BASE_ADDR, 0x0},
{0x70 + PHYD_BASE_ADDR, 0x0},
{0x74 + PHYD_BASE_ADDR, 0x0},
{0x80 + PHYD_BASE_ADDR, 0x0},
{0x84 + PHYD_BASE_ADDR, 0x0},
{0x88 + PHYD_BASE_ADDR, 0x0},
{0x8c + PHYD_BASE_ADDR, 0x0},
{0x90 + PHYD_BASE_ADDR, 0x0},
{0x94 + PHYD_BASE_ADDR, 0x0},
{0xa0 + PHYD_BASE_ADDR, 0x0},
{0xa4 + PHYD_BASE_ADDR, 0x0},
{0xa8 + PHYD_BASE_ADDR, 0x0},
{0xac + PHYD_BASE_ADDR, 0x0},
{0xb0 + PHYD_BASE_ADDR, 0x0},
{0xb4 + PHYD_BASE_ADDR, 0x0},
{0xb8 + PHYD_BASE_ADDR, 0x0},
{0xbc + PHYD_BASE_ADDR, 0x0},
{0xf8 + PHYD_BASE_ADDR, 0x0},
{0xfc + PHYD_BASE_ADDR, 0x0},
{0x100 + PHYD_BASE_ADDR, 0x0},
{0x104 + PHYD_BASE_ADDR, 0x0},
{0x10c + PHYD_BASE_ADDR, 0x0},
{0x110 + PHYD_BASE_ADDR, 0x0},
{0x114 + PHYD_BASE_ADDR, 0x0},
{0x118 + PHYD_BASE_ADDR, 0x0},
{0x11c + PHYD_BASE_ADDR, 0x0},
{0x120 + PHYD_BASE_ADDR, 0x0},
{0x124 + PHYD_BASE_ADDR, 0x0},
{0x128 + PHYD_BASE_ADDR, 0x0},
{0x12c + PHYD_BASE_ADDR, 0x0},
{0x130 + PHYD_BASE_ADDR, 0x0},
{0x134 + PHYD_BASE_ADDR, 0x0},
{0x138 + PHYD_BASE_ADDR, 0x0},
{0x140 + PHYD_BASE_ADDR, 0x0},
{0x144 + PHYD_BASE_ADDR, 0x0},
{0x148 + PHYD_BASE_ADDR, 0x0},
{0x14c + PHYD_BASE_ADDR, 0x0},
{0x150 + PHYD_BASE_ADDR, 0x0},
{0x154 + PHYD_BASE_ADDR, 0x0},
{0x158 + PHYD_BASE_ADDR, 0x0},
{0x15c + PHYD_BASE_ADDR, 0x0},
{0x164 + PHYD_BASE_ADDR, 0x0},
{0x168 + PHYD_BASE_ADDR, 0x0},
{0x16c + PHYD_BASE_ADDR, 0x0},
{0x170 + PHYD_BASE_ADDR, 0x0},
{0x174 + PHYD_BASE_ADDR, 0x0},
{0x180 + PHYD_BASE_ADDR, 0x0},
{0x184 + PHYD_BASE_ADDR, 0x0},
{0x188 + PHYD_BASE_ADDR, 0x0},
{0x18c + PHYD_BASE_ADDR, 0x0},
{0x190 + PHYD_BASE_ADDR, 0x0},
{0x200 + PHYD_BASE_ADDR, 0x0},
{0x204 + PHYD_BASE_ADDR, 0x0},
{0x208 + PHYD_BASE_ADDR, 0x0},
{0x220 + PHYD_BASE_ADDR, 0x0},
{0x224 + PHYD_BASE_ADDR, 0x0},
{0x228 + PHYD_BASE_ADDR, 0x0},
{0x400 + PHYD_BASE_ADDR, 0x0},
{0x404 + PHYD_BASE_ADDR, 0x0},
{0x408 + PHYD_BASE_ADDR, 0x0},
{0x40c + PHYD_BASE_ADDR, 0x0},
{0x410 + PHYD_BASE_ADDR, 0x0},
{0x414 + PHYD_BASE_ADDR, 0x0},
{0x418 + PHYD_BASE_ADDR, 0x0},
{0x41c + PHYD_BASE_ADDR, 0x0},
{0x500 + PHYD_BASE_ADDR, 0x0},
{0x504 + PHYD_BASE_ADDR, 0x0},
{0x508 + PHYD_BASE_ADDR, 0x0},
{0x50c + PHYD_BASE_ADDR, 0x0},
{0x510 + PHYD_BASE_ADDR, 0x0},
{0x514 + PHYD_BASE_ADDR, 0x0},
{0x518 + PHYD_BASE_ADDR, 0x0},
{0x51c + PHYD_BASE_ADDR, 0x0},
{0x520 + PHYD_BASE_ADDR, 0x0},
{0x540 + PHYD_BASE_ADDR, 0x0},
{0x544 + PHYD_BASE_ADDR, 0x0},
{0x548 + PHYD_BASE_ADDR, 0x0},
{0x54c + PHYD_BASE_ADDR, 0x0},
{0x550 + PHYD_BASE_ADDR, 0x0},
{0x554 + PHYD_BASE_ADDR, 0x0},
{0x558 + PHYD_BASE_ADDR, 0x0},
{0x55c + PHYD_BASE_ADDR, 0x0},
{0x560 + PHYD_BASE_ADDR, 0x0},
{0x900 + PHYD_BASE_ADDR, 0x0},
{0x904 + PHYD_BASE_ADDR, 0x0},
{0x908 + PHYD_BASE_ADDR, 0x0},
{0x90c + PHYD_BASE_ADDR, 0x0},
{0x910 + PHYD_BASE_ADDR, 0x0},
{0x914 + PHYD_BASE_ADDR, 0x0},
{0x918 + PHYD_BASE_ADDR, 0x0},
{0x91c + PHYD_BASE_ADDR, 0x0},
{0x920 + PHYD_BASE_ADDR, 0x0},
{0x924 + PHYD_BASE_ADDR, 0x0},
{0x928 + PHYD_BASE_ADDR, 0x0},
{0x92c + PHYD_BASE_ADDR, 0x0},
{0x930 + PHYD_BASE_ADDR, 0x0},
{0x934 + PHYD_BASE_ADDR, 0x0},
{0x938 + PHYD_BASE_ADDR, 0x0},
{0x940 + PHYD_BASE_ADDR, 0x0},
{0x944 + PHYD_BASE_ADDR, 0x0},
{0x948 + PHYD_BASE_ADDR, 0x0},
{0x94c + PHYD_BASE_ADDR, 0x0},
{0x950 + PHYD_BASE_ADDR, 0x0},
{0x954 + PHYD_BASE_ADDR, 0x0},
{0x958 + PHYD_BASE_ADDR, 0x0},
{0x95c + PHYD_BASE_ADDR, 0x0},
{0x960 + PHYD_BASE_ADDR, 0x0},
{0x964 + PHYD_BASE_ADDR, 0x0},
{0x968 + PHYD_BASE_ADDR, 0x0},
{0x96c + PHYD_BASE_ADDR, 0x0},
{0x970 + PHYD_BASE_ADDR, 0x0},
{0x974 + PHYD_BASE_ADDR, 0x0},
{0x978 + PHYD_BASE_ADDR, 0x0},
{0x97c + PHYD_BASE_ADDR, 0x0},
{0x980 + PHYD_BASE_ADDR, 0x0},
{0xa00 + PHYD_BASE_ADDR, 0x0},
{0xa04 + PHYD_BASE_ADDR, 0x0},
{0xa08 + PHYD_BASE_ADDR, 0x0},
{0xa0c + PHYD_BASE_ADDR, 0x0},
{0xa10 + PHYD_BASE_ADDR, 0x0},
{0xa14 + PHYD_BASE_ADDR, 0x0},
{0xa18 + PHYD_BASE_ADDR, 0x0},
{0xa1c + PHYD_BASE_ADDR, 0x0},
{0xa20 + PHYD_BASE_ADDR, 0x0},
{0xa24 + PHYD_BASE_ADDR, 0x0},
{0xa28 + PHYD_BASE_ADDR, 0x0},
{0xa2c + PHYD_BASE_ADDR, 0x0},
{0xa30 + PHYD_BASE_ADDR, 0x0},
{0xa34 + PHYD_BASE_ADDR, 0x0},
{0xa38 + PHYD_BASE_ADDR, 0x0},
{0xa3c + PHYD_BASE_ADDR, 0x0},
{0xa40 + PHYD_BASE_ADDR, 0x0},
{0xa44 + PHYD_BASE_ADDR, 0x0},
{0xa48 + PHYD_BASE_ADDR, 0x0},
{0xa4c + PHYD_BASE_ADDR, 0x0},
{0xa50 + PHYD_BASE_ADDR, 0x0},
{0xa54 + PHYD_BASE_ADDR, 0x0},
{0xa58 + PHYD_BASE_ADDR, 0x0},
{0xa5c + PHYD_BASE_ADDR, 0x0},
{0xa60 + PHYD_BASE_ADDR, 0x0},
{0xa64 + PHYD_BASE_ADDR, 0x0},
{0xa68 + PHYD_BASE_ADDR, 0x0},
{0xa6c + PHYD_BASE_ADDR, 0x0},
{0xa70 + PHYD_BASE_ADDR, 0x0},
{0xa74 + PHYD_BASE_ADDR, 0x0},
{0xa78 + PHYD_BASE_ADDR, 0x0},
{0xa7c + PHYD_BASE_ADDR, 0x0},
{0xb00 + PHYD_BASE_ADDR, 0x0},
{0xb04 + PHYD_BASE_ADDR, 0x0},
{0xb08 + PHYD_BASE_ADDR, 0x0},
{0xb0c + PHYD_BASE_ADDR, 0x0},
{0xb10 + PHYD_BASE_ADDR, 0x0},
{0xb14 + PHYD_BASE_ADDR, 0x0},
{0xb18 + PHYD_BASE_ADDR, 0x0},
{0xb1c + PHYD_BASE_ADDR, 0x0},
{0xb20 + PHYD_BASE_ADDR, 0x0},
{0xb24 + PHYD_BASE_ADDR, 0x0},
{0xb30 + PHYD_BASE_ADDR, 0x0},
{0xb34 + PHYD_BASE_ADDR, 0x0},
{0xb38 + PHYD_BASE_ADDR, 0x0},
{0xb3c + PHYD_BASE_ADDR, 0x0},
{0xb40 + PHYD_BASE_ADDR, 0x0},
{0xb44 + PHYD_BASE_ADDR, 0x0},
{0xb48 + PHYD_BASE_ADDR, 0x0},
{0xb4c + PHYD_BASE_ADDR, 0x0},
{0xb50 + PHYD_BASE_ADDR, 0x0},
{0xb54 + PHYD_BASE_ADDR, 0x0},
{REG_GP_REG3, 0x0}, //reserve for chipid suspend resume
{0xDEADBEEF, 0xDEADBEEF},
};
void cvx16_ddr_phyd_save_sus_res(uint32_t rtc_sram_base)
{
// struct reg *psave_phy_regs = (struct reg *)rtc_sram_base;
uintptr_t temp = rtc_sram_base;
struct reg *psave_phy_regs = (struct reg *)temp;
int i;
for (i = 0; i < ARRAY_SIZE(save_phy_regs) - 1; i++) {
psave_phy_regs[i].addr = save_phy_regs[i].addr;
psave_phy_regs[i].val = mmio_rd32(save_phy_regs[i].addr);
}
}
void rtc_clr_ddr_pwrok(void)
{
mmio_clrbits_32(REG_RTC_BASE + RTC_PG_REG, 0x00000001);
}
void rtc_clr_rmio_pwrok(void)
{
mmio_clrbits_32(REG_RTC_BASE + RTC_PG_REG, 0x00000002);
}
#ifndef SUSPEND_USE_WDG_RST
void rtc_req_suspend(void)
{
// info("Send suspend request\n");
/* Enable power suspend wakeup source mask */
mmio_write_32(REG_RTC_BASE + 0x3C, 0x1); // 1 = select prdata from 32K domain
mmio_write_32(REG_RTC_CTRL_BASE + RTC_CTRL0_UNLOCKKEY, 0xAB18);
mmio_write_32(REG_RTC_BASE + RTC_EN_SUSPEND_REQ, 0x01);
while (mmio_read_32(REG_RTC_BASE + RTC_EN_SUSPEND_REQ) != 0x01)
;
while (1) {
/* Send suspend request to RTC and wait it stable*/
susp_udelay(1000);
mmio_write_32(REG_RTC_CTRL_BASE + RTC_CTRL0, 0x00800080);
}
}
#else
void rtc_req_wdg_rst(void)
{
uint32_t write_data = 0;
write_data = mmio_rd32(REG_RTC_CTRL_BASE + 0x18); //rtcsys_rst_ctrl
write_data = write_data | (0x01 << 24); //reg_rtcsys_reset_en
mmio_wr32(REG_RTC_CTRL_BASE + 0x18, write_data); //
mmio_wr32(REG_RTC_BASE + 0xE8, 0x04); // RTC_DB_REQ_WARM_RST
mmio_wr32(REG_RTC_BASE + 0xE0, 0x01); // RTC_EN_WDG_RST_REQ
mmio_wr32(REG_RTC_CTRL_BASE + 0x60, 0xA5); // write dummy register
mmio_wr32(REG_RTC_CTRL_BASE + 0x04, 0xAB18); // rtc_ctrl0_unlockkey
write_data = mmio_rd32(REG_RTC_CTRL_BASE + 0x08); // rtc_ctrl0
//req_shdn = rtc_ctrl0[0];
//req_sw_thm_shdn = rtc_ctrl0[1];
//hw_thm_shdn_en = rtc_ctrl0[2];
//req_pwr_cyc = rtc_ctrl0[3];
//req_warm_rst = rtc_ctrl0[4];
//req_sw_wdg_rst = rtc_ctrl0[5];
//hw_wdg_rst_en = rtc_ctrl0[6];
//req_suspend = rtc_ctrl0[7];
write_data = 0xffff0000 | write_data | (0x01 << 5);
// printf("[RTC] ----> Set req_sw_wdg_rst to 1 by register setting\n");
mmio_wr32(REG_RTC_CTRL_BASE + 0x08, write_data); //rtc_ctrl0
}
#endif

View File

@@ -12,6 +12,9 @@
#include <cvx16_dram_cap_check.h>
#include <cvx16_pinmux.h>
#include <ddr_pkg_info.h>
#include <regconfig.h>
#include <phy_pll_init.h>
#include <platform_def.h>
#define opdelay(_x) udelay((_x)/1000)
@@ -106,13 +109,17 @@ void ddr_sys_resume(void)
// KC_MSG("ddr_sub_resume1\n");
// pll_init
cvx16_pll_init();
pll_init();
KC_MSG("pll_init_h finish\n");
// ctrl_init
ddrc_init();
KC_MSG("2nd ctrl_init_h finish\n");
// set axi QOS
mmio_wr32(0x030001D8, 0x008899aa);
mmio_wr32(0x030001DC, 0x00002244);
// ddr_sub_resume2
cvx16_ddr_sub_resume2();
KC_MSG("ddr_sub_resume2\n");
@@ -676,20 +683,38 @@ void cvx16_bist_wdqlvl_init(uint32_t mode)
// bist sso_period
mmio_wr32(DDR_BIST_BASE + 0x24, (fmax << 8) + fmin);
#ifdef ENABLE_FASTBOOT0
// cmd queue
// op_code start stop pattern dq_inv dm_inv dq_rotate
// repeat
cmd[0] = (1 << 30) | (sram_st << 21) | (511 << 12) | (5 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(2 << 0); // W 1~17 prbs repeat0
(0 << 0); // W 1~17 prbs repeat0
cmd[1] = (2 << 30) | (sram_st << 21) | (511 << 12) | (5 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(2 << 0); // R 1~17 prbs repeat0
(0 << 0); // R 1~17 prbs repeat0
cmd[2] = (1 << 30) | (sram_st << 21) | (sram_sp << 12) | (6 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(2 << 0); // W 1~17 sram repeat0
(0 << 0); // W 1~17 sram repeat0
cmd[3] = (2 << 30) | (sram_st << 21) | (sram_sp << 12) | (6 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(2 << 0); // R 1~17 sram repeat0
(0 << 0); // R 1~17 sram repeat0
// GOTO addr_not_reset loop_cnt
cmd[4] = (3 << 30) | (0 << 20) | (1 << 0); // GOTO
// cmd[4] = (3 << 30) | (0 << 20) | (1 << 0); // GOTO
cmd[5] = 0; // NOP
cmd[5] = 0; // NOP
#else
// cmd queue
// op_code start stop pattern dq_inv dm_inv dq_rotate
// repeat
cmd[0] = (1 << 30) | (sram_st << 21) | (511 << 12) | (5 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(0 << 0); // W 1~17 prbs repeat0
cmd[1] = (2 << 30) | (sram_st << 21) | (511 << 12) | (5 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(0 << 0); // R 1~17 prbs repeat0
cmd[2] = (1 << 30) | (sram_st << 21) | (sram_sp << 12) | (6 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(0 << 0); // W 1~17 sram repeat0
cmd[3] = (2 << 30) | (sram_st << 21) | (sram_sp << 12) | (6 << 9) | (0 << 8) | (0 << 7) | (0 << 4) |
(0 << 0); // R 1~17 sram repeat0
// GOTO addr_not_reset loop_cnt
cmd[4] = 0; // GOTO
cmd[5] = 0; // NOP
#endif
} else if (mode == 0x11) { // bist write/read
//----for Error enject simulation only
rddata = 0x00000000;
@@ -1923,6 +1948,13 @@ void cvx16_INT_ISR_08(void)
//----------------------------------------------------
cvx16_ddr_phy_power_on_seq2();
// JESD79-3 requires RESET# to remain low for at least 200us after
// VDD is stable. On this platform the RESET# pad is driven low once
// the PHY output stage is enabled (power_on_seq1/seq2) and released
// only after dfi_init_complete lets the DDRC init FSM run. Holding
// 200us here lengthens the RESET# low pulse accordingly (measured
// on board: 40us -> 230+us), clearing the spec minimum with margin.
udelay(200);
cvx16_set_dfi_init_complete();
}
@@ -6141,590 +6173,41 @@ void cvx16_ddr_phyd_save(uint32_t sram_base_addr)
void cvx16_ddr_phyd_restore(uint32_t sram_base_addr)
{
int sram_offset = 0x0;
{
uartlog("cvx16_ddr_phyd_restore\n");
ddr_debug_wr32(0x47);
ddr_debug_num_write();
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x0 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x4 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x8 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xc + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x10 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x14 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x18 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x1c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x20 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x24 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x28 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x2c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x40 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x44 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x48 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x4c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x50 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x54 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x58 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x5c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x60 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x64 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x68 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x70 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x74 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x80 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x84 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x88 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x8c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x90 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x94 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa0 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa4 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa8 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xac + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb0 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb4 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb8 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xbc + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xf0 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xf4 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xf8 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xfc + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x100 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x104 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x10c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x110 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x114 + PHYD_BASE_ADDR, rddata);
uintptr_t temp = sram_base_addr;
struct regconf *psave_phy_regs = (struct regconf *)temp;
int i = 0;
uint32_t addr;
uint32_t val;
while (1) {
addr = psave_phy_regs[i].addr;
val = psave_phy_regs[i].val;
i++;
if (addr != REG_GP_REG3) {
if ((addr < (0x0 + PHYD_BASE_ADDR)) || (addr > (0xb54 + PHYD_BASE_ADDR)))
break;
}
switch (addr) {
case (0x118 + PHYD_BASE_ADDR):
//reset param_phyd_clkctrl_init_complete
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x118 + PHYD_BASE_ADDR, rddata & 0x00000000);
//------------------------------------------------------------
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x11c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x120 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x124 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x128 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x12c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
// mmio_wr32 ( 0x130 + PHYD_BASE_ADDR, rddata );
val &= 0x00000000;
break;
case (0x130 + PHYD_BASE_ADDR):
//ca oenz set by c-code
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x134 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x138 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x140 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x144 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x148 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x14c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x150 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
// param_phyd_sel_cke_oenz=1
mmio_wr32(0x154 + PHYD_BASE_ADDR, (rddata | 0x00000001));
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x158 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x15c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x164 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x168 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x16c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x170 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x174 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x180 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x184 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x188 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x18c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x190 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x200 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
// param_phya_reg_tx_byte0_en_extend_oenz_gated_dline =0
mmio_wr32(0x204 + PHYD_BASE_ADDR, (rddata & 0xFFFBFFFF));
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x208 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x220 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
// param_phya_reg_tx_byte1_en_extend_oenz_gated_dline =0
mmio_wr32(0x224 + PHYD_BASE_ADDR, (rddata & 0xFFFBFFFF));
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x228 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x400 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x404 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x408 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x40c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x410 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x414 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x418 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x41c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x500 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x504 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x508 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x50c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x510 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x514 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x518 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x51c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x520 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x540 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x544 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x548 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x54c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x550 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x554 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x558 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x55c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x560 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x900 + PHYD_BASE_ADDR, rddata);
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x904 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x908 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x90c + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x910 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x914 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x918 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x91c + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x920 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x924 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x928 + PHYD_BASE_ADDR, rddata );
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x92c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x930 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x934 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x938 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x940 + PHYD_BASE_ADDR, rddata);
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x944 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x948 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x94c + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x950 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x954 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x958 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x95c + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x960 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x964 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x968 + PHYD_BASE_ADDR, rddata );
// rddata = mmio_rd32(sram_base_addr + sram_offset);
// sram_offset += 4;
// mmio_wr32 ( 0x96c + PHYD_BASE_ADDR, rddata );
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x970 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x974 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x978 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x97c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0x980 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa00 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa04 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa08 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa0c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa10 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa14 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa18 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa1c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa20 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa24 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa28 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa2c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa30 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa34 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa38 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa3c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa40 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa44 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa48 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa4c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa50 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa54 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa58 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa5c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa60 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa64 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa68 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa6c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa70 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa74 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa78 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xa7c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb00 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb04 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb08 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb0c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb10 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb14 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb18 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb1c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb20 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb24 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb30 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb34 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb38 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb3c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb40 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb44 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb48 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb4c + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb50 + PHYD_BASE_ADDR, rddata);
rddata = mmio_rd32(sram_base_addr + sram_offset);
sram_offset += 4;
mmio_wr32(0xb54 + PHYD_BASE_ADDR, rddata);
continue;
case (0x154 + PHYD_BASE_ADDR):
val |= 0x00000001;
break;
case (0x204 + PHYD_BASE_ADDR):
val &= 0xFFFBFFFF;
break;
case (0x224 + PHYD_BASE_ADDR):
val &= 0xFFFBFFFF;
break;
}
mmio_write_32(addr, val);
}
}

View File

@@ -224,6 +224,7 @@ void ddr_sys_bring_up(void)
uartlog("phy_init !\n");
phy_init();
#endif
mmio_wr32(0x080000a4, 0x02620504);
cvx16_setting_check();
KC_MSG("cvx16_setting_check finish\n");

View File

@@ -0,0 +1,604 @@
/*
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <cpu.h>
#include <debug.h>
#include <delay_timer.h>
#include <emmc.h>
#include <errno.h>
#include <mmio.h>
#include <platform.h>
#include <string.h>
#include <utils.h>
#include <cv_emmc.h>
#include <platform.h>
#define EMMC_INIT_FREQ (200 * 1000)
#ifdef SUPPORT_SD_EMMC_CLOCK_ADJUSTMENT
#define EMMC_TRAN_FREQ (emmc_tran_freq)
#else
#define EMMC_TRAN_FREQ (12 * 1000 * 1000)
#endif
static void bm_emmc_hw_init(void);
static void bm_emmc_dev_reset(void);
static int bm_emmc_send_cmd(emmc_cmd_t *cmd);
static int bm_emmc_set_ios(int clk, int width);
static int bm_emmc_prepare(int lba, uintptr_t buf, size_t size);
static int bm_emmc_read(int lba, uintptr_t buf, size_t size);
static int bm_emmc_write(int lba, uintptr_t buf, size_t size);
static const emmc_ops_t bm_emmc_ops = {
.init = bm_emmc_hw_init,
.reset = bm_emmc_dev_reset,
.send_cmd = bm_emmc_send_cmd,
.set_ios = bm_emmc_set_ios,
.prepare = bm_emmc_prepare,
.read = bm_emmc_read,
.write = bm_emmc_write,
};
static bm_emmc_params_t bm_params = { .reg_base = EMMC_BASE,
.clk_rate = 375 * 1000 * 1000,
.bus_width = EMMC_BUS_WIDTH,
.flags = 0 };
#ifdef SUPPORT_SD_EMMC_CLOCK_ADJUSTMENT
const uint32_t emmc_tran_freq = 12 * 1000 * 1000;
#endif
static int bm_emmc_send_cmd_with_data(emmc_cmd_t *cmd)
{
uintptr_t base;
uint32_t mode = 0, stat, dma_addr, flags = 0;
uint32_t emmc_timer = 0;
base = bm_params.reg_base;
//make sure cmd line is clear
while (1) {
if (!(mmio_read_32(base + SDHCI_PSTATE) & SDHCI_CMD_INHIBIT))
break;
}
switch (cmd->cmd_idx) {
case EMMC_CMD17:
case EMMC_CMD18:
mode = SDHCI_TRNS_DMA | SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_MULTI | SDHCI_TRNS_READ;
break;
case EMMC_CMD24:
case EMMC_CMD25:
mode = (SDHCI_TRNS_DMA | SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_MULTI) & ~SDHCI_TRNS_READ;
break;
default:
ERROR("%s Invalid CMD: %d\n", __func__, cmd->cmd_idx);
return -EINVAL;
}
mmio_write_16(base + SDHCI_TRANSFER_MODE, mode);
mmio_write_32(base + SDHCI_ARGUMENT, cmd->cmd_arg);
// set cmd flags
if (cmd->cmd_idx == 0)
flags |= SDHCI_CMD_RESP_NONE;
else if (cmd->resp_type & EMMC_RESPONSE_R2)
flags |= SDHCI_CMD_RESP_LONG;
else
flags |= SDHCI_CMD_RESP_SHORT;
flags |= SDHCI_CMD_CRC;
flags |= SDHCI_CMD_INDEX;
flags |= SDHCI_CMD_DATA;
// issue the cmd
mmio_write_16(base + SDHCI_COMMAND, SDHCI_MAKE_CMD(cmd->cmd_idx, flags));
// check cmd complete if necessary
if ((mmio_read_16(base + SDHCI_TRANSFER_MODE) & SDHCI_TRNS_RESP_INT) == 0) {
emmc_timer = get_timer(0);
while (1) {
stat = mmio_read_16(base + SDHCI_INT_STATUS);
if (stat & SDHCI_INT_ERROR) {
ERROR("%s CMD: %u INT_STAT: 0x%04x INT_ERR: 0x%04x\n", __func__, cmd->cmd_idx,
mmio_read_16(base + SDHCI_INT_STATUS), mmio_read_16(base + SDHCI_ERR_INT_STATUS));
return -EIO;
}
if (stat & SDHCI_INT_CMD_COMPLETE) {
mmio_write_16(base + SDHCI_INT_STATUS, stat | SDHCI_INT_CMD_COMPLETE);
break;
}
if (get_timer(emmc_timer) > EMMC_CMD_TIMEOUT) {
ERROR("%s send CMD %u timeout!\n", __func__, cmd->cmd_idx);
return -EIO;
}
}
// get cmd respond
if (!(flags & SDHCI_CMD_RESP_NONE))
cmd->resp_data[0] = mmio_read_32(base + SDHCI_RESPONSE_01);
if (flags & SDHCI_CMD_RESP_LONG) {
cmd->resp_data[1] = mmio_read_32(base + SDHCI_RESPONSE_23);
cmd->resp_data[2] = mmio_read_32(base + SDHCI_RESPONSE_45);
cmd->resp_data[3] = mmio_read_32(base + SDHCI_RESPONSE_67);
}
}
// check dma/transfer complete
emmc_timer = get_timer(0);
while (1) {
stat = mmio_read_16(base + SDHCI_INT_STATUS);
if (stat & SDHCI_INT_ERROR) {
ERROR("%s CMD: %u INT_STAT: 0x%04x INT_ERR: 0x%04x\n", __func__, cmd->cmd_idx,
mmio_read_16(base + SDHCI_INT_STATUS), mmio_read_16(base + SDHCI_ERR_INT_STATUS));
return -EIO;
}
if (stat & SDHCI_INT_XFER_COMPLETE) {
mmio_write_16(base + SDHCI_INT_STATUS, stat);
break;
}
if (get_timer(emmc_timer) > EMMC_DATA_CMD_TIMEOUT) {
ERROR("%s DATA_Transfer %u timeout!\n", __func__, cmd->cmd_idx);
return -EIO;
}
if (stat & SDHCI_INT_DMA_END) {
mmio_write_16(base + SDHCI_INT_STATUS, stat);
if (mmio_read_16(base + SDHCI_HOST_CONTROL2) & SDHCI_HOST_VER4_ENABLE) {
dma_addr = mmio_read_32(base + SDHCI_ADMA_SA_LOW);
mmio_write_32(base + SDHCI_ADMA_SA_LOW, dma_addr);
mmio_write_32(base + SDHCI_ADMA_SA_HIGH, 0);
} else {
dma_addr = mmio_read_32(base + SDHCI_DMA_ADDRESS);
mmio_write_32(base + SDHCI_DMA_ADDRESS, dma_addr);
}
}
}
return 0;
}
static int bm_emmc_send_cmd_without_data(emmc_cmd_t *cmd)
{
uintptr_t base;
uint32_t stat, flags = 0x0;
uint32_t emmc_timer = 0;
base = bm_params.reg_base;
//make sure cmd line is clear
while (1) {
if (!(mmio_read_32(base + SDHCI_PSTATE) & SDHCI_CMD_INHIBIT))
break;
}
// set cmd flags
if (cmd->cmd_idx == EMMC_CMD0)
flags |= SDHCI_CMD_RESP_NONE;
else if (cmd->cmd_idx == EMMC_CMD1)
flags |= SDHCI_CMD_RESP_SHORT;
else if (cmd->cmd_idx == EMMC_CMD6)
flags |= SDHCI_CMD_RESP_SHORT_BUSY;
else if (cmd->resp_type & EMMC_RESPONSE_R2) {
flags |= SDHCI_CMD_RESP_LONG;
flags |= SDHCI_CMD_CRC;
} else {
flags |= SDHCI_CMD_RESP_SHORT;
flags |= SDHCI_CMD_CRC;
flags |= SDHCI_CMD_INDEX;
}
// make sure dat line is clear if necessary
if (flags & SDHCI_CMD_RESP_SHORT_BUSY) {
while (1) {
if (!(mmio_read_32(base + SDHCI_PSTATE) & SDHCI_CMD_INHIBIT_DAT))
break;
}
}
// issue the cmd
mmio_write_32(base + SDHCI_ARGUMENT, cmd->cmd_arg);
mmio_write_16(base + SDHCI_COMMAND, SDHCI_MAKE_CMD(cmd->cmd_idx, flags));
// check cmd complete
emmc_timer = get_timer(0);
while (1) {
stat = mmio_read_16(base + SDHCI_INT_STATUS);
if (stat & SDHCI_INT_ERROR) {
ERROR("%s CMD: %u INT_STAT: 0x%04x INT_ERR: 0x%04x\n", __func__, cmd->cmd_idx,
mmio_read_16(base + SDHCI_INT_STATUS), mmio_read_16(base + SDHCI_ERR_INT_STATUS));
return -EIO;
}
if (stat & SDHCI_INT_CMD_COMPLETE) {
mmio_write_16(base + SDHCI_INT_STATUS, stat | SDHCI_INT_CMD_COMPLETE);
break;
}
if (get_timer(emmc_timer) > EMMC_CMD_TIMEOUT) {
ERROR("%s send CMD %u timeout!\n", __func__, cmd->cmd_idx);
return -EIO;
}
}
// get cmd respond
if (!(flags & SDHCI_CMD_RESP_NONE))
cmd->resp_data[0] = mmio_read_32(base + SDHCI_RESPONSE_01);
if (flags & SDHCI_CMD_RESP_LONG) {
cmd->resp_data[1] = mmio_read_32(base + SDHCI_RESPONSE_23);
cmd->resp_data[2] = mmio_read_32(base + SDHCI_RESPONSE_45);
cmd->resp_data[3] = mmio_read_32(base + SDHCI_RESPONSE_67);
}
return 0;
}
static int bm_emmc_send_cmd(emmc_cmd_t *cmd)
{
#if 0
INFO("send cmd, cmd_idx=%d, cmd_arg=0x%x, resp_type=0x%x\n",
cmd->cmd_idx,
cmd->cmd_arg,
cmd->resp_type);
#endif
switch (cmd->cmd_idx) {
case EMMC_CMD17:
case EMMC_CMD18:
case EMMC_CMD24:
case EMMC_CMD25:
return bm_emmc_send_cmd_with_data(cmd);
default:
return bm_emmc_send_cmd_without_data(cmd);
}
}
static int bm_emmc_set_ext_csd(unsigned int index, unsigned int value)
{
emmc_cmd_t cmd;
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD6;
cmd.cmd_arg = EXTCSD_WRITE_BYTES | EXTCSD_CMD(index) | EXTCSD_VALUE(value) | 1;
return bm_emmc_send_cmd(&cmd);
}
int bm_emmc_set_clk(int clk)
{
int base, div, div_high, div_low;
if (clk <= 0) {
ERROR("%s clk: %d is invalid\n", __func__, clk);
return -EINVAL;
}
if (bm_params.clk_rate <= clk) {
div = 0;
} else {
for (div = 0x1; div <= 0x3FF; div++) {
if (bm_params.clk_rate / (2 * div) <= clk)
break;
}
}
if (div > 0x3FF) {
ERROR("%s div: 0x%x is invalid\n", __func__, div);
return -EINVAL;
}
base = bm_params.reg_base;
if (mmio_read_16(base + SDHCI_HOST_CONTROL2) & 1 << 15) {
INFO("Use SDCLK Preset Value\n");
} else {
INFO("Set SDCLK by driver. (Source, Target, div, Actual) = (%d, %d, %d, %d)\n",
bm_params.clk_rate, clk, div, bm_params.clk_rate / (2 * div));
div_high = (div >> 8) & 0x3;
div_low = div & 0xFF;
mmio_write_16(base + SDHCI_CLK_CTRL,
mmio_read_16(base + SDHCI_CLK_CTRL) & ~0x9); // disable INTERNAL_CLK_EN and PLL_ENABLE
mmio_write_16(base + SDHCI_CLK_CTRL,
(mmio_read_16(base + SDHCI_CLK_CTRL) & 0x3F) | (div_low << 8) | (div_high << 6)); // set clk div, div[8:9] -> reg[6:7], div[0:7] -> reg[8:15]
mmio_write_16(base + SDHCI_CLK_CTRL,
mmio_read_16(base + SDHCI_CLK_CTRL) | 0x1); // set INTERNAL_CLK_EN
udelay(150);
if ((mmio_read_16(base + SDHCI_CLK_CTRL) & 0x2) == 0x0) {
ERROR("eMMC clock seting FAILED!\n");
return -EIO;
}
mmio_write_16(base + SDHCI_CLK_CTRL,
mmio_read_16(base + SDHCI_CLK_CTRL) | 0x8); // set PLL_ENABLE
udelay(150);
if ((mmio_read_16(base + SDHCI_CLK_CTRL) & 0x2) == 0x0) {
ERROR("eMMC PLL seting FAILED!\n");
return -EIO;
}
}
return 0;
}
static void bm_emmc_hw_init(void)
{
uintptr_t base, vendor_base;
base = bm_params.reg_base;
vendor_base = base + (mmio_read_16(base + P_VENDOR_SPECIFIC_AREA) & ((1 << 12) - 1));
bm_params.vendor_base = vendor_base;
// reset data & cmd
mmio_write_8(base + SDHCI_SOFTWARE_RESET, 0x6);
// init common parameters
mmio_write_8(base + SDHCI_PWR_CONTROL, SDHCI_BUS_VOL_VDD1_1_8V);
mmio_write_8(base + SDHCI_TOUT_CTRL, 0xe); // for TMCLK 50Khz
mmio_setbits_16(base + SDHCI_HOST_CONTROL2, 1 << 11); // set cmd23 support
mmio_setbits_16(vendor_base + VENDOR_EMMC_CTRL, 0x1);
mmio_clrbits_16(base + SDHCI_CLK_CTRL, (0x1 << 5));
// set clk.Toshiba/Scandisk eMMC don't support 400khz.
bm_emmc_set_clk(EMMC_INIT_FREQ);
// set host version 4 parameters
mmio_setbits_16(base + SDHCI_HOST_CONTROL2, 0x1 << 12); // set HOST_VER4_ENABLE
if (mmio_read_32(base + SDHCI_CAPABILITIES1) & 0x1 << 27)
mmio_setbits_16(base + SDHCI_HOST_CONTROL2, 0x1 << 13); // set 64bit addressing
// set rx src sel to 1
mmio_clrsetbits_32(base + SDHCI_RX_DELAY_LINE, REG_RX_SRC_SEL_CLR_MASK,
REG_RX_SRC_SEL_CLK_TX_INV << REG_RX_SRC_SEL_SHIFT);
// set tx src sel to 1
mmio_clrsetbits_32(base + SDHCI_TX_DELAY_LINE, REG_TX_SRC_SEL_CLR_MASK,
REG_TX_SRC_SEL_CLK_TX_INV << REG_TX_SRC_SEL_SHIFT);
// set PHY_TX_BPS to 1
mmio_clrsetbits_32(base + SDHCI_PHY_CONFIG, REG_TX_BPS_SEL_CLR_MASK,
REG_TX_BPS_SEL_BYPASS << REG_TX_BPS_SEL_SHIFT);
// eMMc card setup
mmio_clrbits_16(base + SDHCI_HOST_CONTROL2, (0x1 << 8)); // clr UHS2_IF_ENABLE
mmio_write_8(base + SDHCI_PWR_CONTROL,
mmio_read_8(base + SDHCI_PWR_CONTROL) | 0x1); // set SD_BUS_PWR_VDD1
mmio_clrbits_16(base + SDHCI_HOST_CONTROL2, 0x7); // clr UHS_MODE_SEL
mmio_setbits_16(base + SDHCI_HOST_CONTROL2, (0x1 << 3)); // set 1.8v signal
mmio_setbits_16(base + SDHCI_CLK_CTRL, 0x1 << 2); // set SD_CLK_EN
udelay(400); // wait for voltage ramp up time at least 74 cycle,1/200k*80=400us
//we enable all interrupt status here for testing
mmio_setbits_16(base + SDHCI_INT_STATUS_EN, 0xFFFF);
mmio_setbits_16(base + SDHCI_ERR_INT_STATUS_EN, 0xFFFF);
INFO("eMMC init done\n");
}
#ifdef CONFIG_ENABLE_EMMC_HW_RESET_QFN
#define GPIO_SWPORTA_DDR 0x004
#define GPIO_SWPORTA_DR 0x000
#define GPIO0_BASE 0x03020000
#define GPIO_NUM 19
static void bm_emmc_dev_reset(void)
{
INFO("emmc hw reset: qfn\n");
/* Set pinmux for emmc reset */
mmio_write_8(PINMUX_BASE + 0x64, 0x3);//0x03001064
INFO("qfn rst: pinmux:%x\n", mmio_read_8(PINMUX_BASE + 0x64));
uint32_t base = GPIO0_BASE;
uint32_t dir_reg_base = base + GPIO_SWPORTA_DDR;
uint32_t val_reg_base = base + GPIO_SWPORTA_DR;
uint32_t dir_reg = mmio_read_32(dir_reg_base);
uint32_t val_reg = mmio_read_32(val_reg_base);
/* Set direction to output */
dir_reg &= ~(1 << GPIO_NUM);
dir_reg |= (1 << GPIO_NUM);
mmio_write_32(dir_reg_base, dir_reg);
udelay(100);
INFO("qfn rst 0: dir:%x, val:%x\n", mmio_read_32(dir_reg_base), mmio_read_32(val_reg_base));
/* Set Value to 0, reset */
val_reg &= ~(1 << GPIO_NUM);
mmio_write_32(val_reg_base, val_reg);
udelay(500);
INFO("qfn rst 1: dir:%x, val:%x\n", mmio_read_32(dir_reg_base), mmio_read_32(val_reg_base));
/* Set value to 1 */
val_reg &= ~(1 << GPIO_NUM);
val_reg |= (1 << GPIO_NUM);
mmio_write_32(val_reg_base, val_reg);
udelay(500);
INFO("qfn rst 2: dir:%x, val:%x\n", mmio_read_32(dir_reg_base), mmio_read_32(val_reg_base));
}
#else
static void bm_emmc_dev_reset(void)
{
INFO("emmc hw reset: bga\n");
uintptr_t base, vendor_base;
base = bm_params.reg_base;
vendor_base = base + (mmio_read_16(base + P_VENDOR_SPECIFIC_AREA) & ((1 << 12) - 1));
INFO("eMMC RST_n 0x%x\n", mmio_read_16(vendor_base + VENDOR_EMMC_CTRL));
mmio_clrbits_16(vendor_base + VENDOR_EMMC_CTRL, SDHCI_RESET_N);
INFO("eMMC RST_n1 n 0x%x\n", mmio_read_16(vendor_base + VENDOR_EMMC_CTRL));
mdelay(1);
mmio_setbits_16(vendor_base + VENDOR_EMMC_CTRL, SDHCI_RESET_N);
INFO("eMMC RST_n2 n 0x%x\n", mmio_read_16(vendor_base + VENDOR_EMMC_CTRL));
mdelay(1);
}
#endif
static int bm_emmc_set_ios(int clk, int width)
{
int ret;
switch (width) {
case EMMC_BUS_WIDTH_1:
ret = bm_emmc_set_ext_csd(183, 0);
if (ret < 0)
return ret;
mmio_write_8(bm_params.reg_base + SDHCI_HOST_CONTROL,
mmio_read_8(bm_params.reg_base + SDHCI_HOST_CONTROL) & ~SDHCI_DAT_XFER_WIDTH);
break;
case EMMC_BUS_WIDTH_4:
ret = bm_emmc_set_ext_csd(183, 1);
if (ret < 0)
return ret;
mmio_write_8(bm_params.reg_base + SDHCI_HOST_CONTROL,
mmio_read_8(bm_params.reg_base + SDHCI_HOST_CONTROL) | SDHCI_DAT_XFER_WIDTH);
break;
case EMMC_BUS_WIDTH_8:
ret = bm_emmc_set_ext_csd(183, 2);
if (ret < 0)
return ret;
mmio_write_8(bm_params.reg_base + SDHCI_HOST_CONTROL,
mmio_read_8(bm_params.reg_base + SDHCI_HOST_CONTROL) | SDHCI_EXT_DAT_XFER);
break;
default:
ERROR("%s Invalid Bus width: %d\n", __func__, width);
return -EINVAL;
}
return bm_emmc_set_clk(clk);
}
static int bm_emmc_prepare(int lba, uintptr_t buf, size_t size)
{
uint64_t load_addr;
uint32_t base, block_cnt;
uint8_t tmp;
load_addr = phys_to_dma(buf);
if (((buf & EMMC_BLOCK_MASK) != 0) || ((size % EMMC_BLOCK_SIZE) != 0))
return -EINVAL;
base = bm_params.reg_base;
block_cnt = size / EMMC_BLOCK_SIZE;
if (mmio_read_16(base + SDHCI_HOST_CONTROL2) & SDHCI_HOST_VER4_ENABLE) {
mmio_write_32(base + SDHCI_ADMA_SA_LOW, load_addr);
mmio_write_32(base + SDHCI_ADMA_SA_HIGH, (load_addr >> 32));
mmio_write_32(base + SDHCI_DMA_ADDRESS, block_cnt);
mmio_write_16(base + SDHCI_BLOCK_COUNT, 0);
} else {
if ((load_addr >> 32) != 0)
return -EINVAL;
mmio_write_32(base + SDHCI_DMA_ADDRESS, load_addr);
mmio_write_16(base + SDHCI_BLOCK_COUNT, block_cnt);
}
mmio_write_16(base + SDHCI_BLOCK_SIZE, SDHCI_MAKE_BLKSZ(7, 512));
// select SDMA
tmp = mmio_read_8(base + SDHCI_HOST_CONTROL);
tmp &= ~SDHCI_CTRL_DMA_MASK;
tmp |= SDHCI_CTRL_SDMA;
mmio_write_8(base + SDHCI_HOST_CONTROL, tmp);
return 0;
}
static int bm_emmc_read(int lba, uintptr_t buf, size_t size)
{
return 0;
}
void bm_emmc_read_data(unsigned int *buf)
{
int i;
uint32_t base;
base = bm_params.reg_base;
for (i = 0; i < 128; i++)
buf[i] = (unsigned int)mmio_read_32(base + SDHCI_BUF_DATA_R);
INFO("read data over\n");
}
static int bm_emmc_write(int lba, uintptr_t buf, size_t size)
{
return 0;
}
static void bm_emmc_hw_reset(void)
{
uintptr_t base = bm_params.reg_base;
// set default clk div before reset IP to avoid CLK glitch
mmio_write_16(base + SDHCI_CLK_CTRL,
(mmio_read_16(base + SDHCI_CLK_CTRL) & 0x3F) | DEFAULT_DIV_EMMC_INIT_CLOCK << 8);
mdelay(1);
// reset IP
mmio_write_8(base + SDHCI_SOFTWARE_RESET, 0x7);
while (mmio_read_8(base + SDHCI_SOFTWARE_RESET))
;
}
#define IO_PAD_CLR_MASK 0xC
#define IO_PAD_SHIFT 2
#define PULL_UP 1
#define PULL_DOWN 2
#define REG_EMMC_RSTN_PAD (PINMUX_BASE + 0x914) // 0x03001914
#define REG_EMMC_CLK_PAD (PINMUX_BASE + 0x91C) // 0x0300191C
#define REG_EMMC_CMD_PAD (PINMUX_BASE + 0x928) // 0x03001928
#define REG_EMMC_DAT0_PAD (PINMUX_BASE + 0x920) // 0x03001920
#define REG_EMMC_DAT1_PAD (PINMUX_BASE + 0x92C) // 0x0300192C
#define REG_EMMC_DAT2_PAD (PINMUX_BASE + 0x918) // 0x03001918
#define REG_EMMC_DAT3_PAD (PINMUX_BASE + 0x924) // 0x03001924
#define REG_EMMC_RSTN_PIO (PINMUX_BASE + 0x48) // 0x03001048
#define REG_EMMC_CLK_PIO (PINMUX_BASE + 0x50) // 0x03001050
#define REG_EMMC_CMD_PIO (PINMUX_BASE + 0x5C) // 0x0300105C
#define REG_EMMC_DAT0_PIO (PINMUX_BASE + 0x54) // 0x03001054
#define REG_EMMC_DAT1_PIO (PINMUX_BASE + 0x60) // 0x03001060
#define REG_EMMC_DAT2_PIO (PINMUX_BASE + 0x4C) // 0x0300104C
#define REG_EMMC_DAT3_PIO (PINMUX_BASE + 0x58) // 0x03001058
static void emmc_pad_setting(void)
{
mmio_clrbits_32(REG_EMMC_RSTN_PIO, 0x7);
mmio_clrbits_32(REG_EMMC_CLK_PIO, 0x7);
mmio_clrbits_32(REG_EMMC_CMD_PIO, 0x7);
mmio_clrbits_32(REG_EMMC_DAT0_PIO, 0x7);
mmio_clrbits_32(REG_EMMC_DAT1_PIO, 0x7);
mmio_clrbits_32(REG_EMMC_DAT2_PIO, 0x7);
mmio_clrbits_32(REG_EMMC_DAT3_PIO, 0x7);
mmio_clrsetbits_32(REG_EMMC_CLK_PAD, IO_PAD_CLR_MASK, PULL_DOWN << IO_PAD_SHIFT);
mmio_clrsetbits_32(REG_EMMC_RSTN_PAD, IO_PAD_CLR_MASK, PULL_UP << IO_PAD_SHIFT);
mmio_clrsetbits_32(REG_EMMC_CMD_PAD, IO_PAD_CLR_MASK, PULL_UP << IO_PAD_SHIFT);
mmio_clrsetbits_32(REG_EMMC_DAT0_PAD, IO_PAD_CLR_MASK, PULL_UP << IO_PAD_SHIFT);
mmio_clrsetbits_32(REG_EMMC_DAT1_PAD, IO_PAD_CLR_MASK, PULL_UP << IO_PAD_SHIFT);
mmio_clrsetbits_32(REG_EMMC_DAT2_PAD, IO_PAD_CLR_MASK, PULL_UP << IO_PAD_SHIFT);
mmio_clrsetbits_32(REG_EMMC_DAT3_PAD, IO_PAD_CLR_MASK, PULL_UP << IO_PAD_SHIFT);
}
void bm_emmc_phy_init(void)
{
bm_emmc_hw_reset();
emmc_pad_setting();
}
void bm_emmc_init(void)
{
NOTICE("EMI/%d/%d.", bm_params.clk_rate, EMMC_TRAN_FREQ);
bm_emmc_phy_init();
if (emmc_init(&bm_emmc_ops, EMMC_TRAN_FREQ, bm_params.bus_width, bm_params.flags) < 0)
ERROR("eMMC initializing failed\n");
}

View File

@@ -0,0 +1,717 @@
/*
* Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Defines a simple and generic interface to access eMMC device.
*/
#include <cpu.h>
#include <debug.h>
#include <emmc.h>
#include <errno.h>
#include <string.h>
#include <utils.h>
#include <platform.h>
#include <delay_timer.h>
static const emmc_ops_t *ops;
static unsigned int emmc_ocr_value;
static emmc_cid_t emmc_cid;
static emmc_csd_t emmc_csd;
static unsigned int emmc_flags;
static int is_cmd23_enabled(void)
{
return (!!(emmc_flags & EMMC_FLAG_CMD23));
}
static int emmc_device_state(void)
{
emmc_cmd_t cmd;
int ret;
unsigned int emmc_timer = 0;
emmc_timer = get_timer(0);
do {
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD13;
cmd.cmd_arg = EMMC_FIX_RCA << RCA_SHIFT_OFFSET;
cmd.resp_type = EMMC_RESPONSE_R1;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
if ((cmd.resp_data[0] & STATUS_SWITCH_ERROR) != 0) {
ERROR("%s Response with Error: 0x%08x\n", __func__, cmd.resp_data[0]);
return -EIO;
}
if (get_timer(emmc_timer) > EMMC_READY_FOR_DATA_TIMEOUT) {
ERROR("%s Card stuck in programming state: 0x%08x\n", __func__, cmd.resp_data[0]);
return -EIO;
}
} while ((cmd.resp_data[0] & STATUS_READY_FOR_DATA) == 0);
return EMMC_GET_STATE(cmd.resp_data[0]);
}
static int emmc_set_ext_csd(unsigned int ext_cmd, unsigned int value)
{
emmc_cmd_t cmd;
int ret, state;
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD6;
cmd.cmd_arg = EXTCSD_WRITE_BYTES | EXTCSD_CMD(ext_cmd) | EXTCSD_VALUE(value) | 1;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
/* wait to exit PRG state */
do {
state = emmc_device_state();
if (state < 0)
return state;
} while (state == EMMC_STATE_PRG);
return ret;
}
extern void bm_emmc_set_ext_csd(unsigned int index, unsigned int value);
static int emmc_set_ios(int clk, int bus_width)
{
int ret;
/* set IO speed & IO bus width */
if (emmc_csd.spec_vers == 4) {
ret = emmc_set_ext_csd(CMD_EXTCSD_BUS_WIDTH, bus_width);
if (ret < 0)
return ret;
}
return ops->set_ios(clk, bus_width);
}
#define MAX_EMMC_INIT_ROUND 2
static int emmc_enumerate(int clk, int bus_width)
{
emmc_cmd_t cmd;
int ret, state;
uint32_t init_round = 0;
uint32_t emmc_timer = 0;
ops->init();
retry:
init_round++;
if (init_round > MAX_EMMC_INIT_ROUND) {
ERROR("eMMC init failed, %d\n", init_round);
return -EIO;
}
ops->reset();
/* CMD0: reset to IDLE */
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD0;
ret = ops->send_cmd(&cmd);
if (ret != 0)
goto retry;
emmc_timer = get_timer(0);
while (1) {
/* CMD1: get OCR register */
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD1;
cmd.cmd_arg = OCR_SECTOR_MODE | OCR_VDD_MIN_1V7;
cmd.resp_type = EMMC_RESPONSE_R3;
ret = ops->send_cmd(&cmd);
if (ret != 0)
goto retry;
emmc_ocr_value = cmd.resp_data[0];
if (emmc_ocr_value & OCR_POWERUP)
break;
if (get_timer(emmc_timer) > EMMC_IDENTIFIED_TIMEOUT) {
ERROR("eMMC wait POWRUP ready timeout: 0x%08x\n", emmc_ocr_value);
return -EIO;
}
}
/* CMD2: Card Identification */
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD2;
cmd.resp_type = EMMC_RESPONSE_R2;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
memcpy(&emmc_cid, &cmd.resp_data, sizeof(cmd.resp_data));
INFO("cid manufacturer_id:0x%x card_bga:0x%x name:%s\n", emmc_cid.manufacturer_id, emmc_cid.card_bga,
emmc_cid.product_name);
/* CMD3: Set Relative Address */
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD3;
cmd.cmd_arg = EMMC_FIX_RCA << RCA_SHIFT_OFFSET;
cmd.resp_type = EMMC_RESPONSE_R1;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
/* CMD9: CSD Register */
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD9;
cmd.cmd_arg = EMMC_FIX_RCA << RCA_SHIFT_OFFSET;
cmd.resp_type = EMMC_RESPONSE_R2;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
memcpy(&emmc_csd, &cmd.resp_data, sizeof(cmd.resp_data));
INFO("csd spec_vers:0x%x erase_grp_size:0x%x\n", emmc_csd.spec_vers, emmc_csd.erase_grp_size);
/* CMD7: Select Card */
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD7;
cmd.cmd_arg = EMMC_FIX_RCA << RCA_SHIFT_OFFSET;
cmd.resp_type = EMMC_RESPONSE_R1;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
/* wait to TRAN state */
do {
state = emmc_device_state();
if (state < 0)
return state;
} while (state != EMMC_STATE_TRAN);
return emmc_set_ios(clk, bus_width);
}
size_t emmc_read_blocks(int lba, uintptr_t buf, size_t size)
{
emmc_cmd_t cmd;
int ret;
if (!((ops != 0) && (ops->read != 0) && ((buf & EMMC_BLOCK_MASK) == 0) && ((size & EMMC_BLOCK_MASK) == 0)))
return -EINVAL;
inv_dcache_range(buf, size);
ret = ops->prepare(lba, buf, size); // bm_emmc_prepare
if (ret < 0)
return ret;
if (is_cmd23_enabled()) {
zeromem(&cmd, sizeof(emmc_cmd_t));
/* set block count */
cmd.cmd_idx = EMMC_CMD23;
cmd.cmd_arg = size / EMMC_BLOCK_SIZE;
cmd.resp_type = EMMC_RESPONSE_R1;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD18;
} else {
if (size > EMMC_BLOCK_SIZE)
cmd.cmd_idx = EMMC_CMD18;
else
cmd.cmd_idx = EMMC_CMD17;
}
if ((emmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE)
cmd.cmd_arg = lba * EMMC_BLOCK_SIZE;
else
cmd.cmd_arg = lba;
cmd.resp_type = EMMC_RESPONSE_R1;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
ret = ops->read(lba, buf, size);
if (ret < 0)
return ret;
if (is_cmd23_enabled() == 0) {
if (size > EMMC_BLOCK_SIZE) {
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD12;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
}
}
/* wait buffer empty */
ret = emmc_device_state();
if (ret < 0)
return ret;
return size;
}
size_t emmc_write_blocks(int lba, const uintptr_t buf, size_t size)
{
emmc_cmd_t cmd;
int ret;
if (!((ops != 0) && (ops->write != 0) && ((buf & EMMC_BLOCK_MASK) == 0) && ((size & EMMC_BLOCK_MASK) == 0)))
return -EINVAL;
clean_dcache_range(buf, size);
ret = ops->prepare(lba, buf, size);
if (ret < 0)
return ret;
if (is_cmd23_enabled()) {
/* set block count */
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD23;
cmd.cmd_arg = size / EMMC_BLOCK_SIZE;
cmd.resp_type = EMMC_RESPONSE_R1;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD25;
} else {
zeromem(&cmd, sizeof(emmc_cmd_t));
if (size > EMMC_BLOCK_SIZE)
cmd.cmd_idx = EMMC_CMD25;
else
cmd.cmd_idx = EMMC_CMD24;
}
if ((emmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE)
cmd.cmd_arg = lba * EMMC_BLOCK_SIZE;
else
cmd.cmd_arg = lba;
cmd.resp_type = EMMC_RESPONSE_R1;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
ret = ops->write(lba, buf, size);
if (ret < 0)
return ret;
if (is_cmd23_enabled() == 0) {
if (size > EMMC_BLOCK_SIZE) {
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD12;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
}
}
/* wait buffer empty */
ret = emmc_device_state();
if (ret < 0)
return ret;
return size;
}
size_t emmc_erase_blocks(int lba, size_t size)
{
emmc_cmd_t cmd;
int ret, state;
if (ops == 0)
return -EINVAL;
if ((size == 0) || ((size % EMMC_BLOCK_SIZE) != 0))
return -EINVAL;
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD35;
cmd.cmd_arg = lba;
cmd.resp_type = EMMC_RESPONSE_R1;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD36;
cmd.cmd_arg = lba + (size / EMMC_BLOCK_SIZE) - 1;
cmd.resp_type = EMMC_RESPONSE_R1;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
zeromem(&cmd, sizeof(emmc_cmd_t));
cmd.cmd_idx = EMMC_CMD38;
cmd.resp_type = EMMC_RESPONSE_R1B;
ret = ops->send_cmd(&cmd);
if (ret < 0)
return ret;
/* wait to TRAN state */
do {
state = emmc_device_state();
if (state < 0)
return state;
} while (state != EMMC_STATE_TRAN);
return size;
}
static inline int emmc_rw_enable(emmc_partition_type type)
{
int ret;
if ((type == 0) && (type == EMMC_PARTITION_MAX))
return -EINVAL;
switch (type) {
case EMMC_PARTITION_BOOT1:
ret = emmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
PART_CFG_BOOT_PARTITION1_ENABLE | PART_CFG_PARTITION_BOOT1_ACCESS);
break;
case EMMC_PARTITION_BOOT2:
ret = emmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
PART_CFG_BOOT_PARTITION1_ENABLE | PART_CFG_PARTITION_BOOT2_ACCESS);
break;
case EMMC_PARTITION_RPMB:
ret = emmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
PART_CFG_BOOT_PARTITION1_ENABLE | PART_CFG_PARTITION_RPMB_ACCESS);
break;
case EMMC_PARTITION_GP1:
ret = emmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
PART_CFG_BOOT_PARTITION1_ENABLE | PART_CFG_PARTITION_GP1_ACCESS);
break;
case EMMC_PARTITION_GP2:
ret = emmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
PART_CFG_BOOT_PARTITION1_ENABLE | PART_CFG_PARTITION_GP2_ACCESS);
break;
case EMMC_PARTITION_GP3:
ret = emmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
PART_CFG_BOOT_PARTITION1_ENABLE | PART_CFG_PARTITION_GP3_ACCESS);
break;
case EMMC_PARTITION_GP4:
ret = emmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
PART_CFG_BOOT_PARTITION1_ENABLE | PART_CFG_PARTITION_GP4_ACCESS);
break;
default:
return -EINVAL;
}
return ret;
}
static inline int emmc_rw_disable(void)
{
return emmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG, PART_CFG_BOOT_PARTITION1_ENABLE);
}
size_t emmc_partition_read_blocks(emmc_partition_type type, int lba, uintptr_t buf, size_t size)
{
size_t size_read;
int ret;
ret = emmc_rw_enable(type);
if (ret < 0)
return ret;
size_read = emmc_read_blocks(lba, buf, size);
ret = emmc_rw_disable();
if (ret < 0)
return ret;
return size_read;
}
size_t emmc_partition_write_blocks(emmc_partition_type type, int lba, const uintptr_t buf, size_t size)
{
size_t size_written;
int ret;
ret = emmc_rw_enable(type);
if (ret < 0)
return ret;
size_written = emmc_write_blocks(lba, buf, size);
ret = emmc_rw_disable();
if (ret < 0)
return ret;
return size_written;
}
size_t emmc_partition_erase_blocks(emmc_partition_type type, int lba, size_t size)
{
size_t size_erased;
int ret;
ret = emmc_rw_enable(type);
if (ret < 0)
return ret;
size_erased = emmc_erase_blocks(lba, size);
ret = emmc_rw_disable();
if (ret < 0)
return ret;
return size_erased;
}
size_t emmc_boot1_read_blocks(int lba, uintptr_t buf, size_t size)
{
return emmc_partition_read_blocks(EMMC_PARTITION_BOOT1, lba, buf, size);
}
size_t emmc_boot1_write_blocks(int lba, uintptr_t buf, size_t size)
{
return emmc_partition_write_blocks(EMMC_PARTITION_BOOT1, lba, buf, size);
}
#if DEBUG && ((defined(IMAGE_BL1) && defined(BL1_INIT_EMMC)) || (defined(IMAGE_BL2) && defined(BL2_INIT_EMMC)))
#define EMMC_TEST_SECTOR_NUMBER 0x64
#define EMMC_MICRON_8G_MAX_SECTOR_NUMBER 0xE30000
#define EMMC_TEST_LARGE_BLOCKS_EWR (64 * 1024)
#define EMMC_TEST_START_LBA 0x0
#define EMMC_TEST_RAM_ADDR 0x100000000
#define EMMC_TEST_NUM_LOOP 10
unsigned int wbuf[128 * 2] __attribute__((aligned(EMMC_BLOCK_SIZE))) = {
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
};
unsigned int rbuf[128 * 2] __attribute__((aligned(EMMC_BLOCK_SIZE))) = { 0 };
static void emmc_partition_ewr_test(emmc_partition_type type, int lba)
{
int i;
INFO("\r\n================type=%d lba=0x%x one sector erase write read start================== \r\n", type,
lba);
if (type <= EMMC_PARTITION_GP4) {
INFO("start erase \r\n");
emmc_partition_erase_blocks(type, lba, EMMC_BLOCK_SIZE);
INFO("start write \r\n");
emmc_partition_write_blocks(type, lba, (uintptr_t)wbuf, EMMC_BLOCK_SIZE);
INFO("start read \r\n");
memset(rbuf, 0, EMMC_BLOCK_SIZE);
emmc_partition_read_blocks(type, lba, (uintptr_t)rbuf, EMMC_BLOCK_SIZE);
} else {
INFO("start erase \r\n");
emmc_erase_blocks(lba, EMMC_BLOCK_SIZE);
INFO("start write \r\n");
emmc_write_blocks(lba, (uintptr_t)wbuf, EMMC_BLOCK_SIZE);
INFO("start read \r\n");
memset(rbuf, 0, EMMC_BLOCK_SIZE);
emmc_read_blocks(lba, (uintptr_t)rbuf, EMMC_BLOCK_SIZE);
}
for (i = 0; i < 128; i++) {
//INFO("%x ",rbuf[i]);
if (wbuf[i] != rbuf[i]) {
ERROR("\r\ndata error:%d w:0x%x r:0x%x\n", i, wbuf[i], rbuf[i]);
return;
}
}
INFO("\r\n================type=%d lba=0x%x one sector erase write read end================== \r\n", type, lba);
}
static void emmc_partition_blocks_ewr_test(emmc_partition_type type, int lba)
{
unsigned int i, j, m, n, k, sector;
unsigned int *p = (unsigned int *)EMMC_TEST_RAM_ADDR;
sector = lba;
INFO("\r\n EWR blocks start type:%d \r\n", type);
m = (EMMC_TEST_NUM_LOOP * EMMC_TEST_LARGE_BLOCKS_EWR) / EMMC_BLOCK_SIZE;
INFO("Total sectors:%d \r\n", m);
for (n = 0; n < m; n++) {
for (j = 0; j < (EMMC_BLOCK_SIZE / sizeof(unsigned int)); j++) {
*p++ = n + j;
//INFO("%d %d",*(p-1),n+j);
}
}
INFO("write ram *p:%d sectors:%d \r\n", (unsigned int)(*(p - 1)),
(unsigned int)((*(p - 1)) - (EMMC_BLOCK_SIZE / sizeof(unsigned int)) + 2));
p = (unsigned int *)EMMC_TEST_RAM_ADDR;
for (i = 0; i < EMMC_TEST_NUM_LOOP; i++) {
//emmc_erase_blocks(lba,EMMC_TEST_LARGE_BLOCKS_EWR);
emmc_partition_erase_blocks(type, sector, EMMC_TEST_LARGE_BLOCKS_EWR);
//INFO("write large blocks start \r\n");
emmc_partition_write_blocks(type, sector, (uintptr_t)p, EMMC_TEST_LARGE_BLOCKS_EWR);
//INFO("read large blocks start \n");
for (j = 0; j < EMMC_TEST_LARGE_BLOCKS_EWR / EMMC_BLOCK_SIZE; j++) {
//INFO("sectors:%d \r\n",i*(EMMC_TEST_LARGE_BLOCKS_EWR/EMMC_BLOCK_SIZE)+j);
memset((char *)rbuf, 0x0, sizeof(rbuf));
emmc_partition_read_blocks(type, i * (EMMC_TEST_LARGE_BLOCKS_EWR / EMMC_BLOCK_SIZE) + j,
(uintptr_t)rbuf, EMMC_BLOCK_SIZE);
for (k = 0; k < EMMC_BLOCK_SIZE / sizeof(unsigned int); k++) {
if (rbuf[k] != k + j + (i * (EMMC_TEST_LARGE_BLOCKS_EWR / EMMC_BLOCK_SIZE))) {
ERROR("\r\nError rbuf[%d]=%d content:%d \r\n", k, rbuf[k],
k + j + i * ((EMMC_TEST_LARGE_BLOCKS_EWR / EMMC_BLOCK_SIZE)));
return;
}
}
}
sector += EMMC_TEST_LARGE_BLOCKS_EWR / EMMC_BLOCK_SIZE;
p += (EMMC_TEST_LARGE_BLOCKS_EWR) / sizeof(unsigned int);
}
INFO("\r\nType:%d EWR blocks test end rbuf[%d]=%d content:%d \r\n", type, k - 1, rbuf[k - 1],
k - 1 + j - 1 + ((i - 1) * (EMMC_TEST_LARGE_BLOCKS_EWR / EMMC_BLOCK_SIZE)));
}
void emmc_ut(void)
{
unsigned int i, j;
INFO("\r\n================50Mhz erase write read start===================== \r\n");
emmc_partition_ewr_test(EMMC_PARTITION_BOOT1, 0);
emmc_partition_ewr_test(EMMC_PARTITION_BOOT2, 0);
//emmc_partition_ewr_test(EMMC_PARTITION_RPMB,0);
emmc_partition_ewr_test(EMMC_PARTITION_UDA, 0);
emmc_partition_ewr_test(EMMC_PARTITION_UDA, (EMMC_MICRON_8G_MAX_SECTOR_NUMBER - 1));
//INFO("\r\n================switch clk to 50MHZ start======================= \r\n");
//send to device change to hight speed.
//emmc_set_ext_csd(CMD_EXTCSD_HS_TIMING, 0x0);// 0X1 high speed 2 hs200 3 hs400
//bm_emmc_set_clk(50*1000*1000);
//INFO("\r\n================switch clk to 50MHZ end========================= \r\n");
emmc_partition_ewr_test(EMMC_PARTITION_BOOT1, 0);
emmc_partition_ewr_test(EMMC_PARTITION_BOOT2, 0);
//emmc_partition_ewr_test(EMMC_PARTITION_RPMB,0);
emmc_partition_ewr_test(EMMC_PARTITION_UDA, 0);
emmc_partition_ewr_test(EMMC_PARTITION_UDA, (EMMC_MICRON_8G_MAX_SECTOR_NUMBER - 1));
INFO("\r\nEMMC_PARTITION_BOOT1 write start\r\n");
for (i = 0; i < EMMC_TEST_SECTOR_NUMBER; i += 2) {
//INFO("sector:%d \r\n",i);
emmc_partition_write_blocks(EMMC_PARTITION_BOOT1, i, (uintptr_t)wbuf, sizeof(wbuf));
}
INFO("\r\nEMMC_PARTITION_BOOT1 read start\r\n");
for (i = 0; i < EMMC_TEST_SECTOR_NUMBER; i += 2) {
memset((char *)rbuf, 0x0, sizeof(rbuf));
emmc_partition_read_blocks(EMMC_PARTITION_BOOT1, i, (uintptr_t)rbuf, sizeof(rbuf));
for (j = 0; j < sizeof(rbuf) / sizeof(unsigned int); j++) {
if (wbuf[j] != rbuf[j]) {
ERROR("\r\nboot1 data error:%d w:0x%x r:0x%x\r\n", j, wbuf[j], rbuf[j]);
return;
}
}
}
INFO("\r\nEMMC_PARTITION_BOOT2 write start\r\n");
for (i = 0; i < EMMC_TEST_SECTOR_NUMBER; i += 2)
emmc_partition_write_blocks(EMMC_PARTITION_BOOT2, i, (uintptr_t)wbuf, sizeof(wbuf));
INFO("\r\nEMMC_PARTITION_BOOT2 read start\r\n");
for (i = 0; i < EMMC_TEST_SECTOR_NUMBER; i += 2) {
memset((char *)rbuf, 0x0, sizeof(rbuf));
emmc_partition_read_blocks(EMMC_PARTITION_BOOT2, i, (uintptr_t)rbuf, sizeof(rbuf));
for (j = 0; j < sizeof(rbuf) / sizeof(unsigned int); j++) {
if (wbuf[j] != rbuf[j]) {
ERROR("\r\nboot2 data error:%d w:0x%x r:0x%x\r\n", j, wbuf[j], rbuf[j]);
return;
}
}
}
INFO("\r\nEMMC_PARTITION_UDA writing low address start \r\n");
for (i = 0; i < EMMC_TEST_SECTOR_NUMBER; i += 2)
emmc_write_blocks(i, (uintptr_t)wbuf, sizeof(wbuf));
INFO("\r\nEMMC_PARTITION_UDA reading low address start\r\n");
for (i = 0; i < EMMC_TEST_SECTOR_NUMBER; i += 2) {
memset((char *)rbuf, 0x0, sizeof(rbuf));
emmc_read_blocks(i, (uintptr_t)rbuf, sizeof(rbuf));
for (j = 0; j < sizeof(rbuf) / sizeof(unsigned int); j++) {
if (wbuf[j] != rbuf[j]) {
ERROR("\r\nuda data error:%d w:0x%x r:0x%x\n", j, wbuf[j], rbuf[j]);
return;
}
}
}
INFO("\r\nEMMC_PARTITION_UDA writing high address start\r\n");
for (i = EMMC_MICRON_8G_MAX_SECTOR_NUMBER - EMMC_TEST_SECTOR_NUMBER; i < EMMC_MICRON_8G_MAX_SECTOR_NUMBER;
i += 2) {
emmc_write_blocks(i, (uintptr_t)wbuf, sizeof(wbuf));
}
INFO("\r\nEMMC_PARTITION_UDA reading high address start\r\n");
for (i = EMMC_MICRON_8G_MAX_SECTOR_NUMBER - EMMC_TEST_SECTOR_NUMBER; i < EMMC_MICRON_8G_MAX_SECTOR_NUMBER;
i += 2) {
memset((char *)rbuf, 0x0, sizeof(rbuf));
emmc_read_blocks(i, (uintptr_t)rbuf, sizeof(rbuf));
for (j = 0; j < sizeof(rbuf) / sizeof(unsigned int); j++) {
if (wbuf[j] != rbuf[j]) {
ERROR("\r\nuda data error:%d w:0x%x r:0x%x\n", j, wbuf[j], rbuf[j]);
return;
}
}
}
emmc_partition_blocks_ewr_test(EMMC_PARTITION_BOOT1, 0x0);
emmc_partition_blocks_ewr_test(EMMC_PARTITION_BOOT2, 0x0);
emmc_partition_blocks_ewr_test(EMMC_PARTITION_UDA, 0x0);
INFO("\r\n================50MHZ erase write read end==================== \r\n");
}
#endif
int emmc_init(const emmc_ops_t *ops_ptr, int clk, int width, unsigned int flags)
{
if (!((ops_ptr != 0) && (ops_ptr->init != 0) && (ops_ptr->reset != 0) && (ops_ptr->send_cmd != 0) &&
(ops_ptr->set_ios != 0) && (ops_ptr->prepare != 0) && (ops_ptr->read != 0) && (ops_ptr->write != 0) &&
(clk != 0) &&
((width == EMMC_BUS_WIDTH_1) || (width == EMMC_BUS_WIDTH_4) || (width == EMMC_BUS_WIDTH_8))))
return -EINVAL;
ops = ops_ptr;
emmc_flags = flags;
return emmc_enumerate(clk, width);
}

View File

@@ -203,8 +203,14 @@ class FIP:
Entry.make("LOADER_2ND_LOADADDR", 4, int),
Entry.make("LOADER_2ND_RESERVED1", 4, int),
Entry.make("LOADER_2ND_RESERVED2", 4, int),
# Reserved
Entry.make("RESERVED_LAST", 4096 - 16 * 5, bytes),
# u-boot_B
Entry.make("LOADER_2ND_B_RESERVED0", 4, int),
Entry.make("LOADER_2ND_B_LOADADDR", 4, int),
Entry.make("LOADER_2ND_B_SIZE", 4, int),
Entry.make("LOADER_2ND_B_RESERVED2", 4, int),
# alios bl
Entry.make("ALIOS_BOOT_SIZE", 4, int),
Entry.make("RESERVED_LAST", 4096 - 16 * 6 - 4, bytes),
]
)
@@ -214,6 +220,7 @@ class FIP:
Entry.make("BLCP_2ND", None, bytes),
Entry.make("MONITOR", None, bytes),
Entry.make("LOADER_2ND", None, bytes),
Entry.make("LOADER_2ND_B", None, bytes),
]
)
@@ -229,6 +236,13 @@ class FIP:
]
)
alios_bl = OrderedDict(
[
Entry.make("BOOT", None, bytes),
Entry.make("PRIM", None, bytes),
]
)
FIP_FLAGS_SCS_MASK = 0x000c
FIP_FLAGS_ENCRYPTED_MASK = 0x0030
@@ -592,6 +606,15 @@ class FIP:
self.body2["LOADER_2ND"].content = self.pad(hdr + body, IMAGE_ALIGN)
def add_loader_2nd_b(self, args):
if args.LOADER_2ND_B == "":
return
with open(args.LOADER_2ND_B, "rb") as fp:
loader_2nd_b = fp.read()
logging.debug("loader_2nd_b=%#x bytes", len(loader_2nd_b))
self.body2["LOADER_2ND_B"].content = loader_2nd_b
def pack_loader_2nd(self, fip_bin):
logging.debug("pack_loader_2nd:")
if not len(self.body2["LOADER_2ND"].content):
@@ -607,6 +630,23 @@ class FIP:
# Append LOADER_2ND to body2
return fip_bin + self.body2["LOADER_2ND"].content
def pack_loader_2nd_b(self, fip_bin):
logging.debug("pack_loader_2nd_b:")
if not len(self.body2["LOADER_2ND_B"].content):
return
fip_bin = self.pad(fip_bin, IMAGE_ALIGN)
# Append LOADER_2ND_B to body2
loader_2nd_b = self.pad(self.body2["LOADER_2ND_B"].content, IMAGE_ALIGN)
logging.debug("pack_loader_2nd_b:LOADER_2ND_B_LOADADDR=%d, LOADER_2ND_B_SIZE=%d ", len(fip_bin), len(loader_2nd_b))
self.param2["LOADER_2ND_B_LOADADDR"].content = len(fip_bin)
self.param2["LOADER_2ND_B_SIZE"].content = len(loader_2nd_b)
return fip_bin + loader_2nd_b
def insert_param1(self, fip_bin, name, value):
fip_bin = bytearray(fip_bin)
e = self.param1[name]
@@ -626,7 +666,7 @@ class FIP:
fip_bin += b"\0" * PARAM2_SIZE
# Pack body
fip_bin = self.pack_ddr_param(fip_bin)
# fip_bin = self.pack_ddr_param(fip_bin)
if len(self.body2["BLCP_2ND"].content):
runaddr = self.param2["BLCP_2ND_RUNADDR"].toint()
@@ -643,6 +683,9 @@ class FIP:
if len(self.body2["LOADER_2ND"].content):
fip_bin = self.pack_loader_2nd(fip_bin)
if len(self.body2["LOADER_2ND_B"].content):
fip_bin = self.pack_loader_2nd_b(fip_bin)
# Pack param2_bin
param2_bin = b"".join((entry.content for entry in self.param2.values()))
self.param2["PARAM2_CKSUM"].content = self.image_crc(param2_bin[self.param2["PARAM2_CKSUM"].end :])
@@ -657,7 +700,7 @@ class FIP:
def make(self, args=None):
fip_bin = self.make_fip1()
if len(self.body2["DDR_PARAM"].content):
fip_bin = self.append_fip2(fip_bin, args)
logging.info("generated fip_bin is %d bytes", len(fip_bin))
@@ -674,10 +717,11 @@ METHODS = {
"CHIP_CONF": FIP.add_chip_conf,
"BLCP": FIP.add_blcp,
"BL2": FIP.add_bl2,
"DDR_PARAM": FIP.add_ddr_param,
# "DDR_PARAM": FIP.add_ddr_param,
"BLCP_2ND": FIP.add_blcp_2nd,
"MONITOR": FIP.add_monitor,
"LOADER_2ND": FIP.add_loader_2nd,
"LOADER_2ND_B": FIP.add_loader_2nd_b,
}

View File

@@ -23,7 +23,12 @@ struct fip_param2 {
uint32_t loader_2nd_loadaddr;
uint32_t loader_2nd_reserved1;
uint32_t loader_2nd_reserved2;
uint8_t reserved4[4016];
uint32_t loader_2nd_b_reserved0;
uint32_t loader_2nd_b_loadaddr;
uint32_t loader_2nd_b_size;
uint32_t loader_2nd_b_reserved2;
uint32_t alios_boot_size;
uint8_t reserved4[3996];
} __packed;
struct loader_2nd_header {

File diff suppressed because it is too large Load Diff

View File

@@ -10,9 +10,19 @@
#define DDR_VENDOR_ETRON_1G 0b00101
#define DDR_VENDOR_ESMT_2G 0b00110
#define DDR_VENDOR_PM_2G 0b00111
#define DDR_VENDOR_PM_1G 0b01000
#define DDR_VENDOR_ETRON_N20_2G 0b01000
#define DDR_VENDOR_ETRON_512M_DDR2 0b01001
#define DDR_VENDOR_ESMT_N25_1G 0b01010
#define DDR_VENDOR_NY_N20_1G 0b01011
#define DDR_VENDOR_ESMT_N21_2G 0b01100
#define DDR_VENDOR_ESMT_N19_4G 0b01101
#define DDR_VENDOR_UNILC_N25_512M_DDR2 0b01110
#define DDR_VENDOR_UNILC_N25_1G 0b01111
#define DDR_VENDOR_UNILC_N21_2G 0b10000
#define DDR_VENDOR_ETRON_N25_2G 0b10001
#define DDR_VENDOR_EXTERN_DDR2_1815J 0b11110
#define DDR_VENDOR_EXTERN_DDR3_1815J 0b11111
#define DDR_VENDOR_EXTERN_DDR3_1815K 0b11101
#define DDR_CAPACITY_UNKNOWN 0b000
#define DDR_CAPACITY_512M 0b001

View File

@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#define SUSPEND_ENTRY __section(".suspend_entry")
#define SUSPEND_FUNC __section(".suspend_func")
#define SUSPEND_DATA __section(".suspend_data")
SUSPEND_ENTRY void ddr_suspend_entry(void);
static SUSPEND_FUNC void susp_udelay(uint32_t delay);
static SUSPEND_FUNC void ddr_sys_suspend_sus_res(void);
static SUSPEND_FUNC void cvx16_ddr_phya_pd_sus_res(void);
static SUSPEND_FUNC void cvx16_ddrc_suspend_sus_res(void);
static SUSPEND_FUNC void cvx16_ddr_phyd_save_sus_res(uint32_t);
static SUSPEND_FUNC void rtc_clr_ddr_pwrok(void);
static SUSPEND_FUNC void rtc_clr_rmio_pwrok(void);
//#define SUSPEND_USE_WDG_RST
#ifndef SUSPEND_USE_WDG_RST
static SUSPEND_FUNC void rtc_req_suspend(void);
#else
static SUSPEND_FUNC void rtc_req_wdg_rst(void);
#endif
struct reg {
uint32_t addr;
uint32_t val;
};

View File

@@ -27,8 +27,10 @@ extern uint32_t ddr3_1866_patch_regs_count;
extern struct regpatch ddr2_1333_patch_regs[];
extern uint32_t ddr2_1333_patch_regs_count;
#else
extern struct regpatch ddr_patch_regs[];
extern struct regpatch *ddr_patch_regs;
extern uint32_t ddr_patch_regs_count;
#endif
void ddr_patch_regs_init(void);
#endif /* __REG_CFG_H__ */

View File

@@ -0,0 +1,191 @@
/*
* Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __CV_EMMC_H__
#define __CV_EMMC_H__
#include <emmc.h>
#define SDHCI_DMA_ADDRESS 0x00
#define SDHCI_BLOCK_SIZE 0x04
#define SDHCI_MAKE_BLKSZ(dma, blksz) ((((dma) & 0x7) << 12) | ((blksz) & 0xFFF))
#define SDHCI_BLOCK_COUNT 0x06
#define SDHCI_ARGUMENT 0x08
#define SDHCI_TRANSFER_MODE 0x0C
#define SDHCI_TRNS_DMA BIT(0)
#define SDHCI_TRNS_BLK_CNT_EN BIT(1)
#define SDHCI_TRNS_ACMD12 BIT(2)
#define SDHCI_TRNS_READ BIT(4)
#define SDHCI_TRNS_MULTI BIT(5)
#define SDHCI_TRNS_RESP_INT BIT(8)
#define SDHCI_COMMAND 0x0E
#define SDHCI_CMD_RESP_MASK 0x03
#define SDHCI_CMD_CRC 0x08
#define SDHCI_CMD_INDEX 0x10
#define SDHCI_CMD_DATA 0x20
#define SDHCI_CMD_ABORTCMD 0xC0
#define SDHCI_CMD_RESP_NONE 0x00
#define SDHCI_CMD_RESP_LONG 0x01
#define SDHCI_CMD_RESP_SHORT 0x02
#define SDHCI_CMD_RESP_SHORT_BUSY 0x03
#define SDHCI_MAKE_CMD(c, f) ((((c) & 0xff) << 8) | ((f) & 0xff))
#define SDHCI_RESPONSE_01 0x10
#define SDHCI_RESPONSE_23 0x14
#define SDHCI_RESPONSE_45 0x18
#define SDHCI_RESPONSE_67 0x1C
#define SDHCI_PSTATE 0x24
#define SDHCI_CMD_INHIBIT BIT(0)
#define SDHCI_CMD_INHIBIT_DAT BIT(1)
#define SDHCI_HOST_CONTROL 0x28
#define SDHCI_DAT_XFER_WIDTH BIT(1)
#define SDHCI_EXT_DAT_XFER BIT(5)
#define SDHCI_CTRL_DMA_MASK 0x18
#define SDHCI_CTRL_SDMA 0x00
#define SDHCI_PWR_CONTROL 0x29
#define SDHCI_BUS_VOL_VDD1_1_8V 0xC
#define SDHCI_BUS_VOL_VDD1_3_0V 0xE
#define SDHCI_BUF_DATA_R 0x20
#define SDHCI_BLOCK_GAP_CONTROL 0x2A
#define SDHCI_CLK_CTRL 0x2C
#define SDHCI_TOUT_CTRL 0x2E
#define SDHCI_SOFTWARE_RESET 0x2F
#define SDHCI_RESET_CMD 0x02
#define SDHCI_RESET_DATA 0x04
#define SDHCI_INT_STATUS 0x30
#define SDHCI_ERR_INT_STATUS 0x32
#define SDHCI_INT_CMD_COMPLETE BIT(0)
#define SDHCI_INT_XFER_COMPLETE BIT(1)
#define SDHCI_INT_DMA_END BIT(3)
#define SDHCI_INT_BUF_RD_READY BIT(5)
#define SDHCI_INT_ERROR BIT(15)
#define SDHCI_INT_STATUS_EN 0x34
#define SDHCI_ERR_INT_STATUS_EN 0x36
#define SDHCI_INT_CMD_COMPLETE_EN BIT(0)
#define SDHCI_INT_XFER_COMPLETE_EN BIT(1)
#define SDHCI_INT_DMA_END_EN BIT(3)
#define SDHCI_INT_ERROR_EN BIT(15)
#define SDHCI_SIGNAL_ENABLE 0x38
#define SDHCI_HOST_CONTROL2 0x3E
#define SDHCI_HOST_VER4_ENABLE BIT(12)
#define SDHCI_CAPABILITIES1 0x40
#define SDHCI_CAPABILITIES2 0x44
#define SDHCI_ADMA_SA_LOW 0x58
#define SDHCI_ADMA_SA_HIGH 0x5C
#define P_VENDOR_SPECIFIC_AREA 0xE8
#define P_VENDOR2_SPECIFIC_AREA 0xEA
#define VENDOR_EMMC_CTRL 0x0
#define SDHCI_RESET_N BIT(8)
#define SDHCI_PHY_R_OFFSET 0x300
#define SDHCI_P_PHY_CNFG (SDHCI_PHY_R_OFFSET + 0x00)
#define SDHCI_P_CMDPAD_CNFG (SDHCI_PHY_R_OFFSET + 0x04)
#define SDHCI_P_DATPAD_CNFG (SDHCI_PHY_R_OFFSET + 0x06)
#define SDHCI_P_CLKPAD_CNFG (SDHCI_PHY_R_OFFSET + 0x08)
#define SDHCI_P_STBPAD_CNFG (SDHCI_PHY_R_OFFSET + 0x0A)
#define SDHCI_P_RSTNPAD_CNFG (SDHCI_PHY_R_OFFSET + 0x0C)
#define SDHCI_P_PADTEST_CNFG (SDHCI_PHY_R_OFFSET + 0x0E)
#define SDHCI_P_PADTEST_OUT (SDHCI_PHY_R_OFFSET + 0x10)
#define SDHCI_P_PADTEST_IN (SDHCI_PHY_R_OFFSET + 0x12)
#define SDHCI_P_COMMDL_CNFG (SDHCI_PHY_R_OFFSET + 0x1C)
#define SDHCI_P_SDCLKDL_CNFG (SDHCI_PHY_R_OFFSET + 0x1D)
#define SDHCI_P_SDCLKDL_DC (SDHCI_PHY_R_OFFSET + 0x1E)
#define SDHCI_P_SMPLDL_CNFG (SDHCI_PHY_R_OFFSET + 0x20)
#define SDHCI_P_ATDL_CNFG (SDHCI_PHY_R_OFFSET + 0x21)
#define SDHCI_P_DLL_CTRL (SDHCI_PHY_R_OFFSET + 0x24)
#define SDHCI_P_DLL_CNFG1 (SDHCI_PHY_R_OFFSET + 0x25)
#define SDHCI_P_DLL_CNFG2 (SDHCI_PHY_R_OFFSET + 0x26)
#define SDHCI_P_DLLDL_CNFG (SDHCI_PHY_R_OFFSET + 0x28)
#define SDHCI_P_DLL_OFFST (SDHCI_PHY_R_OFFSET + 0x29)
#define SDHCI_P_DLLMST_TSTDC (SDHCI_PHY_R_OFFSET + 0x2A)
#define SDHCI_P_DLLLBT_CNFG (SDHCI_PHY_R_OFFSET + 0x2C)
#define SDHCI_P_DLL_STATUS (SDHCI_PHY_R_OFFSET + 0x2E)
#define SDHCI_P_DLLDBG_MLKDC (SDHCI_PHY_R_OFFSET + 0x30)
#define SDHCI_P_DLLDBG_SLKDC (SDHCI_PHY_R_OFFSET + 0x32)
#define SDHCI_RX_DELAY_LINE (0x200 + 0x40) // P_VERDOR_SPECIFIC_AREA + 0x40(0x240) PHY_TX_RX_DLY
#define REG_RX_SRC_SEL_MASK (0xFCFFFFFF) // 0x240 PHY_RX_SRC [25:24]
#define REG_RX_SRC_SEL_CLR_MASK (0x3000000) // 0x240 PHY_RX_SRC [25:24]
#define REG_RX_SRC_SEL_CLK_TX (0) // clk_tx
#define REG_RX_SRC_SEL_CLK_TX_INV (1) // clk_tx_inv
#define REG_RX_SRC_SEL_RES (2) // resvd
#define REG_RX_SRC_SEL_PAD_CLK (1) // pad_clk
#define REG_RX_SRC_SEL_SHIFT (24) // 0x240 PHY_RX_SRC [25:24]
#define SDHCI_TX_DELAY_LINE (0x200 + 0x40) // P_VERDOR_SPECIFIC_AREA + 0x40(0x240) PHY_TX_RX_DLY
#define REG_TX_SRC_SEL_MASK (0xFFFFFCFF) // 0x240 PHY_TX_SRC[9:8]
#define REG_TX_SRC_SEL_CLR_MASK (0x300) // 0x240 PHY_TX_SRC[9:8]
#define REG_TX_SRC_SEL_CLK_TX (0) // clk_tx
#define REG_TX_SRC_SEL_CLK_TX_INV (1) // clk_tx_inv
#define REG_TX_SRC_SEL_RES (2) // resvd
#define REG_TX_SRC_SEL_PAD_CLK (1) // pad_clk
#define REG_TX_SRC_SEL_SHIFT (8) // 0x240 PHY_TX_SRC[9:8]
#define SDHCI_PHY_CONFIG (0x200 + 0x4C) // P_VERDOR_SPECIFIC_AREA + 0x4c(0x24c) PHY_TX_BPS
#define REG_TX_BPS_SEL_MASK (0xFFFFFFFE) // 0x24c PHY_TX_BPS[0:0]
#define REG_TX_BPS_SEL_CLR_MASK (0x1) // 0x24c PHY_TX_BPS[0:0]
#define REG_TX_BPS_SEL_SHIFT (0) // 0x24c PHY_TX_BPS[0:0]
#define REG_TX_BPS_SEL_BYPASS (1) // 0x24c PHY_TX_BPS inv
#define PHY_CNFG_PHY_RSTN 0
#define PHY_CNFG_PHY_PWRGOOD 1
#define PHY_CNFG_PAD_SP 16
#define PHY_CNFG_PAD_SP_MSK 0xf
#define PHY_CNFG_PAD_SN 20
#define PHY_CNFG_PAD_SN_MSK 0xf
#define PAD_CNFG_RXSEL 0
#define PAD_CNFG_RXSEL_MSK 0x7
#define PAD_CNFG_WEAKPULL_EN 3
#define PAD_CNFG_WEAKPULL_EN_MSK 0x3
#define PAD_CNFG_TXSLEW_CTRL_P 5
#define PAD_CNFG_TXSLEW_CTRL_P_MSK 0xf
#define PAD_CNFG_TXSLEW_CTRL_N 9
#define PAD_CNFG_TXSLEW_CTRL_N_MSK 0xf
#define COMMDL_CNFG_DLSTEP_SEL 0
#define COMMDL_CNFG_DLOUT_EN 1
#define SDCLKDL_CNFG_EXTDLY_EN 0
#define SDCLKDL_CNFG_BYPASS_EN 1
#define SDCLKDL_CNFG_INPSEL_CNFG 2
#define SDCLKDL_CNFG_INPSEL_CNFG_MSK 0x3
#define SDCLKDL_CNFG_UPDATE_DC 4
#define SMPLDL_CNFG_EXTDLY_EN 0
#define SMPLDL_CNFG_BYPASS_EN 1
#define SMPLDL_CNFG_INPSEL_CNFG 2
#define SMPLDL_CNFG_INPSEL_CNFG_MSK 0x3
#define SMPLDL_CNFG_INPSEL_OVERRIDE 4
#define ATDL_CNFG_EXTDLY_EN 0
#define ATDL_CNFG_BYPASS_EN 1
#define ATDL_CNFG_INPSEL_CNFG 2
#define ATDL_CNFG_INPSEL_CNFG_MSK 0x3
#define GPIO_SWPORTA_DDR 0x004
#define GPIO_SWPORTA_DR 0x000
#define GPIO0_BASE 0x03020000
#define GPIO1_BASE 0x03021000
#define GPIO2_BASE 0x03022000
#define GPIO3_BASE 0x03023000
typedef struct bm_emmc_params {
uintptr_t reg_base;
uintptr_t vendor_base;
uintptr_t desc_base;
size_t desc_size;
int clk_rate;
int bus_width;
unsigned int flags;
} bm_emmc_params_t;
void bm_emmc_phy_init(void);
void bm_emmc_init(void);
int bm_emmc_set_clk(int clk);
void bm_emmc_read_data(unsigned int *buf);
int bm_emmc_send_cmd_with_data_cmd8(emmc_cmd_t *cmd);
#endif /* __CV_EMMC_H__ */

View File

@@ -0,0 +1,209 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __EMMC_H__
#define __EMMC_H__
#include <stdint.h>
#define EMMC_IDENTIFIED_TIMEOUT (1500)
#define EMMC_CMD_TIMEOUT (100) // Follow same setting
#define EMMC_DATA_CMD_TIMEOUT (10000) // Follow linux kernel setting
#define EMMC_READY_FOR_DATA_TIMEOUT (5000) // Should not be happened
#define EMMC_BLOCK_SIZE 512
#define EMMC_BLOCK_MASK (EMMC_BLOCK_SIZE - 1)
#define EMMC_BOOT_CLK_RATE (400 * 1000)
#define EMMC_CMD0 0
#define EMMC_CMD1 1
#define EMMC_CMD2 2
#define EMMC_CMD3 3
#define EMMC_CMD6 6
#define EMMC_CMD7 7
#define EMMC_CMD8 8
#define EMMC_CMD9 9
#define EMMC_CMD12 12
#define EMMC_CMD13 13
#define EMMC_CMD17 17
#define EMMC_CMD18 18
#define EMMC_CMD23 23
#define EMMC_CMD24 24
#define EMMC_CMD25 25
#define EMMC_CMD35 35
#define EMMC_CMD36 36
#define EMMC_CMD38 38
#define OCR_POWERUP (1 << 31)
#define OCR_BYTE_MODE (0 << 29)
#define OCR_SECTOR_MODE (2 << 29)
#define OCR_ACCESS_MODE_MASK (3 << 29)
#define OCR_VDD_MIN_2V7 (0x1ff << 15)
#define OCR_VDD_MIN_2V0 (0x7f << 8)
#define OCR_VDD_MIN_1V7 (1 << 7)
#define EMMC_RESPONSE_R1 1
#define EMMC_RESPONSE_R1B 1
#define EMMC_RESPONSE_R2 4
#define EMMC_RESPONSE_R3 1
#define EMMC_RESPONSE_R4 1
#define EMMC_RESPONSE_R5 1
#define EMMC_FIX_RCA 6 /* > 1 */
#define RCA_SHIFT_OFFSET 16
#define CMD_EXTCSD_PARTITION_CONFIG 179
#define CMD_EXTCSD_BUS_WIDTH 183
#define CMD_EXTCSD_HS_TIMING 185
#define PART_CFG_BOOT_PARTITION1_ENABLE (1 << 3)
#define PART_CFG_BOOT_PARTITION2_ENABLE (2 << 3)
#define PART_CFG_PARTITION_BOOT1_ACCESS (1 << 0)
#define PART_CFG_PARTITION_BOOT2_ACCESS (2 << 0)
#define PART_CFG_PARTITION_RPMB_ACCESS (3 << 0)
#define PART_CFG_PARTITION_GP1_ACCESS (4 << 0)
#define PART_CFG_PARTITION_GP2_ACCESS (5 << 0)
#define PART_CFG_PARTITION_GP3_ACCESS (6 << 0)
#define PART_CFG_PARTITION_GP4_ACCESS (7 << 0)
/* values in EXT CSD register */
#define EMMC_BUS_WIDTH_1 0
#define EMMC_BUS_WIDTH_4 1
#define EMMC_BUS_WIDTH_8 2
#define EMMC_BOOT_MODE_BACKWARD (0 << 3)
#define EMMC_BOOT_MODE_HS_TIMING (1 << 3)
#define EMMC_BOOT_MODE_DDR (2 << 3)
#define EXTCSD_SET_CMD (0 << 24)
#define EXTCSD_SET_BITS (1 << 24)
#define EXTCSD_CLR_BITS (2 << 24)
#define EXTCSD_WRITE_BYTES (3 << 24)
#define EXTCSD_CMD(x) (((x) & 0xff) << 16)
#define EXTCSD_VALUE(x) (((x) & 0xff) << 8)
#define STATUS_CURRENT_STATE(x) (((x) & 0xf) << 9)
#define STATUS_READY_FOR_DATA (1 << 8)
#define STATUS_SWITCH_ERROR (1 << 7)
#define EMMC_GET_STATE(x) (((x) >> 9) & 0xf)
#define EMMC_STATE_IDLE 0
#define EMMC_STATE_READY 1
#define EMMC_STATE_IDENT 2
#define EMMC_STATE_STBY 3
#define EMMC_STATE_TRAN 4
#define EMMC_STATE_DATA 5
#define EMMC_STATE_RCV 6
#define EMMC_STATE_PRG 7
#define EMMC_STATE_DIS 8
#define EMMC_STATE_BTST 9
#define EMMC_STATE_SLP 10
#define EMMC_FLAG_CMD23 (1 << 0)
typedef enum {
EMMC_PARTITION_BOOT1 = 1,
EMMC_PARTITION_BOOT2 = 2,
EMMC_PARTITION_RPMB = 3,
EMMC_PARTITION_GP1 = 4,
EMMC_PARTITION_GP2 = 5,
EMMC_PARTITION_GP3 = 6,
EMMC_PARTITION_GP4 = 7,
EMMC_PARTITION_UDA = 8,
EMMC_PARTITION_MAX = 0xFF
} emmc_partition_type;
typedef struct emmc_cmd {
unsigned int cmd_idx;
unsigned int cmd_arg;
unsigned int resp_type;
unsigned int resp_data[4];
} emmc_cmd_t;
typedef struct emmc_ops {
void (*init)(void);
void (*reset)(void);
int (*send_cmd)(emmc_cmd_t *cmd);
int (*set_ios)(int clk, int width);
int (*prepare)(int lba, uintptr_t buf, size_t size);
int (*read)(int lba, uintptr_t buf, size_t size);
int (*write)(int lba, const uintptr_t buf, size_t size);
} emmc_ops_t;
typedef struct emmc_cid {
unsigned int manufacturing_date : 8;
unsigned int product_serial_low : 24;
unsigned short product_serial_high : 8;
unsigned short product_revision : 8;
char product_name[6];
unsigned int oem_application_id : 8;
unsigned int card_bga : 2;
unsigned int reserverd_0 : 6;
unsigned int manufacturer_id : 8;
unsigned int reserved_1 : 8; /*dw spec page 231 response135-104 */
} emmc_cid_t;
typedef struct emmc_csd {
/*data0*/
unsigned int ecc : 2;
unsigned int file_format : 2;
unsigned int tmp_write_protect : 1;
unsigned int perm_write_protect : 1;
unsigned int copy : 1;
unsigned int file_format_grp : 1;
unsigned int content_prot_app : 1;
unsigned int reserved_1 : 4;
unsigned int write_bl_partial : 1;
unsigned int write_bl_len : 4;
unsigned int r2w_factor : 3;
unsigned int default_ecc : 2;
unsigned int wp_grp_enable : 1;
unsigned int wp_grp_size : 5;
unsigned int erase_grp_mult_low : 3;
/*data1*/
unsigned int erase_grp_mult_high : 2;
unsigned int erase_grp_size : 5;
unsigned int c_size_mult : 3;
unsigned int vdd_w_curr_max : 3;
unsigned int vdd_w_curr_min : 3;
unsigned int vdd_r_curr_max : 3;
unsigned int vdd_r_curr_min : 3;
unsigned int c_size_low : 10;
/*data2*/
unsigned int c_size_high : 2;
unsigned int reserved_2 : 2;
unsigned int dsr_imp : 1;
unsigned int read_blk_misalign : 1;
unsigned int write_blk_misalign : 1;
unsigned int read_bl_partial : 1;
unsigned int read_bl_len : 4;
unsigned int ccc : 12;
unsigned int tran_speed : 8;
/*data3*/
unsigned int nsac : 8; /*bit 104*/
unsigned int taac : 8;
unsigned int reserved_3 : 2;
unsigned int spec_vers : 4;
unsigned int csd_structure : 2;
unsigned int reserved_4 : 8; /*dw spec page 231 response135-104 */
} emmc_csd_t;
size_t emmc_read_blocks(int lba, uintptr_t buf, size_t size);
size_t emmc_write_blocks(int lba, const uintptr_t buf, size_t size);
size_t emmc_erase_blocks(int lba, size_t size);
size_t emmc_partition_read_blocks(emmc_partition_type type, int lba, uintptr_t buf, size_t size);
size_t emmc_partition_write_blocks(emmc_partition_type type, int lba, const uintptr_t buf, size_t size);
size_t emmc_partition_erase_blocks(emmc_partition_type type, int lba, size_t size);
int emmc_init(const emmc_ops_t *ops, int clk, int bus_width, unsigned int flags);
size_t emmc_read_block_cmd8(int lba, uintptr_t buf, size_t size);
size_t emmc_boot1_read_blocks(int lba, uintptr_t buf, size_t size);
size_t emmc_boot1_write_blocks(int lba, uintptr_t buf, size_t size);
void emmc_ut(void);
#include <cv_emmc.h>
#endif /* __EMMC_H__ */

View File

@@ -118,12 +118,13 @@ void set_rtc_en_registers(void);
void apply_analog_trimming_data(void);
void sys_pll_init(enum CHIP_CLK_MODE mode);
void sys_pll_init(void);
void sys_switch_all_to_pll(void);
void lock_efuse_chipsn(void);
int load_ddr(void);
int load_rest(enum CHIP_CLK_MODE mode);
int load_rest(void);
void jump_to_warmboot_entry(void);
#endif /* __ASSEMBLY__ */

View File

@@ -39,6 +39,19 @@
#define RTC_INFO2 (REG_RTC_BASE + 0x24)
#define RTC_INFO3 (REG_RTC_BASE + 0x28)
/*
* "FSM state change to ST_ON from the state
* 4'h0 = state changed from ST_OFF to ST_ON
* 4'h3 = state changed to ST_PWR_CYC or ST_WARM_RESET then back to ST_ON
* 4'h9 = state changed from ST_SUSP to ST_ON
*/
#define COLD_BOOT 0x0
#define WARM_BOOT 0x3
#define SYS_RESUME 0x9
#define CVI_SAPD_FLAG 0x53415044
#define MCU_FLAG 0x8051
#define REG_RTC_ST_ON_REASON (REG_RTC_BASE + RTC_ST_ON_REASON)
#define RTCSYS_F32KLESS_BASE (RTC_SYS_BASE + 0x0002A000)
@@ -46,4 +59,12 @@
#define RTC_INTERNAL_32K 0
#define RTC_EXTERNAL_32K 1
#define PLAT_BM_TRUSTED_MAILBOX_BASE 0x0E000008
#define PLAT_BM_TRUSTED_MAILBOX_SIZE 8
#define RTC_SRAM_FLAG_ADDR (RTC_CORE_SRAM_BASE + RTC_CORE_SRAM_SIZE - 8)
#define RTC_SRAM_TRUSTED_MAILBOX_BASE (RTC_SRAM_FLAG_ADDR - PLAT_BM_TRUSTED_MAILBOX_SIZE)
#define BL31_WARMBOOT_ENTRY 0x80000040
#endif /* __RTC_H__ */

View File

@@ -11,8 +11,9 @@
#include <rom_api.h>
#include "ddr_pkg_info.h"
#include "rtc.h"
#include <ddr_sys.h>
#include <rtc.h>
extern enum CHIP_CLK_MODE chip_clk_mode;
void panic_handler(void)
{
void *ra;
@@ -135,6 +136,7 @@ void sys_switch_all_to_pll(void)
// Switch all clocks to PLL
mmio_write_32(0x03002030, 0x0); // REG_CLK_BYPASS_SEL0_REG
mmio_write_32(0x03002034, 0x0); // REG_CLK_BYPASS_SEL1_REG
NOTICE("sys_switch_all_to_pll...\n");
}
void sys_pll_od(void)
@@ -144,7 +146,7 @@ void sys_pll_od(void)
uint32_t byp0_value;
uint32_t pll_syn_set[] = {
614400000, // set apll synthesizer 98.304 M
614440960, // set apll synthesizer 98.304 M
610080582, // set disp synthesizer 99 M
610080582, // set cam0 synthesizer 99 M
586388132, // set cam1 synthesizer 103 M
@@ -197,10 +199,6 @@ void sys_pll_od(void)
// set mpll = 1050MHz
mmio_write_32(0x03002908, 0x05548101);
// set clk_sel_23: [23] clk_sel for clk_c906_0 = 1 (DIV_IN0_SRC_MUX)
// set clk_sel_24: [24] clk_sel for clk_c906_1 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x01800000);
// set div, src_mux of clk_c906_0: [20:16]div_factor=1, [9:8]clk_src = 3 (mpll), 1050/1 = 1050MHz
mmio_write_32(0x03002130, 0x00010309);
@@ -210,9 +208,6 @@ void sys_pll_od(void)
// set mpll = 1000MHz
mmio_write_32(0x03002908, 0x05508101);
// set clk_sel_0: [0] clk_sel for clk_a53 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x00000001);
// set div, src_mux of clk_a53: [20:16]div_factor=1, [9:8]clk_src = 3 (mpll)
mmio_write_32(0x03002040, 0x00010309);
#endif
@@ -222,7 +217,7 @@ void sys_pll_od(void)
mmio_write_32(0x03002048, 0x00030009); //clk_cpu_axi0 = FPLL(1500) / 3
mmio_write_32(0x03002054, 0x00020009); //clk_tpu = TPLL(1400) / 2 = 700MHz
mmio_write_32(0x03002064, 0x00080009); //clk_emmc = FPLL(1500) / 8 = 187.5MHz
mmio_write_32(0x03002064, 0x00040009); //clk_emmc = FPLL(1500) / 4 = 375MHz
mmio_write_32(0x03002088, 0x00080009); //clk_spi_nand = FPLL(1500) / 8 = 187.5MHz
mmio_write_32(0x03002098, 0x00200009); //clk_sdma_aud0 = APLL(786.432) / 32 = 24.576MHz
mmio_write_32(0x03002120, 0x000F0009); //clk_pwm_src = FPLL(1500) / 15 = 100MHz
@@ -251,6 +246,16 @@ void sys_pll_od(void)
//wait for pll stable
udelay(200);
#ifdef __riscv
// set clk_sel_23: [23] clk_sel for clk_c906_0 = 1 (DIV_IN0_SRC_MUX)
// set clk_sel_24: [24] clk_sel for clk_c906_1 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x01800000);
#else
// set clk_sel_0: [0] clk_sel for clk_a53 = 1 (DIV_IN0_SRC_MUX)
// set clk_sel_24: [24] clk_sel for clk_c906_1 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x01000001);
#endif
// switch clock to PLL from xtal except clk_axi4 & clk_spi_nand
byp0_value &= (1 << 8 | //clk_spi_nand
1 << 19 //clk_axi4
@@ -266,7 +271,7 @@ void sys_pll_nd(int vc_overdrive)
uint32_t byp0_value;
uint32_t pll_syn_set[] = {
614400000, // set apll synthesizer 98.304 M
614440960, // set apll synthesizer 98.304 M
610080582, // set disp synthesizer 99 M
610080582, // set cam0 synthesizer 99 M
615164587, // set cam1 synthesizer 98.18181818 M
@@ -327,10 +332,6 @@ void sys_pll_nd(int vc_overdrive)
// set mpll = 850MHz
mmio_write_32(0x03002908, 0x00448101);
// set clk_sel_23: [23] clk_sel for clk_c906_0 = 1 (DIV_IN0_SRC_MUX)
// set clk_sel_24: [24] clk_sel for clk_c906_1 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x01800000);
// set div, src_mux of clk_c906_0: [20:16]div_factor=1, [9:8]clk_src = 3 (mpll), 850/1 = 850MHz
mmio_write_32(0x03002130, 0x00010309);
@@ -340,9 +341,6 @@ void sys_pll_nd(int vc_overdrive)
// set mpll = 800MHz
mmio_write_32(0x03002908, 0x00408101);
// set clk_sel_0: [0] clk_sel for clk_a53 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x00000001);
// set div, src_mux of clk_a53: [20:16]div_factor=1, [9:8]clk_src = 3 (mpll)
mmio_write_32(0x03002040, 0x00010309);
#endif
@@ -358,7 +356,7 @@ void sys_pll_nd(int vc_overdrive)
#endif
mmio_write_32(0x03002048, 0x00030009); //clk_cpu_axi0 = FPLL(1500) / 3
mmio_write_32(0x03002064, 0x00080009); //clk_emmc = FPLL(1500) / 8 = 187.5MHz
mmio_write_32(0x03002064, 0x00040009); //clk_emmc = FPLL(1500) / 4 = 375MHz
mmio_write_32(0x03002088, 0x00080009); //clk_spi_nand = FPLL(1500) / 8 = 187.5MHz
mmio_write_32(0x03002098, 0x00120009); //clk_sdma_aud0 = APLL(442.368) / 18 = 24.576MHz
mmio_write_32(0x03002120, 0x000F0009); //clk_pwm_src = FPLL(1500) / 15 = 100MHz
@@ -396,6 +394,16 @@ void sys_pll_nd(int vc_overdrive)
//wait for pll stable
udelay(200);
#ifdef __riscv
// set clk_sel_23: [23] clk_sel for clk_c906_0 = 1 (DIV_IN0_SRC_MUX)
// set clk_sel_24: [24] clk_sel for clk_c906_1 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x01800000);
#else
// set clk_sel_0: [0] clk_sel for clk_a53 = 1 (DIV_IN0_SRC_MUX)
// set clk_sel_24: [24] clk_sel for clk_c906_1 = 1 (DIV_IN0_SRC_MUX)
mmio_write_32(0x03002020, 0x01000001);
#endif
// switch clock to PLL from xtal except clk_axi4 & clk_spi_nand
byp0_value &= (1 << 8 | //clk_spi_nand
1 << 19 //clk_axi4
@@ -405,9 +413,9 @@ void sys_pll_nd(int vc_overdrive)
NOTICE("PLLE.\n");
}
void sys_pll_init(enum CHIP_CLK_MODE mode)
void sys_pll_init(void)
{
switch (mode) {
switch (chip_clk_mode) {
case CLK_VC_OD:
sys_pll_nd(1);
break;
@@ -422,16 +430,87 @@ void sys_pll_init(enum CHIP_CLK_MODE mode)
}
#ifndef NO_DDR_CFG //for fpga
static void *get_warmboot_entry(void)
{
/*
* "FSM state change to ST_ON from the state
* 4'h0 = state changed from ST_OFF to ST_ON
* 4'h3 = state changed to ST_PWR_CYC or ST_WARM_RESET then back to ST_ON
* 4'h9 = state changed from ST_SUSP to ST_ON
*/
#define WANTED_STATE SYS_RESUME
NOTICE("\nREG_RTC_ST_ON_REASON=0x%x\n", mmio_read_32(REG_RTC_ST_ON_REASON));
NOTICE("\nRTC_SRAM_FLAG_ADDR%x=0x%x\n", RTC_SRAM_FLAG_ADDR, mmio_read_32(RTC_SRAM_FLAG_ADDR));
/* Check if RTC state changed from ST_SUSP */
if ((mmio_read_32(REG_RTC_ST_ON_REASON) & 0xF) == WANTED_STATE)
return (void *)(uintptr_t)mmio_read_32(RTC_SRAM_FLAG_ADDR);
return 0;
}
#endif
void rtc_set_ddr_pwrok(void)
{
mmio_setbits_32(REG_RTC_BASE + RTC_PG_REG, 0x00000001);
}
void rtc_set_rmio_pwrok(void)
{
mmio_setbits_32(REG_RTC_BASE + RTC_PG_REG, 0x00000002);
}
#ifndef NO_DDR_CFG //for fpga
static void ddr_resume(void)
{
rtc_set_ddr_pwrok();
rtc_set_rmio_pwrok();
ddr_sys_resume();
}
void jump_to_warmboot_entry(void)
{
void (*warmboot_entry)() = get_warmboot_entry();
// treat next reset as normal boot
mmio_write_64(RTC_SRAM_FLAG_ADDR, 0);
if (warmboot_entry) {
NOTICE("WE=0x%lx\n", (uintptr_t)warmboot_entry);
NOTICE("ddr resume...\n");
ddr_resume();
NOTICE("ddr resume end\n");
sys_pll_init();
sys_switch_all_to_pll();
#ifdef AARCH64
NOTICE("disable_mmu_el3 start...\n");
disable_mmu_el3();
__asm__ volatile("tlbi alle3\n");
/*DO NOT add any log after disable MMU*/
#endif
warmboot_entry();
}
}
#endif
void switch_rtc_mode_1st_stage(void)
{
uint32_t read_data;
uint32_t write_data;
uint32_t rtc_mode;
#ifdef CV181X_SUPPORT_SUSPEND_RESUME
#ifdef AARCH64
void (*warmboot_entry)(void) = get_warmboot_entry();
if (warmboot_entry == (void *)BL31_WARMBOOT_ENTRY)
if (warmboot_entry == (void *)BL31_WARMBOOT_ENTRY){
NOTICE("return %s %dwarmboot_entry\n",__func__,__LINE__);
return;
}
#endif
#ifdef CONFIG_SUSPEND
return;
#endif
@@ -471,6 +550,7 @@ void switch_rtc_mode_1st_stage(void)
// reg_clk32k_cg_en = rtc_ctrl0[11] -> 1
write_data = 0x0C000000 | (read_data & 0xffffffff) | (0x1 << 11);
mmio_write_32(REG_RTC_CTRL_BASE + RTC_CTRL0, write_data); //rtc_ctrl0
NOTICE("Switch RTC mode to xtal32k\n");
}
void switch_rtc_mode_2nd_stage(void)
@@ -497,12 +577,14 @@ void switch_rtc_mode_2nd_stage(void)
void set_rtc_en_registers(void)
{
uint32_t write_data;
#ifndef FSBL_FASTBOOT
uint32_t read_data;
read_data = mmio_read_32(REG_RTC_BASE + RTC_ST_ON_REASON);
NOTICE("st_on_reason=%x\n", read_data);
read_data = mmio_read_32(REG_RTC_BASE + RTC_ST_OFF_REASON);
NOTICE("st_off_reason=%x\n", read_data);
#endif
mmio_write_32(REG_RTC_BASE + RTC_EN_SHDN_REQ, 0x01);
while (mmio_read_32(REG_RTC_BASE + RTC_EN_SHDN_REQ) != 0x01)
@@ -520,8 +602,13 @@ void set_rtc_en_registers(void)
while (mmio_read_32(REG_RTC_BASE + RTC_EN_WDT_RST_REQ) != 0x01)
;
#ifdef CONFIG_SUSPEND
// Set rtcsys_rst_ctrl[24] = 1; bit 24 is reg_rtcsys_reset_en
mmio_setbits_32(REG_RTC_CTRL_BASE + RTC_POR_RST_CTRL, 0X1);
mmio_write_32(REG_RTC_CTRL_BASE + RTC_POR_RST_CTRL, 0X2);
#else
mmio_write_32(REG_RTC_CTRL_BASE + RTC_POR_RST_CTRL, 0X1);
#endif
// rtc_ctrl0_unlockkey
mmio_write_32(REG_RTC_CTRL_BASE + RTC_CTRL0_UNLOCKKEY, 0xAB18);

View File

@@ -38,6 +38,7 @@ INCLUDES += \
${CPU_INCLUDES} \
-Iplat/ \
-Iplat/${CHIP_ARCH}/include/uart \
-Iplat/${CHIP_ARCH}/include/emmc \
-Iplat/${CHIP_ARCH}/include \
-Iplat/${CHIP_ARCH}/include/${BOOT_CPU} \
-Ilib/utils \
@@ -62,6 +63,9 @@ DECOMPRESSION_SOURCES = \
BL2_SRCS = \
${BL_COMMON_SOURCES} \
plat/${CHIP_ARCH}/bl2/bl2_opt.c \
plat/${CHIP_ARCH}/bl2/cvi_spinand.c \
plat/${CHIP_ARCH}/emmc/emmc.c \
plat/${CHIP_ARCH}/emmc/cv_emmc.c \
lib/utils/decompress.c \
${DECOMPRESSION_SOURCES}

Binary file not shown.

Binary file not shown.

1
fsbl/plat/keys/bl_ek.key Normal file
View File

@@ -0,0 +1 @@
=<3D>ύb<><62><EFBFBD>l1#<23>9<EFBFBD>

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAzHe2sPM61Ma5DIJ8C8/khwgsFcuK2GM8zFyNxpSwUFwMIlvH
kEJAAHrzkoaZcTjCmxd+ytV3mvtEYj4+H/QHAz4+C3bqUh5jYRVXKOaB42fTylEv
tUQXBmFyuLOeISTG0UIN9KagK4G4DzKf1c6kt5zgl8d+2pGfKkqtTJhQuLZiXUiA
LKOtdbKGl0suNs2+cpXgRVESzOsQxpmLnPovVecg+bDtUpy7JHeH4YW+5Nrp2aKf
R//Qp/vUbvq0CtEecQKnPop3uP6KkipI999NCR/VUduWygcrZNBngxDAWAWCYh5z
wwEXCNEeP8EyawKAn/7X1x31XxxV2vnVqc6ijwIDAQABAoIBAQC8AQd2xO8/Xkog
eopcwhc7IgSHNdTBCt6IekHSaj2EZl6x6PoiZwg6aNM105WbSbmGqZ/oGUgUtR03
yEuPTe50yPJ70Ce8wjxWtCykau7bjkhrKyNW5PjW4Rt/QYkQqKQ3HSl/3wY/etMn
BkF5crx6KEFKziCSEHvtgyS93P+8FjKOJGDAHr59yNKzTIE07JB7489T5Cb79k7l
SJ8PlruXbtVZgvR+ztE8aWsZMiOiJmTz3i1lxkLmY6j38TVS6GeZMFiqU2Nfd5Fe
obaNGBveE+acu5ZiCFK8CjGmwMikl1HJL07uSaQGYx0ji2Zu6JsJF+JX1t9+rGsp
e5In3wmBAoGBAOstLngf5ZOFJuuFdWmpIcv6VsiXnR96YvswzGygbe6EE9bBHK9X
tZakwS26+l539xRmwHbJGEYnKXrVZxpbCnUeyBw76RMkkfUD3R6dwYAP/baM2mbd
UQFjQD760yYnAGDVksfu6ZvlWxEPKpFxZclSjYAVCKNG3bNMG+B26iLfAoGBAN6S
cePel3cPJxcELQ8P0FLAEyKFdzSGL1WmjvWFyv61IX0QDKVtGVb9CqgafbpM3dJy
yQDM2loAmTAsLuTuZ609ZT0V/Dr8V04tANPlhBPgNJsNyx5/+opwpIJAWYqaYIJs
k7m0e3VK9OO3K8BRP9LoshaxaG+5VsY35u6Bg6ZRAoGAZ2iRg057MxecWnlvfEtb
SgbEvCU2eI3nEg6OBMGyNOuskYSOaWdGuHuvWb1as8lKQpU/0btwygAUVCeb01Hu
0jr7wLZzMPCmoTbWtsylNftSEz/yFMMCCHss18SQrbj+iJXAmdsqq1r5ZRHnJNbY
6+I5x/T3vFu/xkQUCeof378CgYEAprExQQNFlzKvCQrkoEIsuL0H17Pzuk/BBbnP
mcyRYr/Pi/XIMuEJuF+dapckkLHe9C1powLJidym3jBJEsYGufWga+aaWKcC0Bbe
ZtSfXa9uVq428OnSf3qriq2dIjRKkYO2A8BLMmZoEF/wEYIIdfI25s4JtJsvhRb7
CqfPLHECgYEA4VLdshoYa4GsSmeo9BJf+pS03fZSaIpXsKH3ZObOU3dNv1qMRcqd
D9NoNGvzLgRfYsmwvZLKkh0HmPO3JtR6EpD8Ilt7xO3YZRCu9H8T7UWb4NeWLQYz
G6Ne1BwhZln0+qOONoj15AILViERRsVENpmocgcLrbyNdLhp6u3Yhv0=
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1 @@
S<>*<2A>A<EFBFBD>O<EFBFBD>h).<2E>d<EFBFBD><64>

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAxTC8N4enoV8morGtNL6JXoGvX2vuqjBl9PFeB2jNw9BDgDLV
Eu4EeMEvKgCB7+D7SjbXCkcVuELT2TuREYgEUf0YecYWg3aDBcw46wHk95x7SNLt
uzQlK5TAbH8tZd6D4GeUJrvsY3dMSH9IGVfWXo6D9YpjWfIj1tRGVwgsOHqlyxCi
i0DnTPqD+Scl0dzvlUnWWYqIbxTzSgTUlPOe90wgwxnyHgdttDrxiu5SdmBl5joo
si9lVNsXXmdUJDfvdpYLxMLuhtHfw+3qORB+PiXi+LD2ZmbKSAHnZYqmgPzXMtyD
LEpRi4NCB9znvywDUaxoT89eX3H34jI59KvMwQIDAQABAoIBAC9JdJlMaqKEEtvJ
B+QyHPcQ2mFjnKQrXwfSKd5U/6MJemZvyjDz6xaaHRlRbdd8eEZfyEmqqka5n9vk
MPGnUIHo08m/+v4jmV/2jV+t4J6QY/AexOuzoYZF8a8TAGwBZFaYACsZvaJMpXpt
K3kIW1vpiTOEsDaNnpKR7RxJ1XDlbL9FUfTGYNFL7sW2i7qko5369iN3YSG/NV3P
7v3ACk1quyegAG7QE8Hg3XACJIZZwsYmo3HBze1ZauoB6n/yWgO4hYzbGDnRS3C0
0iv5O5e7ol9v4g4q4Rfs2O0AXYnYqKdRU6s5cnSSDJ4SvKuwGiYNMzkQBY9Okf0F
kNm0nJECgYEA5A1pzqk5J6k2gkFQCjD0R5Yo8jDMzsJ6nfn+VJvM9SgYt1SSVht9
/JC8DBgPrCGB2gC9AQces04Vq9dUFMVCjVHfwc7EqRFxirZ4R5M4pPVc7rg4fN4m
TLjBNR5rF4V7zWtW0BXnaMbCbcWN89j6+XlBav1M8UpAfM/qzYpcWKcCgYEA3VsZ
8HPYWpZUyIyOC0FAxrUy8AsR9oMXtXeN4c+Y0RM1GLrGz3AOg86FfP0S1NhiFEU+
+DpS9vnQ0XEamhqHwhXQqBbzssa7ZowN7KcXQM1kH2aM6NnxZwju+et9/n6QLc+z
IVLEro0JQ4tcASbQclJFcElmXbd+/vRxz1WydFcCgYAgGOMzew3YTzCk1Jx3UryO
9st8ivHIiAbKBU2Oiv8l4ibYZsbR57yrt5NAAIL0LyMfk8sGQgJIKk1SilQDOGBN
k6Bynq9/PD1G0LfNGyN11DLoRnVs3bd2ROqsl0NrZBYwq1LkprCTRqZG3O9FytxI
EJDshgo2S8UXzAu4MikdMQKBgEuKFF8PWY0IcmSCOtMycIWfPoPWc0nZ0NR3uS6P
ZsoqsNsAmmoeBoYKi1ltD+kc8tOSEfwqAzgPZqii3X4rgZrFURCbzIx872T+dJ4H
I5NUxE9G8t1fytbroIofSD76N/+6Oporob0jmj63py0pbscktlesZMekoC0nhFNK
Hn0/AoGBAIKC8PFNhP80FHidl0FHaVpmDU2RywKLFNAAW77kTb3Jd0dgId7l6usV
AixeaMugOZNgVkbT3Zv3QJSpzvXoxazPO61IoIw7iDRZewpvC+jeVP2NSW3wv9qk
O482Gap4zEb2dnfOtjXScJDm+GmzA9IkYpROcdzxFv/jzZU+ZW/H
-----END RSA PRIVATE KEY-----