Unverified Commit ba0248b5 authored by danh-arm's avatar danh-arm Committed by GitHub
Browse files

Merge pull request #1450 from MISL-EBU-System-SW/marvell-support-v6

Marvell support for Armada 8K SoC family
parents 992a3536 23e0fe52
...@@ -18,6 +18,7 @@ tools/cert_create/src/*.o ...@@ -18,6 +18,7 @@ tools/cert_create/src/*.o
tools/cert_create/src/**/*.o tools/cert_create/src/**/*.o
tools/cert_create/cert_create tools/cert_create/cert_create
tools/cert_create/cert_create.exe tools/cert_create/cert_create.exe
tools/doimage/doimage
# GNU GLOBAL files # GNU GLOBAL files
GPATH GPATH
......
...@@ -14,5 +14,7 @@ Xilinx, Inc. ...@@ -14,5 +14,7 @@ Xilinx, Inc.
NXP Semiconductors NXP Semiconductors
Marvell International Ltd.
Individuals Individuals
----------- -----------
TF-A Build Instructions
======================
This section describes how to compile the ARM Trusted Firmware (TF-A) project for Marvell's platforms.
Build Instructions
------------------
(1) Set the cross compiler::
> export CROSS_COMPILE=/path/to/toolchain/aarch64-linux-gnu-
(2) Set path for FIP images:
Set U-Boot image path (relatively to TF-A root or absolute path)::
> export BL33=path/to/u-boot.bin
For example: if U-Boot project (and its images) is located at ~/project/u-boot,
BL33 should be ~/project/u-boot/u-boot.bin
.. note::
u-boot.bin should be used and not u-boot-spl.bin
Set MSS/SCP image path (mandatory only for Armada80x0 and Aramada8xxy)::
> export SCP_BL2=path/to/mrvl_scp_bl2*.img
(3) Armada-37x0 build requires WTP tools installation.
See below in the section "Tools Installation for Armada37x0 Builds".
Install ARM 32-bit cross compiler, which is required by building WTMI image for CM3::
> sudo apt-get install gcc-arm-linux-gnueabi
(4) Clean previous build residuals (if any)::
> make distclean
(5) Build TF-A:
There are several build options:
- DEBUG: default is without debug information (=0). in order to enable it use DEBUG=1
- LOG_LEVEL: defines the level of logging which will be purged to the default output port.
LOG_LEVEL_NONE 0
LOG_LEVEL_ERROR 10
LOG_LEVEL_NOTICE 20
LOG_LEVEL_WARNING 30
LOG_LEVEL_INFO 40
LOG_LEVEL_VERBOSE 50
- USE_COHERENT_MEM: This flag determines whether to include the coherent memory region in the
BL memory map or not.
-LLC_ENABLE: Flag defining the LLC (L3) cache state. The cache is enabled by default (LLC_ENABLE=1).
- MARVELL_SECURE_BOOT: build trusted(=1)/non trusted(=0) image, default is non trusted.
- BLE_PATH:
Points to BLE (Binary ROM extension) sources folder. Only required for A8K and A8K+ builds.
The parameter is optional, its default value is "ble".
- MV_DDR_PATH:
For A7/8K, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0,
it is used for ddr_tool build.
Usage example: MV_DDR_PATH=path/to/mv_ddr
The parameter is optional for A7/8K, when this parameter is not set, the mv_ddr
sources are expected to be located at: drivers/marvell/mv_ddr. However, the parameter
is necessary for A37x0.
- DDR_TOPOLOGY: For Armada37x0 only, the DDR topology map index/name, default is 0.
Supported Options:
- DDR3 1CS (0): DB-88F3720-DDR3-Modular (512MB); EspressoBIN (512MB)
- DDR4 1CS (1): DB-88F3720-DDR4-Modular (512MB)
- DDR3 2CS (2): EspressoBIN (1GB)
- DDR4 2CS (3): DB-88F3720-DDR4-Modular (4GB)
- DDR3 1CS (4): DB-88F3720-DDR3-Modular (1GB)
- CUSTOMER (CUST): Customer board, DDR3 1CS 512MB
- CLOCKSPRESET: For Armada37x0 only, the clock tree configuration preset including CPU and DDR frequency,
default is CPU_800_DDR_800.
- CPU_600_DDR_600 - CPU at 600 MHz, DDR at 600 MHz
- CPU_800_DDR_800 - CPU at 800 MHz, DDR at 800 MHz
- CPU_1000_DDR_800 - CPU at 1000 MHz, DDR at 800 MHz
- CPU_1200_DDR_750 - CPU at 1200 MHz, DDR at 750 MHz
- BOOTDEV: For Armada37x0 only, the flash boot device, default is SPINOR,
Currently, Armada37x0 only supports SPINOR, SPINAND, EMMCNORM and SATA:
- SPINOR - SPI NOR flash boot
- SPINAND - SPI NAND flash boot
- EMMCNORM - eMMC Download Mode
Download boot loader or program code from eMMC flash into CM3 or CA53
Requires full initialization and command sequence
- SATA - SATA device boot
- PARTNUM: For Armada37x0 only, the boot partition number, default is 0. To boot from eMMC, the value
should be aligned with the parameter in U-Boot with name of CONFIG_SYS_MMC_ENV_PART, whose
value by default is 1.
For details about CONFIG_SYS_MMC_ENV_PART, please refer to the U-Boot build instructions.
- WTMI_IMG: For Armada37x0 only, the path of the WTMI image can point to an image which does
nothing, an image which supports EFUSE or a customized CM3 firmware binary. The default image
is wtmi.bin that built from sources in WTP folder, which is the next option. If the default
image is OK, then this option should be skipped.
- WTP: For Armada37x0 only, use this parameter to point to wtptools source code directory, which
can be found as a3700_utils.zip in the release.
Usage example: WTP=/path/to/a3700_utils
- CP_NUM: Total amount of CPs (South Bridge) chips wired to the interconnected APs.
When the parameter is omitted, the build is uses the default number of CPs equal to 2.
The parameter is valid for Armada 8K-plus SoC family (PLAT=a8xxy) and results in a build of images
suitable for a8xxY SoC, where "Y" is a number of connected CPs and "xx" is a number of CPU cores.
Valid values with CP_NUM is in a range of 0 to 8.
The CPs defined by this parameter are evenly distributed across interconnected APs that in turn
are dynamically detected. For instance, if the CP_NUM=6 and the TF-A detects 2 interconnected
APs, each AP assumed to have 3 attached CPs. With the same amount of APs and CP_NUM=3, the AP0
will have 2 CPs connected and AP1 - a just single CP.
For example, in order to build the image in debug mode with log level up to 'notice' level run::
> make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 PLAT=<MARVELL_PLATFORM> all fip
And if we want to build a Armada37x0 image in debug mode with log level up to 'notice' level,
the image has the preset CPU at 1000 MHz, preset DDR3 at 800 MHz, the DDR topology of DDR3 2CS,
the image boot from SPI NOR flash partition 0, and the image is non trusted in WTP, the command
line is as following::
> make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 SECURE=0 CLOCKSPRESET=CPU_1000_DDR_800 \
DDR_TOPOLOGY=2 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 all fip
Supported MARVELL_PLATFORM are:
- a3700
- a70x0
- a70x0_amc (for AMC board)
- a70x0_cust (for customers)
- a80x0
- a80x0_mcbin (for MacciatoBin)
Special Build Flags
--------------------
- PLAT_RECOVERY_IMAGE_ENABLE: When set this option to enable secondary recovery function when build
atf. In order to build uart recovery image this operation should be disabled for a70x0 and a80x0
because of hardware limitation(boot from secondary image can interrupt uart recovery process).
This MACRO definition is set in plat/marvell/a8k/common/include/platform_def.h file
(for more information about build options, please refer to section 'Summary of build options' in TF-A user-guide:
https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/user-guide.md)
Build output
-------------
Marvell's TF-A compilation generates 7 files:
- ble.bin - BLe image
- bl1.bin - BL1 image
- bl2.bin - BL2 image
- bl31.bin - BL31 image
- fip.bin - FIP image (contains BL2, BL31 & BL33 (U-Boot) images)
- boot-image.bin - TF-A image (contains BL1 and FIP images)
- flash-image.bin - Image which contains boot-image.bin and SPL image; should be placed on the boot flash/device.
Tools Installation for Armada37x0 Builds
-----------------------------------------
Install a cross GNU ARM tool chain for building the WTMI binary.
Any cross GNU ARM tool chain that is able to build ARM Cortex M3 binaries
is suitable.
On Debian/Uboot hosts the default GNU ARM tool chain can be installed
using the following command::
> sudo apt-get install gcc-arm-linux-gnueabi
If required, the default tool chain prefix "arm-linux-gnueabi-" can be
overwritten using the environment variable CROSS_CM3.
Example for BASH shell::
> export CROSS_CM3=/opt/arm-cross/bin/arm-linux-gnueabi
Address decoding flow and address translation units of Marvell Armada 8K SoC family
+--------------------------------------------------------------------------------------------------+
| +-------------+ +--------------+ |
| | Memory +----- DRAM CS | |
|+------------+ +-----------+ +-----------+ | Controller | +--------------+ |
|| AP DMA | | | | | +-------------+ |
|| SD/eMMC | | CA72 CPUs | | AP MSS | +-------------+ |
|| MCI-0/1 | | | | | | Memory | |
|+------+-----+ +--+--------+ +--------+--+ +------------+ | Controller | +-------------+ |
| | | | | +----- Translaton | |AP | |
| | | | | | +-------------+ |Configuration| |
| | | +-----+ +-------------------------Space | |
| | | +-------------+ | CCU | +-------------+ |
| | | | MMU +---------+ Windows | +-----------+ +-------------+ |
| | +-| translation | | Lookup +---- +--------- AP SPI | |
| | +-------------+ | | | | +-------------+ |
| | +-------------+ | | | IO | +-------------+ |
| +------------| SMMU +---------+ | | Windows +--------- AP MCI0/1 | |
| | translation | +------------+ | Lookup | +-------------+ |
| +---------+---+ | | +-------------+ |
| - | | +--------- AP STM | |
| +----------------- | | +-------------+ |
| AP | | +-+---------+ |
+---------------------------------------------------------------|----------------------------------+
+-------------|-------------------------------------------------|----------------------------------+
| CP | +-------------+ +------+-----+ +-------------------+ |
| | | | | +------- SB CFG Space | |
| | | DIOB | | | +-------------------+ |
| | | Windows ----------------- IOB | +-------------------+ |
| | | Control | | Windows +------| SB PCIe-0 - PCIe2 | |
| | | | | Lookup | +-------------------+ |
| | +------+------+ | | +-------------------+ |
| | | | +------+ SB NAND | |
| | | +------+-----+ +-------------------+ |
| | | | |
| | | | |
| +------------------+ +------------+ +------+-----+ +-------------------+ |
| | Network Engine | | | | +------- SB SPI-0/SPI-1 | |
| | Security Engine | | PCIe, MSS | | RUNIT | +-------------------+ |
| | SATA, USB | | DMA | | Windows | +-------------------+ |
| | SD/eMMC | | | | Lookup +------- SB Device Bus | |
| | TDM, I2C | | | | | +-------------------+ |
| +------------------+ +------------+ +------------+ |
| |
+--------------------------------------------------------------------------------------------------+
AMB - AXI MBUS address decoding
-------------------------------
AXI to M-bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs.
- The Runit offers a second level of address windows lookup. It is used to map transaction towards
the CD BootROM, SPI0, SPI1 and Device bus (NOR).
- The Runit contains eight configurable windows. Each window defines a contiguous,
address space and the properties associated with that address space.
Unit Bank ATTR
Device-Bus DEV_BOOT_CS 0x2F
DEV_CS0 0x3E
DEV_CS1 0x3D
DEV_CS2 0x3B
DEV_CS3 0x37
SPI-0 SPI_A_CS0 0x1E
SPI_A_CS1 0x5E
SPI_A_CS2 0x9E
SPI_A_CS3 0xDE
SPI_A_CS4 0x1F
SPI_A_CS5 0x5F
SPI_A_CS6 0x9F
SPI_A_CS7 0xDF
SPI1 SPI_B_CS0 0x1A
SPI_B_CS1 0x5A
SPI_B_CS2 0x9A
SPI_B_CS3 0xDA
BOOT_ROM BOOT_ROM 0x1D
UART UART 0x01
Mandatory functions:
- marvell_get_amb_memory_map
returns the AMB windows configuration and the number of windows
Mandatory structures:
amb_memory_map - Array that include the configuration of the windows
every window/entry is a struct which has 2 parameters:
- base address of the window
- Attribute of the window
Examples:
struct addr_map_win amb_memory_map[] = {
{0xf900, AMB_DEV_CS0_ID},
};
Marvell CCU address decoding bindings
=====================================
CCU configration driver (1st stage address translation) for Marvell Armada 8K and 8K+ SoCs.
The CCU node includes a description of the address decoding configuration.
Mandatory functions:
- marvell_get_ccu_memory_map
return the CCU windows configuration and the number of windows
of the specific AP.
Mandatory structures:
ccu_memory_map - Array that includes the configuration of the windows
every window/entry is a struct which has 3 parameters:
- Base address of the window
- Size of the window
- Target-ID of the window
Example:
struct addr_map_win ccu_memory_map[] = {
{0x00000000f2000000, 0x00000000e000000, IO_0_TID}, /* IO window */
};
Marvell IO WIN address decoding bindings
=====================================
IO Window configration driver (2nd stage address translation) for Marvell Armada 8K and 8K+ SoCs.
The IO WIN includes a description of the address decoding configuration.
Transactions that are decoded by CCU windows as IO peripheral, have an additional
layer of decoding. This additional address decoding layer defines one of the
following targets:
0x0 = BootRom
0x1 = STM (Serial Trace Macro-cell, a programmer's port into trace stream)
0x2 = SPI direct access
0x3 = PCIe registers
0x4 = MCI Port
0x5 = PCIe port
Mandatory functions:
- marvell_get_io_win_memory_map
returns the IO windows configuration and the number of windows
of the specific AP.
Mandatory structures:
io_win_memory_map - Array that include the configuration of the windows
every window/entry is a struct which has 3 parameters:
- Base address of the window
- Size of the window
- Target-ID of the window
Example:
struct addr_map_win io_win_memory_map[] = {
{0x00000000fe000000, 0x000000001f00000, PCIE_PORT_TID}, /* PCIe window 31Mb for PCIe port*/
{0x00000000ffe00000, 0x000000000100000, PCIE_REGS_TID}, /* PCI-REG window 64Kb for PCIe-reg*/
{0x00000000f6000000, 0x000000000100000, MCIPHY_TID}, /* MCI window 1Mb for PHY-reg*/
};
Marvell IOB address decoding bindings
=====================================
IO bridge configration driver (3rd stage address translation) for Marvell Armada 8K and 8K+ SoCs.
The IOB includes a description of the address decoding configuration.
IOB supports up to n (in CP110 n=24) windows for external memory transaction.
When a transaction passes through the IOB, its address is compared to each of
the enabled windows. If there is a hit and it passes the security checks, it is
advanced to the target port.
Mandatory functions:
- marvell_get_iob_memory_map
returns the IOB windows configuration and the number of windows
Mandatory structures:
iob_memory_map - Array that include the configuration of the windows
every window/entry is a struct which has 3 parameters:
- Base address of the window
- Size of the window
- Target-ID of the window
Target ID options:
- 0x0 = Internal configuration space
- 0x1 = MCI0
- 0x2 = PEX1_X1
- 0x3 = PEX2_X1
- 0x4 = PEX0_X4
- 0x5 = NAND flash
- 0x6 = RUNIT (NOR/SPI/BootRoom)
- 0x7 = MCI1
Example:
struct addr_map_win iob_memory_map[] = {
{0x00000000f7000000, 0x0000000001000000, PEX1_TID}, /* PEX1_X1 window */
{0x00000000f8000000, 0x0000000001000000, PEX2_TID}, /* PEX2_X1 window */
{0x00000000f6000000, 0x0000000001000000, PEX0_TID}, /* PEX0_X4 window */
{0x00000000f9000000, 0x0000000001000000, NAND_TID} /* NAND window */
};
TF-A Porting Guide
=================
This section describes how to port TF-A to a customer board, assuming that the SoC being used is already supported
in TF-A.
Source Code Structure
---------------------
- The customer platform specific code shall reside under "plat/marvell/<soc family>/<soc>_cust"
(e.g. 'plat/marvell/a8k/a7040_cust').
- The platform name for build purposes is called "<soc>_cust" (e.g. a7040_cust).
- The build system will reuse all files from within the soc directory, and take only the porting
files from the customer platform directory.
Files that require porting are located at "plat/marvell/<soc family>/<soc>_cust" directory.
Armada-70x0/Armada-80x0 Porting
-------------------------------
- SoC Physical Address Map (marvell_plat_config.c):
- This file describes the SoC physical memory mapping to be used for the CCU, IOWIN, AXI-MBUS and IOB
address decode units (Refer to the functional spec for more details).
- In most cases, using the default address decode windows should work OK.
- In cases where a special physical address map is needed (e.g. Special size for PCIe MEM windows,
large memory mapped SPI flash...), then porting of the SoC memory map is required.
- Note: For a detailed information on how CCU, IOWIN, AXI-MBUS & IOB work, please refer to the SoC functional spec,
and under "docs/marvell/misc/mvebu-[ccu/iob/amb/io-win].txt" files.
- boot loader recovery (marvell_plat_config.c):
- Background:
boot rom can skip the current image and choose to boot from next position if a specific value
(0xDEADB002) is returned by the ble main function. This feature is used for boot loader recovery
by booting from a valid flash-image saved in next position on flash (e.g. address 2M in SPI flash).
Supported options to implement the skip request are:
- GPIO
- I2C
- User defined
- Porting:
Under marvell_plat_config.c, implement struct skip_image that includes specific board parameters.
.. warning:: to disable this feature make sure the struct skip_image is not implemented.
- Example:
In A7040-DB specific implementation (plat/marvell/a8k/a70x0/board/marvell_plat_config.c),
the image skip is implemented using GPIO: mpp 33 (SW5).
Before resetting the board make sure there is a valid image on the next flash address:
-tftp [valid address] flash-image.bin
-sf update [valid address] 0x2000000 [size]
Press reset and keep pressing the button connected to the chosen GPIO pin. A skip image request
message is printed on the screen and boot rom boots from the saved image at the next position.
- DDR Porting (dram_port.c):
- This file defines the dram topology and parameters of the target board.
- The DDR code is part of the BLE component, which is an extension of ARM Trusted Firmware (TF-A).
- The DDR driver called mv_ddr is released separately apart from TF-A sources.
- The BLE and consequently, the DDR init code is executed at the early stage of the boot process.
- Each supported platform of the TF-A has its own DDR porting file called dram_port.c located at
``atf/plat/marvell/a8k/<platform>/board`` directory.
- Please refer to '<path_to_mv_ddr_sources>/doc/porting_guide.txt' for detailed porting description.
- The build target directory is "build/<platform>/release/ble".
...@@ -372,7 +372,6 @@ static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, ...@@ -372,7 +372,6 @@ static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
uintptr_t backend_handle; uintptr_t backend_handle;
assert(entity != NULL); assert(entity != NULL);
assert(buffer != (uintptr_t)NULL);
assert(length_read != NULL); assert(length_read != NULL);
assert(entity->info != (uintptr_t)NULL); assert(entity->info != (uintptr_t)NULL);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <io_driver.h> #include <io_driver.h>
#include <io_memmap.h> #include <io_memmap.h>
#include <io_storage.h> #include <io_storage.h>
#include <platform_def.h>
#include <string.h> #include <string.h>
#include <utils.h> #include <utils.h>
...@@ -169,7 +170,6 @@ static int memmap_block_read(io_entity_t *entity, uintptr_t buffer, ...@@ -169,7 +170,6 @@ static int memmap_block_read(io_entity_t *entity, uintptr_t buffer,
size_t pos_after; size_t pos_after;
assert(entity != NULL); assert(entity != NULL);
assert(buffer != (uintptr_t)NULL);
assert(length_read != NULL); assert(length_read != NULL);
fp = (file_state_t *) entity->info; fp = (file_state_t *) entity->info;
...@@ -197,7 +197,6 @@ static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer, ...@@ -197,7 +197,6 @@ static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer,
size_t pos_after; size_t pos_after;
assert(entity != NULL); assert(entity != NULL);
assert(buffer != (uintptr_t)NULL);
assert(length_written != NULL); assert(length_written != NULL);
fp = (file_state_t *) entity->info; fp = (file_state_t *) entity->info;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <io_driver.h> #include <io_driver.h>
#include <io_semihosting.h> #include <io_semihosting.h>
#include <io_storage.h> #include <io_storage.h>
#include <platform_def.h>
#include <semihosting.h> #include <semihosting.h>
...@@ -133,7 +134,6 @@ static int sh_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, ...@@ -133,7 +134,6 @@ static int sh_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
long file_handle; long file_handle;
assert(entity != NULL); assert(entity != NULL);
assert(buffer != (uintptr_t)NULL);
assert(length_read != NULL); assert(length_read != NULL);
file_handle = (long)entity->info; file_handle = (long)entity->info;
...@@ -158,7 +158,6 @@ static int sh_file_write(io_entity_t *entity, const uintptr_t buffer, ...@@ -158,7 +158,6 @@ static int sh_file_write(io_entity_t *entity, const uintptr_t buffer,
size_t bytes = length; size_t bytes = length;
assert(entity != NULL); assert(entity != NULL);
assert(buffer != (uintptr_t)NULL);
assert(length_written != NULL); assert(length_written != NULL);
file_handle = (long)entity->info; file_handle = (long)entity->info;
......
...@@ -279,7 +279,7 @@ int io_read(uintptr_t handle, ...@@ -279,7 +279,7 @@ int io_read(uintptr_t handle,
size_t *length_read) size_t *length_read)
{ {
int result = -ENODEV; int result = -ENODEV;
assert(is_valid_entity(handle) && (buffer != (uintptr_t)NULL)); assert(is_valid_entity(handle));
io_entity_t *entity = (io_entity_t *)handle; io_entity_t *entity = (io_entity_t *)handle;
...@@ -299,7 +299,7 @@ int io_write(uintptr_t handle, ...@@ -299,7 +299,7 @@ int io_write(uintptr_t handle,
size_t *length_written) size_t *length_written)
{ {
int result = -ENODEV; int result = -ENODEV;
assert(is_valid_entity(handle) && (buffer != (uintptr_t)NULL)); assert(is_valid_entity(handle));
io_entity_t *entity = (io_entity_t *)handle; io_entity_t *entity = (io_entity_t *)handle;
......
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
/* AXI to M-Bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs */
#include <a8k_common.h>
#include <debug.h>
#include <mmio.h>
#include <mvebu.h>
#include <mvebu_def.h>
#if LOG_LEVEL >= LOG_LEVEL_INFO
#define DEBUG_ADDR_MAP
#endif
/* common defines */
#define WIN_ENABLE_BIT (0x1)
#define MVEBU_AMB_ADEC_OFFSET (0x70ff00)
#define AMB_WIN_CR_OFFSET(win) (amb_base + 0x0 + (0x8 * win))
#define AMB_ATTR_OFFSET 8
#define AMB_ATTR_MASK 0xFF
#define AMB_SIZE_OFFSET 16
#define AMB_SIZE_MASK 0xFF
#define AMB_WIN_BASE_OFFSET(win) (amb_base + 0x4 + (0x8 * win))
#define AMB_BASE_OFFSET 16
#define AMB_BASE_ADDR_MASK ((1 << (32 - AMB_BASE_OFFSET)) - 1)
#define AMB_WIN_ALIGNMENT_64K (0x10000)
#define AMB_WIN_ALIGNMENT_1M (0x100000)
uintptr_t amb_base;
static void amb_check_win(struct addr_map_win *win, uint32_t win_num)
{
uint32_t base_addr;
/* make sure the base address is in 16-bit range */
if (win->base_addr > AMB_BASE_ADDR_MASK) {
WARN("Window %d: base address is too big 0x%llx\n",
win_num, win->base_addr);
win->base_addr = AMB_BASE_ADDR_MASK;
WARN("Set the base address to 0x%llx\n", win->base_addr);
}
base_addr = win->base_addr << AMB_BASE_OFFSET;
/* for AMB The base is always 1M aligned */
/* check if address is aligned to 1M */
if (IS_NOT_ALIGN(base_addr, AMB_WIN_ALIGNMENT_1M)) {
win->base_addr = ALIGN_UP(base_addr, AMB_WIN_ALIGNMENT_1M);
WARN("Window %d: base address unaligned to 0x%x\n",
win_num, AMB_WIN_ALIGNMENT_1M);
WARN("Align up the base address to 0x%llx\n", win->base_addr);
}
/* size parameter validity check */
if (!IS_POWER_OF_2(win->win_size)) {
WARN("Window %d: window size is not power of 2 (0x%llx)\n",
win_num, win->win_size);
win->win_size = ROUND_UP_TO_POW_OF_2(win->win_size);
WARN("Rounding size to 0x%llx\n", win->win_size);
}
}
static void amb_enable_win(struct addr_map_win *win, uint32_t win_num)
{
uint32_t ctrl, base, size;
/*
* size is 64KB granularity.
* The number of ones specifies the size of the
* window in 64 KB granularity. 0 is 64KB
*/
size = (win->win_size / AMB_WIN_ALIGNMENT_64K) - 1;
ctrl = (size << AMB_SIZE_OFFSET) | (win->target_id << AMB_ATTR_OFFSET);
base = win->base_addr << AMB_BASE_OFFSET;
mmio_write_32(AMB_WIN_BASE_OFFSET(win_num), base);
mmio_write_32(AMB_WIN_CR_OFFSET(win_num), ctrl);
/* enable window after configuring window size (and attributes) */
ctrl |= WIN_ENABLE_BIT;
mmio_write_32(AMB_WIN_CR_OFFSET(win_num), ctrl);
}
#ifdef DEBUG_ADDR_MAP
static void dump_amb_adec(void)
{
uint32_t ctrl, base, win_id, attr;
uint32_t size, size_count;
/* Dump all AMB windows */
tf_printf("bank attribute base size\n");
tf_printf("--------------------------------------------\n");
for (win_id = 0; win_id < AMB_MAX_WIN_ID; win_id++) {
ctrl = mmio_read_32(AMB_WIN_CR_OFFSET(win_id));
if (ctrl & WIN_ENABLE_BIT) {
base = mmio_read_32(AMB_WIN_BASE_OFFSET(win_id));
attr = (ctrl >> AMB_ATTR_OFFSET) & AMB_ATTR_MASK;
size_count = (ctrl >> AMB_SIZE_OFFSET) & AMB_SIZE_MASK;
size = (size_count + 1) * AMB_WIN_ALIGNMENT_64K;
tf_printf("amb 0x%04x 0x%08x 0x%08x\n",
attr, base, size);
}
}
}
#endif
int init_amb_adec(uintptr_t base)
{
struct addr_map_win *win;
uint32_t win_id, win_reg;
uint32_t win_count;
INFO("Initializing AXI to MBus Bridge Address decoding\n");
/* Get the base address of the AMB address decoding */
amb_base = base + MVEBU_AMB_ADEC_OFFSET;
/* Get the array of the windows and its size */
marvell_get_amb_memory_map(&win, &win_count, base);
if (win_count <= 0)
INFO("no windows configurations found\n");
if (win_count > AMB_MAX_WIN_ID) {
INFO("number of windows is bigger than %d\n", AMB_MAX_WIN_ID);
return 0;
}
/* disable all AMB windows */
for (win_id = 0; win_id < AMB_MAX_WIN_ID; win_id++) {
win_reg = mmio_read_32(AMB_WIN_CR_OFFSET(win_id));
win_reg &= ~WIN_ENABLE_BIT;
mmio_write_32(AMB_WIN_CR_OFFSET(win_id), win_reg);
}
/* enable relevant windows */
for (win_id = 0; win_id < win_count; win_id++, win++) {
amb_check_win(win, win_id);
amb_enable_win(win, win_id);
}
#ifdef DEBUG_ADDR_MAP
dump_amb_adec();
#endif
INFO("Done AXI to MBus Bridge Address decoding Initializing\n");
return 0;
}
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
/* LLC driver is the Last Level Cache (L3C) driver
* for Marvell SoCs in AP806, AP807, and AP810
*/
#include <arch_helpers.h>
#include <assert.h>
#include <cache_llc.h>
#include <ccu.h>
#include <mmio.h>
#include <mvebu_def.h>
#define CCU_HTC_CR(ap_index) (MVEBU_CCU_BASE(ap_index) + 0x200)
#define CCU_SET_POC_OFFSET 5
extern void ca72_l2_enable_unique_clean(void);
void llc_cache_sync(int ap_index)
{
mmio_write_32(LLC_SYNC(ap_index), 0);
/* Atomic write, no need to wait */
}
void llc_flush_all(int ap_index)
{
mmio_write_32(L2X0_CLEAN_INV_WAY(ap_index), LLC_WAY_MASK);
llc_cache_sync(ap_index);
}
void llc_clean_all(int ap_index)
{
mmio_write_32(L2X0_CLEAN_WAY(ap_index), LLC_WAY_MASK);
llc_cache_sync(ap_index);
}
void llc_inv_all(int ap_index)
{
mmio_write_32(L2X0_INV_WAY(ap_index), LLC_WAY_MASK);
llc_cache_sync(ap_index);
}
void llc_disable(int ap_index)
{
llc_flush_all(ap_index);
mmio_write_32(LLC_CTRL(ap_index), 0);
dsbishst();
}
void llc_enable(int ap_index, int excl_mode)
{
uint32_t val;
dsbsy();
llc_inv_all(ap_index);
dsbsy();
val = LLC_CTRL_EN;
if (excl_mode)
val |= LLC_EXCLUSIVE_EN;
mmio_write_32(LLC_CTRL(ap_index), val);
dsbsy();
}
int llc_is_exclusive(int ap_index)
{
uint32_t reg;
reg = mmio_read_32(LLC_CTRL(ap_index));
if ((reg & (LLC_CTRL_EN | LLC_EXCLUSIVE_EN)) ==
(LLC_CTRL_EN | LLC_EXCLUSIVE_EN))
return 1;
return 0;
}
void llc_runtime_enable(int ap_index)
{
uint32_t reg;
reg = mmio_read_32(LLC_CTRL(ap_index));
if (reg & LLC_CTRL_EN)
return;
INFO("Enabling LLC\n");
/*
* Enable L2 UniqueClean evictions with data
* Note: this configuration assumes that LLC is configured
* in exclusive mode.
* Later on in the code this assumption will be validated
*/
ca72_l2_enable_unique_clean();
llc_enable(ap_index, 1);
/* Set point of coherency to DDR.
* This is required by units which have SW cache coherency
*/
reg = mmio_read_32(CCU_HTC_CR(ap_index));
reg |= (0x1 << CCU_SET_POC_OFFSET);
mmio_write_32(CCU_HTC_CR(ap_index), reg);
}
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
/* CCU unit device driver for Marvell AP807, AP807 and AP810 SoCs */
#include <a8k_common.h>
#include <ccu.h>
#include <debug.h>
#include <mmio.h>
#include <mvebu.h>
#include <mvebu_def.h>
#if LOG_LEVEL >= LOG_LEVEL_INFO
#define DEBUG_ADDR_MAP
#endif
/* common defines */
#define WIN_ENABLE_BIT (0x1)
/* Physical address of the base of the window = {AddrLow[19:0],20’h0} */
#define ADDRESS_SHIFT (20 - 4)
#define ADDRESS_MASK (0xFFFFFFF0)
#define CCU_WIN_ALIGNMENT (0x100000)
#define IS_DRAM_TARGET(tgt) ((((tgt) == DRAM_0_TID) || \
((tgt) == DRAM_1_TID) || \
((tgt) == RAR_TID)) ? 1 : 0)
/* For storage of CR, SCR, ALR, AHR abd GCR */
static uint32_t ccu_regs_save[MVEBU_CCU_MAX_WINS * 4 + 1];
#ifdef DEBUG_ADDR_MAP
static void dump_ccu(int ap_index)
{
uint32_t win_id, win_cr, alr, ahr;
uint8_t target_id;
uint64_t start, end;
/* Dump all AP windows */
tf_printf("\tbank target start end\n");
tf_printf("\t----------------------------------------------------\n");
for (win_id = 0; win_id < MVEBU_CCU_MAX_WINS; win_id++) {
win_cr = mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id));
if (win_cr & WIN_ENABLE_BIT) {
target_id = (win_cr >> CCU_TARGET_ID_OFFSET) &
CCU_TARGET_ID_MASK;
alr = mmio_read_32(CCU_WIN_ALR_OFFSET(ap_index,
win_id));
ahr = mmio_read_32(CCU_WIN_AHR_OFFSET(ap_index,
win_id));
start = ((uint64_t)alr << ADDRESS_SHIFT);
end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT);
tf_printf("\tccu %02x 0x%016llx 0x%016llx\n",
target_id, start, end);
}
}
win_cr = mmio_read_32(CCU_WIN_GCR_OFFSET(ap_index));
target_id = (win_cr >> CCU_GCR_TARGET_OFFSET) & CCU_GCR_TARGET_MASK;
tf_printf("\tccu GCR %d - all other transactions\n", target_id);
}
#endif
void ccu_win_check(struct addr_map_win *win)
{
/* check if address is aligned to 1M */
if (IS_NOT_ALIGN(win->base_addr, CCU_WIN_ALIGNMENT)) {
win->base_addr = ALIGN_UP(win->base_addr, CCU_WIN_ALIGNMENT);
NOTICE("%s: Align up the base address to 0x%llx\n",
__func__, win->base_addr);
}
/* size parameter validity check */
if (IS_NOT_ALIGN(win->win_size, CCU_WIN_ALIGNMENT)) {
win->win_size = ALIGN_UP(win->win_size, CCU_WIN_ALIGNMENT);
NOTICE("%s: Aligning size to 0x%llx\n",
__func__, win->win_size);
}
}
void ccu_enable_win(int ap_index, struct addr_map_win *win, uint32_t win_id)
{
uint32_t ccu_win_reg;
uint32_t alr, ahr;
uint64_t end_addr;
if ((win_id == 0) || (win_id > MVEBU_CCU_MAX_WINS)) {
ERROR("Enabling wrong CCU window %d!\n", win_id);
return;
}
end_addr = (win->base_addr + win->win_size - 1);
alr = (uint32_t)((win->base_addr >> ADDRESS_SHIFT) & ADDRESS_MASK);
ahr = (uint32_t)((end_addr >> ADDRESS_SHIFT) & ADDRESS_MASK);
mmio_write_32(CCU_WIN_ALR_OFFSET(ap_index, win_id), alr);
mmio_write_32(CCU_WIN_AHR_OFFSET(ap_index, win_id), ahr);
ccu_win_reg = WIN_ENABLE_BIT;
ccu_win_reg |= (win->target_id & CCU_TARGET_ID_MASK)
<< CCU_TARGET_ID_OFFSET;
mmio_write_32(CCU_WIN_CR_OFFSET(ap_index, win_id), ccu_win_reg);
}
static void ccu_disable_win(int ap_index, uint32_t win_id)
{
uint32_t win_reg;
if ((win_id == 0) || (win_id > MVEBU_CCU_MAX_WINS)) {
ERROR("Disabling wrong CCU window %d!\n", win_id);
return;
}
win_reg = mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id));
win_reg &= ~WIN_ENABLE_BIT;
mmio_write_32(CCU_WIN_CR_OFFSET(ap_index, win_id), win_reg);
}
/* Insert/Remove temporary window for using the out-of reset default
* CPx base address to access the CP configuration space prior to
* the further base address update in accordance with address mapping
* design.
*
* NOTE: Use the same window array for insertion and removal of
* temporary windows.
*/
void ccu_temp_win_insert(int ap_index, struct addr_map_win *win, int size)
{
uint32_t win_id;
for (int i = 0; i < size; i++) {
win_id = MVEBU_CCU_MAX_WINS - 1 - i;
ccu_win_check(win);
ccu_enable_win(ap_index, win, win_id);
win++;
}
}
/*
* NOTE: Use the same window array for insertion and removal of
* temporary windows.
*/
void ccu_temp_win_remove(int ap_index, struct addr_map_win *win, int size)
{
uint32_t win_id;
for (int i = 0; i < size; i++) {
uint64_t base;
uint32_t target;
win_id = MVEBU_CCU_MAX_WINS - 1 - i;
target = mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id));
target >>= CCU_TARGET_ID_OFFSET;
target &= CCU_TARGET_ID_MASK;
base = mmio_read_32(CCU_WIN_ALR_OFFSET(ap_index, win_id));
base <<= ADDRESS_SHIFT;
if ((win->target_id != target) || (win->base_addr != base)) {
ERROR("%s: Trying to remove bad window-%d!\n",
__func__, win_id);
continue;
}
ccu_disable_win(ap_index, win_id);
win++;
}
}
/* Returns current DRAM window target (DRAM_0_TID, DRAM_1_TID, RAR_TID)
* NOTE: Call only once for each AP.
* The AP0 DRAM window is located at index 2 only at the BL31 execution start.
* Then it relocated to index 1 for matching the rest of APs DRAM settings.
* Calling this function after relocation will produce wrong results on AP0
*/
static uint32_t ccu_dram_target_get(int ap_index)
{
/* On BLE stage the AP0 DRAM window is opened by the BootROM at index 2.
* All the rest of detected APs will use window at index 1.
* The AP0 DRAM window is moved from index 2 to 1 during
* init_ccu() execution.
*/
const uint32_t win_id = (ap_index == 0) ? 2 : 1;
uint32_t target;
target = mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id));
target >>= CCU_TARGET_ID_OFFSET;
target &= CCU_TARGET_ID_MASK;
return target;
}
void ccu_dram_target_set(int ap_index, uint32_t target)
{
/* On BLE stage the AP0 DRAM window is opened by the BootROM at index 2.
* All the rest of detected APs will use window at index 1.
* The AP0 DRAM window is moved from index 2 to 1
* during init_ccu() execution.
*/
const uint32_t win_id = (ap_index == 0) ? 2 : 1;
uint32_t dram_cr;
dram_cr = mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id));
dram_cr &= ~(CCU_TARGET_ID_MASK << CCU_TARGET_ID_OFFSET);
dram_cr |= (target & CCU_TARGET_ID_MASK) << CCU_TARGET_ID_OFFSET;
mmio_write_32(CCU_WIN_CR_OFFSET(ap_index, win_id), dram_cr);
}
/* Setup CCU DRAM window and enable it */
void ccu_dram_win_config(int ap_index, struct addr_map_win *win)
{
#if IMAGE_BLE /* BLE */
/* On BLE stage the AP0 DRAM window is opened by the BootROM at index 2.
* Since the BootROM is not accessing DRAM at BLE stage,
* the DRAM window can be temporarely disabled.
*/
const uint32_t win_id = (ap_index == 0) ? 2 : 1;
#else /* end of BLE */
/* At the ccu_init() execution stage, DRAM windows of all APs
* are arranged at index 1.
* The AP0 still has the old window BootROM DRAM at index 2, so
* the window-1 can be safely disabled without breaking the DRAM access.
*/
const uint32_t win_id = 1;
#endif
ccu_disable_win(ap_index, win_id);
/* enable write secure (and clear read secure) */
mmio_write_32(CCU_WIN_SCR_OFFSET(ap_index, win_id),
CCU_WIN_ENA_WRITE_SECURE);
ccu_win_check(win);
ccu_enable_win(ap_index, win, win_id);
}
/* Save content of CCU window + GCR */
static void ccu_save_win_range(int ap_id, int win_first,
int win_last, uint32_t *buffer)
{
int win_id, idx;
/* Save CCU */
for (idx = 0, win_id = win_first; win_id <= win_last; win_id++) {
buffer[idx++] = mmio_read_32(CCU_WIN_CR_OFFSET(ap_id, win_id));
buffer[idx++] = mmio_read_32(CCU_WIN_SCR_OFFSET(ap_id, win_id));
buffer[idx++] = mmio_read_32(CCU_WIN_ALR_OFFSET(ap_id, win_id));
buffer[idx++] = mmio_read_32(CCU_WIN_AHR_OFFSET(ap_id, win_id));
}
buffer[idx] = mmio_read_32(CCU_WIN_GCR_OFFSET(ap_id));
}
/* Restore content of CCU window + GCR */
static void ccu_restore_win_range(int ap_id, int win_first,
int win_last, uint32_t *buffer)
{
int win_id, idx;
/* Restore CCU */
for (idx = 0, win_id = win_first; win_id <= win_last; win_id++) {
mmio_write_32(CCU_WIN_CR_OFFSET(ap_id, win_id), buffer[idx++]);
mmio_write_32(CCU_WIN_SCR_OFFSET(ap_id, win_id), buffer[idx++]);
mmio_write_32(CCU_WIN_ALR_OFFSET(ap_id, win_id), buffer[idx++]);
mmio_write_32(CCU_WIN_AHR_OFFSET(ap_id, win_id), buffer[idx++]);
}
mmio_write_32(CCU_WIN_GCR_OFFSET(ap_id), buffer[idx]);
}
void ccu_save_win_all(int ap_id)
{
ccu_save_win_range(ap_id, 0, MVEBU_CCU_MAX_WINS - 1, ccu_regs_save);
}
void ccu_restore_win_all(int ap_id)
{
ccu_restore_win_range(ap_id, 0, MVEBU_CCU_MAX_WINS - 1, ccu_regs_save);
}
int init_ccu(int ap_index)
{
struct addr_map_win *win, *dram_win;
uint32_t win_id, win_reg;
uint32_t win_count, array_id;
uint32_t dram_target;
#if IMAGE_BLE
/* In BootROM context CCU Window-1
* has SRAM_TID target and should not be disabled
*/
const uint32_t win_start = 2;
#else
const uint32_t win_start = 1;
#endif
INFO("Initializing CCU Address decoding\n");
/* Get the array of the windows and fill the map data */
marvell_get_ccu_memory_map(ap_index, &win, &win_count);
if (win_count <= 0) {
INFO("No windows configurations found\n");
} else if (win_count > (MVEBU_CCU_MAX_WINS - 1)) {
ERROR("CCU mem map array > than max available windows (%d)\n",
MVEBU_CCU_MAX_WINS);
win_count = MVEBU_CCU_MAX_WINS;
}
/* Need to set GCR to DRAM before all CCU windows are disabled for
* securing the normal access to DRAM location, which the ATF is running
* from. Once all CCU windows are set, which have to include the
* dedicated DRAM window as well, the GCR can be switched to the target
* defined by the platform configuration.
*/
dram_target = ccu_dram_target_get(ap_index);
win_reg = (dram_target & CCU_GCR_TARGET_MASK) << CCU_GCR_TARGET_OFFSET;
mmio_write_32(CCU_WIN_GCR_OFFSET(ap_index), win_reg);
/* If the DRAM window was already configured at the BLE stage,
* only the window target considered valid, the address range should be
* updated according to the platform configuration.
*/
for (dram_win = win, array_id = 0; array_id < win_count;
array_id++, dram_win++) {
if (IS_DRAM_TARGET(dram_win->target_id)) {
dram_win->target_id = dram_target;
break;
}
}
/* Disable all AP CCU windows
* Window-0 is always bypassed since it already contains
* data allowing the internal configuration space access
*/
for (win_id = win_start; win_id < MVEBU_CCU_MAX_WINS; win_id++) {
ccu_disable_win(ap_index, win_id);
/* enable write secure (and clear read secure) */
mmio_write_32(CCU_WIN_SCR_OFFSET(ap_index, win_id),
CCU_WIN_ENA_WRITE_SECURE);
}
/* win_id is the index of the current ccu window
* array_id is the index of the current memory map window entry
*/
for (win_id = win_start, array_id = 0;
((win_id < MVEBU_CCU_MAX_WINS) && (array_id < win_count));
win_id++) {
ccu_win_check(win);
ccu_enable_win(ap_index, win, win_id);
win++;
array_id++;
}
/* Get & set the default target according to board topology */
win_reg = (marvell_get_ccu_gcr_target(ap_index) & CCU_GCR_TARGET_MASK)
<< CCU_GCR_TARGET_OFFSET;
mmio_write_32(CCU_WIN_GCR_OFFSET(ap_index), win_reg);
#ifdef DEBUG_ADDR_MAP
dump_ccu(ap_index);
#endif
INFO("Done CCU Address decoding Initializing\n");
return 0;
}
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
/* Driver for COMPHY unit that is part or Marvell A8K SoCs */
#ifndef _COMPHY_H_
#define _COMPHY_H_
/* COMPHY registers */
#define COMMON_PHY_CFG1_REG 0x0
#define COMMON_PHY_CFG1_PWR_UP_OFFSET 1
#define COMMON_PHY_CFG1_PWR_UP_MASK \
(0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET)
#define COMMON_PHY_CFG1_PIPE_SELECT_OFFSET 2
#define COMMON_PHY_CFG1_PIPE_SELECT_MASK \
(0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET)
#define COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET 13
#define COMMON_PHY_CFG1_PWR_ON_RESET_MASK \
(0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET)
#define COMMON_PHY_CFG1_CORE_RSTN_OFFSET 14
#define COMMON_PHY_CFG1_CORE_RSTN_MASK \
(0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET)
#define COMMON_PHY_PHY_MODE_OFFSET 15
#define COMMON_PHY_PHY_MODE_MASK \
(0x1 << COMMON_PHY_PHY_MODE_OFFSET)
#define COMMON_SELECTOR_PHY_OFFSET 0x140
#define COMMON_SELECTOR_PIPE_OFFSET 0x144
#define COMMON_PHY_SD_CTRL1 0x148
#define COMMON_PHY_SD_CTRL1_COMPHY_0_4_PORT_OFFSET 0
#define COMMON_PHY_SD_CTRL1_COMPHY_0_4_PORT_MASK 0xFFFF
#define COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET 24
#define COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK \
(0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET)
#define COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET 25
#define COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK \
(0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET)
#define DFX_DEV_GEN_CTRL12 0x80
#define DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET 7
#define DFX_DEV_GEN_PCIE_CLK_SRC_MASK \
(0x3 << DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET)
/* HPIPE register */
#define HPIPE_PWR_PLL_REG 0x4
#define HPIPE_PWR_PLL_REF_FREQ_OFFSET 0
#define HPIPE_PWR_PLL_REF_FREQ_MASK \
(0x1f << HPIPE_PWR_PLL_REF_FREQ_OFFSET)
#define HPIPE_PWR_PLL_PHY_MODE_OFFSET 5
#define HPIPE_PWR_PLL_PHY_MODE_MASK \
(0x7 << HPIPE_PWR_PLL_PHY_MODE_OFFSET)
#define HPIPE_DFE_REG0 0x01C
#define HPIPE_DFE_RES_FORCE_OFFSET 15
#define HPIPE_DFE_RES_FORCE_MASK \
(0x1 << HPIPE_DFE_RES_FORCE_OFFSET)
#define HPIPE_G2_SET_1_REG 0x040
#define HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET 0
#define HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK \
(0x7 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET)
#define HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET 3
#define HPIPE_G2_SET_1_G2_RX_SELMUPP_MASK \
(0x7 << HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET)
#define HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET 6
#define HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK \
(0x3 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET)
#define HPIPE_G3_SETTINGS_1_REG 0x048
#define HPIPE_G3_RX_SELMUPI_OFFSET 0
#define HPIPE_G3_RX_SELMUPI_MASK \
(0x7 << HPIPE_G3_RX_SELMUPI_OFFSET)
#define HPIPE_G3_RX_SELMUPF_OFFSET 3
#define HPIPE_G3_RX_SELMUPF_MASK \
(0x7 << HPIPE_G3_RX_SELMUPF_OFFSET)
#define HPIPE_G3_SETTING_BIT_OFFSET 13
#define HPIPE_G3_SETTING_BIT_MASK \
(0x1 << HPIPE_G3_SETTING_BIT_OFFSET)
#define HPIPE_INTERFACE_REG 0x94
#define HPIPE_INTERFACE_GEN_MAX_OFFSET 10
#define HPIPE_INTERFACE_GEN_MAX_MASK \
(0x3 << HPIPE_INTERFACE_GEN_MAX_OFFSET)
#define HPIPE_INTERFACE_DET_BYPASS_OFFSET 12
#define HPIPE_INTERFACE_DET_BYPASS_MASK \
(0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET)
#define HPIPE_INTERFACE_LINK_TRAIN_OFFSET 14
#define HPIPE_INTERFACE_LINK_TRAIN_MASK \
(0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET)
#define HPIPE_VDD_CAL_CTRL_REG 0x114
#define HPIPE_EXT_SELLV_RXSAMPL_OFFSET 5
#define HPIPE_EXT_SELLV_RXSAMPL_MASK \
(0x1f << HPIPE_EXT_SELLV_RXSAMPL_OFFSET)
#define HPIPE_PCIE_REG0 0x120
#define HPIPE_PCIE_IDLE_SYNC_OFFSET 12
#define HPIPE_PCIE_IDLE_SYNC_MASK \
(0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET)
#define HPIPE_PCIE_SEL_BITS_OFFSET 13
#define HPIPE_PCIE_SEL_BITS_MASK \
(0x3 << HPIPE_PCIE_SEL_BITS_OFFSET)
#define HPIPE_LANE_ALIGN_REG 0x124
#define HPIPE_LANE_ALIGN_OFF_OFFSET 12
#define HPIPE_LANE_ALIGN_OFF_MASK \
(0x1 << HPIPE_LANE_ALIGN_OFF_OFFSET)
#define HPIPE_MISC_REG 0x13C
#define HPIPE_MISC_CLK100M_125M_OFFSET 4
#define HPIPE_MISC_CLK100M_125M_MASK \
(0x1 << HPIPE_MISC_CLK100M_125M_OFFSET)
#define HPIPE_MISC_ICP_FORCE_OFFSET 5
#define HPIPE_MISC_ICP_FORCE_MASK \
(0x1 << HPIPE_MISC_ICP_FORCE_OFFSET)
#define HPIPE_MISC_TXDCLK_2X_OFFSET 6
#define HPIPE_MISC_TXDCLK_2X_MASK \
(0x1 << HPIPE_MISC_TXDCLK_2X_OFFSET)
#define HPIPE_MISC_CLK500_EN_OFFSET 7
#define HPIPE_MISC_CLK500_EN_MASK \
(0x1 << HPIPE_MISC_CLK500_EN_OFFSET)
#define HPIPE_MISC_REFCLK_SEL_OFFSET 10
#define HPIPE_MISC_REFCLK_SEL_MASK \
(0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET)
#define HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG 0x16C
#define HPIPE_SMAPLER_OFFSET 12
#define HPIPE_SMAPLER_MASK (0x1 << HPIPE_SMAPLER_OFFSET)
#define HPIPE_PWR_CTR_DTL_REG 0x184
#define HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET 2
#define HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK \
(0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET)
#define HPIPE_FRAME_DET_CONTROL_REG 0x220
#define HPIPE_FRAME_DET_LOCK_LOST_TO_OFFSET 12
#define HPIPE_FRAME_DET_LOCK_LOST_TO_MASK \
(0x1 << HPIPE_FRAME_DET_LOCK_LOST_TO_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_0_REG 0x268
#define HPIPE_TX_TRAIN_P2P_HOLD_OFFSET 15
#define HPIPE_TX_TRAIN_P2P_HOLD_MASK \
(0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_REG 0x26C
#define HPIPE_TX_TRAIN_CTRL_G1_OFFSET 0
#define HPIPE_TX_TRAIN_CTRL_G1_MASK \
(0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_GN1_OFFSET 1
#define HPIPE_TX_TRAIN_CTRL_GN1_MASK \
(0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_G0_OFFSET 2
#define HPIPE_TX_TRAIN_CTRL_G0_MASK \
(0x1 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_4_REG 0x278
#define HPIPE_TRX_TRAIN_TIMER_OFFSET 0
#define HPIPE_TRX_TRAIN_TIMER_MASK \
(0x3FF << HPIPE_TRX_TRAIN_TIMER_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_5_REG 0x2A4
#define HPIPE_TX_TRAIN_START_SQ_EN_OFFSET 11
#define HPIPE_TX_TRAIN_START_SQ_EN_MASK \
(0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET)
#define HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET 12
#define HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK \
(0x1 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET)
#define HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET 13
#define HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK \
(0x1 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET)
#define HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET 14
#define HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK \
(0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET)
#define HPIPE_TX_TRAIN_REG 0x31C
#define HPIPE_TX_TRAIN_CHK_INIT_OFFSET 4
#define HPIPE_TX_TRAIN_CHK_INIT_MASK \
(0x1 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET)
#define HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET 7
#define HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK \
(0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET)
#define HPIPE_CDR_CONTROL_REG 0x418
#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET 14
#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK \
(0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET)
#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET 12
#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK \
(0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET)
#define HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET 9
#define HPIPE_CDR_MAX_DFE_ADAPT_0_MASK \
(0x7 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET)
#define HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET 6
#define HPIPE_CDR_MAX_DFE_ADAPT_1_MASK \
(0x7 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_11_REG 0x438
#define HPIPE_TX_STATUS_CHECK_MODE_OFFSET 6
#define HPIPE_TX_TX_STATUS_CHECK_MODE_MASK \
(0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET)
#define HPIPE_TX_NUM_OF_PRESET_OFFSET 10
#define HPIPE_TX_NUM_OF_PRESET_MASK \
(0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET)
#define HPIPE_TX_SWEEP_PRESET_EN_OFFSET 15
#define HPIPE_TX_SWEEP_PRESET_EN_MASK \
(0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET)
#define HPIPE_G2_SETTINGS_4_REG 0x44C
#define HPIPE_G2_DFE_RES_OFFSET 8
#define HPIPE_G2_DFE_RES_MASK (0x3 << HPIPE_G2_DFE_RES_OFFSET)
#define HPIPE_G3_SETTING_3_REG 0x450
#define HPIPE_G3_FFE_CAP_SEL_OFFSET 0
#define HPIPE_G3_FFE_CAP_SEL_MASK \
(0xf << HPIPE_G3_FFE_CAP_SEL_OFFSET)
#define HPIPE_G3_FFE_RES_SEL_OFFSET 4
#define HPIPE_G3_FFE_RES_SEL_MASK \
(0x7 << HPIPE_G3_FFE_RES_SEL_OFFSET)
#define HPIPE_G3_FFE_SETTING_FORCE_OFFSET 7
#define HPIPE_G3_FFE_SETTING_FORCE_MASK \
(0x1 << HPIPE_G3_FFE_SETTING_FORCE_OFFSET)
#define HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET 12
#define HPIPE_G3_FFE_DEG_RES_LEVEL_MASK \
(0x3 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET)
#define HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET 14
#define HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK \
(0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET)
#define HPIPE_G3_SETTING_4_REG 0x454
#define HPIPE_G3_DFE_RES_OFFSET 8
#define HPIPE_G3_DFE_RES_MASK (0x3 << HPIPE_G3_DFE_RES_OFFSET)
#define HPIPE_DFE_CONTROL_REG 0x470
#define HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET 14
#define HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK \
(0x3 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET)
#define HPIPE_DFE_CTRL_28_REG 0x49C
#define HPIPE_DFE_CTRL_28_PIPE4_OFFSET 7
#define HPIPE_DFE_CTRL_28_PIPE4_MASK \
(0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET)
#define HPIPE_G3_SETTING_5_REG 0x548
#define HPIPE_G3_SETTING_5_G3_ICP_OFFSET 0
#define HPIPE_G3_SETTING_5_G3_ICP_MASK \
(0xf << HPIPE_G3_SETTING_5_G3_ICP_OFFSET)
#define HPIPE_LANE_STATUS1_REG 0x60C
#define HPIPE_LANE_STATUS1_PCLK_EN_OFFSET 0
#define HPIPE_LANE_STATUS1_PCLK_EN_MASK \
(0x1 << HPIPE_LANE_STATUS1_PCLK_EN_OFFSET)
#define HPIPE_LANE_CFG4_REG 0x620
#define HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET 3
#define HPIPE_LANE_CFG4_DFE_EN_SEL_MASK \
(0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET)
#define HPIPE_LANE_EQU_CONFIG_0_REG 0x69C
#define HPIPE_CFG_EQ_FS_OFFSET 0
#define HPIPE_CFG_EQ_FS_MASK (0x3f << HPIPE_CFG_EQ_FS_OFFSET)
#define HPIPE_CFG_EQ_LF_OFFSET 6
#define HPIPE_CFG_EQ_LF_MASK (0x3f << HPIPE_CFG_EQ_LF_OFFSET)
#define HPIPE_CFG_PHY_RC_EP_OFFSET 12
#define HPIPE_CFG_PHY_RC_EP_MASK \
(0x1 << HPIPE_CFG_PHY_RC_EP_OFFSET)
#define HPIPE_LANE_EQ_CFG1_REG 0x6a0
#define HPIPE_CFG_UPDATE_POLARITY_OFFSET 12
#define HPIPE_CFG_UPDATE_POLARITY_MASK \
(0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET)
#define HPIPE_LANE_EQ_CFG2_REG 0x6a4
#define HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET 14
#define HPIPE_CFG_EQ_BUNDLE_DIS_MASK \
(0x1 << HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET)
#define HPIPE_LANE_PRESET_CFG0_REG 0x6a8
#define HPIPE_CFG_CURSOR_PRESET0_OFFSET 0
#define HPIPE_CFG_CURSOR_PRESET0_MASK \
(0x3f << HPIPE_CFG_CURSOR_PRESET0_OFFSET)
#define HPIPE_CFG_CURSOR_PRESET1_OFFSET 6
#define HPIPE_CFG_CURSOR_PRESET1_MASK \
(0x3f << HPIPE_CFG_CURSOR_PRESET1_OFFSET)
#define HPIPE_LANE_PRESET_CFG1_REG 0x6ac
#define HPIPE_CFG_CURSOR_PRESET2_OFFSET 0
#define HPIPE_CFG_CURSOR_PRESET2_MASK \
(0x3f << HPIPE_CFG_CURSOR_PRESET2_OFFSET)
#define HPIPE_CFG_CURSOR_PRESET3_OFFSET 6
#define HPIPE_CFG_CURSOR_PRESET3_MASK \
(0x3f << HPIPE_CFG_CURSOR_PRESET3_OFFSET)
#define HPIPE_LANE_PRESET_CFG2_REG 0x6b0
#define HPIPE_CFG_CURSOR_PRESET4_OFFSET 0
#define HPIPE_CFG_CURSOR_PRESET4_MASK \
(0x3f << HPIPE_CFG_CURSOR_PRESET4_OFFSET)
#define HPIPE_CFG_CURSOR_PRESET5_OFFSET 6
#define HPIPE_CFG_CURSOR_PRESET5_MASK \
(0x3f << HPIPE_CFG_CURSOR_PRESET5_OFFSET)
#define HPIPE_LANE_PRESET_CFG3_REG 0x6b4
#define HPIPE_CFG_CURSOR_PRESET6_OFFSET 0
#define HPIPE_CFG_CURSOR_PRESET6_MASK \
(0x3f << HPIPE_CFG_CURSOR_PRESET6_OFFSET)
#define HPIPE_CFG_CURSOR_PRESET7_OFFSET 6
#define HPIPE_CFG_CURSOR_PRESET7_MASK \
(0x3f << HPIPE_CFG_CURSOR_PRESET7_OFFSET)
#define HPIPE_LANE_PRESET_CFG4_REG 0x6b8
#define HPIPE_CFG_CURSOR_PRESET8_OFFSET 0
#define HPIPE_CFG_CURSOR_PRESET8_MASK \
(0x3f << HPIPE_CFG_CURSOR_PRESET8_OFFSET)
#define HPIPE_CFG_CURSOR_PRESET9_OFFSET 6
#define HPIPE_CFG_CURSOR_PRESET9_MASK \
(0x3f << HPIPE_CFG_CURSOR_PRESET9_OFFSET)
#define HPIPE_LANE_PRESET_CFG5_REG 0x6bc
#define HPIPE_CFG_CURSOR_PRESET10_OFFSET 0
#define HPIPE_CFG_CURSOR_PRESET10_MASK \
(0x3f << HPIPE_CFG_CURSOR_PRESET10_OFFSET)
#define HPIPE_CFG_CURSOR_PRESET11_OFFSET 6
#define HPIPE_CFG_CURSOR_PRESET11_MASK \
(0x3f << HPIPE_CFG_CURSOR_PRESET11_OFFSET)
#define HPIPE_LANE_PRESET_CFG6_REG 0x6c0
#define HPIPE_CFG_PRE_CURSOR_PRESET0_OFFSET 0
#define HPIPE_CFG_PRE_CURSOR_PRESET0_MASK \
(0x3f << HPIPE_CFG_PRE_CURSOR_PRESET0_OFFSET)
#define HPIPE_CFG_POST_CURSOR_PRESET0_OFFSET 6
#define HPIPE_CFG_POST_CURSOR_PRESET0_MASK \
(0x3f << HPIPE_CFG_POST_CURSOR_PRESET0_OFFSET)
#define HPIPE_LANE_PRESET_CFG7_REG 0x6c4
#define HPIPE_CFG_PRE_CURSOR_PRESET1_OFFSET 0
#define HPIPE_CFG_PRE_CURSOR_PRESET1_MASK \
(0x3f << HPIPE_CFG_PRE_CURSOR_PRESET1_OFFSET)
#define HPIPE_CFG_POST_CURSOR_PRESET1_OFFSET 6
#define HPIPE_CFG_POST_CURSOR_PRESET1_MASK \
(0x3f << HPIPE_CFG_POST_CURSOR_PRESET1_OFFSET)
#define HPIPE_LANE_PRESET_CFG8_REG 0x6c8
#define HPIPE_CFG_PRE_CURSOR_PRESET2_OFFSET 0
#define HPIPE_CFG_PRE_CURSOR_PRESET2_MASK \
(0x3f << HPIPE_CFG_PRE_CURSOR_PRESET2_OFFSET)
#define HPIPE_CFG_POST_CURSOR_PRESET2_OFFSET 6
#define HPIPE_CFG_POST_CURSOR_PRESET2_MASK \
(0x3f << HPIPE_CFG_POST_CURSOR_PRESET2_OFFSET)
#define HPIPE_LANE_PRESET_CFG9_REG 0x6cc
#define HPIPE_CFG_PRE_CURSOR_PRESET3_OFFSET 0
#define HPIPE_CFG_PRE_CURSOR_PRESET3_MASK \
(0x3f << HPIPE_CFG_PRE_CURSOR_PRESET3_OFFSET)
#define HPIPE_CFG_POST_CURSOR_PRESET3_OFFSET 6
#define HPIPE_CFG_POST_CURSOR_PRESET3_MASK \
(0x3f << HPIPE_CFG_POST_CURSOR_PRESET3_OFFSET)
#define HPIPE_LANE_PRESET_CFG10_REG 0x6d0
#define HPIPE_CFG_PRE_CURSOR_PRESET4_OFFSET 0
#define HPIPE_CFG_PRE_CURSOR_PRESET4_MASK \
(0x3f << HPIPE_CFG_PRE_CURSOR_PRESET4_OFFSET)
#define HPIPE_CFG_POST_CURSOR_PRESET4_OFFSET 6
#define HPIPE_CFG_POST_CURSOR_PRESET4_MASK \
(0x3f << HPIPE_CFG_POST_CURSOR_PRESET4_OFFSET)
#define HPIPE_LANE_PRESET_CFG11_REG 0x6d4
#define HPIPE_CFG_PRE_CURSOR_PRESET5_OFFSET 0
#define HPIPE_CFG_PRE_CURSOR_PRESET5_MASK \
(0x3f << HPIPE_CFG_PRE_CURSOR_PRESET5_OFFSET)
#define HPIPE_CFG_POST_CURSOR_PRESET5_OFFSET 6
#define HPIPE_CFG_POST_CURSOR_PRESET5_MASK \
(0x3f << HPIPE_CFG_POST_CURSOR_PRESET5_OFFSET)
#define HPIPE_LANE_PRESET_CFG12_REG 0x6d8
#define HPIPE_CFG_PRE_CURSOR_PRESET6_OFFSET 0
#define HPIPE_CFG_PRE_CURSOR_PRESET6_MASK \
(0x3f << HPIPE_CFG_PRE_CURSOR_PRESET6_OFFSET)
#define HPIPE_CFG_POST_CURSOR_PRESET6_OFFSET 6
#define HPIPE_CFG_POST_CURSOR_PRESET6_MASK \
(0x3f << HPIPE_CFG_POST_CURSOR_PRESET6_OFFSET)
#define HPIPE_LANE_PRESET_CFG13_REG 0x6dc
#define HPIPE_CFG_PRE_CURSOR_PRESET7_OFFSET 0
#define HPIPE_CFG_PRE_CURSOR_PRESET7_MASK \
(0x3f << HPIPE_CFG_PRE_CURSOR_PRESET7_OFFSET)
#define HPIPE_CFG_POST_CURSOR_PRESET7_OFFSET 6
#define HPIPE_CFG_POST_CURSOR_PRESET7_MASK \
(0x3f << HPIPE_CFG_POST_CURSOR_PRESET7_OFFSET)
#define HPIPE_LANE_PRESET_CFG14_REG 0x6e0
#define HPIPE_CFG_PRE_CURSOR_PRESET8_OFFSET 0
#define HPIPE_CFG_PRE_CURSOR_PRESET8_MASK \
(0x3f << HPIPE_CFG_PRE_CURSOR_PRESET8_OFFSET)
#define HPIPE_CFG_POST_CURSOR_PRESET8_OFFSET 6
#define HPIPE_CFG_POST_CURSOR_PRESET8_MASK \
(0x3f << HPIPE_CFG_POST_CURSOR_PRESET8_OFFSET)
#define HPIPE_LANE_PRESET_CFG15_REG 0x6e4
#define HPIPE_CFG_PRE_CURSOR_PRESET9_OFFSET 0
#define HPIPE_CFG_PRE_CURSOR_PRESET9_MASK \
(0x3f << HPIPE_CFG_PRE_CURSOR_PRESET9_OFFSET)
#define HPIPE_CFG_POST_CURSOR_PRESET9_OFFSET 6
#define HPIPE_CFG_POST_CURSOR_PRESET9_MASK \
(0x3f << HPIPE_CFG_POST_CURSOR_PRESET9_OFFSET)
#define HPIPE_LANE_PRESET_CFG16_REG 0x6e8
#define HPIPE_CFG_PRE_CURSOR_PRESET10_OFFSET 0
#define HPIPE_CFG_PRE_CURSOR_PRESET10_MASK \
(0x3f << HPIPE_CFG_PRE_CURSOR_PRESET10_OFFSET)
#define HPIPE_CFG_POST_CURSOR_PRESET10_OFFSET 6
#define HPIPE_CFG_POST_CURSOR_PRESET10_MASK \
(0x3f << HPIPE_CFG_POST_CURSOR_PRESET10_OFFSET)
#define HPIPE_LANE_EQ_REMOTE_SETTING_REG 0x6f8
#define HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET 0
#define HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK \
(0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET)
#define HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET 1
#define HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK \
(0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET)
#define HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET 2
#define HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK \
(0xf << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET)
#define HPIPE_RST_CLK_CTRL_REG 0x704
#define HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET 0
#define HPIPE_RST_CLK_CTRL_PIPE_RST_MASK \
(0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET)
#define HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET 2
#define HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK \
(0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET)
#define HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET 3
#define HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK \
(0x1 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET)
#define HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET 9
#define HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK \
(0x1 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET)
#define HPIPE_CLK_SRC_LO_REG 0x70c
#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET 1
#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK \
(0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET)
#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET 2
#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK \
(0x3 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET)
#define HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET 5
#define HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK \
(0x7 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET)
#define HPIPE_CLK_SRC_HI_REG 0x710
#define HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET 0
#define HPIPE_CLK_SRC_HI_LANE_STRT_MASK \
(0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET)
#define HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET 1
#define HPIPE_CLK_SRC_HI_LANE_BREAK_MASK \
(0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET)
#define HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET 2
#define HPIPE_CLK_SRC_HI_LANE_MASTER_MASK \
(0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET)
#define HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET 7
#define HPIPE_CLK_SRC_HI_MODE_PIPE_MASK \
(0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET)
#define HPIPE_GLOBAL_PM_CTRL 0x740
#define HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET 0
#define HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK \
(0xFF << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET)
#endif /* _COMPHY_H_ */
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
/* Marvell CP110 SoC COMPHY unit driver */
#ifndef _PHY_COMPHY_CP110_H
#define _PHY_COMPHY_CP110_H
#define SD_ADDR(base, lane) (base + 0x1000 * lane)
#define HPIPE_ADDR(base, lane) (SD_ADDR(base, lane) + 0x800)
#define COMPHY_ADDR(base, lane) (base + 0x28 * lane)
#define MAX_NUM_OF_FFE 8
#define RX_TRAINING_TIMEOUT 500
/* Comphy registers */
#define COMMON_PHY_CFG1_REG 0x0
#define COMMON_PHY_CFG1_PWR_UP_OFFSET 1
#define COMMON_PHY_CFG1_PWR_UP_MASK \
(0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET)
#define COMMON_PHY_CFG1_PIPE_SELECT_OFFSET 2
#define COMMON_PHY_CFG1_PIPE_SELECT_MASK \
(0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET)
#define COMMON_PHY_CFG1_CORE_RSTN_OFFSET 13
#define COMMON_PHY_CFG1_CORE_RSTN_MASK \
(0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET)
#define COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET 14
#define COMMON_PHY_CFG1_PWR_ON_RESET_MASK \
(0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET)
#define COMMON_PHY_PHY_MODE_OFFSET 15
#define COMMON_PHY_PHY_MODE_MASK \
(0x1 << COMMON_PHY_PHY_MODE_OFFSET)
#define COMMON_PHY_CFG6_REG 0x14
#define COMMON_PHY_CFG6_IF_40_SEL_OFFSET 18
#define COMMON_PHY_CFG6_IF_40_SEL_MASK \
(0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET)
#define COMMON_PHY_CFG6_REG 0x14
#define COMMON_PHY_CFG6_IF_40_SEL_OFFSET 18
#define COMMON_PHY_CFG6_IF_40_SEL_MASK \
(0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET)
#define COMMON_SELECTOR_PHY_REG_OFFSET 0x140
#define COMMON_SELECTOR_PIPE_REG_OFFSET 0x144
#define COMMON_SELECTOR_COMPHY_MASK 0xf
#define COMMON_SELECTOR_COMPHYN_FIELD_WIDTH 4
#define COMMON_SELECTOR_COMPHYN_SATA 0x4
#define COMMON_SELECTOR_PIPE_COMPHY_PCIE 0x4
#define COMMON_SELECTOR_PIPE_COMPHY_USBH 0x1
#define COMMON_SELECTOR_PIPE_COMPHY_USBD 0x2
/* SGMII/HS-SGMII/SFI/RXAUI */
#define COMMON_SELECTOR_COMPHY0_1_2_NETWORK 0x1
#define COMMON_SELECTOR_COMPHY3_RXAUI 0x1
#define COMMON_SELECTOR_COMPHY3_SGMII 0x2
#define COMMON_SELECTOR_COMPHY4_PORT1 0x1
#define COMMON_SELECTOR_COMPHY4_ALL_OTHERS 0x2
#define COMMON_SELECTOR_COMPHY5_RXAUI 0x2
#define COMMON_SELECTOR_COMPHY5_SGMII 0x1
#define COMMON_PHY_SD_CTRL1 0x148
#define COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET 0
#define COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET 4
#define COMMON_PHY_SD_CTRL1_COMPHY_2_PORT_OFFSET 8
#define COMMON_PHY_SD_CTRL1_COMPHY_3_PORT_OFFSET 12
#define COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK 0xFFFF
#define COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK 0xFF
#define COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET 24
#define COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK \
(0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET)
#define COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET 25
#define COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK \
(0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET)
#define COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET 26
#define COMMON_PHY_SD_CTRL1_RXAUI1_MASK \
(0x1 << COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET)
#define COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET 27
#define COMMON_PHY_SD_CTRL1_RXAUI0_MASK \
(0x1 << COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET)
/* DFX register */
#define DFX_BASE (0x400000)
#define DFX_DEV_GEN_CTRL12_REG (0x280)
#define DFX_DEV_GEN_PCIE_CLK_SRC_MUX (0x3)
#define DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET 7
#define DFX_DEV_GEN_PCIE_CLK_SRC_MASK \
(0x3 << DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET)
/* SerDes IP registers */
#define SD_EXTERNAL_CONFIG0_REG 0
#define SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET 1
#define SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK \
(1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET)
#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET 3
#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK \
(0xf << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET)
#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET 7
#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK \
(0xf << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET)
#define SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET 11
#define SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK \
(1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET)
#define SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET 12
#define SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK \
(1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET)
#define SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET 14
#define SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK \
(1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET)
#define SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET 15
#define SD_EXTERNAL_CONFIG0_MEDIA_MODE_MASK \
(0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET)
#define SD_EXTERNAL_CONFIG1_REG 0x4
#define SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET 3
#define SD_EXTERNAL_CONFIG1_RESET_IN_MASK \
(0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET)
#define SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET 4
#define SD_EXTERNAL_CONFIG1_RX_INIT_MASK \
(0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET)
#define SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET 5
#define SD_EXTERNAL_CONFIG1_RESET_CORE_MASK \
(0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET)
#define SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET 6
#define SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK \
(0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET)
#define SD_EXTERNAL_CONFIG2_REG 0x8
#define SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET 4
#define SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK \
(0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET)
#define SD_EXTERNAL_CONFIG2_SSC_ENABLE_OFFSET 7
#define SD_EXTERNAL_CONFIG2_SSC_ENABLE_MASK \
(0x1 << SD_EXTERNAL_CONFIG2_SSC_ENABLE_OFFSET)
#define SD_EXTERNAL_STATUS_REG 0xc
#define SD_EXTERNAL_STATUS_START_RX_TRAINING_OFFSET 7
#define SD_EXTERNAL_STATUS_START_RX_TRAINING_MASK \
(1 << SD_EXTERNAL_STATUS_START_RX_TRAINING_OFFSET)
#define SD_EXTERNAL_STATUS0_REG 0x18
#define SD_EXTERNAL_STATUS0_PLL_TX_OFFSET 2
#define SD_EXTERNAL_STATUS0_PLL_TX_MASK \
(0x1 << SD_EXTERNAL_STATUS0_PLL_TX_OFFSET)
#define SD_EXTERNAL_STATUS0_PLL_RX_OFFSET 3
#define SD_EXTERNAL_STATUS0_PLL_RX_MASK \
(0x1 << SD_EXTERNAL_STATUS0_PLL_RX_OFFSET)
#define SD_EXTERNAL_STATUS0_RX_INIT_OFFSET 4
#define SD_EXTERNAL_STATUS0_RX_INIT_MASK \
(0x1 << SD_EXTERNAL_STATUS0_RX_INIT_OFFSET)
#define SD_EXTERNAL_STATAUS1_REG 0x1c
#define SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_COMP_OFFSET 0
#define SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_COMP_MASK \
(1 << SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_COMP_OFFSET)
#define SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_FAILED_OFFSET 1
#define SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_FAILED_MASK \
(1 << SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_FAILED_OFFSET)
/* HPIPE registers */
#define HPIPE_PWR_PLL_REG 0x4
#define HPIPE_PWR_PLL_REF_FREQ_OFFSET 0
#define HPIPE_PWR_PLL_REF_FREQ_MASK \
(0x1f << HPIPE_PWR_PLL_REF_FREQ_OFFSET)
#define HPIPE_PWR_PLL_PHY_MODE_OFFSET 5
#define HPIPE_PWR_PLL_PHY_MODE_MASK \
(0x7 << HPIPE_PWR_PLL_PHY_MODE_OFFSET)
#define HPIPE_CAL_REG1_REG 0xc
#define HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET 10
#define HPIPE_CAL_REG_1_EXT_TXIMP_MASK \
(0x1f << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET)
#define HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET 15
#define HPIPE_CAL_REG_1_EXT_TXIMP_EN_MASK \
(0x1 << HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET)
#define HPIPE_SQUELCH_FFE_SETTING_REG 0x18
#define HPIPE_SQUELCH_THRESH_IN_OFFSET 8
#define HPIPE_SQUELCH_THRESH_IN_MASK \
(0xf << HPIPE_SQUELCH_THRESH_IN_OFFSET)
#define HPIPE_SQUELCH_DETECTED_OFFSET 14
#define HPIPE_SQUELCH_DETECTED_MASK \
(0x1 << HPIPE_SQUELCH_DETECTED_OFFSET)
#define HPIPE_DFE_REG0 0x1c
#define HPIPE_DFE_RES_FORCE_OFFSET 15
#define HPIPE_DFE_RES_FORCE_MASK \
(0x1 << HPIPE_DFE_RES_FORCE_OFFSET)
#define HPIPE_DFE_F3_F5_REG 0x28
#define HPIPE_DFE_F3_F5_DFE_EN_OFFSET 14
#define HPIPE_DFE_F3_F5_DFE_EN_MASK \
(0x1 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET)
#define HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET 15
#define HPIPE_DFE_F3_F5_DFE_CTRL_MASK \
(0x1 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET)
#define HPIPE_G1_SET_0_REG 0x34
#define HPIPE_G1_SET_0_G1_TX_AMP_OFFSET 1
#define HPIPE_G1_SET_0_G1_TX_AMP_MASK \
(0x1f << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET)
#define HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET 6
#define HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK \
(0x1 << HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET)
#define HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET 7
#define HPIPE_G1_SET_0_G1_TX_EMPH1_MASK \
(0xf << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET)
#define HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET 11
#define HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK \
(0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET)
#define HPIPE_G1_SET_1_REG 0x38
#define HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET 0
#define HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK \
(0x7 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET)
#define HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET 3
#define HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK \
(0x7 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET)
#define HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET 6
#define HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK \
(0x3 << HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET)
#define HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET 8
#define HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK \
(0x3 << HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET)
#define HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET 10
#define HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK \
(0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET)
#define HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET 11
#define HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK \
(0x3 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET)
#define HPIPE_G2_SET_0_REG 0x3c
#define HPIPE_G2_SET_0_G2_TX_AMP_OFFSET 1
#define HPIPE_G2_SET_0_G2_TX_AMP_MASK \
(0x1f << HPIPE_G2_SET_0_G2_TX_AMP_OFFSET)
#define HPIPE_G2_SET_0_G2_TX_AMP_ADJ_OFFSET 6
#define HPIPE_G2_SET_0_G2_TX_AMP_ADJ_MASK \
(0x1 << HPIPE_G2_SET_0_G2_TX_AMP_ADJ_OFFSET)
#define HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET 7
#define HPIPE_G2_SET_0_G2_TX_EMPH1_MASK \
(0xf << HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET)
#define HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET 11
#define HPIPE_G2_SET_0_G2_TX_EMPH1_EN_MASK \
(0x1 << HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET)
#define HPIPE_G2_SET_1_REG 0x40
#define HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET 0
#define HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK \
(0x7 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET)
#define HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET 3
#define HPIPE_G2_SET_1_G2_RX_SELMUPP_MASK \
(0x7 << HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET)
#define HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET 6
#define HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK \
(0x3 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET)
#define HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET 8
#define HPIPE_G2_SET_1_G2_RX_SELMUFF_MASK \
(0x3 << HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET)
#define HPIPE_G2_SET_1_G2_RX_DFE_EN_OFFSET 10
#define HPIPE_G2_SET_1_G2_RX_DFE_EN_MASK \
(0x1 << HPIPE_G2_SET_1_G2_RX_DFE_EN_OFFSET)
#define HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_OFFSET 11
#define HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_MASK \
(0x3 << HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_OFFSET)
#define HPIPE_G3_SET_0_REG 0x44
#define HPIPE_G3_SET_0_G3_TX_AMP_OFFSET 1
#define HPIPE_G3_SET_0_G3_TX_AMP_MASK \
(0x1f << HPIPE_G3_SET_0_G3_TX_AMP_OFFSET)
#define HPIPE_G3_SET_0_G3_TX_AMP_ADJ_OFFSET 6
#define HPIPE_G3_SET_0_G3_TX_AMP_ADJ_MASK \
(0x1 << HPIPE_G3_SET_0_G3_TX_AMP_ADJ_OFFSET)
#define HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET 7
#define HPIPE_G3_SET_0_G3_TX_EMPH1_MASK \
(0xf << HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET)
#define HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET 11
#define HPIPE_G3_SET_0_G3_TX_EMPH1_EN_MASK \
(0x1 << HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET)
#define HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_OFFSET 12
#define HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_MASK \
(0x7 << HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_OFFSET)
#define HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_OFFSET 15
#define HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_MASK \
(0x1 << HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_OFFSET)
#define HPIPE_G3_SET_1_REG 0x48
#define HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET 0
#define HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK \
(0x7 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET)
#define HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET 3
#define HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK \
(0x7 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET)
#define HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET 6
#define HPIPE_G3_SET_1_G3_RX_SELMUFI_MASK \
(0x3 << HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET)
#define HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET 8
#define HPIPE_G3_SET_1_G3_RX_SELMUFF_MASK \
(0x3 << HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET)
#define HPIPE_G3_SET_1_G3_RX_DFE_EN_OFFSET 10
#define HPIPE_G3_SET_1_G3_RX_DFE_EN_MASK \
(0x1 << HPIPE_G3_SET_1_G3_RX_DFE_EN_OFFSET)
#define HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_OFFSET 11
#define HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_MASK \
(0x3 << HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_OFFSET)
#define HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET 13
#define HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK \
(0x1 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET)
#define HPIPE_PHY_TEST_CONTROL_REG 0x54
#define HPIPE_PHY_TEST_PATTERN_SEL_OFFSET 4
#define HPIPE_PHY_TEST_PATTERN_SEL_MASK \
(0xf << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET)
#define HPIPE_PHY_TEST_RESET_OFFSET 14
#define HPIPE_PHY_TEST_RESET_MASK \
(0x1 << HPIPE_PHY_TEST_RESET_OFFSET)
#define HPIPE_PHY_TEST_EN_OFFSET 15
#define HPIPE_PHY_TEST_EN_MASK \
(0x1 << HPIPE_PHY_TEST_EN_OFFSET)
#define HPIPE_PHY_TEST_DATA_REG 0x6c
#define HPIPE_PHY_TEST_DATA_OFFSET 0
#define HPIPE_PHY_TEST_DATA_MASK \
(0xffff << HPIPE_PHY_TEST_DATA_OFFSET)
#define HPIPE_LOOPBACK_REG 0x8c
#define HPIPE_LOOPBACK_SEL_OFFSET 1
#define HPIPE_LOOPBACK_SEL_MASK \
(0x7 << HPIPE_LOOPBACK_SEL_OFFSET)
#define HPIPE_CDR_LOCK_OFFSET 7
#define HPIPE_CDR_LOCK_MASK \
(0x1 << HPIPE_CDR_LOCK_OFFSET)
#define HPIPE_CDR_LOCK_DET_EN_OFFSET 8
#define HPIPE_CDR_LOCK_DET_EN_MASK \
(0x1 << HPIPE_CDR_LOCK_DET_EN_OFFSET)
#define HPIPE_INTERFACE_REG 0x94
#define HPIPE_INTERFACE_GEN_MAX_OFFSET 10
#define HPIPE_INTERFACE_GEN_MAX_MASK \
(0x3 << HPIPE_INTERFACE_GEN_MAX_OFFSET)
#define HPIPE_INTERFACE_DET_BYPASS_OFFSET 12
#define HPIPE_INTERFACE_DET_BYPASS_MASK \
(0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET)
#define HPIPE_INTERFACE_LINK_TRAIN_OFFSET 14
#define HPIPE_INTERFACE_LINK_TRAIN_MASK \
(0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET)
#define HPIPE_G1_SET_2_REG 0xf4
#define HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET 0
#define HPIPE_G1_SET_2_G1_TX_EMPH0_MASK \
(0xf << HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET)
#define HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET 4
#define HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK \
(0x1 << HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET)
#define HPIPE_G2_SET_2_REG 0xf8
#define HPIPE_G2_TX_SSC_AMP_OFFSET 9
#define HPIPE_G2_TX_SSC_AMP_MASK \
(0x7f << HPIPE_G2_TX_SSC_AMP_OFFSET)
#define HPIPE_VDD_CAL_0_REG 0x108
#define HPIPE_CAL_VDD_CONT_MODE_OFFSET 15
#define HPIPE_CAL_VDD_CONT_MODE_MASK \
(0x1 << HPIPE_CAL_VDD_CONT_MODE_OFFSET)
#define HPIPE_VDD_CAL_CTRL_REG 0x114
#define HPIPE_EXT_SELLV_RXSAMPL_OFFSET 5
#define HPIPE_EXT_SELLV_RXSAMPL_MASK \
(0x1f << HPIPE_EXT_SELLV_RXSAMPL_OFFSET)
#define HPIPE_PCIE_REG0 0x120
#define HPIPE_PCIE_IDLE_SYNC_OFFSET 12
#define HPIPE_PCIE_IDLE_SYNC_MASK \
(0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET)
#define HPIPE_PCIE_SEL_BITS_OFFSET 13
#define HPIPE_PCIE_SEL_BITS_MASK \
(0x3 << HPIPE_PCIE_SEL_BITS_OFFSET)
#define HPIPE_LANE_ALIGN_REG 0x124
#define HPIPE_LANE_ALIGN_OFF_OFFSET 12
#define HPIPE_LANE_ALIGN_OFF_MASK \
(0x1 << HPIPE_LANE_ALIGN_OFF_OFFSET)
#define HPIPE_MISC_REG 0x13C
#define HPIPE_MISC_CLK100M_125M_OFFSET 4
#define HPIPE_MISC_CLK100M_125M_MASK \
(0x1 << HPIPE_MISC_CLK100M_125M_OFFSET)
#define HPIPE_MISC_ICP_FORCE_OFFSET 5
#define HPIPE_MISC_ICP_FORCE_MASK \
(0x1 << HPIPE_MISC_ICP_FORCE_OFFSET)
#define HPIPE_MISC_TXDCLK_2X_OFFSET 6
#define HPIPE_MISC_TXDCLK_2X_MASK \
(0x1 << HPIPE_MISC_TXDCLK_2X_OFFSET)
#define HPIPE_MISC_CLK500_EN_OFFSET 7
#define HPIPE_MISC_CLK500_EN_MASK \
(0x1 << HPIPE_MISC_CLK500_EN_OFFSET)
#define HPIPE_MISC_REFCLK_SEL_OFFSET 10
#define HPIPE_MISC_REFCLK_SEL_MASK \
(0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET)
#define HPIPE_RX_CONTROL_1_REG 0x140
#define HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET 11
#define HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK \
(0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET)
#define HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET 12
#define HPIPE_RX_CONTROL_1_CLK8T_EN_MASK \
(0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET)
#define HPIPE_PWR_CTR_REG 0x148
#define HPIPE_PWR_CTR_RST_DFE_OFFSET 0
#define HPIPE_PWR_CTR_RST_DFE_MASK \
(0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET)
#define HPIPE_PWR_CTR_SFT_RST_OFFSET 10
#define HPIPE_PWR_CTR_SFT_RST_MASK \
(0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET)
#define HPIPE_SPD_DIV_FORCE_REG 0x154
#define HPIPE_TXDIGCK_DIV_FORCE_OFFSET 7
#define HPIPE_TXDIGCK_DIV_FORCE_MASK \
(0x1 << HPIPE_TXDIGCK_DIV_FORCE_OFFSET)
#define HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET 8
#define HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_MASK \
(0x3 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET)
#define HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET 10
#define HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_MASK \
(0x1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET)
#define HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET 13
#define HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_MASK \
(0x3 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET)
#define HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET 15
#define HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_MASK \
(0x1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET)
#define HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG 0x16C
#define HPIPE_RX_SAMPLER_OS_GAIN_OFFSET 6
#define HPIPE_RX_SAMPLER_OS_GAIN_MASK \
(0x3 << HPIPE_RX_SAMPLER_OS_GAIN_OFFSET)
#define HPIPE_SMAPLER_OFFSET 12
#define HPIPE_SMAPLER_MASK \
(0x1 << HPIPE_SMAPLER_OFFSET)
#define HPIPE_TX_REG1_REG 0x174
#define HPIPE_TX_REG1_TX_EMPH_RES_OFFSET 5
#define HPIPE_TX_REG1_TX_EMPH_RES_MASK \
(0x3 << HPIPE_TX_REG1_TX_EMPH_RES_OFFSET)
#define HPIPE_TX_REG1_SLC_EN_OFFSET 10
#define HPIPE_TX_REG1_SLC_EN_MASK \
(0x3f << HPIPE_TX_REG1_SLC_EN_OFFSET)
#define HPIPE_PWR_CTR_DTL_REG 0x184
#define HPIPE_PWR_CTR_DTL_SQ_DET_EN_OFFSET 0
#define HPIPE_PWR_CTR_DTL_SQ_DET_EN_MASK \
(0x1 << HPIPE_PWR_CTR_DTL_SQ_DET_EN_OFFSET)
#define HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_OFFSET 1
#define HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_MASK \
(0x1 << HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_OFFSET)
#define HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET 2
#define HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK \
(0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET)
#define HPIPE_PWR_CTR_DTL_CLAMPING_SEL_OFFSET 4
#define HPIPE_PWR_CTR_DTL_CLAMPING_SEL_MASK \
(0x7 << HPIPE_PWR_CTR_DTL_CLAMPING_SEL_OFFSET)
#define HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_OFFSET 10
#define HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_MASK \
(0x1 << HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_OFFSET)
#define HPIPE_PWR_CTR_DTL_CLK_MODE_OFFSET 12
#define HPIPE_PWR_CTR_DTL_CLK_MODE_MASK \
(0x3 << HPIPE_PWR_CTR_DTL_CLK_MODE_OFFSET)
#define HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_OFFSET 14
#define HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_MASK \
(1 << HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_OFFSET)
#define HPIPE_PHASE_CONTROL_REG 0x188
#define HPIPE_OS_PH_OFFSET_OFFSET 0
#define HPIPE_OS_PH_OFFSET_MASK \
(0x7f << HPIPE_OS_PH_OFFSET_OFFSET)
#define HPIPE_OS_PH_OFFSET_FORCE_OFFSET 7
#define HPIPE_OS_PH_OFFSET_FORCE_MASK \
(0x1 << HPIPE_OS_PH_OFFSET_FORCE_OFFSET)
#define HPIPE_OS_PH_VALID_OFFSET 8
#define HPIPE_OS_PH_VALID_MASK \
(0x1 << HPIPE_OS_PH_VALID_OFFSET)
#define HPIPE_SQ_GLITCH_FILTER_CTRL 0x1c8
#define HPIPE_SQ_DEGLITCH_WIDTH_P_OFFSET 0
#define HPIPE_SQ_DEGLITCH_WIDTH_P_MASK \
(0xf << HPIPE_SQ_DEGLITCH_WIDTH_P_OFFSET)
#define HPIPE_SQ_DEGLITCH_WIDTH_N_OFFSET 4
#define HPIPE_SQ_DEGLITCH_WIDTH_N_MASK \
(0xf << HPIPE_SQ_DEGLITCH_WIDTH_N_OFFSET)
#define HPIPE_SQ_DEGLITCH_EN_OFFSET 8
#define HPIPE_SQ_DEGLITCH_EN_MASK \
(0x1 << HPIPE_SQ_DEGLITCH_EN_OFFSET)
#define HPIPE_FRAME_DETECT_CTRL_0_REG 0x214
#define HPIPE_TRAIN_PAT_NUM_OFFSET 0x7
#define HPIPE_TRAIN_PAT_NUM_MASK \
(0x1FF << HPIPE_TRAIN_PAT_NUM_OFFSET)
#define HPIPE_FRAME_DETECT_CTRL_3_REG 0x220
#define HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET 12
#define HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK \
(0x1 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET)
#define HPIPE_DME_REG 0x228
#define HPIPE_DME_ETHERNET_MODE_OFFSET 7
#define HPIPE_DME_ETHERNET_MODE_MASK \
(0x1 << HPIPE_DME_ETHERNET_MODE_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_0_REG 0x268
#define HPIPE_TX_TRAIN_P2P_HOLD_OFFSET 15
#define HPIPE_TX_TRAIN_P2P_HOLD_MASK \
(0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_REG 0x26C
#define HPIPE_TX_TRAIN_CTRL_G1_OFFSET 0
#define HPIPE_TX_TRAIN_CTRL_G1_MASK \
(0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_GN1_OFFSET 1
#define HPIPE_TX_TRAIN_CTRL_GN1_MASK \
(0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_G0_OFFSET 2
#define HPIPE_TX_TRAIN_CTRL_G0_MASK \
(0x1 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_4_REG 0x278
#define HPIPE_TRX_TRAIN_TIMER_OFFSET 0
#define HPIPE_TRX_TRAIN_TIMER_MASK \
(0x3FF << HPIPE_TRX_TRAIN_TIMER_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_5_REG 0x2A4
#define HPIPE_RX_TRAIN_TIMER_OFFSET 0
#define HPIPE_RX_TRAIN_TIMER_MASK \
(0x3ff << HPIPE_RX_TRAIN_TIMER_OFFSET)
#define HPIPE_TX_TRAIN_START_SQ_EN_OFFSET 11
#define HPIPE_TX_TRAIN_START_SQ_EN_MASK \
(0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET)
#define HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET 12
#define HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK \
(0x1 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET)
#define HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET 13
#define HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK \
(0x1 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET)
#define HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET 14
#define HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK \
(0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET)
#define HPIPE_TX_TRAIN_REG 0x31C
#define HPIPE_TX_TRAIN_CHK_INIT_OFFSET 4
#define HPIPE_TX_TRAIN_CHK_INIT_MASK \
(0x1 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET)
#define HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET 7
#define HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK \
(0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET)
#define HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET 8
#define HPIPE_TX_TRAIN_16BIT_AUTO_EN_MASK \
(0x1 << HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET)
#define HPIPE_TX_TRAIN_PAT_SEL_OFFSET 9
#define HPIPE_TX_TRAIN_PAT_SEL_MASK \
(0x1 << HPIPE_TX_TRAIN_PAT_SEL_OFFSET)
#define HPIPE_SAVED_DFE_VALUES_REG 0x328
#define HPIPE_SAVED_DFE_VALUES_SAV_F0D_OFFSET 10
#define HPIPE_SAVED_DFE_VALUES_SAV_F0D_MASK \
(0x3f << HPIPE_SAVED_DFE_VALUES_SAV_F0D_OFFSET)
#define HPIPE_CDR_CONTROL_REG 0x418
#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET 14
#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK \
(0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET)
#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET 12
#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK \
(0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET)
#define HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET 9
#define HPIPE_CDR_MAX_DFE_ADAPT_0_MASK \
(0x7 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET)
#define HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET 6
#define HPIPE_CDR_MAX_DFE_ADAPT_1_MASK \
(0x7 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET)
#define HPIPE_TX_TRAIN_CTRL_11_REG 0x438
#define HPIPE_TX_STATUS_CHECK_MODE_OFFSET 6
#define HPIPE_TX_TX_STATUS_CHECK_MODE_MASK \
(0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET)
#define HPIPE_TX_NUM_OF_PRESET_OFFSET 10
#define HPIPE_TX_NUM_OF_PRESET_MASK \
(0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET)
#define HPIPE_TX_SWEEP_PRESET_EN_OFFSET 15
#define HPIPE_TX_SWEEP_PRESET_EN_MASK \
(0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET)
#define HPIPE_G1_SETTINGS_3_REG 0x440
#define HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET 0
#define HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK \
(0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET)
#define HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET 4
#define HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK \
(0x7 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET)
#define HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET 7
#define HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK \
(0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET)
#define HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET 9
#define HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_MASK \
(0x1 << HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET)
#define HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_OFFSET 12
#define HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_MASK \
(0x3 << HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_OFFSET)
#define HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_OFFSET 14
#define HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_MASK \
(0x3 << HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_OFFSET)
#define HPIPE_G1_SETTINGS_4_REG 0x444
#define HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET 8
#define HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK \
(0x3 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET)
#define HPIPE_G2_SETTINGS_4_REG 0x44c
#define HPIPE_G2_DFE_RES_OFFSET 8
#define HPIPE_G2_DFE_RES_MASK \
(0x3 << HPIPE_G2_DFE_RES_OFFSET)
#define HPIPE_G3_SETTING_3_REG 0x450
#define HPIPE_G3_FFE_CAP_SEL_OFFSET 0
#define HPIPE_G3_FFE_CAP_SEL_MASK \
(0xf << HPIPE_G3_FFE_CAP_SEL_OFFSET)
#define HPIPE_G3_FFE_RES_SEL_OFFSET 4
#define HPIPE_G3_FFE_RES_SEL_MASK \
(0x7 << HPIPE_G3_FFE_RES_SEL_OFFSET)
#define HPIPE_G3_FFE_SETTING_FORCE_OFFSET 7
#define HPIPE_G3_FFE_SETTING_FORCE_MASK \
(0x1 << HPIPE_G3_FFE_SETTING_FORCE_OFFSET)
#define HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET 12
#define HPIPE_G3_FFE_DEG_RES_LEVEL_MASK \
(0x3 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET)
#define HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET 14
#define HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK \
(0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET)
#define HPIPE_G3_SETTING_4_REG 0x454
#define HPIPE_G3_DFE_RES_OFFSET 8
#define HPIPE_G3_DFE_RES_MASK (0x3 << HPIPE_G3_DFE_RES_OFFSET)
#define HPIPE_TX_PRESET_INDEX_REG 0x468
#define HPIPE_TX_PRESET_INDEX_OFFSET 0
#define HPIPE_TX_PRESET_INDEX_MASK \
(0xf << HPIPE_TX_PRESET_INDEX_OFFSET)
#define HPIPE_DFE_CONTROL_REG 0x470
#define HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET 14
#define HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK \
(0x3 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET)
#define HPIPE_DFE_CTRL_28_REG 0x49C
#define HPIPE_DFE_CTRL_28_PIPE4_OFFSET 7
#define HPIPE_DFE_CTRL_28_PIPE4_MASK \
(0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET)
#define HPIPE_G1_SETTING_5_REG 0x538
#define HPIPE_G1_SETTING_5_G1_ICP_OFFSET 0
#define HPIPE_G1_SETTING_5_G1_ICP_MASK \
(0xf << HPIPE_G1_SETTING_5_G1_ICP_OFFSET)
#define HPIPE_G3_SETTING_5_REG 0x548
#define HPIPE_G3_SETTING_5_G3_ICP_OFFSET 0
#define HPIPE_G3_SETTING_5_G3_ICP_MASK \
(0xf << HPIPE_G3_SETTING_5_G3_ICP_OFFSET)
#define HPIPE_LANE_CONFIG0_REG 0x600
#define HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET 0
#define HPIPE_LANE_CONFIG0_TXDEEMPH0_MASK \
(0x1 << HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET)
#define HPIPE_LANE_STATUS1_REG 0x60C
#define HPIPE_LANE_STATUS1_PCLK_EN_OFFSET 0
#define HPIPE_LANE_STATUS1_PCLK_EN_MASK \
(0x1 << HPIPE_LANE_STATUS1_PCLK_EN_OFFSET)
#define HPIPE_LANE_CFG4_REG 0x620
#define HPIPE_LANE_CFG4_DFE_CTRL_OFFSET 0
#define HPIPE_LANE_CFG4_DFE_CTRL_MASK \
(0x7 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET)
#define HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET 3
#define HPIPE_LANE_CFG4_DFE_EN_SEL_MASK \
(0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET)
#define HPIPE_LANE_CFG4_DFE_OVER_OFFSET 6
#define HPIPE_LANE_CFG4_DFE_OVER_MASK \
(0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET)
#define HPIPE_LANE_CFG4_SSC_CTRL_OFFSET 7
#define HPIPE_LANE_CFG4_SSC_CTRL_MASK \
(0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET)
#define HPIPE_LANE_EQ_REMOTE_SETTING_REG 0x6f8
#define HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET 0
#define HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK \
(0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET)
#define HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET 1
#define HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK \
(0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET)
#define HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET 2
#define HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK \
(0xf << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET)
#define HPIPE_LANE_EQU_CONFIG_0_REG 0x69C
#define HPIPE_CFG_PHY_RC_EP_OFFSET 12
#define HPIPE_CFG_PHY_RC_EP_MASK \
(0x1 << HPIPE_CFG_PHY_RC_EP_OFFSET)
#define HPIPE_LANE_EQ_CFG1_REG 0x6a0
#define HPIPE_CFG_UPDATE_POLARITY_OFFSET 12
#define HPIPE_CFG_UPDATE_POLARITY_MASK \
(0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET)
#define HPIPE_LANE_EQ_CFG2_REG 0x6a4
#define HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET 14
#define HPIPE_CFG_EQ_BUNDLE_DIS_MASK \
(0x1 << HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET)
#define HPIPE_RST_CLK_CTRL_REG 0x704
#define HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET 0
#define HPIPE_RST_CLK_CTRL_PIPE_RST_MASK \
(0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET)
#define HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET 2
#define HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK \
(0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET)
#define HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET 3
#define HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK \
(0x1 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET)
#define HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET 9
#define HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK \
(0x1 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET)
#define HPIPE_TST_MODE_CTRL_REG 0x708
#define HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET 2
#define HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK \
(0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET)
#define HPIPE_CLK_SRC_LO_REG 0x70c
#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET 1
#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK \
(0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET)
#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET 2
#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK \
(0x3 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET)
#define HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET 5
#define HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK \
(0x7 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET)
#define HPIPE_CLK_SRC_HI_REG 0x710
#define HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET 0
#define HPIPE_CLK_SRC_HI_LANE_STRT_MASK \
(0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET)
#define HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET 1
#define HPIPE_CLK_SRC_HI_LANE_BREAK_MASK \
(0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET)
#define HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET 2
#define HPIPE_CLK_SRC_HI_LANE_MASTER_MASK \
(0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET)
#define HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET 7
#define HPIPE_CLK_SRC_HI_MODE_PIPE_MASK \
(0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET)
#define HPIPE_GLOBAL_MISC_CTRL 0x718
#define HPIPE_GLOBAL_PM_CTRL 0x740
#define HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET 0
#define HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK \
(0xFF << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET)
/* General defines */
#define PLL_LOCK_TIMEOUT 15000
#endif /* _PHY_COMPHY_CP110_H */
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
/* Marvell CP110 SoC COMPHY unit driver */
#include <debug.h>
#include <delay_timer.h>
#include <errno.h>
#include <mmio.h>
#include <mvebu_def.h>
#include <spinlock.h>
#include "mvebu.h"
#include "comphy-cp110.h"
/* #define DEBUG_COMPHY */
#ifdef DEBUG_COMPHY
#define debug(format...) printf(format)
#else
#define debug(format, arg...)
#endif
/* A lane is described by 4 fields:
* - bit 1~0 represent comphy polarity invert
* - bit 7~2 represent comphy speed
* - bit 11~8 represent unit index
* - bit 16~12 represent mode
* - bit 17 represent comphy indication of clock source
* - bit 19-18 represents pcie width (in case of pcie comphy config.)
* - bit 31~20 reserved
*/
#define COMPHY_INVERT_OFFSET 0
#define COMPHY_INVERT_LEN 2
#define COMPHY_INVERT_MASK COMPHY_MASK(COMPHY_INVERT_OFFSET, \
COMPHY_INVERT_LEN)
#define COMPHY_SPEED_OFFSET (COMPHY_INVERT_OFFSET + COMPHY_INVERT_LEN)
#define COMPHY_SPEED_LEN 6
#define COMPHY_SPEED_MASK COMPHY_MASK(COMPHY_SPEED_OFFSET, \
COMPHY_SPEED_LEN)
#define COMPHY_UNIT_ID_OFFSET (COMPHY_SPEED_OFFSET + COMPHY_SPEED_LEN)
#define COMPHY_UNIT_ID_LEN 4
#define COMPHY_UNIT_ID_MASK COMPHY_MASK(COMPHY_UNIT_ID_OFFSET, \
COMPHY_UNIT_ID_LEN)
#define COMPHY_MODE_OFFSET (COMPHY_UNIT_ID_OFFSET + COMPHY_UNIT_ID_LEN)
#define COMPHY_MODE_LEN 5
#define COMPHY_MODE_MASK COMPHY_MASK(COMPHY_MODE_OFFSET, COMPHY_MODE_LEN)
#define COMPHY_CLK_SRC_OFFSET (COMPHY_MODE_OFFSET + COMPHY_MODE_LEN)
#define COMPHY_CLK_SRC_LEN 1
#define COMPHY_CLK_SRC_MASK COMPHY_MASK(COMPHY_CLK_SRC_OFFSET, \
COMPHY_CLK_SRC_LEN)
#define COMPHY_PCI_WIDTH_OFFSET (COMPHY_CLK_SRC_OFFSET + COMPHY_CLK_SRC_LEN)
#define COMPHY_PCI_WIDTH_LEN 3
#define COMPHY_PCI_WIDTH_MASK COMPHY_MASK(COMPHY_PCI_WIDTH_OFFSET, \
COMPHY_PCI_WIDTH_LEN)
#define COMPHY_MASK(offset, len) (((1 << (len)) - 1) << (offset))
/* Macro which extracts mode from lane description */
#define COMPHY_GET_MODE(x) (((x) & COMPHY_MODE_MASK) >> \
COMPHY_MODE_OFFSET)
/* Macro which extracts unit index from lane description */
#define COMPHY_GET_ID(x) (((x) & COMPHY_UNIT_ID_MASK) >> \
COMPHY_UNIT_ID_OFFSET)
/* Macro which extracts speed from lane description */
#define COMPHY_GET_SPEED(x) (((x) & COMPHY_SPEED_MASK) >> \
COMPHY_SPEED_OFFSET)
/* Macro which extracts clock source indication from lane description */
#define COMPHY_GET_CLK_SRC(x) (((x) & COMPHY_CLK_SRC_MASK) >> \
COMPHY_CLK_SRC_OFFSET)
/* Macro which extracts pcie width indication from lane description */
#define COMPHY_GET_PCIE_WIDTH(x) (((x) & COMPHY_PCI_WIDTH_MASK) >> \
COMPHY_PCI_WIDTH_OFFSET)
#define COMPHY_SATA_MODE 0x1
#define COMPHY_SGMII_MODE 0x2 /* SGMII 1G */
#define COMPHY_HS_SGMII_MODE 0x3 /* SGMII 2.5G */
#define COMPHY_USB3H_MODE 0x4
#define COMPHY_USB3D_MODE 0x5
#define COMPHY_PCIE_MODE 0x6
#define COMPHY_RXAUI_MODE 0x7
#define COMPHY_XFI_MODE 0x8
#define COMPHY_SFI_MODE 0x9
#define COMPHY_USB3_MODE 0xa
#define COMPHY_AP_MODE 0xb
/* COMPHY speed macro */
#define COMPHY_SPEED_1_25G 0 /* SGMII 1G */
#define COMPHY_SPEED_2_5G 1
#define COMPHY_SPEED_3_125G 2 /* SGMII 2.5G */
#define COMPHY_SPEED_5G 3
#define COMPHY_SPEED_5_15625G 4 /* XFI 5G */
#define COMPHY_SPEED_6G 5
#define COMPHY_SPEED_10_3125G 6 /* XFI 10G */
#define COMPHY_SPEED_MAX 0x3F
/* The default speed for IO with fixed known speed */
#define COMPHY_SPEED_DEFAULT COMPHY_SPEED_MAX
/* Commands for comphy driver */
#define COMPHY_COMMAND_DIGITAL_PWR_OFF 0x00000001
#define COMPHY_COMMAND_DIGITAL_PWR_ON 0x00000002
#define COMPHY_PIPE_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + 0x120000)
/* System controller registers */
#define PCIE_MAC_RESET_MASK_PORT0 BIT(13)
#define PCIE_MAC_RESET_MASK_PORT1 BIT(11)
#define PCIE_MAC_RESET_MASK_PORT2 BIT(12)
#define SYS_CTRL_UINIT_SOFT_RESET_REG 0x268
#define SYS_CTRL_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + 0x440000)
/* DFX register spaces */
#define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET (0)
#define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK (0x1 << \
SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET)
#define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET (1)
#define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK (0x1 << \
SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET)
#define SAR_STATUS_0_REG 200
#define DFX_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + DFX_BASE)
/* The same Units Soft Reset Config register are accessed in all PCIe ports
* initialization, so a spin lock is defined in case when more than 1 CPUs
* resets PCIe MAC and need to access the register in the same time. The spin
* lock is shared by all CP110 units.
*/
spinlock_t cp110_mac_reset_lock;
enum reg_width_type {
REG_16BIT = 0,
REG_32BIT,
};
enum {
COMPHY_LANE0 = 0,
COMPHY_LANE1,
COMPHY_LANE2,
COMPHY_LANE3,
COMPHY_LANE4,
COMPHY_LANE5,
COMPHY_LANE_MAX,
};
/* These values come from the PCI Express Spec */
enum pcie_link_width {
PCIE_LNK_WIDTH_RESRV = 0x00,
PCIE_LNK_X1 = 0x01,
PCIE_LNK_X2 = 0x02,
PCIE_LNK_X4 = 0x04,
PCIE_LNK_X8 = 0x08,
PCIE_LNK_X12 = 0x0C,
PCIE_LNK_X16 = 0x10,
PCIE_LNK_X32 = 0x20,
PCIE_LNK_WIDTH_UNKNOWN = 0xFF,
};
static inline uint32_t polling_with_timeout(uintptr_t addr,
uint32_t val,
uint32_t mask,
uint32_t usec_timeout,
enum reg_width_type type)
{
uint32_t data;
do {
udelay(1);
if (type == REG_16BIT)
data = mmio_read_16(addr) & mask;
else
data = mmio_read_32(addr) & mask;
} while (data != val && --usec_timeout > 0);
if (usec_timeout == 0)
return data;
return 0;
}
static inline void reg_set(uintptr_t addr, uint32_t data, uint32_t mask)
{
debug("<atf>: WR to addr = %#010lx, data = %#010x (mask = %#010x) - ",
addr, data, mask);
debug("old value = %#010x ==> ", mmio_read_32(addr));
mmio_clrsetbits_32(addr, mask, data);
debug("new val %#010x\n", mmio_read_32(addr));
}
/* Clear PIPE selector - avoid collision with previous configuration */
static void mvebu_cp110_comphy_clr_pipe_selector(uint64_t comphy_base,
uint8_t comphy_index)
{
uint32_t reg, mask, field;
uint32_t comphy_offset =
COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
field = reg & mask;
if (field) {
reg &= ~mask;
mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET,
reg);
}
}
/* Clear PHY selector - avoid collision with previous configuration */
static void mvebu_cp110_comphy_clr_phy_selector(uint64_t comphy_base,
uint8_t comphy_index)
{
uint32_t reg, mask, field;
uint32_t comphy_offset =
COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET);
field = reg & mask;
/* Clear comphy selector - if it was already configured.
* (might be that this comphy was configured as PCIe/USB,
* in such case, no need to clear comphy selector because PCIe/USB
* are controlled by hpipe selector).
*/
if (field) {
reg &= ~mask;
mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET,
reg);
}
}
/* PHY selector configures SATA and Network modes */
static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base,
uint8_t comphy_index, uint32_t comphy_mode)
{
uint32_t reg, mask;
uint32_t comphy_offset =
COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
int mode;
/* If phy selector is used the pipe selector should be marked as
* unconnected.
*/
mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
/* Comphy mode (compound of the IO mode and id). Here, only the IO mode
* is required to distinguish between SATA and network modes.
*/
mode = COMPHY_GET_MODE(comphy_mode);
mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET);
reg &= ~mask;
/* SATA port 0/1 require the same configuration */
if (mode == COMPHY_SATA_MODE) {
/* SATA selector values is always 4 */
reg |= COMMON_SELECTOR_COMPHYN_SATA << comphy_offset;
} else {
switch (comphy_index) {
case(0):
case(1):
case(2):
/* For comphy 0,1, and 2:
* Network selector value is always 1.
*/
reg |= COMMON_SELECTOR_COMPHY0_1_2_NETWORK <<
comphy_offset;
break;
case(3):
/* For comphy 3:
* 0x1 = RXAUI_Lane1
* 0x2 = SGMII/HS-SGMII Port1
*/
if (mode == COMPHY_RXAUI_MODE)
reg |= COMMON_SELECTOR_COMPHY3_RXAUI <<
comphy_offset;
else
reg |= COMMON_SELECTOR_COMPHY3_SGMII <<
comphy_offset;
break;
case(4):
/* For comphy 4:
* 0x1 = SGMII/HS-SGMII Port1, XFI1/SFI1
* 0x2 = SGMII/HS-SGMII Port0: XFI0/SFI0, RXAUI_Lane0
*
* We want to check if SGMII1/HS_SGMII1 is the
* requested mode in order to determine which value
* should be set (all other modes use the same value)
* so we need to strip the mode, and check the ID
* because we might handle SGMII0/HS_SGMII0 too.
*/
/* TODO: need to distinguish between CP110 and CP115
* as SFI1/XFI1 available only for CP115.
*/
if ((mode == COMPHY_SGMII_MODE ||
mode == COMPHY_HS_SGMII_MODE ||
mode == COMPHY_SFI_MODE) &&
COMPHY_GET_ID(comphy_mode) == 1)
reg |= COMMON_SELECTOR_COMPHY4_PORT1 <<
comphy_offset;
else
reg |= COMMON_SELECTOR_COMPHY4_ALL_OTHERS <<
comphy_offset;
break;
case(5):
/* For comphy 5:
* 0x1 = SGMII/HS-SGMII Port2
* 0x2 = RXAUI Lane1
*/
if (mode == COMPHY_RXAUI_MODE)
reg |= COMMON_SELECTOR_COMPHY5_RXAUI <<
comphy_offset;
else
reg |= COMMON_SELECTOR_COMPHY5_SGMII <<
comphy_offset;
break;
}
}
mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET, reg);
}
/* PIPE selector configures for PCIe, USB 3.0 Host, and USB 3.0 Device mode */
static void mvebu_cp110_comphy_set_pipe_selector(uint64_t comphy_base,
uint8_t comphy_index, uint32_t comphy_mode)
{
uint32_t reg;
uint32_t shift = COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
int mode = COMPHY_GET_MODE(comphy_mode);
uint32_t mask = COMMON_SELECTOR_COMPHY_MASK << shift;
uint32_t pipe_sel = 0x0;
/* If pipe selector is used the phy selector should be marked as
* unconnected.
*/
mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
reg &= ~mask;
switch (mode) {
case (COMPHY_PCIE_MODE):
/* For lanes support PCIE, selector value are all same */
pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_PCIE;
break;
case (COMPHY_USB3H_MODE):
/* Only lane 1-4 support USB host, selector value is same */
if (comphy_index == COMPHY_LANE0 ||
comphy_index == COMPHY_LANE5)
ERROR("COMPHY[%d] mode[%d] is invalid\n",
comphy_index, mode);
else
pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBH;
break;
case (COMPHY_USB3D_MODE):
/* Lane 1 and 4 support USB device, selector value is same */
if (comphy_index == COMPHY_LANE1 ||
comphy_index == COMPHY_LANE4)
pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBD;
else
ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index,
mode);
break;
default:
ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index, mode);
break;
}
mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET, reg |
(pipe_sel << shift));
}
int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base, uint8_t comphy_index)
{
uintptr_t sd_ip_addr, addr;
uint32_t mask, data;
int ret = 0;
debug_enter();
sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
data = SD_EXTERNAL_STATUS0_PLL_TX_MASK &
SD_EXTERNAL_STATUS0_PLL_RX_MASK;
mask = data;
data = polling_with_timeout(addr, data, mask,
PLL_LOCK_TIMEOUT, REG_32BIT);
if (data != 0) {
if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
ERROR("RX PLL is not locked\n");
if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
ERROR("TX PLL is not locked\n");
ret = -ETIMEDOUT;
}
debug_exit();
return ret;
}
static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base,
uint8_t comphy_index, uint32_t comphy_mode)
{
uintptr_t hpipe_addr, sd_ip_addr, comphy_addr;
uint32_t mask, data;
int ret = 0;
debug_enter();
/* configure phy selector for SATA */
mvebu_cp110_comphy_set_phy_selector(comphy_base,
comphy_index, comphy_mode);
hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
debug(" add hpipe 0x%lx, sd 0x%lx, comphy 0x%lx\n",
hpipe_addr, sd_ip_addr, comphy_addr);
debug("stage: RFU configurations - hard reset comphy\n");
/* RFU configurations - hard reset comphy */
mask = COMMON_PHY_CFG1_PWR_UP_MASK;
data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
/* Set select data width 40Bit - SATA mode only */
reg_set(comphy_addr + COMMON_PHY_CFG6_REG,
0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET,
COMMON_PHY_CFG6_IF_40_SEL_MASK);
/* release from hard reset in SD external */
mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
/* Wait 1ms - until band gap and ref clock ready */
mdelay(1);
debug("stage: Comphy configuration\n");
/* Start comphy Configuration */
/* Set reference clock to comes from group 1 - choose 25Mhz */
reg_set(hpipe_addr + HPIPE_MISC_REG,
0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
HPIPE_MISC_REFCLK_SEL_MASK);
/* Reference frequency select set 1 (for SATA = 25Mhz) */
mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
/* PHY mode select (set SATA = 0x0 */
mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
data |= 0x0 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
/* Set max PHY generation setting - 6Gbps */
reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
HPIPE_INTERFACE_GEN_MAX_MASK);
/* Set select data width 40Bit (SEL_BITS[2:0]) */
reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
0x2 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
debug("stage: Analog parameters from ETP(HW)\n");
/* G1 settings */
mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
data = 0x0 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK;
data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET;
mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
data |= 0x0 << HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
data |= 0x3 << HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
data = 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
data |= 0x2 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
mask |= HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_MASK;
data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_OFFSET;
mask |= HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_MASK;
data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_OFFSET;
reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
/* G2 settings */
mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
mask |= HPIPE_G2_SET_1_G2_RX_SELMUPP_MASK;
data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET;
mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
mask |= HPIPE_G2_SET_1_G2_RX_SELMUFF_MASK;
data |= 0x3 << HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET;
mask |= HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_MASK;
data |= 0x1 << HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_OFFSET;
reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
/* G3 settings */
mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
data = 0x2 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
data |= 0x2 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
mask |= HPIPE_G3_SET_1_G3_RX_SELMUFI_MASK;
data |= 0x3 << HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET;
mask |= HPIPE_G3_SET_1_G3_RX_SELMUFF_MASK;
data |= 0x3 << HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET;
mask |= HPIPE_G3_SET_1_G3_RX_DFE_EN_MASK;
data |= 0x1 << HPIPE_G3_SET_1_G3_RX_DFE_EN_OFFSET;
mask |= HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_MASK;
data |= 0x2 << HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_OFFSET;
mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
/* DTL Control */
mask = HPIPE_PWR_CTR_DTL_SQ_DET_EN_MASK;
data = 0x1 << HPIPE_PWR_CTR_DTL_SQ_DET_EN_OFFSET;
mask |= HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_MASK;
data |= 0x1 << HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_OFFSET;
mask |= HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
data |= 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
mask |= HPIPE_PWR_CTR_DTL_CLAMPING_SEL_MASK;
data |= 0x1 << HPIPE_PWR_CTR_DTL_CLAMPING_SEL_OFFSET;
mask |= HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_MASK;
data |= 0x1 << HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_OFFSET;
mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_MASK;
data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_OFFSET;
mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_MASK;
data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_OFFSET;
reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
/* Trigger sampler enable pulse */
mask = HPIPE_SMAPLER_MASK;
data = 0x1 << HPIPE_SMAPLER_OFFSET;
reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
mask = HPIPE_SMAPLER_MASK;
data = 0x0 << HPIPE_SMAPLER_OFFSET;
reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
/* VDD Calibration Control 3 */
mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
data = 0x10 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
/* DFE Resolution Control */
mask = HPIPE_DFE_RES_FORCE_MASK;
data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
/* DFE F3-F5 Coefficient Control */
mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
data = 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
/* G3 Setting 3 */
mask = HPIPE_G3_FFE_CAP_SEL_MASK;
data = 0xf << HPIPE_G3_FFE_CAP_SEL_OFFSET;
mask |= HPIPE_G3_FFE_RES_SEL_MASK;
data |= 0x4 << HPIPE_G3_FFE_RES_SEL_OFFSET;
mask |= HPIPE_G3_FFE_SETTING_FORCE_MASK;
data |= 0x1 << HPIPE_G3_FFE_SETTING_FORCE_OFFSET;
mask |= HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
data |= 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
/* G3 Setting 4 */
mask = HPIPE_G3_DFE_RES_MASK;
data = 0x1 << HPIPE_G3_DFE_RES_OFFSET;
reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
/* Offset Phase Control */
mask = HPIPE_OS_PH_OFFSET_MASK;
data = 0x61 << HPIPE_OS_PH_OFFSET_OFFSET;
mask |= HPIPE_OS_PH_OFFSET_FORCE_MASK;
data |= 0x1 << HPIPE_OS_PH_OFFSET_FORCE_OFFSET;
mask |= HPIPE_OS_PH_VALID_MASK;
data |= 0x0 << HPIPE_OS_PH_VALID_OFFSET;
reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
mask = HPIPE_OS_PH_VALID_MASK;
data = 0x1 << HPIPE_OS_PH_VALID_OFFSET;
reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
mask = HPIPE_OS_PH_VALID_MASK;
data = 0x0 << HPIPE_OS_PH_VALID_OFFSET;
reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
/* Set G1 TX amplitude and TX post emphasis value */
mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
data = 0x8 << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
data |= 0x1 << HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET;
mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
data |= 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
data |= 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
/* Set G2 TX amplitude and TX post emphasis value */
mask = HPIPE_G2_SET_0_G2_TX_AMP_MASK;
data = 0xa << HPIPE_G2_SET_0_G2_TX_AMP_OFFSET;
mask |= HPIPE_G2_SET_0_G2_TX_AMP_ADJ_MASK;
data |= 0x1 << HPIPE_G2_SET_0_G2_TX_AMP_ADJ_OFFSET;
mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_MASK;
data |= 0x2 << HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET;
mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_EN_MASK;
data |= 0x1 << HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_G2_SET_0_REG, data, mask);
/* Set G3 TX amplitude and TX post emphasis value */
mask = HPIPE_G3_SET_0_G3_TX_AMP_MASK;
data = 0x1e << HPIPE_G3_SET_0_G3_TX_AMP_OFFSET;
mask |= HPIPE_G3_SET_0_G3_TX_AMP_ADJ_MASK;
data |= 0x1 << HPIPE_G3_SET_0_G3_TX_AMP_ADJ_OFFSET;
mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_MASK;
data |= 0xe << HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET;
mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_EN_MASK;
data |= 0x1 << HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET;
mask |= HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_MASK;
data |= 0x4 << HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_OFFSET;
mask |= HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_MASK;
data |= 0x0 << HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_G3_SET_0_REG, data, mask);
/* SERDES External Configuration 2 register */
mask = SD_EXTERNAL_CONFIG2_SSC_ENABLE_MASK;
data = 0x1 << SD_EXTERNAL_CONFIG2_SSC_ENABLE_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
/* DFE reset sequence */
reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
HPIPE_PWR_CTR_RST_DFE_MASK);
reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
HPIPE_PWR_CTR_RST_DFE_MASK);
/* SW reset for interrupt logic */
reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
HPIPE_PWR_CTR_SFT_RST_MASK);
reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
HPIPE_PWR_CTR_SFT_RST_MASK);
debug_exit();
return ret;
}
static int mvebu_cp110_comphy_sgmii_power_on(uint64_t comphy_base,
uint8_t comphy_index, uint32_t comphy_mode)
{
uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
uint32_t mask, data, sgmii_speed = COMPHY_GET_SPEED(comphy_mode);
int ret = 0;
debug_enter();
hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
/* configure phy selector for SGMII */
mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
comphy_mode);
/* Confiugre the lane */
debug("stage: RFU configurations - hard reset comphy\n");
/* RFU configurations - hard reset comphy */
mask = COMMON_PHY_CFG1_PWR_UP_MASK;
data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
/* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
if (sgmii_speed == COMPHY_SPEED_1_25G) {
/* SGMII 1G, SerDes speed 1.25G */
data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
} else if (sgmii_speed == COMPHY_SPEED_3_125G) {
/* HS SGMII (2.5G), SerDes speed 3.125G */
data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
} else {
/* Other rates are not supported */
ERROR("unsupported SGMII speed on comphy%d\n", comphy_index);
return -EINVAL;
}
mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
data |= 1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
/* Set hard reset */
mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
/* Release hard reset */
mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
/* Wait 1ms - until band gap and ref clock ready */
mdelay(1);
/* Make sure that 40 data bits is disabled
* This bit is not cleared by reset
*/
mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
/* Start comphy Configuration */
debug("stage: Comphy configuration\n");
/* set reference clock */
mask = HPIPE_MISC_REFCLK_SEL_MASK;
data = 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
/* Power and PLL Control */
mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
/* Loopback register */
mask = HPIPE_LOOPBACK_SEL_MASK;
data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
/* rx control 1 */
mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
data |= 0x0 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
/* DTL Control */
mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
/* Set analog parameters from ETP(HW) - for now use the default datas */
debug("stage: Analog parameters from ETP(HW)\n");
reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
/* SERDES External Configuration */
mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
ret = mvebu_cp110_comphy_is_pll_locked(comphy_base, comphy_index);
if (ret)
return ret;
/* RX init */
mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
/* check that RX init done */
addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
mask = data;
data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
if (data != 0) {
ERROR("RX init failed\n");
ret = -ETIMEDOUT;
}
debug("stage: RF Reset\n");
/* RF Reset */
mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
debug_exit();
return ret;
}
static int mvebu_cp110_comphy_xfi_power_on(uint64_t comphy_base,
uint8_t comphy_index,
uint32_t comphy_mode)
{
uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
uint32_t mask, data, speed = COMPHY_GET_SPEED(comphy_mode);
int ret = 0;
debug_enter();
if ((speed != COMPHY_SPEED_5_15625G) &&
(speed != COMPHY_SPEED_10_3125G) &&
(speed != COMPHY_SPEED_DEFAULT)) {
ERROR("comphy:%d: unsupported sfi/xfi speed\n", comphy_index);
return -EINVAL;
}
hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
/* configure phy selector for XFI/SFI */
mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
comphy_mode);
debug("stage: RFU configurations - hard reset comphy\n");
/* RFU configurations - hard reset comphy */
mask = COMMON_PHY_CFG1_PWR_UP_MASK;
data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
/* Make sure that 40 data bits is disabled
* This bit is not cleared by reset
*/
mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
/* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
data |= 0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
/* release from hard reset */
mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
/* Wait 1ms - until band gap and ref clock ready */
mdelay(1);
/* Start comphy Configuration */
debug("stage: Comphy configuration\n");
/* set reference clock */
mask = HPIPE_MISC_ICP_FORCE_MASK;
data = (speed == COMPHY_SPEED_5_15625G) ?
(0x0 << HPIPE_MISC_ICP_FORCE_OFFSET) :
(0x1 << HPIPE_MISC_ICP_FORCE_OFFSET);
mask |= HPIPE_MISC_REFCLK_SEL_MASK;
data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
/* Power and PLL Control */
mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
/* Loopback register */
mask = HPIPE_LOOPBACK_SEL_MASK;
data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
/* rx control 1 */
mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
/* DTL Control */
mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
data = 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
/* Transmitter/Receiver Speed Divider Force */
if (speed == COMPHY_SPEED_5_15625G) {
mask = HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_MASK;
data = 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET;
mask |= HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_MASK;
data |= 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET;
mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_MASK;
data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET;
mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_MASK;
data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET;
} else {
mask = HPIPE_TXDIGCK_DIV_FORCE_MASK;
data = 0x1 << HPIPE_TXDIGCK_DIV_FORCE_OFFSET;
}
reg_set(hpipe_addr + HPIPE_SPD_DIV_FORCE_REG, data, mask);
/* Set analog parameters from ETP(HW) */
debug("stage: Analog parameters from ETP(HW)\n");
/* SERDES External Configuration 2 */
mask = SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK;
data = 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
/* 0x7-DFE Resolution control */
mask = HPIPE_DFE_RES_FORCE_MASK;
data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
/* 0xd-G1_Setting_0 */
if (speed == COMPHY_SPEED_5_15625G) {
mask = HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
data = 0x6 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
} else {
mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
data = 0x1c << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
data |= 0xe << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
}
reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
/* Genration 1 setting 2 (G1_Setting_2) */
mask = HPIPE_G1_SET_2_G1_TX_EMPH0_MASK;
data = 0x0 << HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET;
mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK;
data |= 0x1 << HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask);
/* Transmitter Slew Rate Control register (tx_reg1) */
mask = HPIPE_TX_REG1_TX_EMPH_RES_MASK;
data = 0x3 << HPIPE_TX_REG1_TX_EMPH_RES_OFFSET;
mask |= HPIPE_TX_REG1_SLC_EN_MASK;
data |= 0x3f << HPIPE_TX_REG1_SLC_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_TX_REG1_REG, data, mask);
/* Impedance Calibration Control register (cal_reg1) */
mask = HPIPE_CAL_REG_1_EXT_TXIMP_MASK;
data = 0xe << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
mask |= HPIPE_CAL_REG_1_EXT_TXIMP_EN_MASK;
data |= 0x1 << HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_CAL_REG1_REG, data, mask);
/* Generation 1 Setting 5 (g1_setting_5) */
mask = HPIPE_G1_SETTING_5_G1_ICP_MASK;
data = 0 << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
reg_set(hpipe_addr + HPIPE_G1_SETTING_5_REG, data, mask);
/* 0xE-G1_Setting_1 */
mask = HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
data = 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
if (speed == COMPHY_SPEED_5_15625G) {
mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK;
data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET;
} else {
mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
data |= 0x2 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK;
data |= 0x2 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET;
mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
data |= 0x0 << HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
data |= 0x3 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
}
reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
/* 0xA-DFE_Reg3 */
mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
/* 0x111-G1_Setting_4 */
mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
/* Genration 1 setting 3 (G1_Setting_3) */
mask = HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_MASK;
data = 0x1 << HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET;
if (speed == COMPHY_SPEED_5_15625G) {
/* Force FFE (Feed Forward Equalization) to 5G */
mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
data |= 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
data |= 0x4 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
}
reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
/* Connfigure RX training timer */
mask = HPIPE_RX_TRAIN_TIMER_MASK;
data = 0x13 << HPIPE_RX_TRAIN_TIMER_OFFSET;
reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
/* Enable TX train peak to peak hold */
mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
/* Configure TX preset index */
mask = HPIPE_TX_PRESET_INDEX_MASK;
data = 0x2 << HPIPE_TX_PRESET_INDEX_OFFSET;
reg_set(hpipe_addr + HPIPE_TX_PRESET_INDEX_REG, data, mask);
/* Disable pattern lock lost timeout */
mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
/* Configure TX training pattern and TX training 16bit auto */
mask = HPIPE_TX_TRAIN_16BIT_AUTO_EN_MASK;
data = 0x1 << HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET;
mask |= HPIPE_TX_TRAIN_PAT_SEL_MASK;
data |= 0x1 << HPIPE_TX_TRAIN_PAT_SEL_OFFSET;
reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
/* Configure Training patten number */
mask = HPIPE_TRAIN_PAT_NUM_MASK;
data = 0x88 << HPIPE_TRAIN_PAT_NUM_OFFSET;
reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_0_REG, data, mask);
/* Configure differencial manchester encoter to ethernet mode */
mask = HPIPE_DME_ETHERNET_MODE_MASK;
data = 0x1 << HPIPE_DME_ETHERNET_MODE_OFFSET;
reg_set(hpipe_addr + HPIPE_DME_REG, data, mask);
/* Configure VDD Continuous Calibration */
mask = HPIPE_CAL_VDD_CONT_MODE_MASK;
data = 0x1 << HPIPE_CAL_VDD_CONT_MODE_OFFSET;
reg_set(hpipe_addr + HPIPE_VDD_CAL_0_REG, data, mask);
/* Trigger sampler enable pulse (by toggleing the bit) */
mask = HPIPE_RX_SAMPLER_OS_GAIN_MASK;
data = 0x3 << HPIPE_RX_SAMPLER_OS_GAIN_OFFSET;
mask |= HPIPE_SMAPLER_MASK;
data |= 0x1 << HPIPE_SMAPLER_OFFSET;
reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
mask = HPIPE_SMAPLER_MASK;
data = 0x0 << HPIPE_SMAPLER_OFFSET;
reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
/* Set External RX Regulator Control */
mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
data = 0x1A << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
/* SERDES External Configuration */
mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
/* check PLL rx & tx ready */
addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
SD_EXTERNAL_STATUS0_PLL_TX_MASK;
mask = data;
data = polling_with_timeout(addr, data, mask,
PLL_LOCK_TIMEOUT, REG_32BIT);
if (data != 0) {
if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
ERROR("RX PLL is not locked\n");
if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
ERROR("TX PLL is not locked\n");
ret = -ETIMEDOUT;
}
/* RX init */
mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
/* check that RX init done */
addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
mask = data;
data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
if (data != 0) {
ERROR("RX init failed\n");
ret = -ETIMEDOUT;
}
debug("stage: RF Reset\n");
/* RF Reset */
mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
debug_exit();
return ret;
}
static int mvebu_cp110_comphy_pcie_power_on(uint64_t comphy_base,
uint8_t comphy_index, uint32_t comphy_mode)
{
int ret = 0;
uint32_t reg, mask, data, pcie_width;
uint32_t clk_dir;
uintptr_t hpipe_addr, comphy_addr, addr;
_Bool clk_src = COMPHY_GET_CLK_SRC(comphy_mode);
hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
pcie_width = COMPHY_GET_PCIE_WIDTH(comphy_mode);
debug_enter();
spin_lock(&cp110_mac_reset_lock);
reg = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
SYS_CTRL_UINIT_SOFT_RESET_REG);
switch (comphy_index) {
case COMPHY_LANE0:
reg |= PCIE_MAC_RESET_MASK_PORT0;
break;
case COMPHY_LANE4:
reg |= PCIE_MAC_RESET_MASK_PORT1;
break;
case COMPHY_LANE5:
reg |= PCIE_MAC_RESET_MASK_PORT2;
break;
}
mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
SYS_CTRL_UINIT_SOFT_RESET_REG, reg);
spin_unlock(&cp110_mac_reset_lock);
/* Configure PIPE selector for PCIE */
mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
comphy_mode);
/*
* Read SAR (Sample-At-Reset) configuration for the PCIe clock
* direction.
*
* SerDes Lane 4/5 got the PCIe ref-clock #1,
* and SerDes Lane 0 got PCIe ref-clock #0
*/
reg = mmio_read_32(DFX_FROM_COMPHY_ADDR(comphy_base) +
SAR_STATUS_0_REG);
if (comphy_index == COMPHY_LANE4 || comphy_index == COMPHY_LANE5)
clk_dir = (reg & SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK) >>
SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET;
else
clk_dir = (reg & SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK) >>
SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET;
debug("On lane %d\n", comphy_index);
debug("PCIe clock direction = %x\n", clk_dir);
debug("PCIe Width = %d\n", pcie_width);
/* enable PCIe X4 and X2 */
if (comphy_index == COMPHY_LANE0) {
if (pcie_width == PCIE_LNK_X4) {
data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET;
mask = COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK;
reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
data, mask);
} else if (pcie_width == PCIE_LNK_X2) {
data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET;
mask = COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK;
reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
}
}
/* If PCIe clock is output and clock source from SerDes lane 5,
* need to configure the clock-source MUX.
* By default, the clock source is from lane 4
*/
if (clk_dir && clk_src && (comphy_index == COMPHY_LANE5)) {
data = DFX_DEV_GEN_PCIE_CLK_SRC_MUX <<
DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET;
mask = DFX_DEV_GEN_PCIE_CLK_SRC_MASK;
reg_set(DFX_FROM_COMPHY_ADDR(comphy_base) +
DFX_DEV_GEN_CTRL12_REG, data, mask);
}
debug("stage: RFU configurations - hard reset comphy\n");
/* RFU configurations - hard reset comphy */
mask = COMMON_PHY_CFG1_PWR_UP_MASK;
data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
mask |= COMMON_PHY_PHY_MODE_MASK;
data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET;
reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
/* release from hard reset */
mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
/* Wait 1ms - until band gap and ref clock ready */
mdelay(1);
/* Start comphy Configuration */
debug("stage: Comphy configuration\n");
/* Set PIPE soft reset */
mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
/* Set PHY datapath width mode for V0 */
mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
/* Set Data bus width USB mode for V0 */
mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
/* Set CORE_CLK output frequency for 250Mhz */
mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
/* Set PLL ready delay for 0x2 */
data = 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET;
mask = HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK;
if (pcie_width != PCIE_LNK_X1) {
data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET;
mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK;
data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET;
mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK;
}
reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG, data, mask);
/* Set PIPE mode interface to PCIe3 - 0x1 & set lane order */
data = 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET;
mask = HPIPE_CLK_SRC_HI_MODE_PIPE_MASK;
if (pcie_width != PCIE_LNK_X1) {
mask |= HPIPE_CLK_SRC_HI_LANE_STRT_MASK;
mask |= HPIPE_CLK_SRC_HI_LANE_MASTER_MASK;
mask |= HPIPE_CLK_SRC_HI_LANE_BREAK_MASK;
if (comphy_index == 0) {
data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET;
data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET;
} else if (comphy_index == (pcie_width - 1)) {
data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET;
}
}
reg_set(hpipe_addr + HPIPE_CLK_SRC_HI_REG, data, mask);
/* Config update polarity equalization */
data = 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET;
mask = HPIPE_CFG_UPDATE_POLARITY_MASK;
reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG1_REG, data, mask);
/* Set PIPE version 4 to mode enable */
data = 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET;
mask = HPIPE_DFE_CTRL_28_PIPE4_MASK;
reg_set(hpipe_addr + HPIPE_DFE_CTRL_28_REG, data, mask);
/* TODO: check if pcie clock is output/input - for bringup use input*/
/* Enable PIN clock 100M_125M */
mask = 0;
data = 0;
/* Only if clock is output, configure the clock-source mux */
if (clk_dir) {
mask |= HPIPE_MISC_CLK100M_125M_MASK;
data |= 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET;
}
/* Set PIN_TXDCLK_2X Clock Freq. Selection for outputs 500MHz clock */
mask |= HPIPE_MISC_TXDCLK_2X_MASK;
data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET;
/* Enable 500MHz Clock */
mask |= HPIPE_MISC_CLK500_EN_MASK;
data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET;
if (clk_dir) { /* output */
/* Set reference clock comes from group 1 */
mask |= HPIPE_MISC_REFCLK_SEL_MASK;
data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
} else {
/* Set reference clock comes from group 2 */
mask |= HPIPE_MISC_REFCLK_SEL_MASK;
data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET;
}
mask |= HPIPE_MISC_ICP_FORCE_MASK;
data |= 0x1 << HPIPE_MISC_ICP_FORCE_OFFSET;
reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
if (clk_dir) { /* output */
/* Set reference frequcency select - 0x2 for 25MHz*/
mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
} else {
/* Set reference frequcency select - 0x0 for 100MHz*/
mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
}
/* Set PHY mode to PCIe */
mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
/* ref clock alignment */
if (pcie_width != PCIE_LNK_X1) {
mask = HPIPE_LANE_ALIGN_OFF_MASK;
data = 0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET;
reg_set(hpipe_addr + HPIPE_LANE_ALIGN_REG, data, mask);
}
/* Set the amount of time spent in the LoZ state - set for 0x7 only if
* the PCIe clock is output
*/
if (clk_dir)
reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
/* Set Maximal PHY Generation Setting(8Gbps) */
mask = HPIPE_INTERFACE_GEN_MAX_MASK;
data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET;
/* Bypass frame detection and sync detection for RX DATA */
mask |= HPIPE_INTERFACE_DET_BYPASS_MASK;
data |= 0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET;
/* Set Link Train Mode (Tx training control pins are used) */
mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK;
data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET;
reg_set(hpipe_addr + HPIPE_INTERFACE_REG, data, mask);
/* Set Idle_sync enable */
mask = HPIPE_PCIE_IDLE_SYNC_MASK;
data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET;
/* Select bits for PCIE Gen3(32bit) */
mask |= HPIPE_PCIE_SEL_BITS_MASK;
data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET;
reg_set(hpipe_addr + HPIPE_PCIE_REG0, data, mask);
/* Enable Tx_adapt_g1 */
mask = HPIPE_TX_TRAIN_CTRL_G1_MASK;
data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET;
/* Enable Tx_adapt_gn1 */
mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK;
data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET;
/* Disable Tx_adapt_g0 */
mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK;
data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
/* Set reg_tx_train_chk_init */
mask = HPIPE_TX_TRAIN_CHK_INIT_MASK;
data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET;
/* Enable TX_COE_FM_PIN_PCIE3_EN */
mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK;
data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET;
reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
debug("stage: TRx training parameters\n");
/* Set Preset sweep configurations */
mask = HPIPE_TX_TX_STATUS_CHECK_MODE_MASK;
data = 0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET;
mask |= HPIPE_TX_NUM_OF_PRESET_MASK;
data |= 0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET;
mask |= HPIPE_TX_SWEEP_PRESET_EN_MASK;
data |= 0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_11_REG, data, mask);
/* Tx train start configuration */
mask = HPIPE_TX_TRAIN_START_SQ_EN_MASK;
data = 0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET;
mask |= HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK;
data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET;
mask |= HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK;
data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET;
mask |= HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK;
data |= 0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
/* Enable Tx train P2P */
mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
/* Configure Tx train timeout */
mask = HPIPE_TRX_TRAIN_TIMER_MASK;
data = 0x17 << HPIPE_TRX_TRAIN_TIMER_OFFSET;
reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_4_REG, data, mask);
/* Disable G0/G1/GN1 adaptation */
mask = HPIPE_TX_TRAIN_CTRL_G1_MASK | HPIPE_TX_TRAIN_CTRL_GN1_MASK
| HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
data = 0;
reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
/* Disable DTL frequency loop */
mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
/* Configure G3 DFE */
mask = HPIPE_G3_DFE_RES_MASK;
data = 0x3 << HPIPE_G3_DFE_RES_OFFSET;
reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
/* Use TX/RX training result for DFE */
mask = HPIPE_DFE_RES_FORCE_MASK;
data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
/* Configure initial and final coefficient value for receiver */
mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
data = 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
data |= 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
/* Trigger sampler enable pulse */
mask = HPIPE_SMAPLER_MASK;
data = 0x1 << HPIPE_SMAPLER_OFFSET;
reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
udelay(5);
reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, 0, mask);
/* FFE resistor tuning for different bandwidth */
mask = HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
data = 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
/* Pattern lock lost timeout disable */
mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
/* Configure DFE adaptations */
mask = HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK;
data = 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET;
mask |= HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK;
data |= 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET;
mask |= HPIPE_CDR_MAX_DFE_ADAPT_0_MASK;
data |= 0x0 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET;
mask |= HPIPE_CDR_MAX_DFE_ADAPT_1_MASK;
data |= 0x1 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET;
reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask);
mask = HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK;
data = 0x0 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET;
reg_set(hpipe_addr + HPIPE_DFE_CONTROL_REG, data, mask);
/* Genration 2 setting 1*/
mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
mask |= HPIPE_G2_SET_1_G2_RX_SELMUPP_MASK;
data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET;
mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
/* DFE enable */
mask = HPIPE_G2_DFE_RES_MASK;
data = 0x3 << HPIPE_G2_DFE_RES_OFFSET;
reg_set(hpipe_addr + HPIPE_G2_SETTINGS_4_REG, data, mask);
/* Configure DFE Resolution */
mask = HPIPE_LANE_CFG4_DFE_EN_SEL_MASK;
data = 0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET;
reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
/* VDD calibration control */
mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
data = 0x16 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
/* Set PLL Charge-pump Current Control */
mask = HPIPE_G3_SETTING_5_G3_ICP_MASK;
data = 0x4 << HPIPE_G3_SETTING_5_G3_ICP_OFFSET;
reg_set(hpipe_addr + HPIPE_G3_SETTING_5_REG, data, mask);
/* Set lane rqualization remote setting */
mask = HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK;
data = 0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET;
mask |= HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK;
data |= 0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET;
mask |= HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK;
data |= 0x6 << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET;
reg_set(hpipe_addr + HPIPE_LANE_EQ_REMOTE_SETTING_REG, data, mask);
mask = HPIPE_CFG_EQ_BUNDLE_DIS_MASK;
data = 0x1 << HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET;
reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG2_REG, data, mask);
debug("stage: Comphy power up\n");
/* For PCIe X4 or X2:
* release from reset only after finish to configure all lanes
*/
if ((pcie_width == PCIE_LNK_X1) || (comphy_index == (pcie_width - 1))) {
uint32_t i, start_lane, end_lane;
if (pcie_width != PCIE_LNK_X1) {
/* allows writing to all lanes in one write */
data = 0x0;
if (pcie_width == PCIE_LNK_X2)
mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
else if (pcie_width == PCIE_LNK_X4)
mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
start_lane = 0;
end_lane = pcie_width;
/* Release from PIPE soft reset
* For PCIe by4 or by2:
* release from soft reset all lanes - can't use
* read modify write
*/
reg_set(HPIPE_ADDR(
COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), 0) +
HPIPE_RST_CLK_CTRL_REG, 0x24, 0xffffffff);
} else {
start_lane = comphy_index;
end_lane = comphy_index + 1;
/* Release from PIPE soft reset
* for PCIe by4 or by2:
* release from soft reset all lanes
*/
reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
}
if (pcie_width != PCIE_LNK_X1) {
/* disable writing to all lanes with one write */
if (pcie_width == PCIE_LNK_X2) {
data = (COMPHY_LANE0 <<
COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
(COMPHY_LANE1 <<
COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET);
mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
} else if (pcie_width == PCIE_LNK_X4) {
data = (COMPHY_LANE0 <<
COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
(COMPHY_LANE1 <<
COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET) |
(COMPHY_LANE2 <<
COMMON_PHY_SD_CTRL1_COMPHY_2_PORT_OFFSET) |
(COMPHY_LANE3 <<
COMMON_PHY_SD_CTRL1_COMPHY_3_PORT_OFFSET);
mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
}
reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
data, mask);
}
debug("stage: Check PLL\n");
/* Read lane status */
for (i = start_lane; i < end_lane; i++) {
addr = HPIPE_ADDR(
COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), i) +
HPIPE_LANE_STATUS1_REG;
data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
mask = data;
ret = polling_with_timeout(addr, data, mask,
PLL_LOCK_TIMEOUT,
REG_32BIT);
if (ret)
ERROR("Failed to lock PCIE PLL\n");
}
}
debug_exit();
return ret;
}
static int mvebu_cp110_comphy_rxaui_power_on(uint64_t comphy_base,
uint8_t comphy_index, uint32_t comphy_mode)
{
uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
uint32_t mask, data;
int ret = 0;
debug_enter();
hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
/* configure phy selector for RXAUI */
mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
comphy_mode);
/* RFU configurations - hard reset comphy */
mask = COMMON_PHY_CFG1_PWR_UP_MASK;
data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
if (comphy_index == 2) {
reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
0x1 << COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET,
COMMON_PHY_SD_CTRL1_RXAUI0_MASK);
}
if (comphy_index == 4) {
reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
0x1 << COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET,
COMMON_PHY_SD_CTRL1_RXAUI1_MASK);
}
/* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
data |= 0x0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_MEDIA_MODE_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
/* release from hard reset */
mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
/* Wait 1ms - until band gap and ref clock ready */
mdelay(1);
/* Start comphy Configuration */
debug("stage: Comphy configuration\n");
/* set reference clock */
reg_set(hpipe_addr + HPIPE_MISC_REG,
0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
HPIPE_MISC_REFCLK_SEL_MASK);
/* Power and PLL Control */
mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
/* Loopback register */
reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
/* rx control 1 */
mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
/* DTL Control */
reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG,
0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET,
HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK);
/* Set analog parameters from ETP(HW) */
debug("stage: Analog parameters from ETP(HW)\n");
/* SERDES External Configuration 2 */
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG,
0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET,
SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK);
/* 0x7-DFE Resolution control */
reg_set(hpipe_addr + HPIPE_DFE_REG0, 0x1 << HPIPE_DFE_RES_FORCE_OFFSET,
HPIPE_DFE_RES_FORCE_MASK);
/* 0xd-G1_Setting_0 */
reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
0xd << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
/* 0xE-G1_Setting_1 */
mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
data = 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK;
data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET;
mask |= HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
/* 0xA-DFE_Reg3 */
mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
/* 0x111-G1_Setting_4 */
mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
/* SERDES External Configuration */
mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
/* check PLL rx & tx ready */
addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
SD_EXTERNAL_STATUS0_PLL_TX_MASK;
mask = data;
data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
if (data != 0) {
debug("Read from reg = %lx - value = 0x%x\n",
sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
ERROR("SD_EXTERNAL_STATUS0_PLL_RX is %d, -\"-_PLL_TX is %d\n",
(data & SD_EXTERNAL_STATUS0_PLL_RX_MASK),
(data & SD_EXTERNAL_STATUS0_PLL_TX_MASK));
ret = -ETIMEDOUT;
}
/* RX init */
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG,
0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET,
SD_EXTERNAL_CONFIG1_RX_INIT_MASK);
/* check that RX init done */
addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
mask = data;
data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
if (data != 0) {
debug("Read from reg = %lx - value = 0x%x\n",
sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
ERROR("SD_EXTERNAL_STATUS0_RX_INIT is 0\n");
ret = -ETIMEDOUT;
}
debug("stage: RF Reset\n");
/* RF Reset */
mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
debug_exit();
return ret;
}
static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base,
uint8_t comphy_index, uint32_t comphy_mode)
{
uintptr_t hpipe_addr, comphy_addr, addr;
uint32_t mask, data;
int ret = 0;
debug_enter();
/* Configure PIPE selector for USB3 */
mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
comphy_mode);
hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
debug("stage: RFU configurations - hard reset comphy\n");
/* RFU configurations - hard reset comphy */
mask = COMMON_PHY_CFG1_PWR_UP_MASK;
data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
mask |= COMMON_PHY_PHY_MODE_MASK;
data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET;
reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
/* release from hard reset */
mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
/* Wait 1ms - until band gap and ref clock ready */
mdelay(1);
/* Start comphy Configuration */
debug("stage: Comphy configuration\n");
/* Set PIPE soft reset */
mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
/* Set PHY datapath width mode for V0 */
mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
/* Set Data bus width USB mode for V0 */
mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
/* Set CORE_CLK output frequency for 250Mhz */
mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
/* Set PLL ready delay for 0x2 */
reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG,
0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET,
HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK);
/* Set reference clock to come from group 1 - 25Mhz */
reg_set(hpipe_addr + HPIPE_MISC_REG,
0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
HPIPE_MISC_REFCLK_SEL_MASK);
/* Set reference frequcency select - 0x2 */
mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
/* Set PHY mode to USB - 0x5 */
mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
/* Set the amount of time spent in the LoZ state - set for 0x7 */
reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
/* Set max PHY generation setting - 5Gbps */
reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
HPIPE_INTERFACE_GEN_MAX_MASK);
/* Set select data width 20Bit (SEL_BITS[2:0]) */
reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
0x1 << HPIPE_LOOPBACK_SEL_OFFSET,
HPIPE_LOOPBACK_SEL_MASK);
/* select de-emphasize 3.5db */
reg_set(hpipe_addr + HPIPE_LANE_CONFIG0_REG,
0x1 << HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET,
HPIPE_LANE_CONFIG0_TXDEEMPH0_MASK);
/* override tx margining from the MAC */
reg_set(hpipe_addr + HPIPE_TST_MODE_CTRL_REG,
0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET,
HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK);
/* Start analog parameters from ETP(HW) */
debug("stage: Analog parameters from ETP(HW)\n");
/* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */
mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK;
data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET;
/* Set Override PHY DFE control pins for 0x1 */
mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK;
data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET;
/* Set Spread Spectrum Clock Enable fot 0x1 */
mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK;
data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET;
reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
/* Confifure SSC amplitude */
mask = HPIPE_G2_TX_SSC_AMP_MASK;
data = 0x1f << HPIPE_G2_TX_SSC_AMP_OFFSET;
reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
/* End of analog parameters */
debug("stage: Comphy power up\n");
/* Release from PIPE soft reset */
reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
/* wait 15ms - for comphy calibration done */
debug("stage: Check PLL\n");
/* Read lane status */
addr = hpipe_addr + HPIPE_LANE_STATUS1_REG;
data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
mask = data;
data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
if (data != 0) {
debug("Read from reg = %lx - value = 0x%x\n",
hpipe_addr + HPIPE_LANE_STATUS1_REG, data);
ERROR("HPIPE_LANE_STATUS1_PCLK_EN_MASK is 0\n");
ret = -ETIMEDOUT;
}
debug_exit();
return ret;
}
/* This function performs RX training for one Feed Forward Equalization (FFE)
* value.
* The RX traiing result is stored in 'Saved DFE values Register' (SAV_F0D).
*
* Return '0' on success, error code in a case of failure.
*/
static int mvebu_cp110_comphy_test_single_ffe(uint64_t comphy_base,
uint8_t comphy_index,
uint32_t ffe, uint32_t *result)
{
uint32_t mask, data, timeout;
uintptr_t hpipe_addr, sd_ip_addr;
hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
/* Configure PRBS counters */
mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK;
data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET;
reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
mask = HPIPE_PHY_TEST_DATA_MASK;
data = 0x64 << HPIPE_PHY_TEST_DATA_OFFSET;
reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask);
mask = HPIPE_PHY_TEST_EN_MASK;
data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
mdelay(50);
/* Set the FFE value */
mask = HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
data = ffe << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
/* Start RX training */
mask = SD_EXTERNAL_STATUS_START_RX_TRAINING_MASK;
data = 1 << SD_EXTERNAL_STATUS_START_RX_TRAINING_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_STATUS_REG, data, mask);
/* Check the result of RX training */
timeout = RX_TRAINING_TIMEOUT;
while (timeout) {
data = mmio_read_32(sd_ip_addr + SD_EXTERNAL_STATAUS1_REG);
if (data & SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_COMP_MASK)
break;
mdelay(1);
timeout--;
}
if (timeout == 0)
return -ETIMEDOUT;
if (data & SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_FAILED_MASK)
return -EINVAL;
/* Stop RX training */
mask = SD_EXTERNAL_STATUS_START_RX_TRAINING_MASK;
data = 0 << SD_EXTERNAL_STATUS_START_RX_TRAINING_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_STATUS_REG, data, mask);
/* Read the result */
data = mmio_read_32(hpipe_addr + HPIPE_SAVED_DFE_VALUES_REG);
data &= HPIPE_SAVED_DFE_VALUES_SAV_F0D_MASK;
data >>= HPIPE_SAVED_DFE_VALUES_SAV_F0D_OFFSET;
*result = data;
mask = HPIPE_PHY_TEST_RESET_MASK;
data = 0x1 << HPIPE_PHY_TEST_RESET_OFFSET;
mask |= HPIPE_PHY_TEST_EN_MASK;
data |= 0x0 << HPIPE_PHY_TEST_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
mask = HPIPE_PHY_TEST_RESET_MASK;
data = 0x0 << HPIPE_PHY_TEST_RESET_OFFSET;
reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
return 0;
}
/* This function runs complete RX training sequence:
* - Run RX training for all possible Feed Forward Equalization values
* - Choose the FFE which gives the best result.
* - Run RX training again with the best result.
*
* Return '0' on success, error code in a case of failure.
*/
int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base,
uint8_t comphy_index)
{
uint32_t mask, data, max_rx_train = 0, max_rx_train_index = 0;
uintptr_t hpipe_addr;
uint32_t rx_train_result;
int ret, i;
hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
debug_enter();
/* Configure SQ threshold and CDR lock */
mask = HPIPE_SQUELCH_THRESH_IN_MASK;
data = 0xc << HPIPE_SQUELCH_THRESH_IN_OFFSET;
reg_set(hpipe_addr + HPIPE_SQUELCH_FFE_SETTING_REG, data, mask);
mask = HPIPE_SQ_DEGLITCH_WIDTH_P_MASK;
data = 0xf << HPIPE_SQ_DEGLITCH_WIDTH_P_OFFSET;
mask |= HPIPE_SQ_DEGLITCH_WIDTH_N_MASK;
data |= 0xf << HPIPE_SQ_DEGLITCH_WIDTH_N_OFFSET;
mask |= HPIPE_SQ_DEGLITCH_EN_MASK;
data |= 0x1 << HPIPE_SQ_DEGLITCH_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_SQ_GLITCH_FILTER_CTRL, data, mask);
mask = HPIPE_CDR_LOCK_DET_EN_MASK;
data = 0x1 << HPIPE_CDR_LOCK_DET_EN_OFFSET;
reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
udelay(100);
/* Determine if we have a cable attached to this comphy, if not,
* we can't perform RX training.
*/
data = mmio_read_32(hpipe_addr + HPIPE_SQUELCH_FFE_SETTING_REG);
if (data & HPIPE_SQUELCH_DETECTED_MASK) {
ERROR("Squelsh is not detected, can't perform RX training\n");
return -EINVAL;
}
data = mmio_read_32(hpipe_addr + HPIPE_LOOPBACK_REG);
if (!(data & HPIPE_CDR_LOCK_MASK)) {
ERROR("CDR is not locked, can't perform RX training\n");
return -EINVAL;
}
/* Do preparations for RX training */
mask = HPIPE_DFE_RES_FORCE_MASK;
data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
data = 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
data |= 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
/* Perform RX training for all possible FFE (Feed Forward
* Equalization, possible values are 0-7).
* We update the best value reached and the FFE which gave this value.
*/
for (i = 0; i < MAX_NUM_OF_FFE; i++) {
rx_train_result = 0;
ret = mvebu_cp110_comphy_test_single_ffe(comphy_base,
comphy_index, i,
&rx_train_result);
if ((!ret) && (rx_train_result > max_rx_train)) {
max_rx_train = rx_train_result;
max_rx_train_index = i;
}
}
/* If we were able to determine which FFE gives the best value,
* now we need to set it and run RX training again (only for this
* FFE).
*/
if (max_rx_train) {
ret = mvebu_cp110_comphy_test_single_ffe(comphy_base,
comphy_index,
max_rx_train_index,
&rx_train_result);
if (ret == 0)
debug("RX Training passed (FFE = %d, result = 0x%x)\n",
max_rx_train_index, rx_train_result);
} else {
ERROR("RX Training failed for comphy%d\n", comphy_index);
ret = -EINVAL;
}
debug_exit();
return ret;
}
/* During AP the proper mode is auto-negotiated and the mac, pcs and serdes
* configuration are done by the firmware loaded to the MG's CM3 for appropriate
* negotiated mode. Therefore there is no need to configure the mac, pcs and
* serdes from u-boot. The only thing that need to be setup is powering up
* the comphy, which is done through Common PHY<n> Configuration 1 Register
* (CP0: 0xF2441000, CP1: 0xF4441000). This step can't be done by MG's CM3,
* since it doesn't have an access to this register-set (but it has access to
* the network registers like: MG, AP, MAC, PCS, Serdes etc.)
*/
static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base,
uint8_t comphy_index)
{
uint32_t mask, data;
uintptr_t comphy_addr = comphy_addr =
COMPHY_ADDR(comphy_base, comphy_index);
debug_enter();
debug("stage: RFU configurations - hard reset comphy\n");
/* RFU configurations - hard reset comphy */
mask = COMMON_PHY_CFG1_PWR_UP_MASK;
data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
debug_exit();
return 0;
}
/*
* This function allows to reset the digital synchronizers between
* the MAC and the PHY, it is required when the MAC changes its state.
*/
int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base,
uint8_t comphy_index,
uint32_t comphy_mode, uint32_t command)
{
int mode = COMPHY_GET_MODE(comphy_mode);
uintptr_t sd_ip_addr;
uint32_t mask, data;
sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
switch (mode) {
case (COMPHY_SGMII_MODE):
case (COMPHY_HS_SGMII_MODE):
case (COMPHY_XFI_MODE):
case (COMPHY_SFI_MODE):
case (COMPHY_RXAUI_MODE):
mask = SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
data = ((command == COMPHY_COMMAND_DIGITAL_PWR_OFF) ?
0x0 : 0x1) << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
break;
default:
ERROR("comphy%d: Digital PWR ON/OFF is not supported\n",
comphy_index);
return -EINVAL;
}
return 0;
}
int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint64_t comphy_index,
uint64_t comphy_mode)
{
int mode = COMPHY_GET_MODE(comphy_mode);
int err = 0;
debug_enter();
switch (mode) {
case(COMPHY_SATA_MODE):
err = mvebu_cp110_comphy_sata_power_on(comphy_base,
comphy_index,
comphy_mode);
break;
case(COMPHY_SGMII_MODE):
case(COMPHY_HS_SGMII_MODE):
err = mvebu_cp110_comphy_sgmii_power_on(comphy_base,
comphy_index,
comphy_mode);
break;
/* From comphy perspective, XFI and SFI are the same */
case (COMPHY_XFI_MODE):
case (COMPHY_SFI_MODE):
err = mvebu_cp110_comphy_xfi_power_on(comphy_base,
comphy_index,
comphy_mode);
break;
case (COMPHY_PCIE_MODE):
err = mvebu_cp110_comphy_pcie_power_on(comphy_base,
comphy_index,
comphy_mode);
break;
case (COMPHY_RXAUI_MODE):
err = mvebu_cp110_comphy_rxaui_power_on(comphy_base,
comphy_index,
comphy_mode);
case (COMPHY_USB3H_MODE):
case (COMPHY_USB3D_MODE):
err = mvebu_cp110_comphy_usb3_power_on(comphy_base,
comphy_index,
comphy_mode);
break;
case (COMPHY_AP_MODE):
err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index);
break;
default:
ERROR("comphy%lld: unsupported comphy mode\n", comphy_index);
err = -EINVAL;
break;
}
debug_exit();
return err;
}
int mvebu_cp110_comphy_power_off(uint64_t comphy_base, uint64_t comphy_index)
{
uintptr_t sd_ip_addr, comphy_ip_addr;
uint32_t mask, data;
debug_enter();
sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
comphy_index);
comphy_ip_addr = COMPHY_ADDR(comphy_base, comphy_index);
/* Hard reset the comphy, for Ethernet modes and Sata */
mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
/* PCIe reset */
spin_lock(&cp110_mac_reset_lock);
/* The mvebu_cp110_comphy_power_off will be called only from Linux (to
* override settings done by bootloader) and it will be relevant only
* to PCIe (called before check if to skip pcie power off or not).
*/
data = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
SYS_CTRL_UINIT_SOFT_RESET_REG);
switch (comphy_index) {
case COMPHY_LANE0:
data &= ~PCIE_MAC_RESET_MASK_PORT0;
break;
case COMPHY_LANE4:
data &= ~PCIE_MAC_RESET_MASK_PORT1;
break;
case COMPHY_LANE5:
data &= ~PCIE_MAC_RESET_MASK_PORT2;
break;
}
mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
SYS_CTRL_UINIT_SOFT_RESET_REG, data);
spin_unlock(&cp110_mac_reset_lock);
/* Hard reset the comphy, for PCIe and usb3 */
mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
data = 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
reg_set(comphy_ip_addr + COMMON_PHY_CFG1_REG, data, mask);
/* Clear comphy PHY and PIPE selector, can't rely on previous config. */
mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
debug_exit();
return 0;
}
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
/* Marvell CP110 SoC COMPHY unit driver */
int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base,
uint64_t comphy_index);
int mvebu_cp110_comphy_power_off(uint64_t comphy_base,
uint64_t comphy_index);
int mvebu_cp110_comphy_power_on(uint64_t comphy_base,
uint64_t comphy_index, uint64_t comphy_mode);
int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base,
uint8_t comphy_index);
int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base, uint8_t comphy_index,
uint32_t comphy_mode, uint32_t command);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment