Merge branch 'master' of git://git.denx.de/u-boot-fsl-qoriq
This commit is contained in:
commit
b217c89e85
15
README
15
README
@ -5063,6 +5063,21 @@ within that device.
|
||||
normal addressable memory via the LBC. CONFIG_SYS_LS_MC_FW_ADDR is the
|
||||
virtual address in NOR flash.
|
||||
|
||||
Freescale Layerscape Debug Server Support:
|
||||
-------------------------------------------
|
||||
The Freescale Layerscape Debug Server Support supports the loading of
|
||||
"Debug Server firmware" and triggering SP boot-rom.
|
||||
This firmware often needs to be loaded during U-Boot booting.
|
||||
|
||||
- CONFIG_FSL_DEBUG_SERVER
|
||||
Enable the Debug Server for Layerscape SoCs.
|
||||
|
||||
- CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE
|
||||
Define minimum DDR size required for debug server image
|
||||
|
||||
- CONFIG_SYS_MEM_TOP_HIDE_MIN
|
||||
Define minimum DDR size to be hided from top of the DDR memory
|
||||
|
||||
Building the Software:
|
||||
======================
|
||||
|
||||
|
@ -12,3 +12,7 @@ obj-y += fsl_epu.o
|
||||
obj-$(CONFIG_OF_LIBFDT) += fdt.o
|
||||
obj-$(CONFIG_SYS_HAS_SERDES) += fsl_ls1_serdes.o ls102xa_serdes.o
|
||||
obj-$(CONFIG_SPL) += spl.o
|
||||
|
||||
ifdef CONFIG_ARMV7_PSCI
|
||||
obj-y += psci.o
|
||||
endif
|
||||
|
@ -29,29 +29,30 @@ void ft_fixup_enet_phy_connect_type(void *fdt)
|
||||
char phy[16];
|
||||
int phy_node;
|
||||
int i = 0;
|
||||
int enet_id = 0;
|
||||
uint32_t ph;
|
||||
|
||||
while ((dev = eth_get_dev_by_index(i++)) != NULL) {
|
||||
if (strstr(dev->name, "eTSEC1"))
|
||||
enet_id = 0;
|
||||
else if (strstr(dev->name, "eTSEC2"))
|
||||
enet_id = 1;
|
||||
else if (strstr(dev->name, "eTSEC3"))
|
||||
enet_id = 2;
|
||||
else
|
||||
if (strstr(dev->name, "eTSEC1")) {
|
||||
strcpy(enet, "ethernet0");
|
||||
strcpy(phy, "enet0_rgmii_phy");
|
||||
} else if (strstr(dev->name, "eTSEC2")) {
|
||||
strcpy(enet, "ethernet1");
|
||||
strcpy(phy, "enet1_rgmii_phy");
|
||||
} else if (strstr(dev->name, "eTSEC3")) {
|
||||
strcpy(enet, "ethernet2");
|
||||
strcpy(phy, "enet2_rgmii_phy");
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
priv = dev->priv;
|
||||
if (priv->flags & TSEC_SGMII)
|
||||
continue;
|
||||
|
||||
sprintf(enet, "ethernet%d", enet_id);
|
||||
enet_path = fdt_get_alias(fdt, enet);
|
||||
if (!enet_path)
|
||||
continue;
|
||||
|
||||
sprintf(phy, "enet%d_rgmii_phy", enet_id);
|
||||
phy_path = fdt_get_alias(fdt, phy);
|
||||
if (!phy_path)
|
||||
continue;
|
||||
|
126
arch/arm/cpu/armv7/ls102xa/psci.S
Normal file
126
arch/arm/cpu/armv7/ls102xa/psci.S
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
* Author: Wang Dongsheng <dongsheng.wang@freescale.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#include <asm/armv7.h>
|
||||
#include <asm/arch-armv7/generictimer.h>
|
||||
#include <asm/psci.h>
|
||||
|
||||
#define SCFG_CORE0_SFT_RST 0x130
|
||||
#define SCFG_CORESRENCR 0x204
|
||||
|
||||
#define DCFG_CCSR_BRR 0x0E4
|
||||
#define DCFG_CCSR_SCRATCHRW1 0x200
|
||||
|
||||
.pushsection ._secure.text, "ax"
|
||||
|
||||
.arch_extension sec
|
||||
|
||||
#define ONE_MS (GENERIC_TIMER_CLK / 1000)
|
||||
#define RESET_WAIT (30 * ONE_MS)
|
||||
|
||||
@ r1 = target CPU
|
||||
@ r2 = target PC
|
||||
.globl psci_cpu_on
|
||||
psci_cpu_on:
|
||||
push {lr}
|
||||
|
||||
@ Clear and Get the correct CPU number
|
||||
@ r1 = 0xf01
|
||||
and r1, r1, #0xff
|
||||
|
||||
mov r0, r1
|
||||
bl psci_get_cpu_stack_top
|
||||
str r2, [r0]
|
||||
dsb
|
||||
|
||||
@ Get DCFG base address
|
||||
movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
|
||||
movt r4, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16)
|
||||
|
||||
@ Detect target CPU state
|
||||
ldr r2, [r4, #DCFG_CCSR_BRR]
|
||||
rev r2, r2
|
||||
lsr r2, r2, r1
|
||||
ands r2, r2, #1
|
||||
beq holdoff_release
|
||||
|
||||
@ Reset target CPU
|
||||
@ Get SCFG base address
|
||||
movw r0, #(CONFIG_SYS_FSL_SCFG_ADDR & 0xffff)
|
||||
movt r0, #(CONFIG_SYS_FSL_SCFG_ADDR >> 16)
|
||||
|
||||
@ Enable CORE Soft Reset
|
||||
movw r5, #0
|
||||
movt r5, #(1 << 15)
|
||||
rev r5, r5
|
||||
str r5, [r0, #SCFG_CORESRENCR]
|
||||
|
||||
@ Get CPUx offset register
|
||||
mov r6, #0x4
|
||||
mul r6, r6, r1
|
||||
add r2, r0, r6
|
||||
|
||||
@ Do reset on target CPU
|
||||
movw r5, #0
|
||||
movt r5, #(1 << 15)
|
||||
rev r5, r5
|
||||
str r5, [r2, #SCFG_CORE0_SFT_RST]
|
||||
|
||||
@ Wait target CPU up
|
||||
timer_wait r2, RESET_WAIT
|
||||
|
||||
@ Disable CORE soft reset
|
||||
mov r5, #0
|
||||
str r5, [r0, #SCFG_CORESRENCR]
|
||||
|
||||
holdoff_release:
|
||||
@ Release on target CPU
|
||||
ldr r2, [r4, #DCFG_CCSR_BRR]
|
||||
mov r6, #1
|
||||
lsl r6, r6, r1 @ 32 bytes per CPU
|
||||
|
||||
rev r6, r6
|
||||
orr r2, r2, r6
|
||||
str r2, [r4, #DCFG_CCSR_BRR]
|
||||
|
||||
@ Set secondary boot entry
|
||||
ldr r6, =psci_cpu_entry
|
||||
rev r6, r6
|
||||
str r6, [r4, #DCFG_CCSR_SCRATCHRW1]
|
||||
|
||||
isb
|
||||
dsb
|
||||
|
||||
@ Return
|
||||
mov r0, #ARM_PSCI_RET_SUCCESS
|
||||
|
||||
pop {lr}
|
||||
bx lr
|
||||
|
||||
.globl psci_cpu_off
|
||||
psci_cpu_off:
|
||||
bl psci_cpu_off_common
|
||||
|
||||
1: wfi
|
||||
b 1b
|
||||
|
||||
.globl psci_arch_init
|
||||
psci_arch_init:
|
||||
mov r6, lr
|
||||
|
||||
bl psci_get_cpu_id
|
||||
bl psci_get_cpu_stack_top
|
||||
mov sp, r0
|
||||
|
||||
bx r6
|
||||
|
||||
.globl psci_text_end
|
||||
psci_text_end:
|
||||
.popsection
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <asm/arch-armv7/generictimer.h>
|
||||
#include <asm/gic.h>
|
||||
#include <asm/macro.h>
|
||||
#include <asm/psci.h>
|
||||
@ -43,26 +45,6 @@
|
||||
#define GICD_BASE 0x1c81000
|
||||
#define GICC_BASE 0x1c82000
|
||||
|
||||
.macro timer_wait reg, ticks
|
||||
@ Program CNTP_TVAL
|
||||
movw \reg, #(\ticks & 0xffff)
|
||||
movt \reg, #(\ticks >> 16)
|
||||
mcr p15, 0, \reg, c14, c2, 0
|
||||
isb
|
||||
@ Enable physical timer, mask interrupt
|
||||
mov \reg, #3
|
||||
mcr p15, 0, \reg, c14, c2, 1
|
||||
@ Poll physical timer until ISTATUS is on
|
||||
1: isb
|
||||
mrc p15, 0, \reg, c14, c2, 1
|
||||
ands \reg, \reg, #4
|
||||
bne 1b
|
||||
@ Disable timer
|
||||
mov \reg, #0
|
||||
mcr p15, 0, \reg, c14, c2, 1
|
||||
isb
|
||||
.endm
|
||||
|
||||
.globl psci_fiq_enter
|
||||
psci_fiq_enter:
|
||||
push {r0-r12}
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <asm/arch-armv7/generictimer.h>
|
||||
#include <asm/gic.h>
|
||||
#include <asm/macro.h>
|
||||
#include <asm/psci.h>
|
||||
@ -43,26 +45,6 @@
|
||||
#define GICD_BASE 0x1c81000
|
||||
#define GICC_BASE 0x1c82000
|
||||
|
||||
.macro timer_wait reg, ticks
|
||||
@ Program CNTP_TVAL
|
||||
movw \reg, #(\ticks & 0xffff)
|
||||
movt \reg, #(\ticks >> 16)
|
||||
mcr p15, 0, \reg, c14, c2, 0
|
||||
isb
|
||||
@ Enable physical timer, mask interrupt
|
||||
mov \reg, #3
|
||||
mcr p15, 0, \reg, c14, c2, 1
|
||||
@ Poll physical timer until ISTATUS is on
|
||||
1: isb
|
||||
mrc p15, 0, \reg, c14, c2, 1
|
||||
ands \reg, \reg, #4
|
||||
bne 1b
|
||||
@ Disable timer
|
||||
mov \reg, #0
|
||||
mcr p15, 0, \reg, c14, c2, 1
|
||||
isb
|
||||
.endm
|
||||
|
||||
.globl psci_fiq_enter
|
||||
psci_fiq_enter:
|
||||
push {r0-r12}
|
||||
|
@ -9,6 +9,31 @@ Freescale LayerScape with Chassis Generation 3
|
||||
This architecture supports Freescale ARMv8 SoCs with Chassis generation 3,
|
||||
for example LS2085A.
|
||||
|
||||
DDR Layout
|
||||
============
|
||||
Entire DDR region splits into two regions.
|
||||
- Region 1 is at address 0x8000_0000 to 0xffff_ffff.
|
||||
- Region 2 is at 0x80_8000_0000 to the top of total memory,
|
||||
for example 16GB, 0x83_ffff_ffff.
|
||||
|
||||
All DDR memory is marked as cache-enabled.
|
||||
|
||||
When MC and Debug server is enabled, they carve 512MB away from the high
|
||||
end of DDR. For example, if the total DDR is 16GB, it shrinks to 15.5GB
|
||||
with MC and Debug server enabled. Linux only sees 15.5GB.
|
||||
|
||||
The reserved 512MB layout looks like
|
||||
|
||||
+---------------+ <-- top/end of memory
|
||||
| 256MB | debug server
|
||||
+---------------+
|
||||
| 256MB | MC
|
||||
+---------------+
|
||||
| ... |
|
||||
|
||||
MC requires the memory to be aligned with 512MB, so even debug server is
|
||||
not enabled, 512MB is reserved, not 256MB.
|
||||
|
||||
Flash Layout
|
||||
============
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <asm/system.h>
|
||||
#include <asm/armv8/mmu.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-fsl-lsch3/soc.h>
|
||||
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
|
||||
#include <fsl_debug_server.h>
|
||||
#include <fsl-mc/fsl_mc.h>
|
||||
@ -22,6 +23,35 @@
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static struct cpu_type cpu_type_list[] = {
|
||||
#ifdef CONFIG_LS2085A
|
||||
CPU_TYPE_ENTRY(LS2085, LS2085, 8),
|
||||
CPU_TYPE_ENTRY(LS2080, LS2080, 8),
|
||||
CPU_TYPE_ENTRY(LS2045, LS2045, 4),
|
||||
#endif
|
||||
};
|
||||
|
||||
void cpu_name(char *name)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
unsigned int i, svr, ver;
|
||||
|
||||
svr = in_le32(&gur->svr);
|
||||
ver = SVR_SOC_VER(svr);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++)
|
||||
if ((cpu_type_list[i].soc_ver & SVR_WO_E) == ver) {
|
||||
strcpy(name, cpu_type_list[i].name);
|
||||
|
||||
if (IS_E_PROCESSOR(svr))
|
||||
strcat(name, "E");
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(cpu_type_list))
|
||||
strcpy(name, "unknown");
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SYS_DCACHE_OFF
|
||||
/*
|
||||
* To start MMU before DDR is available, we create MMU table in SRAM.
|
||||
@ -52,6 +82,12 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
TCR_ORGN_NC | \
|
||||
TCR_IRGN_NC | \
|
||||
TCR_T0SZ(LSCH3_VA_BITS))
|
||||
#define LSCH3_TCR_FINAL (TCR_TG0_4K | \
|
||||
TCR_EL2_PS_40BIT | \
|
||||
TCR_SHARED_OUTER | \
|
||||
TCR_ORGN_WBWA | \
|
||||
TCR_IRGN_WBWA | \
|
||||
TCR_T0SZ(LSCH3_VA_BITS))
|
||||
|
||||
/*
|
||||
* Final MMU
|
||||
@ -236,21 +272,8 @@ static inline void final_mmu_setup(void)
|
||||
|
||||
/* point TTBR to the new table */
|
||||
el = current_el();
|
||||
asm volatile("dsb sy");
|
||||
if (el == 1) {
|
||||
asm volatile("msr ttbr0_el1, %0"
|
||||
: : "r" ((u64)level0_table) : "memory");
|
||||
} else if (el == 2) {
|
||||
asm volatile("msr ttbr0_el2, %0"
|
||||
: : "r" ((u64)level0_table) : "memory");
|
||||
} else if (el == 3) {
|
||||
asm volatile("msr ttbr0_el3, %0"
|
||||
: : "r" ((u64)level0_table) : "memory");
|
||||
} else {
|
||||
hang();
|
||||
}
|
||||
asm volatile("isb");
|
||||
|
||||
set_ttbr_tcr_mair(el, (u64)level0_table, LSCH3_TCR_FINAL,
|
||||
MEMORY_ATTRIBUTES);
|
||||
/*
|
||||
* MMU is already enabled, just need to invalidate TLB to load the
|
||||
* new table. The new table is compatible with the current table, if
|
||||
@ -380,6 +403,13 @@ int print_cpuinfo(void)
|
||||
unsigned int i, core;
|
||||
u32 type;
|
||||
|
||||
puts("SoC: ");
|
||||
|
||||
cpu_name(buf);
|
||||
printf(" %s (0x%x)\n", buf, in_le32(&gur->svr));
|
||||
|
||||
memset((u8 *)buf, 0x00, ARRAY_SIZE(buf));
|
||||
|
||||
get_sys_info(&sysinfo);
|
||||
puts("Clock Configuration:");
|
||||
for_each_cpu(i, core, cpu_numcores(), cpu_mask()) {
|
||||
@ -394,8 +424,8 @@ int print_cpuinfo(void)
|
||||
}
|
||||
printf("\n Bus: %-4s MHz ",
|
||||
strmhz(buf, sysinfo.freq_systembus));
|
||||
printf("DDR: %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus));
|
||||
printf(" DP-DDR: %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus2));
|
||||
printf("DDR: %-4s MT/s", strmhz(buf, sysinfo.freq_ddrbus));
|
||||
printf(" DP-DDR: %-4s MT/s", strmhz(buf, sysinfo.freq_ddrbus2));
|
||||
puts("\n");
|
||||
|
||||
/* Display the RCW, so that no one gets confused as to what RCW
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <common.h>
|
||||
#include <libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include <asm/arch-fsl-lsch3/fdt.h>
|
||||
#ifdef CONFIG_FSL_ESDHC
|
||||
#include <fsl_esdhc.h>
|
||||
#endif
|
||||
@ -58,6 +59,113 @@ void ft_fixup_cpu(void *blob)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* the burden is on the the caller to not request a count
|
||||
* exceeding the bounds of the stream_ids[] array
|
||||
*/
|
||||
void alloc_stream_ids(int start_id, int count, u32 *stream_ids, int max_cnt)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (count > max_cnt) {
|
||||
printf("\n%s: ERROR: max per-device stream ID count exceed\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
stream_ids[i] = start_id++;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function updates the mmu-masters property on the SMMU
|
||||
* node as per the SMMU binding-- phandle and list of stream IDs
|
||||
* for each MMU master.
|
||||
*/
|
||||
void append_mmu_masters(void *blob, const char *smmu_path,
|
||||
const char *master_name, u32 *stream_ids, int count)
|
||||
{
|
||||
u32 phandle;
|
||||
int smmu_nodeoffset;
|
||||
int master_nodeoffset;
|
||||
int i;
|
||||
|
||||
/* get phandle of mmu master device */
|
||||
master_nodeoffset = fdt_path_offset(blob, master_name);
|
||||
if (master_nodeoffset < 0) {
|
||||
printf("\n%s: ERROR: master not found\n", __func__);
|
||||
return;
|
||||
}
|
||||
phandle = fdt_get_phandle(blob, master_nodeoffset);
|
||||
if (!phandle) { /* if master has no phandle, create one */
|
||||
phandle = fdt_create_phandle(blob, master_nodeoffset);
|
||||
if (!phandle) {
|
||||
printf("\n%s: ERROR: unable to create phandle\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* append it to mmu-masters */
|
||||
smmu_nodeoffset = fdt_path_offset(blob, smmu_path);
|
||||
if (fdt_appendprop_u32(blob, smmu_nodeoffset, "mmu-masters",
|
||||
phandle) < 0) {
|
||||
printf("\n%s: ERROR: unable to update SMMU node\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* for each stream ID, append to mmu-masters */
|
||||
for (i = 0; i < count; i++) {
|
||||
fdt_appendprop_u32(blob, smmu_nodeoffset, "mmu-masters",
|
||||
stream_ids[i]);
|
||||
}
|
||||
|
||||
/* fix up #stream-id-cells with stream ID count */
|
||||
if (fdt_setprop_u32(blob, master_nodeoffset, "#stream-id-cells",
|
||||
count) < 0)
|
||||
printf("\n%s: ERROR: unable to update #stream-id-cells\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The info below summarizes how streamID partitioning works
|
||||
* for ls2085a and how it is conveyed to the OS via the device tree.
|
||||
*
|
||||
* -non-PCI legacy, platform devices (USB, SD/MMC, SATA, DMA)
|
||||
* -all legacy devices get a unique ICID assigned and programmed in
|
||||
* their AMQR registers by u-boot
|
||||
* -u-boot updates the hardware device tree with streamID properties
|
||||
* for each platform/legacy device (smmu-masters property)
|
||||
*
|
||||
* -PCIe
|
||||
* -for each PCI controller that is active (as per RCW settings),
|
||||
* u-boot will allocate a range of ICID and convey that to Linux via
|
||||
* the device tree (smmu-masters property)
|
||||
*
|
||||
* -DPAA2
|
||||
* -u-boot will allocate a range of ICIDs to be used by the Management
|
||||
* Complex for containers and will set these values in the MC DPC image.
|
||||
* -the MC is responsible for allocating and setting up ICIDs
|
||||
* for all DPAA2 devices.
|
||||
*
|
||||
*/
|
||||
static void fdt_fixup_smmu(void *blob)
|
||||
{
|
||||
int nodeoffset;
|
||||
|
||||
nodeoffset = fdt_path_offset(blob, "/iommu@5000000");
|
||||
if (nodeoffset < 0) {
|
||||
printf("\n%s: WARNING: no SMMU node found\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* fixup for all PCI controllers */
|
||||
#ifdef CONFIG_PCI
|
||||
fdt_fixup_smmu_pcie(blob);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ft_cpu_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
#ifdef CONFIG_MP
|
||||
@ -69,7 +177,13 @@ void ft_cpu_setup(void *blob, bd_t *bd)
|
||||
"clock-frequency", CONFIG_SYS_NS16550_CLK, 1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
ft_pci_setup(blob, bd);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FSL_ESDHC)
|
||||
fdt_fixup_esdhc(blob, bd);
|
||||
#endif
|
||||
|
||||
fdt_fixup_smmu(blob);
|
||||
}
|
||||
|
@ -180,6 +180,8 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
|
||||
switch (clk) {
|
||||
case MXC_I2C_CLK:
|
||||
return get_bus_freq(0) / 2;
|
||||
case MXC_DSPI_CLK:
|
||||
return get_bus_freq(0) / 2;
|
||||
default:
|
||||
printf("Unsupported clock\n");
|
||||
}
|
||||
|
@ -115,18 +115,18 @@ apply_a57_core_errata:
|
||||
#ifdef CONFIG_ARM_ERRATA_828024
|
||||
mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
|
||||
/* Disable non-allocate hint of w-b-n-a memory type */
|
||||
mov x0, #0x1 << 49
|
||||
orr x0, x0, #1 << 49
|
||||
/* Disable write streaming no L1-allocate threshold */
|
||||
mov x0, #0x3 << 25
|
||||
orr x0, x0, #3 << 25
|
||||
/* Disable write streaming no-allocate threshold */
|
||||
mov x0, #0x3 << 27
|
||||
orr x0, x0, #3 << 27
|
||||
msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM_ERRATA_826974
|
||||
mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
|
||||
/* Disable speculative load execution ahead of a DMB */
|
||||
mov x0, #0x1 << 59
|
||||
orr x0, x0, #1 << 59
|
||||
msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
|
||||
#endif
|
||||
|
||||
|
@ -57,6 +57,8 @@ dtb-$(CONFIG_TARGET_STV0991) += stv0991.dtb
|
||||
|
||||
dtb-$(CONFIG_LS102XA) += ls1021a-qds.dtb \
|
||||
ls1021a-twr.dtb
|
||||
dtb-$(CONFIG_FSL_LSCH3) += fsl-ls2085a-qds.dtb \
|
||||
fsl-ls2085a-rdb.dtb
|
||||
|
||||
dtb-$(CONFIG_MACH_SUN4I) += \
|
||||
sun4i-a10-a1000.dtb \
|
||||
|
53
arch/arm/dts/fsl-ls2085a-qds.dts
Normal file
53
arch/arm/dts/fsl-ls2085a-qds.dts
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Freescale ls2085a QDS board device tree source
|
||||
*
|
||||
* Copyright 2013-2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "fsl-ls2085a.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Freescale Layerscape 2085a QDS Board";
|
||||
compatible = "fsl,ls2085a-qds", "fsl,ls2085a";
|
||||
|
||||
aliases {
|
||||
spi1 = &dspi;
|
||||
};
|
||||
};
|
||||
|
||||
&dspi {
|
||||
bus-num = <0>;
|
||||
status = "okay";
|
||||
|
||||
dflash0: n25q128a {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "spi-flash";
|
||||
spi-max-frequency = <3000000>;
|
||||
spi-cpol;
|
||||
spi-cpha;
|
||||
reg = <0>;
|
||||
};
|
||||
dflash1: sst25wf040b {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "spi-flash";
|
||||
spi-max-frequency = <3000000>;
|
||||
spi-cpol;
|
||||
spi-cpha;
|
||||
reg = <1>;
|
||||
};
|
||||
dflash2: en25s64 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "spi-flash";
|
||||
spi-max-frequency = <3000000>;
|
||||
spi-cpol;
|
||||
spi-cpha;
|
||||
reg = <2>;
|
||||
};
|
||||
};
|
35
arch/arm/dts/fsl-ls2085a-rdb.dts
Normal file
35
arch/arm/dts/fsl-ls2085a-rdb.dts
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Freescale ls2085a RDB board device tree source
|
||||
*
|
||||
* Copyright 2013-2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "fsl-ls2085a.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Freescale Layerscape 2085a RDB Board";
|
||||
compatible = "fsl,ls2085a-rdb", "fsl,ls2085a";
|
||||
|
||||
aliases {
|
||||
spi1 = &dspi;
|
||||
};
|
||||
};
|
||||
|
||||
&dspi {
|
||||
bus-num = <0>;
|
||||
status = "okay";
|
||||
|
||||
dflash0: n25q512a {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "spi-flash";
|
||||
spi-max-frequency = <3000000>;
|
||||
spi-cpol;
|
||||
spi-cpha;
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
129
arch/arm/dts/fsl-ls2085a.dtsi
Normal file
129
arch/arm/dts/fsl-ls2085a.dtsi
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Freescale ls2085a SOC common device tree source
|
||||
*
|
||||
* Copyright 2013-2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/ {
|
||||
compatible = "fsl,ls2085a";
|
||||
interrupt-parent = <&gic>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/*
|
||||
* We expect the enable-method for cpu's to be "psci", but this
|
||||
* is dependent on the SoC FW, which will fill this in.
|
||||
*
|
||||
* Currently supported enable-method is psci v0.2
|
||||
*/
|
||||
|
||||
/* We have 4 clusters having 2 Cortex-A57 cores each */
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a57";
|
||||
reg = <0x0 0x0>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a57";
|
||||
reg = <0x0 0x1>;
|
||||
};
|
||||
|
||||
cpu@100 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a57";
|
||||
reg = <0x0 0x100>;
|
||||
};
|
||||
|
||||
cpu@101 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a57";
|
||||
reg = <0x0 0x101>;
|
||||
};
|
||||
|
||||
cpu@200 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a57";
|
||||
reg = <0x0 0x200>;
|
||||
};
|
||||
|
||||
cpu@201 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a57";
|
||||
reg = <0x0 0x201>;
|
||||
};
|
||||
|
||||
cpu@300 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a57";
|
||||
reg = <0x0 0x300>;
|
||||
};
|
||||
|
||||
cpu@301 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a57";
|
||||
reg = <0x0 0x301>;
|
||||
};
|
||||
};
|
||||
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x80000000 0 0x80000000>;
|
||||
/* DRAM space - 1, size : 2 GB DRAM */
|
||||
};
|
||||
|
||||
gic: interrupt-controller@6000000 {
|
||||
compatible = "arm,gic-v3";
|
||||
reg = <0x0 0x06000000 0 0x10000>, /* GIC Dist */
|
||||
<0x0 0x06100000 0 0x100000>; /* GICR (RD_base + SGI_base) */
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-controller;
|
||||
interrupts = <1 9 0x4>;
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv8-timer";
|
||||
interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
|
||||
<1 14 0x8>, /* Physical Non-Secure PPI, active-low */
|
||||
<1 11 0x8>, /* Virtual PPI, active-low */
|
||||
<1 10 0x8>; /* Hypervisor PPI, active-low */
|
||||
};
|
||||
|
||||
serial0: serial@21c0500 {
|
||||
device_type = "serial";
|
||||
compatible = "fsl,ns16550", "ns16550a";
|
||||
reg = <0x0 0x21c0500 0x0 0x100>;
|
||||
clock-frequency = <0>; /* Updated by bootloader */
|
||||
interrupts = <0 32 0x1>; /* edge triggered */
|
||||
};
|
||||
|
||||
serial1: serial@21c0600 {
|
||||
device_type = "serial";
|
||||
compatible = "fsl,ns16550", "ns16550a";
|
||||
reg = <0x0 0x21c0600 0x0 0x100>;
|
||||
clock-frequency = <0>; /* Updated by bootloader */
|
||||
interrupts = <0 32 0x1>; /* edge triggered */
|
||||
};
|
||||
|
||||
fsl_mc: fsl-mc@80c000000 {
|
||||
compatible = "fsl,qoriq-mc";
|
||||
reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */
|
||||
<0x00000000 0x08340000 0 0x40000>; /* MC control reg */
|
||||
};
|
||||
|
||||
dspi: dspi@2100000 {
|
||||
compatible = "fsl,vf610-dspi";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x0 0x2100000 0x0 0x10000>;
|
||||
interrupts = <0 26 0x4>; /* Level high type */
|
||||
num-cs = <6>;
|
||||
};
|
||||
};
|
50
arch/arm/include/asm/arch-armv7/generictimer.h
Normal file
50
arch/arm/include/asm/arch-armv7/generictimer.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2013 - ARM Ltd
|
||||
* Author: Marc Zyngier <marc.zyngier@arm.com>
|
||||
*
|
||||
* Based on code by Carl van Schaik <carl@ok-labs.com>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _GENERICTIMER_H_
|
||||
#define _GENERICTIMER_H_
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* This macro provide a physical timer that can be used for delay in the code.
|
||||
* The macro is moved from sunxi/psci_sun7i.S
|
||||
*
|
||||
* reg: is used in this macro.
|
||||
* ticks: The freq is based on generic timer.
|
||||
*/
|
||||
.macro timer_wait reg, ticks
|
||||
movw \reg, #(\ticks & 0xffff)
|
||||
movt \reg, #(\ticks >> 16)
|
||||
mcr p15, 0, \reg, c14, c2, 0
|
||||
isb
|
||||
mov \reg, #3
|
||||
mcr p15, 0, \reg, c14, c2, 1
|
||||
1 : isb
|
||||
mrc p15, 0, \reg, c14, c2, 1
|
||||
ands \reg, \reg, #4
|
||||
bne 1b
|
||||
mov \reg, #0
|
||||
mcr p15, 0, \reg, c14, c2, 1
|
||||
isb
|
||||
.endm
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _GENERICTIMER_H_ */
|
@ -16,6 +16,7 @@ enum mxc_clock {
|
||||
MXC_UART_CLK,
|
||||
MXC_ESDHC_CLK,
|
||||
MXC_I2C_CLK,
|
||||
MXC_DSPI_CLK,
|
||||
};
|
||||
|
||||
unsigned int mxc_get_clock(enum mxc_clock clk);
|
||||
|
@ -137,6 +137,8 @@
|
||||
#define DCFG_PORSR1 0x000
|
||||
#define DCFG_PORSR1_RCW_SRC 0xff800000
|
||||
#define DCFG_PORSR1_RCW_SRC_NOR 0x12f00000
|
||||
#define DCFG_RCWSR13 0x130
|
||||
#define DCFG_RCWSR13_DSPI (0 << 8)
|
||||
|
||||
#define DCFG_DCSR_BASE 0X700100000ULL
|
||||
#define DCFG_DCSR_PORCR1 0x000
|
||||
|
10
arch/arm/include/asm/arch-fsl-lsch3/fdt.h
Normal file
10
arch/arm/include/asm/arch-fsl-lsch3/fdt.h
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
void alloc_stream_ids(int start_id, int count, u32 *stream_ids, int max_cnt);
|
||||
void append_mmu_masters(void *blob, const char *smmu_path,
|
||||
const char *master_name, u32 *stream_ids, int count);
|
||||
void fdt_fixup_smmu_pcie(void *blob);
|
64
arch/arm/include/asm/arch-fsl-lsch3/ls2085a_stream_id.h
Normal file
64
arch/arm/include/asm/arch-fsl-lsch3/ls2085a_stream_id.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
*/
|
||||
#ifndef __FSL_STREAM_ID_H
|
||||
#define __FSL_STREAM_ID_H
|
||||
|
||||
/* Stream IDs on ls2085a devices are not hardwired and are
|
||||
* programmed by sw. There are a limited number of stream IDs
|
||||
* available, and the partitioning of them is scenario dependent.
|
||||
* This header defines the partitioning between legacy, PCI,
|
||||
* and DPAA2 devices.
|
||||
*
|
||||
* This partitiong can be customized in this file depending
|
||||
* on the specific hardware config-- e.g. perhaps not all
|
||||
* PEX controllers are in use.
|
||||
*
|
||||
* On LS2085 stream IDs are programmed in AMQ registers (32-bits) for
|
||||
* each of the different bus masters. The relationship between
|
||||
* the AMQ registers and stream IDs is defined in the table below:
|
||||
* AMQ bit streamID bit
|
||||
* ---------------------------
|
||||
* PL[18] 9
|
||||
* BMT[17] 8
|
||||
* VA[16] 7
|
||||
* [15] -
|
||||
* ICID[14:7] -
|
||||
* ICID[6:0] 6-0
|
||||
* ----------------------------
|
||||
*/
|
||||
|
||||
#define AMQ_PL_MASK (0x1 << 18) /* priviledge bit */
|
||||
#define AMQ_BMT_MASK (0x1 << 17) /* bypass bit */
|
||||
|
||||
#define FSL_INVALID_STREAM_ID 0
|
||||
|
||||
#define FSL_BYPASS_AMQ (AMQ_PL_MASK | AMQ_BMT_MASK)
|
||||
|
||||
/* legacy devices */
|
||||
#define FSL_USB1_STREAM_ID 1
|
||||
#define FSL_USB2_STREAM_ID 2
|
||||
#define FSL_SDMMC_STREAM_ID 3
|
||||
#define FSL_SATA1_STREAM_ID 4
|
||||
#define FSL_SATA2_STREAM_ID 5
|
||||
#define FSL_DMA_STREAM_ID 6
|
||||
|
||||
/* PCI - programmed in PEXn_LUT by OS */
|
||||
/* 4 IDs per controller */
|
||||
#define FSL_PEX1_STREAM_ID_START 7
|
||||
#define FSL_PEX1_STREAM_ID_END 10
|
||||
#define FSL_PEX2_STREAM_ID_START 11
|
||||
#define FSL_PEX2_STREAM_ID_END 14
|
||||
#define FSL_PEX3_STREAM_ID_START 15
|
||||
#define FSL_PEX3_STREAM_ID_END 18
|
||||
#define FSL_PEX4_STREAM_ID_START 19
|
||||
#define FSL_PEX4_STREAM_ID_END 22
|
||||
|
||||
/* DPAA2 - set in MC DPC and alloced by MC */
|
||||
#define FSL_DPAA2_STREAM_ID_START 23
|
||||
#define FSL_DPAA2_STREAM_ID_END 63
|
||||
|
||||
#endif
|
@ -4,5 +4,25 @@
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
void fsl_lsch3_early_init_f(void);
|
||||
struct cpu_type {
|
||||
char name[15];
|
||||
u32 soc_ver;
|
||||
u32 num_cores;
|
||||
};
|
||||
|
||||
#define CPU_TYPE_ENTRY(n, v, nc) \
|
||||
{ .name = #n, .soc_ver = SVR_##v, .num_cores = (nc)}
|
||||
|
||||
#define SVR_WO_E 0xFFFFFE
|
||||
#define SVR_LS2045 0x870120
|
||||
#define SVR_LS2080 0x870110
|
||||
#define SVR_LS2085 0x870100
|
||||
|
||||
#define SVR_MAJ(svr) (((svr) >> 4) & 0xf)
|
||||
#define SVR_MIN(svr) (((svr) >> 0) & 0xf)
|
||||
#define SVR_SOC_VER(svr) (((svr) >> 8) & SVR_WO_E)
|
||||
#define IS_E_PROCESSOR(svr) (!((svr >> 8) & 0x1))
|
||||
|
||||
void fsl_lsch3_early_init_f(void);
|
||||
void cpu_name(char *name);
|
||||
|
||||
|
@ -149,6 +149,7 @@ struct ccsr_gur {
|
||||
#define SCFG_ETSECCMCR_GE1_CLK125 0x08000000
|
||||
#define SCFG_PIXCLKCR_PXCKEN 0x80000000
|
||||
#define SCFG_QSPI_CLKSEL 0xc0100000
|
||||
#define SCFG_ENDIANCR_LE 0x80000000
|
||||
|
||||
/* Supplemental Configuration Unit */
|
||||
struct ccsr_scfg {
|
||||
@ -207,7 +208,7 @@ struct ccsr_scfg {
|
||||
u32 qos2;
|
||||
u32 qos3;
|
||||
u32 cci_cfg;
|
||||
u32 resv8[1];
|
||||
u32 endiancr;
|
||||
u32 etsecdmamcr;
|
||||
u32 usb3prm3cr;
|
||||
u32 resv9[1];
|
||||
|
@ -93,8 +93,8 @@
|
||||
#define TCR_ORGN_WBNWA (3 << 10)
|
||||
#define TCR_ORGN_MASK (3 << 10)
|
||||
#define TCR_SHARED_NON (0 << 12)
|
||||
#define TCR_SHARED_OUTER (1 << 12)
|
||||
#define TCR_SHARED_INNER (2 << 12)
|
||||
#define TCR_SHARED_OUTER (2 << 12)
|
||||
#define TCR_SHARED_INNER (3 << 12)
|
||||
#define TCR_TG0_4K (0 << 14)
|
||||
#define TCR_TG0_64K (1 << 14)
|
||||
#define TCR_TG0_16K (2 << 14)
|
||||
|
@ -90,7 +90,7 @@ static void show_eeprom(void)
|
||||
/* EEPROM tag ID, either CCID or NXID */
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
printf("ID: %c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
|
||||
e.version);
|
||||
be32_to_cpu(e.version));
|
||||
#else
|
||||
printf("ID: %c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
|
||||
#endif
|
||||
@ -340,7 +340,7 @@ int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
if (cmd == 'i') {
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
memcpy(e.id, "NXID", sizeof(e.id));
|
||||
e.version = NXID_VERSION;
|
||||
e.version = cpu_to_be32(NXID_VERSION);
|
||||
#else
|
||||
memcpy(e.id, "CCID", sizeof(e.id));
|
||||
#endif
|
||||
@ -485,7 +485,7 @@ int mac_read_from_eeprom(void)
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
printf("%c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
|
||||
e.version);
|
||||
be32_to_cpu(e.version));
|
||||
#else
|
||||
printf("%c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
|
||||
#endif
|
||||
@ -496,7 +496,7 @@ int mac_read_from_eeprom(void)
|
||||
* that at boot time, U-Boot will still say "NXID v0".
|
||||
*/
|
||||
if (e.version == 0) {
|
||||
e.version = NXID_VERSION;
|
||||
e.version = cpu_to_be32(NXID_VERSION);
|
||||
update_crc();
|
||||
}
|
||||
#endif
|
||||
|
@ -209,6 +209,9 @@ int board_early_init_f(void)
|
||||
out_be32(&scfg->pixclkcr, SCFG_PIXCLKCR_PXCKEN);
|
||||
#endif
|
||||
|
||||
/* Configure Little endian for SAI, ASRC and SPDIF */
|
||||
out_be32(&scfg->endiancr, SCFG_ENDIANCR_LE);
|
||||
|
||||
/*
|
||||
* Enable snoop requests and DVM message requests for
|
||||
* Slave insterface S4 (A7 core cluster)
|
||||
|
@ -368,6 +368,9 @@ int board_early_init_f(void)
|
||||
out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
|
||||
#endif
|
||||
|
||||
/* Configure Little endian for SAI, ASRC and SPDIF */
|
||||
out_be32(&scfg->endiancr, SCFG_ENDIANCR_LE);
|
||||
|
||||
/*
|
||||
* Enable snoop requests and DVM message requests for
|
||||
* Slave insterface S4 (A7 core cluster)
|
||||
|
@ -14,3 +14,14 @@ Memory map from core's view
|
||||
|
||||
Other addresses are either reserved, or not used directly by u-boot.
|
||||
This list should be updated when more addresses are used.
|
||||
|
||||
Booting Linux flavors which do not support 48-bit VA (< Linux 3.18)
|
||||
-------------------------------------------------------------------
|
||||
One needs to use appropriate bootargs to boot Linux flavors which do
|
||||
not support 48-bit VA (for e.g. < Linux 3.18) by appending mem=2048M, as shown
|
||||
below:
|
||||
|
||||
=> setenv bootargs 'console=ttyS1,115200 root=/dev/ram
|
||||
earlycon=uart8250,mmio,0x21c0600,115200 default_hugepagesz=2m hugepagesz=2m
|
||||
hugepages=16 mem=2048M'
|
||||
|
||||
|
@ -80,7 +80,7 @@ unsigned long get_dram_size_to_hide(void)
|
||||
dram_to_hide += mc_get_dram_block_size();
|
||||
#endif
|
||||
|
||||
return dram_to_hide;
|
||||
return roundup(dram_to_hide, CONFIG_SYS_MEM_TOP_HIDE_MIN);
|
||||
}
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
@ -127,15 +127,18 @@ void fdt_fixup_board_enet(void *fdt)
|
||||
#ifdef CONFIG_OF_BOARD_SETUP
|
||||
int ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
phys_addr_t base;
|
||||
phys_size_t size;
|
||||
u64 base[CONFIG_NR_DRAM_BANKS];
|
||||
u64 size[CONFIG_NR_DRAM_BANKS];
|
||||
|
||||
ft_cpu_setup(blob, bd);
|
||||
|
||||
/* limit the memory size to bank 1 until Linux can handle 40-bit PA */
|
||||
base = getenv_bootm_low();
|
||||
size = getenv_bootm_size();
|
||||
fdt_fixup_memory(blob, (u64)base, (u64)size);
|
||||
/* fixup DT for the two GPP DDR banks */
|
||||
base[0] = gd->bd->bi_dram[0].start;
|
||||
size[0] = gd->bd->bi_dram[0].size;
|
||||
base[1] = gd->bd->bi_dram[1].start;
|
||||
size[1] = gd->bd->bi_dram[1].size;
|
||||
|
||||
fdt_fixup_memory_banks(blob, base, size, 2);
|
||||
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
fdt_fixup_board_enet(blob);
|
||||
|
@ -127,3 +127,22 @@ b) NOR boot
|
||||
c) NAND boot
|
||||
d) SD boot
|
||||
e) QSPI boot
|
||||
|
||||
Environment Variables
|
||||
---------------------
|
||||
- mcboottimeout: MC boot timeout in milliseconds. If this variable is not defined
|
||||
the value CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS will be assumed.
|
||||
|
||||
- mcmemsize: MC DRAM block size. If this variable is not defined
|
||||
the value CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE will be assumed.
|
||||
|
||||
Booting Linux flavors which do not support 48-bit VA (< Linux 3.18)
|
||||
-------------------------------------------------------------------
|
||||
One needs to use appropriate bootargs to boot Linux flavors which do
|
||||
not support 48-bit VA (for e.g. < Linux 3.18) by appending mem=2048M, as shown
|
||||
below:
|
||||
|
||||
=> setenv bootargs 'console=ttyS1,115200 root=/dev/ram
|
||||
earlycon=uart8250,mmio,0x21c0600,115200 default_hugepagesz=2m hugepagesz=2m
|
||||
hugepages=16 mem=2048M'
|
||||
|
||||
|
@ -53,7 +53,7 @@ static int riser_phy_addr[] = {
|
||||
#define EMI1_SLOT5 4
|
||||
#define EMI1_SLOT6 5
|
||||
#define EMI2 6
|
||||
#define SFP_TX 1
|
||||
#define SFP_TX 0
|
||||
|
||||
static const char * const mdio_names[] = {
|
||||
"LS2085A_QDS_MDIO0",
|
||||
@ -210,6 +210,7 @@ static void initialize_dpmac_to_slot(void)
|
||||
switch (serdes2_prtcl) {
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
case 0x49:
|
||||
printf("qds: WRIOP: Supported SerDes Protocol 0x%02x\n",
|
||||
serdes2_prtcl);
|
||||
lane_to_slot_fsm2[0] = EMI1_SLOT4;
|
||||
@ -247,6 +248,7 @@ void ls2085a_handle_phy_interface_sgmii(int dpmac_id)
|
||||
switch (serdes2_prtcl) {
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
case 0x49:
|
||||
lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
|
||||
(dpmac_id - 9));
|
||||
slot = lane_to_slot_fsm2[lane];
|
||||
|
@ -17,12 +17,23 @@
|
||||
#include <environment.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/arch-fsl-lsch3/soc.h>
|
||||
#include <hwconfig.h>
|
||||
|
||||
#include "../common/qixis.h"
|
||||
#include "ls2085aqds_qixis.h"
|
||||
|
||||
#define PIN_MUX_SEL_SDHC 0x00
|
||||
#define PIN_MUX_SEL_DSPI 0x0a
|
||||
|
||||
#define SET_SDHC_MUX_SEL(reg, value) ((reg & 0xf0) | value)
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum {
|
||||
MUX_TYPE_SDHC,
|
||||
MUX_TYPE_DSPI,
|
||||
};
|
||||
|
||||
unsigned long long get_qixis_addr(void)
|
||||
{
|
||||
unsigned long long addr;
|
||||
@ -49,11 +60,15 @@ int checkboard(void)
|
||||
"100 separate SSCG"};
|
||||
int clock;
|
||||
|
||||
cpu_name(buf);
|
||||
printf("Board: %s-QDS, ", buf);
|
||||
|
||||
sw = QIXIS_READ(arch);
|
||||
printf("Board: %s, ", CONFIG_IDENT_STRING);
|
||||
printf("Board Arch: V%d, ", sw >> 4);
|
||||
printf("Board version: %c, boot from ", (sw & 0xf) + 'A' - 1);
|
||||
|
||||
memset((u8 *)buf, 0x00, ARRAY_SIZE(buf));
|
||||
|
||||
sw = QIXIS_READ(brdcfg[0]);
|
||||
sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
|
||||
|
||||
@ -149,10 +164,47 @@ int select_i2c_ch_pca9547(u8 ch)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_board_mux(int ctrl_type)
|
||||
{
|
||||
u8 reg5;
|
||||
|
||||
reg5 = QIXIS_READ(brdcfg[5]);
|
||||
|
||||
switch (ctrl_type) {
|
||||
case MUX_TYPE_SDHC:
|
||||
reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_SDHC);
|
||||
break;
|
||||
case MUX_TYPE_DSPI:
|
||||
reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_DSPI);
|
||||
break;
|
||||
default:
|
||||
printf("Wrong mux interface type\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
QIXIS_WRITE(brdcfg[5], reg5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
char *env_hwconfig;
|
||||
u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
|
||||
u32 val;
|
||||
|
||||
init_final_memctl_regs();
|
||||
|
||||
val = in_le32(dcfg_ccsr + DCFG_RCWSR13 / 4);
|
||||
|
||||
env_hwconfig = getenv("hwconfig");
|
||||
|
||||
if (hwconfig_f("dspi", env_hwconfig) &&
|
||||
DCFG_RCWSR13_DSPI == (val & (u32)(0xf << 8)))
|
||||
config_board_mux(MUX_TYPE_DSPI);
|
||||
else
|
||||
config_board_mux(MUX_TYPE_SDHC);
|
||||
|
||||
#ifdef CONFIG_ENV_IS_NOWHERE
|
||||
gd->env_addr = (ulong)&default_environment[0];
|
||||
#endif
|
||||
@ -211,7 +263,7 @@ unsigned long get_dram_size_to_hide(void)
|
||||
dram_to_hide += mc_get_dram_block_size();
|
||||
#endif
|
||||
|
||||
return dram_to_hide;
|
||||
return roundup(dram_to_hide, CONFIG_SYS_MEM_TOP_HIDE_MIN);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
@ -240,15 +292,18 @@ void fdt_fixup_board_enet(void *fdt)
|
||||
#ifdef CONFIG_OF_BOARD_SETUP
|
||||
int ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
phys_addr_t base;
|
||||
phys_size_t size;
|
||||
u64 base[CONFIG_NR_DRAM_BANKS];
|
||||
u64 size[CONFIG_NR_DRAM_BANKS];
|
||||
|
||||
ft_cpu_setup(blob, bd);
|
||||
|
||||
/* limit the memory size to bank 1 until Linux can handle 40-bit PA */
|
||||
base = getenv_bootm_low();
|
||||
size = getenv_bootm_size();
|
||||
fdt_fixup_memory(blob, (u64)base, (u64)size);
|
||||
/* fixup DT for the two GPP DDR banks */
|
||||
base[0] = gd->bd->bi_dram[0].start;
|
||||
size[0] = gd->bd->bi_dram[0].size;
|
||||
base[1] = gd->bd->bi_dram[1].start;
|
||||
size[1] = gd->bd->bi_dram[1].size;
|
||||
|
||||
fdt_fixup_memory_banks(blob, base, size, 2);
|
||||
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
fdt_fixup_board_enet(blob);
|
||||
|
@ -4,5 +4,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += ls2085ardb.o
|
||||
obj-y += ls2085ardb.o eth_ls2085rdb.o
|
||||
obj-y += ddr.o
|
||||
|
@ -107,3 +107,14 @@ Booting Options
|
||||
---------------
|
||||
a) NOR boot
|
||||
b) NAND boot
|
||||
|
||||
Booting Linux flavors which do not support 48-bit VA (< Linux 3.18)
|
||||
-------------------------------------------------------------------
|
||||
One needs to use appropriate bootargs to boot Linux flavors which do
|
||||
not support 48-bit VA (for e.g. < Linux 3.18) by appending mem=2048M, as shown
|
||||
below:
|
||||
|
||||
=> setenv bootargs 'console=ttyS1,115200 root=/dev/ram
|
||||
earlycon=uart8250,mmio,0x21c0600,115200 default_hugepagesz=2m hugepagesz=2m
|
||||
hugepages=16 mem=2048M'
|
||||
|
||||
|
148
board/freescale/ls2085ardb/eth_ls2085rdb.c
Normal file
148
board/freescale/ls2085ardb/eth_ls2085rdb.c
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <netdev.h>
|
||||
#include <malloc.h>
|
||||
#include <fsl_mdio.h>
|
||||
#include <miiphy.h>
|
||||
#include <phy.h>
|
||||
#include <fm_eth.h>
|
||||
#include <asm/io.h>
|
||||
#include <exports.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
|
||||
#include <fsl-mc/ldpaa_wriop.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int load_firmware_cortina(struct phy_device *phy_dev)
|
||||
{
|
||||
if (phy_dev->drv->config)
|
||||
return phy_dev->drv->config(phy_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void load_phy_firmware(void)
|
||||
{
|
||||
int i;
|
||||
u8 phy_addr;
|
||||
struct phy_device *phy_dev;
|
||||
struct mii_dev *dev;
|
||||
phy_interface_t interface;
|
||||
|
||||
/*Initialize and upload firmware for all the PHYs*/
|
||||
for (i = WRIOP1_DPMAC1; i <= WRIOP1_DPMAC8; i++) {
|
||||
interface = wriop_get_enet_if(i);
|
||||
if (interface == PHY_INTERFACE_MODE_XGMII) {
|
||||
dev = wriop_get_mdio(i);
|
||||
phy_addr = wriop_get_phy_address(i);
|
||||
phy_dev = phy_find_by_mask(dev, 1 << phy_addr,
|
||||
interface);
|
||||
if (!phy_dev) {
|
||||
printf("No phydev for phyaddr %d\n", phy_addr);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*Flash firmware for All CS4340 PHYS */
|
||||
if (phy_dev->phy_id == PHY_UID_CS4340)
|
||||
load_firmware_cortina(phy_dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
#if defined(CONFIG_FSL_MC_ENET)
|
||||
int i, interface;
|
||||
struct memac_mdio_info mdio_info;
|
||||
struct mii_dev *dev;
|
||||
struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
u32 srds_s1;
|
||||
struct memac_mdio_controller *reg;
|
||||
|
||||
srds_s1 = in_le32(&gur->rcwsr[28]) &
|
||||
FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK;
|
||||
srds_s1 >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
|
||||
|
||||
reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO1;
|
||||
mdio_info.regs = reg;
|
||||
mdio_info.name = DEFAULT_WRIOP_MDIO1_NAME;
|
||||
|
||||
/* Register the EMI 1 */
|
||||
fm_memac_mdio_init(bis, &mdio_info);
|
||||
|
||||
reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO2;
|
||||
mdio_info.regs = reg;
|
||||
mdio_info.name = DEFAULT_WRIOP_MDIO2_NAME;
|
||||
|
||||
/* Register the EMI 2 */
|
||||
fm_memac_mdio_init(bis, &mdio_info);
|
||||
|
||||
switch (srds_s1) {
|
||||
case 0x2A:
|
||||
wriop_set_phy_address(WRIOP1_DPMAC1, CORTINA_PHY_ADDR1);
|
||||
wriop_set_phy_address(WRIOP1_DPMAC2, CORTINA_PHY_ADDR2);
|
||||
wriop_set_phy_address(WRIOP1_DPMAC3, CORTINA_PHY_ADDR3);
|
||||
wriop_set_phy_address(WRIOP1_DPMAC4, CORTINA_PHY_ADDR4);
|
||||
wriop_set_phy_address(WRIOP1_DPMAC5, AQ_PHY_ADDR1);
|
||||
wriop_set_phy_address(WRIOP1_DPMAC6, AQ_PHY_ADDR2);
|
||||
wriop_set_phy_address(WRIOP1_DPMAC7, AQ_PHY_ADDR3);
|
||||
wriop_set_phy_address(WRIOP1_DPMAC8, AQ_PHY_ADDR4);
|
||||
|
||||
break;
|
||||
default:
|
||||
printf("SerDes1 protocol 0x%x is not supported on LS2085aRDB\n",
|
||||
srds_s1);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = WRIOP1_DPMAC1; i <= WRIOP1_DPMAC4; i++) {
|
||||
interface = wriop_get_enet_if(i);
|
||||
switch (interface) {
|
||||
case PHY_INTERFACE_MODE_XGMII:
|
||||
dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME);
|
||||
wriop_set_mdio(i, dev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = WRIOP1_DPMAC5; i <= WRIOP1_DPMAC8; i++) {
|
||||
switch (wriop_get_enet_if(i)) {
|
||||
case PHY_INTERFACE_MODE_XGMII:
|
||||
dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME);
|
||||
wriop_set_mdio(i, dev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Load CORTINA CS4340 PHY firmware */
|
||||
load_phy_firmware();
|
||||
|
||||
cpu_eth_init(bis);
|
||||
#endif /* CONFIG_FMAN_ENET */
|
||||
|
||||
#ifdef CONFIG_PHY_AQUANTIA
|
||||
/*
|
||||
* Export functions to be used by AQ firmware
|
||||
* upload application
|
||||
*/
|
||||
gd->jt->strcpy = strcpy;
|
||||
gd->jt->mdelay = mdelay;
|
||||
gd->jt->mdio_get_current_dev = mdio_get_current_dev;
|
||||
gd->jt->phy_find_by_mask = phy_find_by_mask;
|
||||
gd->jt->mdio_phydev_for_ethname = mdio_phydev_for_ethname;
|
||||
gd->jt->miiphy_set_current_dev = miiphy_set_current_dev;
|
||||
#endif
|
||||
return pci_eth_init(bis);
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
#include <fsl_ifc.h>
|
||||
#include <fsl_ddr.h>
|
||||
#include <asm/io.h>
|
||||
#include <hwconfig.h>
|
||||
#include <fdt_support.h>
|
||||
#include <libfdt.h>
|
||||
#include <fsl_debug_server.h>
|
||||
@ -21,8 +22,17 @@
|
||||
#include "../common/qixis.h"
|
||||
#include "ls2085ardb_qixis.h"
|
||||
|
||||
#define PIN_MUX_SEL_SDHC 0x00
|
||||
#define PIN_MUX_SEL_DSPI 0x0a
|
||||
|
||||
#define SET_SDHC_MUX_SEL(reg, value) ((reg & 0xf0) | value)
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum {
|
||||
MUX_TYPE_SDHC,
|
||||
MUX_TYPE_DSPI,
|
||||
};
|
||||
|
||||
unsigned long long get_qixis_addr(void)
|
||||
{
|
||||
unsigned long long addr;
|
||||
@ -44,11 +54,14 @@ unsigned long long get_qixis_addr(void)
|
||||
int checkboard(void)
|
||||
{
|
||||
u8 sw;
|
||||
char buf[15];
|
||||
|
||||
cpu_name(buf);
|
||||
printf("Board: %s-RDB, ", buf);
|
||||
|
||||
sw = QIXIS_READ(arch);
|
||||
printf("Board: %s, ", CONFIG_IDENT_STRING);
|
||||
printf("Board Arch: V%d, ", sw >> 4);
|
||||
printf("Board version: %c, boot from ", (sw & 0xf) + 'A' - 1);
|
||||
printf("Board version: %c, boot from ", (sw & 0xf) + 'A');
|
||||
|
||||
sw = QIXIS_READ(brdcfg[0]);
|
||||
sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
|
||||
@ -109,10 +122,47 @@ int select_i2c_ch_pca9547(u8 ch)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_board_mux(int ctrl_type)
|
||||
{
|
||||
u8 reg5;
|
||||
|
||||
reg5 = QIXIS_READ(brdcfg[5]);
|
||||
|
||||
switch (ctrl_type) {
|
||||
case MUX_TYPE_SDHC:
|
||||
reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_SDHC);
|
||||
break;
|
||||
case MUX_TYPE_DSPI:
|
||||
reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_DSPI);
|
||||
break;
|
||||
default:
|
||||
printf("Wrong mux interface type\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
QIXIS_WRITE(brdcfg[5], reg5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
char *env_hwconfig;
|
||||
u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
|
||||
u32 val;
|
||||
|
||||
init_final_memctl_regs();
|
||||
|
||||
val = in_le32(dcfg_ccsr + DCFG_RCWSR13 / 4);
|
||||
|
||||
env_hwconfig = getenv("hwconfig");
|
||||
|
||||
if (hwconfig_f("dspi", env_hwconfig) &&
|
||||
DCFG_RCWSR13_DSPI == (val & (u32)(0xf << 8)))
|
||||
config_board_mux(MUX_TYPE_DSPI);
|
||||
else
|
||||
config_board_mux(MUX_TYPE_SDHC);
|
||||
|
||||
#ifdef CONFIG_ENV_IS_NOWHERE
|
||||
gd->env_addr = (ulong)&default_environment[0];
|
||||
#endif
|
||||
@ -129,6 +179,14 @@ int board_early_init_f(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int misc_init_r(void)
|
||||
{
|
||||
if (hwconfig("sdhc"))
|
||||
config_board_mux(MUX_TYPE_SDHC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void detail_board_ddr_info(void)
|
||||
{
|
||||
puts("\nDDR ");
|
||||
@ -173,20 +231,7 @@ unsigned long get_dram_size_to_hide(void)
|
||||
dram_to_hide += mc_get_dram_block_size();
|
||||
#endif
|
||||
|
||||
return dram_to_hide;
|
||||
}
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
error = cpu_eth_init(bis);
|
||||
#endif
|
||||
|
||||
error = pci_eth_init(bis);
|
||||
|
||||
return error;
|
||||
return roundup(dram_to_hide, CONFIG_SYS_MEM_TOP_HIDE_MIN);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
@ -215,15 +260,18 @@ void fdt_fixup_board_enet(void *fdt)
|
||||
#ifdef CONFIG_OF_BOARD_SETUP
|
||||
int ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
phys_addr_t base;
|
||||
phys_size_t size;
|
||||
u64 base[CONFIG_NR_DRAM_BANKS];
|
||||
u64 size[CONFIG_NR_DRAM_BANKS];
|
||||
|
||||
ft_cpu_setup(blob, bd);
|
||||
|
||||
/* limit the memory size to bank 1 until Linux can handle 40-bit PA */
|
||||
base = getenv_bootm_low();
|
||||
size = getenv_bootm_size();
|
||||
fdt_fixup_memory(blob, (u64)base, (u64)size);
|
||||
/* fixup DT for the two GPP DDR banks */
|
||||
base[0] = gd->bd->bi_dram[0].start;
|
||||
size[0] = gd->bd->bi_dram[0].size;
|
||||
base[1] = gd->bd->bi_dram[1].start;
|
||||
size[1] = gd->bd->bi_dram[1].size;
|
||||
|
||||
fdt_fixup_memory_banks(blob, base, size, 2);
|
||||
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
fdt_fixup_board_enet(blob);
|
||||
@ -247,3 +295,22 @@ void qixis_dump_switch(void)
|
||||
printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1]));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Board rev C and earlier has duplicated I2C addresses for 2nd controller.
|
||||
* Both slots has 0x54, resulting 2nd slot unusable.
|
||||
*/
|
||||
void update_spd_address(unsigned int ctrl_num,
|
||||
unsigned int slot,
|
||||
unsigned int *addr)
|
||||
{
|
||||
u8 sw;
|
||||
|
||||
sw = QIXIS_READ(arch);
|
||||
if ((sw & 0xf) < 0x3) {
|
||||
if (ctrl_num == 1 && slot == 0)
|
||||
*addr = SPD_EEPROM_ADDRESS4;
|
||||
else if (ctrl_num == 1 && slot == 1)
|
||||
*addr = SPD_EEPROM_ADDRESS3;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,13 @@ unsigned long get_version(void)
|
||||
|
||||
#define EXPORT_FUNC(f, a, x, ...) gd->jt->x = f;
|
||||
|
||||
#ifndef CONFIG_PHY_AQUANTIA
|
||||
# define mdio_get_current_dev dummy
|
||||
# define phy_find_by_mask dummy
|
||||
# define mdio_phydev_for_ethname dummy
|
||||
# define miiphy_set_current_dev dummy
|
||||
#endif
|
||||
|
||||
void jumptable_init(void)
|
||||
{
|
||||
gd->jt = malloc(sizeof(struct jt_funcs));
|
||||
|
@ -1,4 +1,11 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_TARGET_LS2085AQDS=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="fsl-ls2085a-qds"
|
||||
# CONFIG_SYS_MALLOC_F is not set
|
||||
CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4"
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DM=y
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_FSL_DSPI=y
|
||||
|
@ -1,4 +1,11 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_TARGET_LS2085ARDB=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="fsl-ls2085a-rdb"
|
||||
# CONFIG_SYS_MALLOC_F is not set
|
||||
CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4"
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DM=y
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_FSL_DSPI=y
|
||||
|
@ -135,6 +135,13 @@ static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address)
|
||||
__attribute__((weak, alias("__get_spd")))
|
||||
void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address);
|
||||
|
||||
/* This function allows boards to update SPD address */
|
||||
__weak void update_spd_address(unsigned int ctrl_num,
|
||||
unsigned int slot,
|
||||
unsigned int *addr)
|
||||
{
|
||||
}
|
||||
|
||||
void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
|
||||
unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl)
|
||||
{
|
||||
@ -148,6 +155,7 @@ void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
|
||||
|
||||
for (i = 0; i < dimm_slots_per_ctrl; i++) {
|
||||
i2c_address = spd_i2c_addr[ctrl_num][i];
|
||||
update_spd_address(ctrl_num, i, &i2c_address);
|
||||
get_spd(&(ctrl_dimms_spd[i]), i2c_address);
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <asm/system.h>
|
||||
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
|
||||
|
||||
#include <fsl-mc/fsl_mc.h>
|
||||
#include <fsl_debug_server.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
@ -151,6 +152,10 @@ int debug_server_init(void)
|
||||
debug_server_ram_addr =
|
||||
gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
|
||||
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
debug_server_ram_addr += mc_get_dram_block_size();
|
||||
#endif
|
||||
|
||||
error = debug_server_parse_firmware_fit_image(&raw_image_addr,
|
||||
&raw_image_size);
|
||||
if (error != 0)
|
||||
|
@ -64,7 +64,7 @@ enum qbman_sdqcr_fc {
|
||||
struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
|
||||
{
|
||||
int ret;
|
||||
struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
|
||||
struct qbman_swp *p = malloc(sizeof(struct qbman_swp));
|
||||
|
||||
if (!p)
|
||||
return NULL;
|
||||
@ -77,7 +77,7 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
|
||||
qb_attr_code_encode(&code_sdqcr_dct, &p->sdq, qbman_sdqcr_dct_prio_ics);
|
||||
qb_attr_code_encode(&code_sdqcr_fc, &p->sdq, qbman_sdqcr_fc_up_to_3);
|
||||
qb_attr_code_encode(&code_sdqcr_tok, &p->sdq, 0xbb);
|
||||
p->vdq.busy = 0; /* TODO: convert to atomic_t */
|
||||
atomic_set(&p->vdq.busy, 1);
|
||||
p->vdq.valid_bit = QB_VALID_BIT;
|
||||
p->dqrr.next_idx = 0;
|
||||
p->dqrr.valid_bit = QB_VALID_BIT;
|
||||
@ -165,7 +165,6 @@ static struct qb_attr_code code_eq_qd_bin = QB_CODE(4, 0, 16);
|
||||
static struct qb_attr_code code_eq_qd_pri = QB_CODE(4, 16, 4);
|
||||
static struct qb_attr_code code_eq_rsp_stash = QB_CODE(5, 16, 1);
|
||||
static struct qb_attr_code code_eq_rsp_lo = QB_CODE(6, 0, 32);
|
||||
static struct qb_attr_code code_eq_rsp_hi = QB_CODE(7, 0, 32);
|
||||
|
||||
enum qbman_eq_cmd_e {
|
||||
/* No enqueue, primarily for plugging ORP gaps for dropped frames */
|
||||
@ -197,8 +196,7 @@ void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
|
||||
{
|
||||
uint32_t *cl = qb_cl(d);
|
||||
|
||||
qb_attr_code_encode(&code_eq_rsp_lo, cl, lower32(storage_phys));
|
||||
qb_attr_code_encode(&code_eq_rsp_hi, cl, upper32(storage_phys));
|
||||
qb_attr_code_encode_64(&code_eq_rsp_lo, (uint64_t *)cl, storage_phys);
|
||||
qb_attr_code_encode(&code_eq_rsp_stash, cl, !!stash);
|
||||
}
|
||||
|
||||
@ -253,7 +251,6 @@ static struct qb_attr_code code_pull_numframes = QB_CODE(0, 8, 4);
|
||||
static struct qb_attr_code code_pull_token = QB_CODE(0, 16, 8);
|
||||
static struct qb_attr_code code_pull_dqsource = QB_CODE(1, 0, 24);
|
||||
static struct qb_attr_code code_pull_rsp_lo = QB_CODE(2, 0, 32);
|
||||
static struct qb_attr_code code_pull_rsp_hi = QB_CODE(3, 0, 32);
|
||||
|
||||
enum qb_pull_dt_e {
|
||||
qb_pull_dt_channel,
|
||||
@ -282,8 +279,7 @@ void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
|
||||
}
|
||||
qb_attr_code_encode(&code_pull_rls, cl, 1);
|
||||
qb_attr_code_encode(&code_pull_stash, cl, !!stash);
|
||||
qb_attr_code_encode(&code_pull_rsp_lo, cl, lower32(storage_phys));
|
||||
qb_attr_code_encode(&code_pull_rsp_hi, cl, upper32(storage_phys));
|
||||
qb_attr_code_encode_64(&code_pull_rsp_lo, (uint64_t *)cl, storage_phys);
|
||||
}
|
||||
|
||||
void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes)
|
||||
@ -316,10 +312,10 @@ int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
|
||||
uint32_t *p;
|
||||
uint32_t *cl = qb_cl(d);
|
||||
|
||||
/* TODO: convert to atomic_t */
|
||||
if (s->vdq.busy)
|
||||
if (!atomic_dec_and_test(&s->vdq.busy)) {
|
||||
atomic_inc(&s->vdq.busy);
|
||||
return -EBUSY;
|
||||
s->vdq.busy = 1;
|
||||
}
|
||||
s->vdq.storage = *(void **)&cl[4];
|
||||
s->vdq.token = qb_attr_code_decode(&code_pull_token, cl);
|
||||
p = qbman_cena_write_start(&s->sys, QBMAN_CENA_SWP_VDQCR);
|
||||
@ -359,36 +355,44 @@ const struct ldpaa_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
|
||||
{
|
||||
uint32_t verb;
|
||||
uint32_t response_verb;
|
||||
const struct ldpaa_dq *dq = qbman_cena_read(&s->sys,
|
||||
QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
|
||||
const uint32_t *p = qb_cl(dq);
|
||||
uint32_t flags;
|
||||
const struct ldpaa_dq *dq;
|
||||
const uint32_t *p;
|
||||
|
||||
dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
|
||||
p = qb_cl(dq);
|
||||
verb = qb_attr_code_decode(&code_dqrr_verb, p);
|
||||
/* If the valid-bit isn't of the expected polarity, nothing there */
|
||||
|
||||
/* If the valid-bit isn't of the expected polarity, nothing there. Note,
|
||||
* in the DQRR reset bug workaround, we shouldn't need to skip these
|
||||
* check, because we've already determined that a new entry is available
|
||||
* and we've invalidated the cacheline before reading it, so the
|
||||
* valid-bit behaviour is repaired and should tell us what we already
|
||||
* knew from reading PI.
|
||||
*/
|
||||
if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) {
|
||||
qbman_cena_invalidate_prefetch(&s->sys,
|
||||
QBMAN_CENA_SWP_DQRR(
|
||||
s->dqrr.next_idx));
|
||||
QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
|
||||
return NULL;
|
||||
}
|
||||
/* There's something there. Move "next_idx" attention to the next ring
|
||||
* entry (and prefetch it) before returning what we found. */
|
||||
s->dqrr.next_idx++;
|
||||
s->dqrr.next_idx &= 3; /* Wrap around at 4 */
|
||||
s->dqrr.next_idx &= QBMAN_DQRR_SIZE - 1; /* Wrap around at 4 */
|
||||
/* TODO: it's possible to do all this without conditionals, optimise it
|
||||
* later. */
|
||||
if (!s->dqrr.next_idx)
|
||||
s->dqrr.valid_bit ^= QB_VALID_BIT;
|
||||
/* VDQCR "no longer busy" hook - if VDQCR shows "busy" and this is a
|
||||
* VDQCR result, mark it as non-busy. */
|
||||
if (s->vdq.busy) {
|
||||
uint32_t flags = ldpaa_dq_flags(dq);
|
||||
|
||||
response_verb = qb_attr_code_decode(&code_dqrr_response, &verb);
|
||||
if ((response_verb == QBMAN_DQRR_RESPONSE_DQ) &&
|
||||
(flags & LDPAA_DQ_STAT_VOLATILE))
|
||||
s->vdq.busy = 0;
|
||||
}
|
||||
/* If this is the final response to a volatile dequeue command
|
||||
indicate that the vdq is no longer busy */
|
||||
flags = ldpaa_dq_flags(dq);
|
||||
response_verb = qb_attr_code_decode(&code_dqrr_response, &verb);
|
||||
if ((response_verb == QBMAN_DQRR_RESPONSE_DQ) &&
|
||||
(flags & LDPAA_DQ_STAT_VOLATILE) &&
|
||||
(flags & LDPAA_DQ_STAT_EXPIRED))
|
||||
atomic_inc(&s->vdq.busy);
|
||||
|
||||
qbman_cena_invalidate_prefetch(&s->sys,
|
||||
QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
|
||||
return dq;
|
||||
@ -448,8 +452,10 @@ int qbman_dq_entry_has_newtoken(struct qbman_swp *s,
|
||||
* reset "busy". We instead base the decision on whether the current
|
||||
* result is sitting at the first 'storage' location of the busy
|
||||
* command. */
|
||||
if (s->vdq.busy && (s->vdq.storage == dq))
|
||||
s->vdq.busy = 0;
|
||||
if (s->vdq.storage == dq) {
|
||||
s->vdq.storage = NULL;
|
||||
atomic_inc(&s->vdq.busy);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,10 @@
|
||||
/* Management command result codes */
|
||||
#define QBMAN_MC_RSLT_OK 0xf0
|
||||
|
||||
/* TBD: as of QBMan 4.1, DQRR will be 8 rather than 4! */
|
||||
#define QBMAN_DQRR_SIZE 4
|
||||
|
||||
|
||||
/* --------------------- */
|
||||
/* portal data structure */
|
||||
/* --------------------- */
|
||||
@ -48,14 +52,13 @@ struct qbman_swp {
|
||||
* to whether or not a command can be submitted, not whether or
|
||||
* not a previously-submitted command is still executing. In
|
||||
* other words, once proof is seen that the previously-submitted
|
||||
* command is executing, "vdq" is no longer "busy". TODO:
|
||||
* convert this to "atomic_t" so that it is thread-safe (without
|
||||
* locking). */
|
||||
int busy;
|
||||
* command is executing, "vdq" is no longer "busy".
|
||||
*/
|
||||
atomic_t busy;
|
||||
uint32_t valid_bit; /* 0x00 or 0x80 */
|
||||
/* We need to determine when vdq is no longer busy. This depends
|
||||
* on whether the "busy" (last-submitted) dequeue command is
|
||||
* targetting DQRR or main-memory, and detected is based on the
|
||||
* targeting DQRR or main-memory, and detected is based on the
|
||||
* presence of the dequeue command's "token" showing up in
|
||||
* dequeue entries in DQRR or main-memory (respectively). Debug
|
||||
* builds will, when submitting vdq commands, verify that the
|
||||
@ -127,6 +130,7 @@ static inline uint32_t qb_attr_code_decode(const struct qb_attr_code *code,
|
||||
return d32_uint32_t(code->lsoffset, code->width, cacheline[code->word]);
|
||||
}
|
||||
|
||||
|
||||
/* encode a field to a cacheline */
|
||||
static inline void qb_attr_code_encode(const struct qb_attr_code *code,
|
||||
uint32_t *cacheline, uint32_t val)
|
||||
@ -136,6 +140,12 @@ static inline void qb_attr_code_encode(const struct qb_attr_code *code,
|
||||
| e32_uint32_t(code->lsoffset, code->width, val);
|
||||
}
|
||||
|
||||
static inline void qb_attr_code_encode_64(const struct qb_attr_code *code,
|
||||
uint64_t *cacheline, uint64_t val)
|
||||
{
|
||||
cacheline[code->word / 2] = val;
|
||||
}
|
||||
|
||||
/* ---------------------- */
|
||||
/* Descriptors/cachelines */
|
||||
/* ---------------------- */
|
||||
@ -144,7 +154,7 @@ static inline void qb_attr_code_encode(const struct qb_attr_code *code,
|
||||
* a "descriptor" type that the caller can instantiate however they like.
|
||||
* Ultimately though, it is just a cacheline of binary storage (or something
|
||||
* smaller when it is known that the descriptor doesn't need all 64 bytes) for
|
||||
* holding pre-formatted pieces of harware commands. The performance-critical
|
||||
* holding pre-formatted pieces of hardware commands. The performance-critical
|
||||
* code can then copy these descriptors directly into hardware command
|
||||
* registers more efficiently than trying to construct/format commands
|
||||
* on-the-fly. The API user sees the descriptor as an array of 32-bit words in
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/compat.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <malloc.h>
|
||||
#include <fsl-mc/fsl_qbman_base.h>
|
||||
|
||||
|
@ -313,7 +313,7 @@ int dpni_set_counter(struct fsl_mc_io *mc_io,
|
||||
|
||||
int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
|
||||
uint16_t token,
|
||||
struct dpni_link_cfg *cfg)
|
||||
const struct dpni_link_cfg *cfg)
|
||||
{
|
||||
struct mc_command cmd = { 0 };
|
||||
|
||||
|
@ -3,13 +3,15 @@
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include <fsl-mc/fsl_mc.h>
|
||||
#include <fsl-mc/fsl_mc_sys.h>
|
||||
#include <fsl-mc/fsl_mc_private.h>
|
||||
#include <fsl-mc/fsl_dpmng.h>
|
||||
#include <fsl_debug_server.h>
|
||||
#include <fsl-mc/fsl_dprc.h>
|
||||
#include <fsl-mc/fsl_dpio.h>
|
||||
#include <fsl-mc/fsl_qbman_portal.h>
|
||||
@ -186,6 +188,36 @@ static int calculate_mc_private_ram_params(u64 mc_private_ram_start_addr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mc_fixup_dpc(u64 dpc_addr)
|
||||
{
|
||||
void *blob = (void *)dpc_addr;
|
||||
int nodeoffset;
|
||||
|
||||
/* delete any existing ICID pools */
|
||||
nodeoffset = fdt_path_offset(blob, "/resources/icid_pools");
|
||||
if (fdt_del_node(blob, nodeoffset) < 0)
|
||||
printf("\nfsl-mc: WARNING: could not delete ICID pool\n");
|
||||
|
||||
/* add a new pool */
|
||||
nodeoffset = fdt_path_offset(blob, "/resources");
|
||||
if (nodeoffset < 0) {
|
||||
printf("\nfsl-mc: ERROR: DPC is missing /resources\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pools");
|
||||
nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pool@0");
|
||||
do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0",
|
||||
"base_icid", FSL_DPAA2_STREAM_ID_START, 1);
|
||||
do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0",
|
||||
"num",
|
||||
FSL_DPAA2_STREAM_ID_END -
|
||||
FSL_DPAA2_STREAM_ID_START + 1, 1);
|
||||
|
||||
flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size)
|
||||
{
|
||||
u64 mc_dpc_offset;
|
||||
@ -225,13 +257,13 @@ static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size)
|
||||
* Don't return with error here, since the MC firmware can
|
||||
* still boot without a DPC
|
||||
*/
|
||||
printf("fsl-mc: WARNING: No DPC image found\n");
|
||||
printf("\nfsl-mc: WARNING: No DPC image found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dpc_size = fdt_totalsize(dpc_fdt_hdr);
|
||||
if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) {
|
||||
printf("fsl-mc: ERROR: Bad DPC image (too large: %d)\n",
|
||||
printf("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n",
|
||||
dpc_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -240,6 +272,9 @@ static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size)
|
||||
(u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset);
|
||||
#endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */
|
||||
|
||||
if (mc_fixup_dpc(mc_ram_addr + mc_dpc_offset))
|
||||
return -EINVAL;
|
||||
|
||||
dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset));
|
||||
return 0;
|
||||
}
|
||||
@ -279,13 +314,13 @@ static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size)
|
||||
|
||||
error = fdt_check_header(dpl_fdt_hdr);
|
||||
if (error != 0) {
|
||||
printf("fsl-mc: ERROR: Bad DPL image (bad header)\n");
|
||||
printf("\nfsl-mc: ERROR: Bad DPL image (bad header)\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
dpl_size = fdt_totalsize(dpl_fdt_hdr);
|
||||
if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) {
|
||||
printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n",
|
||||
printf("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n",
|
||||
dpl_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -322,6 +357,23 @@ static unsigned long get_mc_boot_timeout_ms(void)
|
||||
return timeout_ms;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR
|
||||
static int load_mc_aiop_img(u64 mc_ram_addr, size_t mc_ram_size)
|
||||
{
|
||||
void *aiop_img;
|
||||
|
||||
/*
|
||||
* Load the MC AIOP image in the MC private DRAM block:
|
||||
*/
|
||||
|
||||
aiop_img = (void *)CONFIG_SYS_LS_MC_AIOP_IMG_ADDR;
|
||||
mc_copy_image("MC AIOP image",
|
||||
(u64)aiop_img, CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH,
|
||||
mc_ram_addr + CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
|
||||
{
|
||||
u32 reg_gsr;
|
||||
@ -330,7 +382,6 @@ static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
|
||||
struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
|
||||
|
||||
dmb();
|
||||
debug("Polling mc_ccsr_regs->reg_gsr ...\n");
|
||||
assert(timeout_ms > 0);
|
||||
for (;;) {
|
||||
udelay(1000); /* throttle polling */
|
||||
@ -345,10 +396,7 @@ static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
|
||||
}
|
||||
|
||||
if (timeout_ms == 0) {
|
||||
if (booting_mc)
|
||||
printf("fsl-mc: timeout booting management complex firmware\n");
|
||||
else
|
||||
printf("fsl-mc: timeout deploying data path layout\n");
|
||||
printf("ERROR: timeout\n");
|
||||
|
||||
/* TODO: Get an error status from an MC CCSR register */
|
||||
return -ETIMEDOUT;
|
||||
@ -361,15 +409,13 @@ static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
|
||||
* appropriate errno, so that the status property is set to
|
||||
* failure in the fsl,dprc device tree node.
|
||||
*/
|
||||
if (booting_mc) {
|
||||
printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n",
|
||||
reg_gsr);
|
||||
} else {
|
||||
printf("fsl-mc: WARNING: Data path layout deployed with error (GSR: %#x)\n",
|
||||
reg_gsr);
|
||||
}
|
||||
printf("WARNING: Firmware returned an error (GSR: %#x)\n",
|
||||
reg_gsr);
|
||||
} else {
|
||||
printf("SUCCESS\n");
|
||||
}
|
||||
|
||||
|
||||
*final_reg_gsr = reg_gsr;
|
||||
return 0;
|
||||
}
|
||||
@ -403,13 +449,6 @@ int mc_init(void)
|
||||
gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_DEBUG_SERVER
|
||||
/*
|
||||
* FIXME: I don't think this is right. See get_dram_size_to_hide()
|
||||
*/
|
||||
mc_ram_addr -= debug_server_get_dram_block_size();
|
||||
#endif
|
||||
|
||||
error = calculate_mc_private_ram_params(mc_ram_addr,
|
||||
mc_ram_size,
|
||||
&mc_ram_aligned_base_addr,
|
||||
@ -454,6 +493,12 @@ int mc_init(void)
|
||||
if (error != 0)
|
||||
goto out;
|
||||
|
||||
#ifdef CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR
|
||||
error = load_mc_aiop_img(mc_ram_addr, mc_ram_size);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
|
||||
dump_mc_ccsr_regs(mc_ccsr_regs);
|
||||
|
||||
@ -465,14 +510,14 @@ int mc_init(void)
|
||||
out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr);
|
||||
out_le32(&mc_ccsr_regs->reg_mcfbahr,
|
||||
(u32)(mc_ram_aligned_base_addr >> 32));
|
||||
out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK);
|
||||
out_le32(&mc_ccsr_regs->reg_mcfapr, FSL_BYPASS_AMQ);
|
||||
|
||||
/*
|
||||
* Tell the MC that we want delayed DPL deployment.
|
||||
*/
|
||||
out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00);
|
||||
|
||||
printf("\nfsl-mc: Booting Management Complex ...\n");
|
||||
printf("\nfsl-mc: Booting Management Complex ... ");
|
||||
|
||||
/*
|
||||
* Deassert reset and release MC core 0 to run
|
||||
@ -509,9 +554,14 @@ int mc_init(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (MC_VER_MAJOR != mc_ver_info.major)
|
||||
if (MC_VER_MAJOR != mc_ver_info.major) {
|
||||
printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n",
|
||||
mc_ver_info.major, MC_VER_MAJOR);
|
||||
printf("fsl-mc: Update the Management Complex firmware\n");
|
||||
|
||||
error = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (MC_VER_MINOR != mc_ver_info.minor)
|
||||
printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n",
|
||||
@ -525,13 +575,14 @@ int mc_init(void)
|
||||
* Tell the MC to deploy the DPL:
|
||||
*/
|
||||
out_le32(&mc_ccsr_regs->reg_gsr, 0x0);
|
||||
printf("\nfsl-mc: Deploying data path layout ...\n");
|
||||
printf("fsl-mc: Deploying data path layout ... ");
|
||||
error = wait_for_mc(false, ®_gsr);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
if (error != 0)
|
||||
mc_boot_status = -error;
|
||||
mc_boot_status = error;
|
||||
else
|
||||
mc_boot_status = 0;
|
||||
|
||||
@ -600,14 +651,16 @@ int dpio_init(struct dprc_obj_desc obj_desc)
|
||||
printf("dpio_enable() failed %d\n", err);
|
||||
goto err_get_enable;
|
||||
}
|
||||
debug("ce_paddr=0x%llx, ci_paddr=0x%llx, portalid=%d, prios=%d\n",
|
||||
attr.qbman_portal_ce_paddr,
|
||||
attr.qbman_portal_ci_paddr,
|
||||
debug("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n",
|
||||
attr.qbman_portal_ce_offset,
|
||||
attr.qbman_portal_ci_offset,
|
||||
attr.qbman_portal_id,
|
||||
attr.num_priorities);
|
||||
|
||||
p_des.cena_bar = (void *)attr.qbman_portal_ce_paddr;
|
||||
p_des.cinh_bar = (void *)attr.qbman_portal_ci_paddr;
|
||||
p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR
|
||||
+ attr.qbman_portal_ce_offset);
|
||||
p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR
|
||||
+ attr.qbman_portal_ci_offset);
|
||||
|
||||
dflt_dpio->sw_portal = qbman_swp_init(&p_des);
|
||||
if (dflt_dpio->sw_portal == NULL) {
|
||||
|
@ -31,6 +31,8 @@ static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
|
||||
uint32_t fd_length;
|
||||
struct ldpaa_fas *fas;
|
||||
uint32_t status, err;
|
||||
u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
|
||||
u32 time_start;
|
||||
struct qbman_release_desc releasedesc;
|
||||
struct qbman_swp *swp = dflt_dpio->sw_portal;
|
||||
|
||||
@ -65,10 +67,15 @@ error:
|
||||
flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
|
||||
qbman_release_desc_clear(&releasedesc);
|
||||
qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
|
||||
time_start = get_timer(0);
|
||||
do {
|
||||
/* Release buffer into the QBMAN */
|
||||
err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
|
||||
} while (err == -EBUSY);
|
||||
} while (get_timer(time_start) < timeo && err == -EBUSY);
|
||||
|
||||
if (err == -EBUSY)
|
||||
printf("Rx frame: QBMAN buffer release fails\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -77,7 +84,9 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
|
||||
struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
|
||||
const struct ldpaa_dq *dq;
|
||||
const struct dpaa_fd *fd;
|
||||
int i = 5, err = 0, status, loop = 20;
|
||||
int i = 5, err = 0, status;
|
||||
u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
|
||||
u32 time_start;
|
||||
static struct qbman_pull_desc pulldesc;
|
||||
struct qbman_swp *swp = dflt_dpio->sw_portal;
|
||||
|
||||
@ -92,13 +101,11 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
loop--;
|
||||
dq = qbman_swp_dqrr_next(swp);
|
||||
time_start = get_timer(0);
|
||||
|
||||
if (!loop)
|
||||
break;
|
||||
} while (!dq);
|
||||
do {
|
||||
dq = qbman_swp_dqrr_next(swp);
|
||||
} while (get_timer(time_start) < timeo && !dq);
|
||||
|
||||
if (dq) {
|
||||
/* Check for valid frame. If not sent a consume
|
||||
@ -112,7 +119,7 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
|
||||
debug("No frame delivered\n");
|
||||
|
||||
qbman_swp_dqrr_consume(swp, dq);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
fd = ldpaa_dq_fd(dq);
|
||||
@ -121,92 +128,9 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
|
||||
ldpaa_eth_rx(priv, fd);
|
||||
qbman_swp_dqrr_consume(swp, dq);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ldpaa_eth_tx_conf(struct ldpaa_eth_priv *priv,
|
||||
const struct dpaa_fd *fd)
|
||||
{
|
||||
uint64_t fd_addr;
|
||||
struct ldpaa_fas *fas;
|
||||
uint32_t status, err;
|
||||
struct qbman_release_desc releasedesc;
|
||||
struct qbman_swp *swp = dflt_dpio->sw_portal;
|
||||
|
||||
fd_addr = ldpaa_fd_get_addr(fd);
|
||||
|
||||
|
||||
debug("TX Conf frame:data addr=0x%p\n", (u64 *)fd_addr);
|
||||
|
||||
/* Check the status from the Frame Annotation */
|
||||
if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
|
||||
fas = (struct ldpaa_fas *)
|
||||
((uint8_t *)(fd_addr) +
|
||||
priv->buf_layout.private_data_size);
|
||||
status = le32_to_cpu(fas->status);
|
||||
if (status & LDPAA_ETH_TXCONF_ERR_MASK) {
|
||||
printf("TxConf frame error(s): 0x%08x\n",
|
||||
status & LDPAA_ETH_TXCONF_ERR_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
qbman_release_desc_clear(&releasedesc);
|
||||
qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
|
||||
do {
|
||||
/* Release buffer into the QBMAN */
|
||||
err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
|
||||
} while (err == -EBUSY);
|
||||
}
|
||||
|
||||
static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv)
|
||||
{
|
||||
const struct ldpaa_dq *dq;
|
||||
const struct dpaa_fd *fd;
|
||||
int err = 0;
|
||||
int i = 5, status, loop = 20;
|
||||
static struct qbman_pull_desc pulldesc;
|
||||
struct qbman_swp *swp = dflt_dpio->sw_portal;
|
||||
|
||||
while (--i) {
|
||||
qbman_pull_desc_clear(&pulldesc);
|
||||
qbman_pull_desc_set_numframes(&pulldesc, 1);
|
||||
qbman_pull_desc_set_fq(&pulldesc, priv->tx_conf_fqid);
|
||||
|
||||
err = qbman_swp_pull(swp, &pulldesc);
|
||||
if (err < 0) {
|
||||
printf("Dequeue TX conf frames error:0x%08x\n", err);
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
loop--;
|
||||
dq = qbman_swp_dqrr_next(swp);
|
||||
|
||||
if (!loop)
|
||||
break;
|
||||
} while (!dq);
|
||||
|
||||
if (dq) {
|
||||
/* Check for valid frame. If not sent a consume
|
||||
* confirmation to QBMAN otherwise give it to NADK
|
||||
* application and then send consume confirmation to
|
||||
* QBMAN.
|
||||
*/
|
||||
status = (uint8_t)ldpaa_dq_flags(dq);
|
||||
if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
|
||||
debug("Dequeue TX conf frames:");
|
||||
debug("No frame is delivered\n");
|
||||
|
||||
qbman_swp_dqrr_consume(swp, dq);
|
||||
break;
|
||||
}
|
||||
fd = ldpaa_dq_fd(dq);
|
||||
|
||||
ldpaa_eth_tx_conf(priv, fd);
|
||||
qbman_swp_dqrr_consume(swp, dq);
|
||||
} else {
|
||||
err = -ENODATA;
|
||||
debug("No DQRR entries\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -220,8 +144,11 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
|
||||
struct dpaa_fd fd;
|
||||
u64 buffer_start;
|
||||
int data_offset, err;
|
||||
u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
|
||||
u32 time_start;
|
||||
struct qbman_swp *swp = dflt_dpio->sw_portal;
|
||||
struct qbman_eq_desc ed;
|
||||
struct qbman_release_desc releasedesc;
|
||||
|
||||
/* Setup the FD fields */
|
||||
memset(&fd, 0, sizeof(fd));
|
||||
@ -257,15 +184,34 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
|
||||
qbman_eq_desc_clear(&ed);
|
||||
qbman_eq_desc_set_no_orp(&ed, 0);
|
||||
qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
|
||||
err = qbman_swp_enqueue(swp, &ed, (const struct qbman_fd *)(&fd));
|
||||
if (err < 0)
|
||||
|
||||
time_start = get_timer(0);
|
||||
|
||||
while (get_timer(time_start) < timeo) {
|
||||
err = qbman_swp_enqueue(swp, &ed,
|
||||
(const struct qbman_fd *)(&fd));
|
||||
if (err != -EBUSY)
|
||||
break;
|
||||
}
|
||||
|
||||
if (err < 0) {
|
||||
printf("error enqueueing Tx frame\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
mdelay(1);
|
||||
return err;
|
||||
|
||||
err = ldpaa_eth_pull_dequeue_tx_conf(priv);
|
||||
if (err < 0)
|
||||
printf("error Tx Conf frame\n");
|
||||
error:
|
||||
qbman_release_desc_clear(&releasedesc);
|
||||
qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
|
||||
time_start = get_timer(0);
|
||||
do {
|
||||
/* Release buffer into the QBMAN */
|
||||
err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1);
|
||||
} while (get_timer(time_start) < timeo && err == -EBUSY);
|
||||
|
||||
if (err == -EBUSY)
|
||||
printf("TX data: QBMAN buffer release fails\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -274,7 +220,6 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
|
||||
{
|
||||
struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
|
||||
struct dpni_queue_attr rx_queue_attr;
|
||||
struct dpni_tx_flow_attr tx_flow_attr;
|
||||
uint8_t mac_addr[6];
|
||||
int err;
|
||||
|
||||
@ -345,21 +290,11 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
|
||||
goto err_qdid;
|
||||
}
|
||||
|
||||
err = dpni_get_tx_flow(dflt_mc_io, priv->dpni_handle, priv->tx_flow_id,
|
||||
&tx_flow_attr);
|
||||
if (err) {
|
||||
printf("dpni_get_tx_flow() failed\n");
|
||||
goto err_tx_flow;
|
||||
}
|
||||
|
||||
priv->tx_conf_fqid = tx_flow_attr.conf_err_attr.queue_attr.fqid;
|
||||
|
||||
if (!priv->phydev->link)
|
||||
printf("%s: No link.\n", priv->phydev->dev->name);
|
||||
|
||||
return priv->phydev->link ? 0 : -1;
|
||||
|
||||
err_tx_flow:
|
||||
err_qdid:
|
||||
err_rx_flow:
|
||||
dpni_disable(dflt_mc_io, priv->dpni_handle);
|
||||
@ -626,6 +561,9 @@ static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
|
||||
priv->tx_flow_id = DPNI_NEW_FLOW_ID;
|
||||
memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
|
||||
|
||||
dflt_tx_flow.options = DPNI_TX_FLOW_OPT_ONLY_TX_ERROR;
|
||||
dflt_tx_flow.conf_err_cfg.use_default_queue = 0;
|
||||
dflt_tx_flow.conf_err_cfg.errors_only = 1;
|
||||
err = dpni_set_tx_flow(dflt_mc_io, priv->dpni_handle,
|
||||
&priv->tx_flow_id, &dflt_tx_flow);
|
||||
if (err) {
|
||||
|
@ -128,7 +128,6 @@ struct ldpaa_eth_priv {
|
||||
|
||||
uint32_t rx_dflt_fqid;
|
||||
uint16_t tx_qdid;
|
||||
uint32_t tx_conf_fqid;
|
||||
uint16_t tx_flow_id;
|
||||
|
||||
enum ldpaa_eth_type type; /* 1G or 10G ethernet */
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/arch-fsl-lsch3/fdt.h>
|
||||
|
||||
#ifndef CONFIG_SYS_PCI_MEMORY_BUS
|
||||
#define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE
|
||||
@ -528,3 +529,64 @@ void ft_pci_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LS2085A
|
||||
|
||||
void pcie_set_available_streamids(void *blob, const char *pcie_path,
|
||||
u32 *stream_ids, int count)
|
||||
{
|
||||
int nodeoffset;
|
||||
int i;
|
||||
|
||||
nodeoffset = fdt_path_offset(blob, pcie_path);
|
||||
if (nodeoffset < 0) {
|
||||
printf("\n%s: ERROR: unable to update PCIe node\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* for each stream ID, append to mmu-masters */
|
||||
for (i = 0; i < count; i++) {
|
||||
fdt_appendprop_u32(blob, nodeoffset, "available-stream-ids",
|
||||
stream_ids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_STREAM_IDS 4
|
||||
void fdt_fixup_smmu_pcie(void *blob)
|
||||
{
|
||||
int count;
|
||||
u32 stream_ids[MAX_STREAM_IDS];
|
||||
|
||||
#ifdef CONFIG_PCIE1
|
||||
/* PEX1 stream ID fixup */
|
||||
count = FSL_PEX1_STREAM_ID_END - FSL_PEX1_STREAM_ID_START + 1;
|
||||
alloc_stream_ids(FSL_PEX1_STREAM_ID_START, count, stream_ids,
|
||||
MAX_STREAM_IDS);
|
||||
pcie_set_available_streamids(blob, "/pcie@3400000", stream_ids, count);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCIE2
|
||||
/* PEX2 stream ID fixup */
|
||||
count = FSL_PEX2_STREAM_ID_END - FSL_PEX2_STREAM_ID_START + 1;
|
||||
alloc_stream_ids(FSL_PEX2_STREAM_ID_START, count, stream_ids,
|
||||
MAX_STREAM_IDS);
|
||||
pcie_set_available_streamids(blob, "/pcie@3500000", stream_ids, count);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCIE3
|
||||
/* PEX3 stream ID fixup */
|
||||
count = FSL_PEX3_STREAM_ID_END - FSL_PEX3_STREAM_ID_START + 1;
|
||||
alloc_stream_ids(FSL_PEX3_STREAM_ID_START, count, stream_ids,
|
||||
MAX_STREAM_IDS);
|
||||
pcie_set_available_streamids(blob, "/pcie@3600000", stream_ids, count);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCIE4
|
||||
/* PEX4 stream ID fixup */
|
||||
count = FSL_PEX4_STREAM_ID_END - FSL_PEX4_STREAM_ID_START + 1;
|
||||
alloc_stream_ids(FSL_PEX4_STREAM_ID_START, count, stream_ids,
|
||||
MAX_STREAM_IDS);
|
||||
pcie_set_available_streamids(blob, "/pcie@3700000", stream_ids, count);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@ -73,3 +73,16 @@
|
||||
const char *, char **, unsigned int)
|
||||
EXPORT_FUNC(ustrtoull, unsigned long long, ustrtoull,
|
||||
const char *, char **, unsigned int)
|
||||
EXPORT_FUNC(strcpy, char *, strcpy, char *dest, const char *src)
|
||||
EXPORT_FUNC(mdelay, void, mdelay, unsigned long msec)
|
||||
#ifdef CONFIG_PHY_AQUANTIA
|
||||
EXPORT_FUNC(mdio_get_current_dev, struct mii_dev *,
|
||||
mdio_get_current_dev, void)
|
||||
EXPORT_FUNC(phy_find_by_mask, struct phy_device *, phy_find_by_mask,
|
||||
struct mii_dev *bus, unsigned phy_mask,
|
||||
phy_interface_t interface)
|
||||
EXPORT_FUNC(mdio_phydev_for_ethname, struct phy_device *,
|
||||
mdio_phydev_for_ethname, const char *ethname)
|
||||
EXPORT_FUNC(miiphy_set_current_dev, int, miiphy_set_current_dev,
|
||||
const char *devname)
|
||||
#endif
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#define CONFIG_LS102XA
|
||||
|
||||
#define CONFIG_ARMV7_PSCI
|
||||
|
||||
#define CONFIG_SYS_GENERIC_BOARD
|
||||
|
||||
#define CONFIG_DISPLAY_CPUINFO
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#define CONFIG_LS102XA
|
||||
|
||||
#define CONFIG_ARMV7_PSCI
|
||||
|
||||
#define CONFIG_SYS_GENERIC_BOARD
|
||||
|
||||
#define CONFIG_DISPLAY_CPUINFO
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define CONFIG_ARM_ERRATA_828024
|
||||
#define CONFIG_ARM_ERRATA_826974
|
||||
|
||||
#include <asm/arch-fsl-lsch3/ls2085a_stream_id.h>
|
||||
#include <asm/arch-fsl-lsch3/config.h>
|
||||
#if (defined(CONFIG_SYS_FSL_SRDS_1) || defined(CONFIG_SYS_FSL_SRDS_2))
|
||||
#define CONFIG_SYS_HAS_SERDES
|
||||
@ -163,21 +164,30 @@ unsigned long long get_qixis_addr(void);
|
||||
#define CONFIG_SYS_NAND_BASE_PHYS 0x30000000
|
||||
|
||||
/* Debug Server firmware */
|
||||
#define CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024)
|
||||
#define CONFIG_FSL_DEBUG_SERVER
|
||||
/* 2 sec timeout */
|
||||
#define CONFIG_SYS_DEBUG_SERVER_TIMEOUT (2 * 1000 * 1000)
|
||||
|
||||
/* MC firmware */
|
||||
#define CONFIG_FSL_MC_ENET
|
||||
#define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024)
|
||||
/* TODO Actual DPL max length needs to be confirmed with the MC FW team */
|
||||
#define CONFIG_SYS_LS_MC_DPC_MAX_LENGTH 0x20000
|
||||
#define CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET 0x00F00000
|
||||
#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH 0x20000
|
||||
#define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0x00F20000
|
||||
#define CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH 0x200000
|
||||
#define CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 0x07000000
|
||||
|
||||
/* Carve out a DDR region which will not be used by u-boot/Linux */
|
||||
/*
|
||||
* Carve out a DDR region which will not be used by u-boot/Linux
|
||||
*
|
||||
* It will be used by MC and Debug Server. The MC region must be
|
||||
* 512MB aligned, so the min size to hide is 512MB.
|
||||
*/
|
||||
#if defined(CONFIG_FSL_MC_ENET) || defined(CONFIG_FSL_DEBUG_SERVER)
|
||||
#define CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE (256UL * 1024 * 1024)
|
||||
#define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (256UL * 1024 * 1024)
|
||||
#define CONFIG_SYS_MEM_TOP_HIDE_MIN (512UL * 1024 * 1024)
|
||||
#define CONFIG_SYS_MEM_TOP_HIDE get_dram_size_to_hide()
|
||||
#endif
|
||||
|
||||
@ -186,7 +196,8 @@ unsigned long long get_qixis_addr(void);
|
||||
#define CONFIG_PCIE2 /* PCIE controler 2 */
|
||||
#define CONFIG_PCIE3 /* PCIE controler 3 */
|
||||
#define CONFIG_PCIE4 /* PCIE controler 4 */
|
||||
#define FSL_PCIE_COMPAT "fsl,20851a-pcie"
|
||||
#define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */
|
||||
#define FSL_PCIE_COMPAT "fsl,ls2085a-pcie"
|
||||
|
||||
#define CONFIG_SYS_PCI_64BIT
|
||||
|
||||
@ -236,13 +247,13 @@ unsigned long long get_qixis_addr(void);
|
||||
"initrd_high=0xffffffffffffffff\0" \
|
||||
"kernel_start=0x581200000\0" \
|
||||
"kernel_load=0xa0000000\0" \
|
||||
"kernel_size=0x1000000\0" \
|
||||
"kernel_size=0x2800000\0" \
|
||||
"console=ttyAMA0,38400n8\0"
|
||||
|
||||
#define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \
|
||||
"earlycon=uart8250,mmio,0x21c0600,115200 " \
|
||||
"default_hugepagesz=2m hugepagesz=2m " \
|
||||
"hugepages=16"
|
||||
"ramdisk_size=0x2000000 default_hugepagesz=2m" \
|
||||
" hugepagesz=2m hugepages=16"
|
||||
#define CONFIG_BOOTCOMMAND "cp.b $kernel_start $kernel_load " \
|
||||
"$kernel_size && bootm $kernel_load"
|
||||
#define CONFIG_BOOTDELAY 10
|
||||
@ -289,4 +300,7 @@ unsigned long get_dram_size_to_hide(void);
|
||||
#define CONFIG_SYS_SPL_MALLOC_START 0x80200000
|
||||
#define CONFIG_SYS_MONITOR_LEN (512 * 1024)
|
||||
|
||||
#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* Increase max gunzip size */
|
||||
|
||||
|
||||
#endif /* __LS2_COMMON_H */
|
||||
|
@ -9,9 +9,6 @@
|
||||
|
||||
#include "ls2085a_common.h"
|
||||
|
||||
#define CONFIG_IDENT_STRING " LS2085A-QDS"
|
||||
#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-QDS"
|
||||
|
||||
#define CONFIG_DISPLAY_BOARDINFO
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
@ -263,6 +260,8 @@ unsigned long get_board_ddr_clk(void);
|
||||
#define CONFIG_SYS_LS_MC_DPC_ADDR 0x580800000ULL
|
||||
|
||||
#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000
|
||||
#define CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR
|
||||
#define CONFIG_SYS_LS_MC_AIOP_IMG_ADDR 0x580900000ULL
|
||||
|
||||
/*
|
||||
* I2C
|
||||
@ -273,6 +272,15 @@ unsigned long get_board_ddr_clk(void);
|
||||
/* I2C bus multiplexer */
|
||||
#define I2C_MUX_CH_DEFAULT 0x8
|
||||
|
||||
/* SPI */
|
||||
#ifdef CONFIG_FSL_DSPI
|
||||
#define CONFIG_CMD_SF
|
||||
#define CONFIG_SPI_FLASH
|
||||
#define CONFIG_SPI_FLASH_STMICRO
|
||||
#define CONFIG_SPI_FLASH_SST
|
||||
#define CONFIG_SPI_FLASH_EON
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MMC
|
||||
*/
|
||||
@ -287,6 +295,7 @@ unsigned long get_board_ddr_clk(void);
|
||||
#define RTC
|
||||
#define CONFIG_RTC_DS3231 1
|
||||
#define CONFIG_SYS_I2C_RTC_ADDR 0x68
|
||||
#define CONFIG_CMD_DATE
|
||||
|
||||
/* EEPROM */
|
||||
#define CONFIG_ID_EEPROM
|
||||
@ -332,7 +341,7 @@ unsigned long get_board_ddr_clk(void);
|
||||
"initrd_high=0xffffffffffffffff\0" \
|
||||
"kernel_start=0x581100000\0" \
|
||||
"kernel_load=0xa0000000\0" \
|
||||
"kernel_size=0x1000000\0"
|
||||
"kernel_size=0x28000000\0"
|
||||
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
#define CONFIG_FSL_MEMAC
|
||||
|
@ -8,8 +8,6 @@
|
||||
#define __LS2_RDB_H
|
||||
|
||||
#include "ls2085a_common.h"
|
||||
#define CONFIG_IDENT_STRING " LS2085A-RDB"
|
||||
#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-RDB"
|
||||
|
||||
#undef CONFIG_CONS_INDEX
|
||||
#define CONFIG_CONS_INDEX 2
|
||||
@ -30,8 +28,8 @@ unsigned long get_board_sys_clk(void);
|
||||
#define CONFIG_MEM_INIT_VALUE 0xdeadbeef
|
||||
#define SPD_EEPROM_ADDRESS1 0x51
|
||||
#define SPD_EEPROM_ADDRESS2 0x52
|
||||
#define SPD_EEPROM_ADDRESS3 0x54
|
||||
#define SPD_EEPROM_ADDRESS4 0x53 /* Board error */
|
||||
#define SPD_EEPROM_ADDRESS3 0x53
|
||||
#define SPD_EEPROM_ADDRESS4 0x54
|
||||
#define SPD_EEPROM_ADDRESS5 0x55
|
||||
#define SPD_EEPROM_ADDRESS6 0x56 /* dummy address */
|
||||
#define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1
|
||||
@ -235,22 +233,33 @@ unsigned long get_board_sys_clk(void);
|
||||
#define CONFIG_SYS_LS_MC_DPC_ADDR 0x580800000ULL
|
||||
|
||||
#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000
|
||||
#define CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR
|
||||
#define CONFIG_SYS_LS_MC_AIOP_IMG_ADDR 0x580900000ULL
|
||||
|
||||
/*
|
||||
* I2C
|
||||
*/
|
||||
#define I2C_MUX_PCA_ADDR 0x77
|
||||
#define I2C_MUX_PCA_ADDR_PRI 0x77 /* Primary Mux*/
|
||||
#define I2C_MUX_PCA_ADDR 0x75
|
||||
#define I2C_MUX_PCA_ADDR_PRI 0x75 /* Primary Mux*/
|
||||
|
||||
/* I2C bus multiplexer */
|
||||
#define I2C_MUX_CH_DEFAULT 0x8
|
||||
|
||||
/* SPI */
|
||||
#ifdef CONFIG_FSL_DSPI
|
||||
#define CONFIG_CMD_SF
|
||||
#define CONFIG_SPI_FLASH
|
||||
#define CONFIG_SPI_FLASH_STMICRO
|
||||
#define CONFIG_SPI_FLASH_BAR
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RTC configuration
|
||||
*/
|
||||
#define RTC
|
||||
#define CONFIG_RTC_DS3231 1
|
||||
#define CONFIG_SYS_I2C_RTC_ADDR 0x68
|
||||
#define CONFIG_CMD_DATE
|
||||
|
||||
/* EEPROM */
|
||||
#define CONFIG_ID_EEPROM
|
||||
@ -284,6 +293,8 @@ unsigned long get_board_sys_clk(void);
|
||||
#define CONFIG_DOS_PARTITION
|
||||
#endif
|
||||
|
||||
#define CONFIG_MISC_INIT_R
|
||||
|
||||
/* Initial environment variables */
|
||||
#undef CONFIG_EXTRA_ENV_SETTINGS
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
@ -296,6 +307,30 @@ unsigned long get_board_sys_clk(void);
|
||||
"initrd_high=0xffffffffffffffff\0" \
|
||||
"kernel_start=0x581100000\0" \
|
||||
"kernel_load=0xa0000000\0" \
|
||||
"kernel_size=0x1000000\0"
|
||||
"kernel_size=0x2800000\0"
|
||||
|
||||
/* MAC/PHY configuration */
|
||||
#ifdef CONFIG_FSL_MC_ENET
|
||||
#define CONFIG_PHYLIB_10G
|
||||
#define CONFIG_PHY_CORTINA
|
||||
#define CONFIG_PHYLIB
|
||||
#define CONFIG_SYS_CORTINA_FW_IN_NOR
|
||||
#define CONFIG_CORTINA_FW_ADDR 0x581000000
|
||||
#define CONFIG_CORTINA_FW_LENGTH 0x40000
|
||||
|
||||
#define CORTINA_PHY_ADDR1 0x10
|
||||
#define CORTINA_PHY_ADDR2 0x11
|
||||
#define CORTINA_PHY_ADDR3 0x12
|
||||
#define CORTINA_PHY_ADDR4 0x13
|
||||
#define AQ_PHY_ADDR1 0x00
|
||||
#define AQ_PHY_ADDR2 0x01
|
||||
#define AQ_PHY_ADDR3 0x02
|
||||
#define AQ_PHY_ADDR4 0x03
|
||||
|
||||
#define CONFIG_MII
|
||||
#define CONFIG_ETHPRIME "DPNI1"
|
||||
#define CONFIG_PHY_GIGE
|
||||
#define CONFIG_PHY_AQUANTIA
|
||||
#endif
|
||||
|
||||
#endif /* __LS2_RDB_H */
|
||||
|
@ -2,6 +2,10 @@
|
||||
#define __EXPORTS_H__
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifdef CONFIG_PHY_AQUANTIA
|
||||
#include <miiphy.h>
|
||||
#include <phy.h>
|
||||
#endif
|
||||
|
||||
struct spi_slave;
|
||||
|
||||
@ -34,6 +38,13 @@ unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base);
|
||||
int i2c_write (uchar, uint, int , uchar* , int);
|
||||
int i2c_read (uchar, uint, int , uchar* , int);
|
||||
#endif
|
||||
#ifdef CONFIG_PHY_AQUANTIA
|
||||
struct mii_dev *mdio_get_current_dev(void);
|
||||
struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
|
||||
phy_interface_t interface);
|
||||
struct phy_device *mdio_phydev_for_ethname(const char *ethname);
|
||||
int miiphy_set_current_dev(const char *devname);
|
||||
#endif
|
||||
|
||||
void app_startup(char * const *);
|
||||
|
||||
@ -46,7 +57,7 @@ struct jt_funcs {
|
||||
};
|
||||
|
||||
|
||||
#define XF_VERSION 7
|
||||
#define XF_VERSION 8
|
||||
|
||||
#if defined(CONFIG_X86)
|
||||
extern gd_t *global_data;
|
||||
|
@ -8,8 +8,8 @@
|
||||
#define _FSL_DPIO_H
|
||||
|
||||
/* DPIO Version */
|
||||
#define DPIO_VER_MAJOR 2
|
||||
#define DPIO_VER_MINOR 1
|
||||
#define DPIO_VER_MAJOR 3
|
||||
#define DPIO_VER_MINOR 0
|
||||
|
||||
/* Command IDs */
|
||||
#define DPIO_CMDID_CLOSE 0x800
|
||||
@ -31,8 +31,8 @@ do { \
|
||||
MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qbman_portal_id);\
|
||||
MC_RSP_OP(cmd, 0, 48, 8, uint8_t, attr->num_priorities);\
|
||||
MC_RSP_OP(cmd, 0, 56, 4, enum dpio_channel_mode, attr->channel_mode);\
|
||||
MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_paddr);\
|
||||
MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_paddr);\
|
||||
MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_offset);\
|
||||
MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_offset);\
|
||||
MC_RSP_OP(cmd, 3, 0, 16, uint16_t, attr->version.major);\
|
||||
MC_RSP_OP(cmd, 3, 16, 16, uint16_t, attr->version.minor);\
|
||||
} while (0)
|
||||
@ -42,6 +42,7 @@ do { \
|
||||
*/
|
||||
|
||||
struct fsl_mc_io;
|
||||
|
||||
/**
|
||||
* dpio_open() - Open a control session for the specified object
|
||||
* @mc_io: Pointer to MC portal's I/O object
|
||||
@ -61,18 +62,9 @@ struct fsl_mc_io;
|
||||
int dpio_open(struct fsl_mc_io *mc_io, int dpio_id, uint16_t *token);
|
||||
|
||||
/**
|
||||
* dpio_open() - Open a control session for the specified object
|
||||
* dpio_close() - Close the control session of the object
|
||||
* @mc_io: Pointer to MC portal's I/O object
|
||||
* @dpio_id: DPIO unique ID
|
||||
* @token: Returned token; use in subsequent API calls
|
||||
*
|
||||
* This function can be used to open a control session for an
|
||||
* already created object; an object may have been declared in
|
||||
* the DPL or by calling the dpio_create() function.
|
||||
* This function returns a unique authentication token,
|
||||
* associated with the specific object ID and the specific MC
|
||||
* portal; this token must be used in all subsequent commands for
|
||||
* this specific object.
|
||||
* @token: Token of DPIO object
|
||||
*
|
||||
* Return: '0' on Success; Error code otherwise.
|
||||
*/
|
||||
@ -121,10 +113,8 @@ int dpio_reset(struct fsl_mc_io *mc_io, uint16_t token);
|
||||
* struct dpio_attr - Structure representing DPIO attributes
|
||||
* @id: DPIO object ID
|
||||
* @version: DPIO version
|
||||
* @qbman_portal_ce_paddr: Physical address of the software portal
|
||||
* cache-enabled area
|
||||
* @qbman_portal_ci_paddr: Physical address of the software portal
|
||||
* cache-inhibited area
|
||||
* @qbman_portal_ce_offset: offset of the software portal cache-enabled area
|
||||
* @qbman_portal_ci_offset: offset of the software portal cache-inhibited area
|
||||
* @qbman_portal_id: Software portal ID
|
||||
* @channel_mode: Notification channel mode
|
||||
* @num_priorities: Number of priorities for the notification channel (1-8);
|
||||
@ -141,8 +131,8 @@ struct dpio_attr {
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
} version;
|
||||
uint64_t qbman_portal_ce_paddr;
|
||||
uint64_t qbman_portal_ci_paddr;
|
||||
uint64_t qbman_portal_ce_offset;
|
||||
uint64_t qbman_portal_ci_offset;
|
||||
uint16_t qbman_portal_id;
|
||||
enum dpio_channel_mode channel_mode;
|
||||
uint8_t num_priorities;
|
||||
|
@ -14,7 +14,7 @@ struct fsl_mc_io;
|
||||
/**
|
||||
* Management Complex firmware version information
|
||||
*/
|
||||
#define MC_VER_MAJOR 6
|
||||
#define MC_VER_MAJOR 7
|
||||
#define MC_VER_MINOR 0
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define _FSL_DPNI_H
|
||||
|
||||
/* DPNI Version */
|
||||
#define DPNI_VER_MAJOR 4
|
||||
#define DPNI_VER_MAJOR 5
|
||||
#define DPNI_VER_MINOR 0
|
||||
|
||||
/* Command IDs */
|
||||
@ -78,7 +78,7 @@ do { \
|
||||
MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->max_tcs); \
|
||||
MC_RSP_OP(cmd, 0, 40, 8, uint8_t, attr->max_senders); \
|
||||
MC_RSP_OP(cmd, 0, 48, 8, enum net_prot, attr->start_hdr); \
|
||||
MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->options); \
|
||||
MC_RSP_OP(cmd, 1, 0, 32, uint32_t, attr->options); \
|
||||
MC_RSP_OP(cmd, 2, 0, 8, uint8_t, attr->max_unicast_filters); \
|
||||
MC_RSP_OP(cmd, 2, 8, 8, uint8_t, attr->max_multicast_filters);\
|
||||
MC_RSP_OP(cmd, 2, 16, 8, uint8_t, attr->max_vlan_filters); \
|
||||
@ -98,7 +98,9 @@ do { \
|
||||
MC_RSP_OP(cmd, 4, 16, 16, uint16_t, \
|
||||
attr->ipr_cfg.min_frag_size_ipv4); \
|
||||
MC_RSP_OP(cmd, 4, 32, 16, uint16_t, \
|
||||
attr->ipr_cfg.min_frag_size_ipv6); \
|
||||
attr->ipr_cfg.min_frag_size_ipv6);\
|
||||
MC_RSP_OP(cmd, 4, 48, 8, uint8_t, attr->max_policers); \
|
||||
MC_RSP_OP(cmd, 4, 56, 8, uint8_t, attr->max_congestion_ctrl); \
|
||||
MC_RSP_OP(cmd, 5, 0, 16, uint16_t, \
|
||||
attr->ipr_cfg.max_open_frames_ipv4); \
|
||||
MC_RSP_OP(cmd, 5, 16, 16, uint16_t, \
|
||||
@ -208,7 +210,7 @@ do { \
|
||||
/* cmd, param, offset, width, type, arg_name */
|
||||
#define DPNI_CMD_SET_LINK_CFG(cmd, cfg) \
|
||||
do { \
|
||||
MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->rate);\
|
||||
MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->rate);\
|
||||
MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options);\
|
||||
} while (0)
|
||||
|
||||
@ -216,7 +218,7 @@ do { \
|
||||
#define DPNI_RSP_GET_LINK_STATE(cmd, state) \
|
||||
do { \
|
||||
MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
|
||||
MC_RSP_OP(cmd, 1, 0, 64, uint64_t, state->rate);\
|
||||
MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\
|
||||
MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
|
||||
} while (0)
|
||||
|
||||
@ -326,6 +328,13 @@ do { \
|
||||
MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->user_ctx); \
|
||||
MC_CMD_OP(cmd, 2, 16, 8, uint8_t, tc_id); \
|
||||
MC_CMD_OP(cmd, 2, 32, 32, uint32_t, cfg->options); \
|
||||
MC_CMD_OP(cmd, 3, 0, 4, enum dpni_flc_type, cfg->flc_cfg.flc_type); \
|
||||
MC_CMD_OP(cmd, 3, 4, 4, enum dpni_stash_size, \
|
||||
cfg->flc_cfg.frame_data_size);\
|
||||
MC_CMD_OP(cmd, 3, 8, 4, enum dpni_stash_size, \
|
||||
cfg->flc_cfg.flow_context_size);\
|
||||
MC_CMD_OP(cmd, 3, 32, 32, uint32_t, cfg->flc_cfg.options);\
|
||||
MC_CMD_OP(cmd, 4, 0, 64, uint64_t, cfg->flc_cfg.flow_context);\
|
||||
} while (0)
|
||||
|
||||
/* cmd, param, offset, width, type, arg_name */
|
||||
@ -343,6 +352,13 @@ do { \
|
||||
MC_RSP_OP(cmd, 0, 40, 2, enum dpni_dest, attr->dest_cfg.dest_type); \
|
||||
MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->user_ctx); \
|
||||
MC_RSP_OP(cmd, 2, 32, 32, uint32_t, attr->fqid); \
|
||||
MC_RSP_OP(cmd, 3, 0, 4, enum dpni_flc_type, attr->flc_cfg.flc_type); \
|
||||
MC_RSP_OP(cmd, 3, 4, 4, enum dpni_stash_size, \
|
||||
attr->flc_cfg.frame_data_size);\
|
||||
MC_RSP_OP(cmd, 3, 8, 4, enum dpni_stash_size, \
|
||||
attr->flc_cfg.flow_context_size);\
|
||||
MC_RSP_OP(cmd, 3, 32, 32, uint32_t, attr->flc_cfg.options);\
|
||||
MC_RSP_OP(cmd, 4, 0, 64, uint64_t, attr->flc_cfg.flow_context);\
|
||||
} while (0)
|
||||
|
||||
enum net_prot {
|
||||
@ -399,7 +415,8 @@ enum net_prot {
|
||||
NET_PROT_DUMMY_LAST
|
||||
};
|
||||
|
||||
/* Data Path Network Interface API
|
||||
/**
|
||||
* Data Path Network Interface API
|
||||
* Contains initialization APIs and runtime control APIs for DPNI
|
||||
*/
|
||||
|
||||
@ -545,6 +562,8 @@ int dpni_reset(struct fsl_mc_io *mc_io, uint16_t token);
|
||||
* @max_qos_entries: if 'max_tcs > 1', declares the maximum entries in QoS table
|
||||
* @max_qos_key_size: Maximum key size for the QoS look-up
|
||||
* @max_dist_key_size: Maximum key size for the distribution look-up
|
||||
* @max_policers: Maximum number of policers;
|
||||
* @max_congestion_ctrl: Maximum number of congestion control groups (CGs);
|
||||
* @ipr_cfg: IP reassembly configuration
|
||||
*/
|
||||
struct dpni_attr {
|
||||
@ -559,7 +578,7 @@ struct dpni_attr {
|
||||
uint16_t minor;
|
||||
} version;
|
||||
enum net_prot start_hdr;
|
||||
uint64_t options;
|
||||
uint32_t options;
|
||||
uint8_t max_senders;
|
||||
uint8_t max_tcs;
|
||||
uint8_t max_dist_per_tc[DPNI_MAX_TC];
|
||||
@ -569,8 +588,11 @@ struct dpni_attr {
|
||||
uint8_t max_qos_entries;
|
||||
uint8_t max_qos_key_size;
|
||||
uint8_t max_dist_key_size;
|
||||
uint8_t max_policers;
|
||||
uint8_t max_congestion_ctrl;
|
||||
struct dpni_ipr_cfg ipr_cfg;
|
||||
};
|
||||
|
||||
/**
|
||||
* dpni_get_attributes() - Retrieve DPNI attributes.
|
||||
* @mc_io: Pointer to MC portal's I/O objec
|
||||
@ -634,6 +656,7 @@ struct dpni_buffer_layout {
|
||||
int dpni_get_rx_buffer_layout(struct fsl_mc_io *mc_io,
|
||||
uint16_t token,
|
||||
struct dpni_buffer_layout *layout);
|
||||
|
||||
/**
|
||||
* dpni_set_rx_buffer_layout() - Set Rx buffer layout configuration.
|
||||
* @mc_io: Pointer to MC portal's I/O object
|
||||
@ -661,19 +684,19 @@ int dpni_get_tx_buffer_layout(struct fsl_mc_io *mc_io,
|
||||
struct dpni_buffer_layout *layout);
|
||||
|
||||
/**
|
||||
* @brief Set Tx buffer layout configuration.
|
||||
* dpni_set_tx_buffer_layout() - Set Tx buffer layout configuration.
|
||||
* @mc_io: Pointer to MC portal's I/O object
|
||||
* @token: Token of DPNI object
|
||||
* @layout: Buffer layout configuration
|
||||
*
|
||||
* @param[in] mc_io Pointer to MC portal's I/O object
|
||||
* @param[in] token Token of DPNI object
|
||||
* @param[in] layout Buffer layout configuration
|
||||
*
|
||||
* @returns '0' on Success; Error code otherwise.
|
||||
* Return: '0' on Success; Error code otherwise.
|
||||
*
|
||||
* @warning Allowed only when DPNI is disabled
|
||||
*/
|
||||
int dpni_set_tx_buffer_layout(struct fsl_mc_io *mc_io,
|
||||
uint16_t token,
|
||||
const struct dpni_buffer_layout *layout);
|
||||
|
||||
/**
|
||||
* dpni_get_tx_conf_buffer_layout() - Retrieve Tx confirmation buffer layout
|
||||
* attributes.
|
||||
@ -686,6 +709,7 @@ int dpni_set_tx_buffer_layout(struct fsl_mc_io *mc_io,
|
||||
int dpni_get_tx_conf_buffer_layout(struct fsl_mc_io *mc_io,
|
||||
uint16_t token,
|
||||
struct dpni_buffer_layout *layout);
|
||||
|
||||
/**
|
||||
* dpni_set_tx_conf_buffer_layout() - Set Tx confirmation buffer layout
|
||||
* configuration.
|
||||
@ -700,15 +724,16 @@ int dpni_get_tx_conf_buffer_layout(struct fsl_mc_io *mc_io,
|
||||
int dpni_set_tx_conf_buffer_layout(struct fsl_mc_io *mc_io,
|
||||
uint16_t token,
|
||||
const struct dpni_buffer_layout *layout);
|
||||
|
||||
/**
|
||||
* dpni_get_spid() - Get the AIOP storage profile ID associated with the DPNI
|
||||
* dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
|
||||
* for enqueue operations
|
||||
* @mc_io: Pointer to MC portal's I/O object
|
||||
* @token: Token of DPNI object
|
||||
* @spid: Returned aiop storage-profile ID
|
||||
* @qdid: Returned virtual QDID value that should be used as an argument
|
||||
* in all enqueue operations
|
||||
*
|
||||
* Return: '0' on Success; Error code otherwise.
|
||||
*
|
||||
* @warning Only relevant for DPNI that belongs to AIOP container.
|
||||
*/
|
||||
int dpni_get_qdid(struct fsl_mc_io *mc_io, uint16_t token, uint16_t *qdid);
|
||||
|
||||
@ -781,13 +806,23 @@ int dpni_set_counter(struct fsl_mc_io *mc_io,
|
||||
uint16_t token,
|
||||
enum dpni_counter counter,
|
||||
uint64_t value);
|
||||
|
||||
/* Enable auto-negotiation */
|
||||
#define DPNI_LINK_OPT_AUTONEG 0x0000000000000001ULL
|
||||
/* Enable half-duplex mode */
|
||||
#define DPNI_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
|
||||
/* Enable pause frames */
|
||||
#define DPNI_LINK_OPT_PAUSE 0x0000000000000004ULL
|
||||
/* Enable a-symmetric pause frames */
|
||||
#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
|
||||
|
||||
/**
|
||||
* struct - Structure representing DPNI link configuration
|
||||
* @rate: Rate
|
||||
* @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
|
||||
*/
|
||||
struct dpni_link_cfg {
|
||||
uint64_t rate;
|
||||
uint32_t rate;
|
||||
uint64_t options;
|
||||
};
|
||||
|
||||
@ -801,7 +836,7 @@ struct dpni_link_cfg {
|
||||
*/
|
||||
int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
|
||||
uint16_t token,
|
||||
struct dpni_link_cfg *cfg);
|
||||
const struct dpni_link_cfg *cfg);
|
||||
|
||||
/**
|
||||
* struct dpni_link_state - Structure representing DPNI link state
|
||||
@ -810,7 +845,7 @@ int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
|
||||
* @up: Link state; '0' for down, '1' for up
|
||||
*/
|
||||
struct dpni_link_state {
|
||||
uint64_t rate;
|
||||
uint32_t rate;
|
||||
uint64_t options;
|
||||
int up;
|
||||
};
|
||||
@ -838,6 +873,7 @@ int dpni_get_link_state(struct fsl_mc_io *mc_io,
|
||||
int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
|
||||
uint16_t token,
|
||||
const uint8_t mac_addr[6]);
|
||||
|
||||
/**
|
||||
* dpni_get_primary_mac_addr() - Get the primary MAC address
|
||||
* @mc_io: Pointer to MC portal's I/O object
|
||||
@ -849,6 +885,7 @@ int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
|
||||
int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
|
||||
uint16_t token,
|
||||
uint8_t mac_addr[6]);
|
||||
|
||||
/**
|
||||
* dpni_add_mac_addr() - Add MAC address filter
|
||||
* @mc_io: Pointer to MC portal's I/O object
|
||||
@ -875,7 +912,7 @@ int dpni_remove_mac_addr(struct fsl_mc_io *mc_io,
|
||||
|
||||
/**
|
||||
* enum dpni_dest - DPNI destination types
|
||||
* DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
|
||||
* @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
|
||||
* does not generate FQDAN notifications; user is expected to
|
||||
* dequeue from the queue based on polling or other user-defined
|
||||
* method
|
||||
@ -906,12 +943,69 @@ struct dpni_dest_cfg {
|
||||
uint8_t priority;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dpni_flc_type - DPNI FLC types
|
||||
* @DPNI_FLC_USER_DEFINED: select the FLC to be used for user defined value
|
||||
* @DPNI_FLC_STASH: select the FLC to be used for stash control
|
||||
*/
|
||||
enum dpni_flc_type {
|
||||
DPNI_FLC_USER_DEFINED = 0,
|
||||
DPNI_FLC_STASH = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dpni_stash_size - DPNI FLC stashing size
|
||||
* @DPNI_STASH_SIZE_0B: no stash
|
||||
* @DPNI_STASH_SIZE_64B: stashes 64 bytes
|
||||
* @DPNI_STASH_SIZE_128B: stashes 128 bytes
|
||||
* @DPNI_STASH_SIZE_192B: stashes 192 bytes
|
||||
*/
|
||||
enum dpni_stash_size {
|
||||
DPNI_STASH_SIZE_0B = 0,
|
||||
DPNI_STASH_SIZE_64B = 1,
|
||||
DPNI_STASH_SIZE_128B = 2,
|
||||
DPNI_STASH_SIZE_192B = 3,
|
||||
};
|
||||
|
||||
/* DPNI FLC stash options */
|
||||
|
||||
/* stashes the whole annotation area (up to 192 bytes) */
|
||||
#define DPNI_FLC_STASH_FRAME_ANNOTATION 0x00000001
|
||||
|
||||
/**
|
||||
* struct dpni_flc_cfg - Structure representing DPNI FLC configuration
|
||||
* @flc_type: FLC type
|
||||
* @options: Mask of available options;
|
||||
* use 'DPNI_FLC_STASH_<X>' values
|
||||
* @frame_data_size: Size of frame data to be stashed
|
||||
* @flow_context_size: Size of flow context to be stashed
|
||||
* @flow_context: 1. In case flc_type is 'DPNI_FLC_USER_DEFINED':
|
||||
* this value will be provided in the frame descriptor
|
||||
* (FD[FLC])
|
||||
* 2. In case flc_type is 'DPNI_FLC_STASH':
|
||||
* this value will be I/O virtual address of the
|
||||
* flow-context;
|
||||
* Must be cacheline-aligned and DMA-able memory
|
||||
*/
|
||||
struct dpni_flc_cfg {
|
||||
enum dpni_flc_type flc_type;
|
||||
uint32_t options;
|
||||
enum dpni_stash_size frame_data_size;
|
||||
enum dpni_stash_size flow_context_size;
|
||||
uint64_t flow_context;
|
||||
};
|
||||
|
||||
/* DPNI queue modification options */
|
||||
|
||||
/* Select to modify the user's context associated with the queue */
|
||||
#define DPNI_QUEUE_OPT_USER_CTX 0x00000001
|
||||
/* Select to modify the queue's destination */
|
||||
#define DPNI_QUEUE_OPT_DEST 0x00000002
|
||||
/** Select to modify the flow-context parameters;
|
||||
* not applicable for Tx-conf/Err queues as the FD comes from the user
|
||||
*/
|
||||
#define DPNI_QUEUE_OPT_FLC 0x00000004
|
||||
|
||||
|
||||
/**
|
||||
* struct dpni_queue_cfg - Structure representing queue configuration
|
||||
@ -922,11 +1016,17 @@ struct dpni_dest_cfg {
|
||||
* is contained in 'options'
|
||||
* @dest_cfg: Queue destination parameters;
|
||||
* valid only if 'DPNI_QUEUE_OPT_DEST' is contained in 'options'
|
||||
* @flc_cfg: Flow context configuration; in case the TC's distribution
|
||||
* is either NONE or HASH the FLC's settings of flow#0 are used.
|
||||
* in the case of FS (flow-steering) the flow's FLC settings
|
||||
* are used.
|
||||
* valid only if 'DPNI_QUEUE_OPT_FLC' is contained in 'options'
|
||||
*/
|
||||
struct dpni_queue_cfg {
|
||||
uint32_t options;
|
||||
uint64_t user_ctx;
|
||||
struct dpni_dest_cfg dest_cfg;
|
||||
struct dpni_flc_cfg flc_cfg;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -934,11 +1034,13 @@ struct dpni_queue_cfg {
|
||||
* @user_ctx: User context value provided in the frame descriptor of each
|
||||
* dequeued frame
|
||||
* @dest_cfg: Queue destination configuration
|
||||
* @flc_cfg: Flow context configuration
|
||||
* @fqid: Virtual fqid value to be used for dequeue operations
|
||||
*/
|
||||
struct dpni_queue_attr {
|
||||
uint64_t user_ctx;
|
||||
struct dpni_dest_cfg dest_cfg;
|
||||
struct dpni_flc_cfg flc_cfg;
|
||||
uint32_t fqid;
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#define _FSL_DPRC_H
|
||||
|
||||
/* DPRC Version */
|
||||
#define DPRC_VER_MAJOR 2
|
||||
#define DPRC_VER_MAJOR 4
|
||||
#define DPRC_VER_MINOR 0
|
||||
|
||||
/* Command IDs */
|
||||
@ -88,6 +88,22 @@ do { \
|
||||
MC_RSP_OP(cmd, 4, 40, 8, char, obj_desc->type[13]);\
|
||||
MC_RSP_OP(cmd, 4, 48, 8, char, obj_desc->type[14]);\
|
||||
MC_RSP_OP(cmd, 4, 56, 8, char, obj_desc->type[15]);\
|
||||
MC_RSP_OP(cmd, 5, 0, 8, char, obj_desc->label[0]);\
|
||||
MC_RSP_OP(cmd, 5, 8, 8, char, obj_desc->label[1]);\
|
||||
MC_RSP_OP(cmd, 5, 16, 8, char, obj_desc->label[2]);\
|
||||
MC_RSP_OP(cmd, 5, 24, 8, char, obj_desc->label[3]);\
|
||||
MC_RSP_OP(cmd, 5, 32, 8, char, obj_desc->label[4]);\
|
||||
MC_RSP_OP(cmd, 5, 40, 8, char, obj_desc->label[5]);\
|
||||
MC_RSP_OP(cmd, 5, 48, 8, char, obj_desc->label[6]);\
|
||||
MC_RSP_OP(cmd, 5, 56, 8, char, obj_desc->label[7]);\
|
||||
MC_RSP_OP(cmd, 6, 0, 8, char, obj_desc->label[8]);\
|
||||
MC_RSP_OP(cmd, 6, 8, 8, char, obj_desc->label[9]);\
|
||||
MC_RSP_OP(cmd, 6, 16, 8, char, obj_desc->label[10]);\
|
||||
MC_RSP_OP(cmd, 6, 24, 8, char, obj_desc->label[11]);\
|
||||
MC_RSP_OP(cmd, 6, 32, 8, char, obj_desc->label[12]);\
|
||||
MC_RSP_OP(cmd, 6, 40, 8, char, obj_desc->label[13]);\
|
||||
MC_RSP_OP(cmd, 6, 48, 8, char, obj_desc->label[14]);\
|
||||
MC_RSP_OP(cmd, 6, 56, 8, char, obj_desc->label[15]);\
|
||||
} while (0)
|
||||
|
||||
/* cmd, param, offset, width, type, arg_name */
|
||||
@ -175,10 +191,32 @@ do { \
|
||||
/* param, offset, width, type, arg_name */
|
||||
#define DPRC_RSP_GET_OBJ_REGION(cmd, region_desc) \
|
||||
do { \
|
||||
MC_RSP_OP(cmd, 1, 0, 64, uint64_t, region_desc->base_paddr);\
|
||||
MC_RSP_OP(cmd, 1, 0, 64, uint64_t, region_desc->base_offset);\
|
||||
MC_RSP_OP(cmd, 2, 0, 32, uint32_t, region_desc->size); \
|
||||
} while (0)
|
||||
|
||||
/* cmd, param, offset, width, type, arg_name */
|
||||
#define DPRC_CMD_SET_OBJ_LABEL(cmd, obj_index, label) \
|
||||
do { \
|
||||
MC_CMD_OP(cmd, 0, 0, 32, int, obj_index); \
|
||||
MC_CMD_OP(cmd, 1, 0, 8, char, label[0]);\
|
||||
MC_CMD_OP(cmd, 1, 8, 8, char, label[1]);\
|
||||
MC_CMD_OP(cmd, 1, 16, 8, char, label[2]);\
|
||||
MC_CMD_OP(cmd, 1, 24, 8, char, label[3]);\
|
||||
MC_CMD_OP(cmd, 1, 32, 8, char, label[4]);\
|
||||
MC_CMD_OP(cmd, 1, 40, 8, char, label[5]);\
|
||||
MC_CMD_OP(cmd, 1, 48, 8, char, label[6]);\
|
||||
MC_CMD_OP(cmd, 1, 56, 8, char, label[7]);\
|
||||
MC_CMD_OP(cmd, 2, 0, 8, char, label[8]);\
|
||||
MC_CMD_OP(cmd, 2, 8, 8, char, label[9]);\
|
||||
MC_CMD_OP(cmd, 2, 16, 8, char, label[10]);\
|
||||
MC_CMD_OP(cmd, 2, 24, 8, char, label[11]);\
|
||||
MC_CMD_OP(cmd, 2, 32, 8, char, label[12]);\
|
||||
MC_CMD_OP(cmd, 2, 40, 8, char, label[13]);\
|
||||
MC_CMD_OP(cmd, 2, 48, 8, char, label[14]);\
|
||||
MC_CMD_OP(cmd, 2, 56, 8, char, label[15]);\
|
||||
} while (0)
|
||||
|
||||
/* cmd, param, offset, width, type, arg_name */
|
||||
#define DPRC_CMD_CONNECT(cmd, endpoint1, endpoint2) \
|
||||
do { \
|
||||
@ -294,6 +332,7 @@ do { \
|
||||
/* Data Path Resource Container API
|
||||
* Contains DPRC API for managing and querying DPAA resources
|
||||
*/
|
||||
|
||||
struct fsl_mc_io;
|
||||
|
||||
/**
|
||||
@ -366,7 +405,7 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token);
|
||||
/* Object initialization allowed - software context associated with this
|
||||
* container is allowed to invoke object initialization operations.
|
||||
*/
|
||||
#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004
|
||||
#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004
|
||||
|
||||
/* Topology change allowed - software context associated with this
|
||||
* container is allowed to invoke topology operations, such as attach/detach
|
||||
@ -389,11 +428,13 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token);
|
||||
* @portal_id: Portal ID; if set to 'DPRC_GET_PORTAL_ID_FROM_POOL', a free
|
||||
* portal ID is allocated by the DPRC
|
||||
* @options: Combination of 'DPRC_CFG_OPT_<X>' options
|
||||
* @label: Object's label
|
||||
*/
|
||||
struct dprc_cfg {
|
||||
uint16_t icid;
|
||||
int portal_id;
|
||||
uint64_t options;
|
||||
char label[16];
|
||||
};
|
||||
|
||||
/**
|
||||
@ -484,6 +525,7 @@ int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count);
|
||||
* @irq_count: Number of interrupts supported by the object
|
||||
* @region_count: Number of mappable regions supported by the object
|
||||
* @state: Object state: combination of DPRC_OBJ_STATE_ states
|
||||
* @label: Object label
|
||||
*/
|
||||
struct dprc_obj_desc {
|
||||
char type[16];
|
||||
@ -494,6 +536,7 @@ struct dprc_obj_desc {
|
||||
uint8_t irq_count;
|
||||
uint8_t region_count;
|
||||
uint32_t state;
|
||||
char label[16];
|
||||
};
|
||||
|
||||
/**
|
||||
@ -516,8 +559,8 @@ int dprc_get_obj(struct fsl_mc_io *mc_io,
|
||||
struct dprc_obj_desc *obj_desc);
|
||||
|
||||
/**
|
||||
* dprc_get_res_count() - Obtains the number of free resources that are assigned
|
||||
* to this container, by pool type
|
||||
* dprc_get_res_count() - Obtains the number of free resources that are
|
||||
* assigned to this container, by pool type
|
||||
* @mc_io: Pointer to MC portal's I/O object
|
||||
* @token: Token of DPRC object
|
||||
* @type: pool type
|
||||
@ -574,11 +617,14 @@ int dprc_get_res_ids(struct fsl_mc_io *mc_io,
|
||||
|
||||
/**
|
||||
* struct dprc_region_desc - Mappable region descriptor
|
||||
* @base_paddr: Region base physical address
|
||||
* @base_offset: Region offset from region's base address.
|
||||
* For DPMCP and DPRC objects, region base is offset from SoC MC portals
|
||||
* base address; For DPIO, region base is offset from SoC QMan portals
|
||||
* base address
|
||||
* @size: Region size (in bytes)
|
||||
*/
|
||||
struct dprc_region_desc {
|
||||
uint64_t base_paddr;
|
||||
uint64_t base_offset;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
@ -642,8 +688,8 @@ int dprc_disconnect(struct fsl_mc_io *mc_io,
|
||||
/**
|
||||
* dprc_get_connection() - Get connected endpoint and link status if connection
|
||||
* exists.
|
||||
* @mc_io Pointer to MC portal's I/O object
|
||||
* @token Token of DPRC object
|
||||
* @mc_io Pointer to MC portal's I/O object
|
||||
* @token Token of DPRC object
|
||||
* @endpoint1 Endpoint 1 configuration parameters
|
||||
* @endpoint2 Returned endpoint 2 configuration parameters
|
||||
* @state: Returned link state: 1 - link is up, 0 - link is down
|
||||
|
@ -21,12 +21,9 @@
|
||||
#define GCR1_M2_DE_RST BIT(14)
|
||||
#define GCR1_M_ALL_DE_RST (GCR1_M1_DE_RST | GCR1_M2_DE_RST)
|
||||
#define GSR_FS_MASK 0x3fffffff
|
||||
#define MCFAPR_PL_MASK (0x1 << 18)
|
||||
#define MCFAPR_BMT_MASK (0x1 << 17)
|
||||
#define MCFAPR_BYPASS_ICID_MASK \
|
||||
(MCFAPR_PL_MASK | MCFAPR_BMT_MASK)
|
||||
|
||||
#define SOC_MC_PORTALS_BASE_ADDR ((void __iomem *)0x00080C000000)
|
||||
#define SOC_QBMAN_PORTALS_BASE_ADDR ((void __iomem *)0x000818000000)
|
||||
#define SOC_MC_PORTAL_STRIDE 0x10000
|
||||
|
||||
#define SOC_MC_PORTAL_ADDR(_portal_id) \
|
||||
|
@ -136,4 +136,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||
int fsl_ddr_get_dimm_params(dimm_params_t *pdimm,
|
||||
unsigned int controller_number,
|
||||
unsigned int dimm_number);
|
||||
void update_spd_address(unsigned int ctrl_num,
|
||||
unsigned int slot,
|
||||
unsigned int *addr);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user