GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef BOARD_FAMILY_H
|
||||
#define BOARD_FAMILY_H
|
||||
|
||||
#if defined(DRIVER_SPD_ENABLE) && !defined(DRIVER_SPD_SPOOF)
|
||||
#include <spd.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_GPIO
|
||||
/* max number of supported GPIOs to construct the bitmap for board detection */
|
||||
#define MAX_NR_GPIOS 4
|
||||
|
||||
/* max GPIO bitmap value */
|
||||
#define MAX_GPIO_BITMAP_VAL (BIT(MAX_NR_GPIOS) - 1)
|
||||
#endif
|
||||
|
||||
struct mcb_ref_group {
|
||||
uint32_t mcb_ref;
|
||||
unsigned int *mcb_cfg;
|
||||
};
|
||||
|
||||
#define MCB_REF_GROUP(ref) \
|
||||
{ \
|
||||
.mcb_ref = 0x ## ref, \
|
||||
.mcb_cfg = mcb_ ## ref, \
|
||||
}
|
||||
|
||||
#endif
|
||||
+302
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/bl_common.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
static void brcm_stingray_pnor_pinmux_init(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
INFO(" - pnor pinmux init start.\n");
|
||||
|
||||
/* Set PNOR_ADV_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2dc),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set PNOR_BAA_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2e0),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set PNOR_BLS_0_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2e4),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set PNOR_BLS_1_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2e8),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set PNOR_CRE_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2ec),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set PNOR_CS_2_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2f0),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set PNOR_CS_1_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2f4),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set PNOR_CS_0_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2f8),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set PNOR_WE_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2fc),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set PNOR_OE_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x300),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set PNOR_INTR_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x304),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set PNOR_DAT_x_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
for (i = 0; i < 0x40; i += 0x4) {
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x308 + i),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
}
|
||||
|
||||
/* Set NAND_CE1_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x348),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set NAND_CE0_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x34c),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set NAND_WE_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x350),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set NAND_WP_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x354),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set NAND_RE_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x358),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set NAND_RDY_BSY_N_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x35c),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set NAND_IOx_0_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
for (i = 0; i < 0x40; i += 0x4) {
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x360 + i),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
}
|
||||
|
||||
/* Set NAND_ALE_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x3a0),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
/* Set NAND_CLE_MODE_SEL_CONTROL.fsel = 0x2 */
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x3a4),
|
||||
MODE_SEL_CONTROL_FSEL_MASK,
|
||||
MODE_SEL_CONTROL_FSEL_MODE2);
|
||||
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x40), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x44), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x48), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x4c), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x50), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x54), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x58), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x5c), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x60), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x64), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x68), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x6c), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x70), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x74), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x78), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x7c), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x80), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x84), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x88), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x8c), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x90), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x94), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x98), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x9c), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0xa0), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0xa4), (7 << 1), 0x8);
|
||||
mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0xa8), (7 << 1), 0x8);
|
||||
|
||||
INFO(" - pnor pinmux init done.\n");
|
||||
}
|
||||
|
||||
#if BL2_TEST_EXT_SRAM
|
||||
#define SRAM_CHECKS_GRANUL 0x100000
|
||||
#define SRAM_CHECKS_CNT 8
|
||||
static unsigned int sram_checks[SRAM_CHECKS_CNT] = {
|
||||
/* offset, magic */
|
||||
0xd00dfeed,
|
||||
0xfadebabe,
|
||||
0xc001d00d,
|
||||
0xa5a5b5b5,
|
||||
0x5a5a5b5b,
|
||||
0xc5c5d5d5,
|
||||
0x5c5c5d5d,
|
||||
0xe5e5f5f5,
|
||||
};
|
||||
#endif
|
||||
|
||||
static void brcm_stingray_pnor_sram_init(void)
|
||||
{
|
||||
unsigned int val, tmp;
|
||||
#if BL2_TEST_EXT_SRAM
|
||||
unsigned int off, i;
|
||||
#endif
|
||||
INFO(" - pnor sram init start.\n");
|
||||
|
||||
/* Enable PNOR Clock */
|
||||
INFO(" -- enable pnor clock\n");
|
||||
mmio_write_32((uintptr_t)(PNOR_IDM_IO_CONTROL_DIRECT), 0x1);
|
||||
udelay(500);
|
||||
|
||||
/* Reset PNOR */
|
||||
INFO(" -- reset pnor\n");
|
||||
mmio_setbits_32((uintptr_t)(PNOR_IDM_IO_RESET_CONTROL), 0x1);
|
||||
udelay(500);
|
||||
mmio_clrbits_32((uintptr_t)(PNOR_IDM_IO_RESET_CONTROL), 0x1);
|
||||
udelay(500);
|
||||
|
||||
/* Configure slave address to chip-select mapping */
|
||||
INFO(" -- configure pnor slave address to chip-select mapping\n");
|
||||
/* 0x74000000-0x75ffffff => CS0 (32MB) */
|
||||
val = (0xfe << PNOR_ICFG_CS_x_MASK0_SHIFT);
|
||||
val |= (0x74);
|
||||
mmio_write_32((uintptr_t)(PNOR_ICFG_CS_0), val);
|
||||
/* 0x76000000-0x77ffffff => CS1 (32MB) */
|
||||
val = (0xfe << PNOR_ICFG_CS_x_MASK0_SHIFT);
|
||||
val |= (0x76);
|
||||
mmio_write_32((uintptr_t)(PNOR_ICFG_CS_1), val);
|
||||
/* 0xffffffff-0xffffffff => CS2 (0MB) */
|
||||
val = (0x00 << PNOR_ICFG_CS_x_MASK0_SHIFT);
|
||||
val |= (0xff);
|
||||
mmio_write_32((uintptr_t)(PNOR_ICFG_CS_2), val);
|
||||
|
||||
/* Print PNOR ID */
|
||||
tmp = 0x0;
|
||||
val = mmio_read_32((uintptr_t)(PNOR_REG_PERIPH_ID0));
|
||||
tmp |= (val & PNOR_REG_PERIPH_IDx_MASK);
|
||||
val = mmio_read_32((uintptr_t)(PNOR_REG_PERIPH_ID1));
|
||||
tmp |= ((val & PNOR_REG_PERIPH_IDx_MASK) << 8);
|
||||
val = mmio_read_32((uintptr_t)(PNOR_REG_PERIPH_ID2));
|
||||
tmp |= ((val & PNOR_REG_PERIPH_IDx_MASK) << 16);
|
||||
val = mmio_read_32((uintptr_t)(PNOR_REG_PERIPH_ID3));
|
||||
tmp |= ((val & PNOR_REG_PERIPH_IDx_MASK) << 24);
|
||||
INFO(" -- pnor primecell_id = 0x%x\n", tmp);
|
||||
|
||||
/* PNOR set_cycles */
|
||||
#ifdef EMULATION_SETUP
|
||||
val = 0x00129A44;
|
||||
#else
|
||||
val = 0x00125954; /* 0x00002DEF; */
|
||||
#endif
|
||||
mmio_write_32((uintptr_t)(PNOR_REG_SET_CYCLES), val);
|
||||
INFO(" -- pnor set_cycles = 0x%x\n", val);
|
||||
|
||||
/* PNOR set_opmode */
|
||||
val = 0x0;
|
||||
#ifdef EMULATION_SETUP
|
||||
/* TODO: Final values to be provided by DV folks */
|
||||
val &= ~(0x7 << 7); /* set_wr_bl */
|
||||
val &= ~(0x7 << 3); /* set_rd_bl */
|
||||
val &= ~(0x3);
|
||||
val |= (0x1); /* set_mw */
|
||||
#else
|
||||
/* TODO: Final values to be provided by DV folks */
|
||||
val &= ~(0x7 << 7); /* set_wr_bl */
|
||||
val &= ~(0x7 << 3); /* set_rd_bl */
|
||||
val &= ~(0x3);
|
||||
val |= (0x1); /* set_mw */
|
||||
#endif
|
||||
mmio_write_32((uintptr_t)(PNOR_REG_SET_OPMODE), val);
|
||||
INFO(" -- pnor set_opmode = 0x%x\n", val);
|
||||
|
||||
#ifndef EMULATION_SETUP
|
||||
/* Actual SRAM chip will require self-refresh */
|
||||
val = 0x1;
|
||||
mmio_write_32((uintptr_t)(PNOR_REG_REFRESH_0), val);
|
||||
INFO(" -- pnor refresh_0 = 0x%x\n", val);
|
||||
#endif
|
||||
|
||||
#if BL2_TEST_EXT_SRAM
|
||||
/* Check PNOR SRAM access */
|
||||
for (off = 0; off < NOR_SIZE; off += SRAM_CHECKS_GRANUL) {
|
||||
i = (off / SRAM_CHECKS_GRANUL) % SRAM_CHECKS_CNT;
|
||||
val = sram_checks[i];
|
||||
INFO(" -- pnor sram write addr=0x%lx value=0x%lx\n",
|
||||
(unsigned long)(NOR_BASE_ADDR + off),
|
||||
(unsigned long)val);
|
||||
mmio_write_32((uintptr_t)(NOR_BASE_ADDR + off), val);
|
||||
}
|
||||
tmp = 0;
|
||||
for (off = 0; off < NOR_SIZE; off += SRAM_CHECKS_GRANUL) {
|
||||
i = (off / SRAM_CHECKS_GRANUL) % SRAM_CHECKS_CNT;
|
||||
val = mmio_read_32((uintptr_t)(NOR_BASE_ADDR + off));
|
||||
INFO(" -- pnor sram read addr=0x%lx value=0x%lx\n",
|
||||
(unsigned long)(NOR_BASE_ADDR + off),
|
||||
(unsigned long)val);
|
||||
if (val == sram_checks[i])
|
||||
tmp++;
|
||||
}
|
||||
INFO(" -- pnor sram checks pass=%d total=%d\n",
|
||||
tmp, (NOR_SIZE / SRAM_CHECKS_GRANUL));
|
||||
|
||||
if (tmp != (NOR_SIZE / SRAM_CHECKS_GRANUL)) {
|
||||
INFO(" - pnor sram init failed.\n");
|
||||
while (1)
|
||||
;
|
||||
} else {
|
||||
INFO(" - pnor sram init done.\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ext_sram_init(void)
|
||||
{
|
||||
INFO("%s start.\n", __func__);
|
||||
|
||||
brcm_stingray_pnor_pinmux_init();
|
||||
|
||||
brcm_stingray_pnor_sram_init();
|
||||
|
||||
INFO("%s done.\n", __func__);
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef EXT_SRAM_INIT_H
|
||||
#define EXT_SRAM_INIT_H
|
||||
|
||||
void ext_sram_init(void);
|
||||
#endif
|
||||
+287
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <dmu.h>
|
||||
|
||||
#define IHOST0_CONFIG_ROOT 0x66000000
|
||||
#define IHOST1_CONFIG_ROOT 0x66002000
|
||||
#define IHOST2_CONFIG_ROOT 0x66004000
|
||||
#define IHOST3_CONFIG_ROOT 0x66006000
|
||||
#define A72_CRM_PLL_PWR_ON 0x00000070
|
||||
#define A72_CRM_PLL_PWR_ON__PLL0_RESETB_R 4
|
||||
#define A72_CRM_PLL_PWR_ON__PLL0_POST_RESETB_R 5
|
||||
#define A72_CRM_PLL_CHNL_BYPS_EN 0x000000ac
|
||||
#define A72_CRM_PLL_CHNL_BYPS_EN__PLL_0_CHNL_0_BYPS_EN_R 0
|
||||
#define A72_CRM_PLL_CHNL_BYPS_EN_DATAMASK 0x0000ec1f
|
||||
#define A72_CRM_PLL_CMD 0x00000080
|
||||
#define A72_CRM_PLL_CMD__UPDATE_PLL0_FREQUENCY_VCO_R 0
|
||||
#define A72_CRM_PLL_CMD__UPDATE_PLL0_FREQUENCY_POST_R 1
|
||||
#define A72_CRM_PLL_STATUS 0x00000084
|
||||
#define A72_CRM_PLL_STATUS__PLL0_LOCK_R 9
|
||||
#define A72_CRM_PLL0_CTRL1 0x00000100
|
||||
#define A72_CRM_PLL0_CTRL2 0x00000104
|
||||
#define A72_CRM_PLL0_CTRL3 0x00000108
|
||||
#define A72_CRM_PLL0_CTRL3__PLL0_PDIV_R 12
|
||||
#define A72_CRM_PLL0_CTRL4 0x0000010c
|
||||
#define A72_CRM_PLL0_CTRL4__PLL0_KP_R 0
|
||||
#define A72_CRM_PLL0_CTRL4__PLL0_KI_R 4
|
||||
#define A72_CRM_PLL0_CTRL4__PLL0_KA_R 7
|
||||
#define A72_CRM_PLL0_CTRL4__PLL0_FREFEFF_INFO_R 10
|
||||
|
||||
#define PLL_MODE_VCO 0x0
|
||||
#define PLL_MODE_BYPASS 0x1
|
||||
#define PLL_RESET_TYPE_PLL 0x1
|
||||
#define PLL_RESET_TYPE_POST 0x2
|
||||
#define PLL_VCO 0x1
|
||||
#define PLL_POSTDIV 0x2
|
||||
#define ARM_FREQ_3G PLL_FREQ_FULL
|
||||
#define ARM_FREQ_1P5G PLL_FREQ_HALF
|
||||
#define ARM_FREQ_750M PLL_FREQ_QRTR
|
||||
|
||||
static unsigned int ARMCOE_crm_getBaseAddress(unsigned int cluster_num)
|
||||
{
|
||||
unsigned int ihostx_config_root;
|
||||
|
||||
switch (cluster_num) {
|
||||
case 0:
|
||||
default:
|
||||
ihostx_config_root = IHOST0_CONFIG_ROOT;
|
||||
break;
|
||||
case 1:
|
||||
ihostx_config_root = IHOST1_CONFIG_ROOT;
|
||||
break;
|
||||
case 2:
|
||||
ihostx_config_root = IHOST2_CONFIG_ROOT;
|
||||
break;
|
||||
case 3:
|
||||
ihostx_config_root = IHOST3_CONFIG_ROOT;
|
||||
break;
|
||||
}
|
||||
|
||||
return ihostx_config_root;
|
||||
}
|
||||
|
||||
static void ARMCOE_crm_pllAssertReset(unsigned int cluster_num,
|
||||
unsigned int reset_type)
|
||||
{
|
||||
unsigned long ihostx_config_root;
|
||||
unsigned int pll_rst_ctrl;
|
||||
|
||||
ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
|
||||
pll_rst_ctrl = mmio_read_32(ihostx_config_root + A72_CRM_PLL_PWR_ON);
|
||||
|
||||
// PLL reset
|
||||
if (reset_type & PLL_RESET_TYPE_PLL) {
|
||||
pll_rst_ctrl &= ~(0x1<<A72_CRM_PLL_PWR_ON__PLL0_RESETB_R);
|
||||
}
|
||||
// post-div channel reset
|
||||
if (reset_type & PLL_RESET_TYPE_POST) {
|
||||
pll_rst_ctrl &= ~(0x1<<A72_CRM_PLL_PWR_ON__PLL0_POST_RESETB_R);
|
||||
}
|
||||
|
||||
mmio_write_32(ihostx_config_root + A72_CRM_PLL_PWR_ON, pll_rst_ctrl);
|
||||
}
|
||||
|
||||
static void ARMCOE_crm_pllSetMode(unsigned int cluster_num, unsigned int mode)
|
||||
{
|
||||
unsigned long ihostx_config_root;
|
||||
unsigned int pll_byp_ctrl;
|
||||
|
||||
ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
|
||||
pll_byp_ctrl = mmio_read_32(ihostx_config_root +
|
||||
A72_CRM_PLL_CHNL_BYPS_EN);
|
||||
|
||||
if (mode == PLL_MODE_VCO) {
|
||||
// use PLL DCO output
|
||||
pll_byp_ctrl &=
|
||||
~BIT(A72_CRM_PLL_CHNL_BYPS_EN__PLL_0_CHNL_0_BYPS_EN_R);
|
||||
} else {
|
||||
// use PLL bypass sources
|
||||
pll_byp_ctrl |=
|
||||
BIT(A72_CRM_PLL_CHNL_BYPS_EN__PLL_0_CHNL_0_BYPS_EN_R);
|
||||
}
|
||||
|
||||
mmio_write_32(ihostx_config_root + A72_CRM_PLL_CHNL_BYPS_EN,
|
||||
pll_byp_ctrl);
|
||||
}
|
||||
|
||||
static void ARMCOE_crm_pllFreqSet(unsigned int cluster_num,
|
||||
unsigned int ihost_pll_freq_sel,
|
||||
unsigned int pdiv)
|
||||
{
|
||||
unsigned int ndiv_int;
|
||||
unsigned int ndiv_frac_low, ndiv_frac_high;
|
||||
unsigned long ihostx_config_root;
|
||||
|
||||
ndiv_frac_low = 0x0;
|
||||
ndiv_frac_high = 0x0;
|
||||
|
||||
if (ihost_pll_freq_sel == ARM_FREQ_3G) {
|
||||
ndiv_int = 0x78;
|
||||
} else if (ihost_pll_freq_sel == ARM_FREQ_1P5G) {
|
||||
ndiv_int = 0x3c;
|
||||
} else if (ihost_pll_freq_sel == ARM_FREQ_750M) {
|
||||
ndiv_int = 0x1e;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
ndiv_int &= 0x3FF; // low 10 bits
|
||||
ndiv_frac_low &= 0x3FF;
|
||||
ndiv_frac_high &= 0x3FF;
|
||||
|
||||
ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
|
||||
|
||||
mmio_write_32(ihostx_config_root+A72_CRM_PLL0_CTRL1, ndiv_frac_low);
|
||||
mmio_write_32(ihostx_config_root+A72_CRM_PLL0_CTRL2, ndiv_frac_high);
|
||||
mmio_write_32(ihostx_config_root+A72_CRM_PLL0_CTRL3,
|
||||
ndiv_int |
|
||||
((pdiv << A72_CRM_PLL0_CTRL3__PLL0_PDIV_R & 0xF000)));
|
||||
|
||||
mmio_write_32(ihostx_config_root + A72_CRM_PLL0_CTRL4,
|
||||
/* From Section 10 of PLL spec */
|
||||
(3 << A72_CRM_PLL0_CTRL4__PLL0_KP_R) |
|
||||
/* From Section 10 of PLL spec */
|
||||
(2 << A72_CRM_PLL0_CTRL4__PLL0_KI_R) |
|
||||
/* Normal mode (i.e. not fast-locking) */
|
||||
(0 << A72_CRM_PLL0_CTRL4__PLL0_KA_R) |
|
||||
/* 50 MHz */
|
||||
(50 << A72_CRM_PLL0_CTRL4__PLL0_FREFEFF_INFO_R));
|
||||
}
|
||||
|
||||
static void ARMCOE_crm_pllDeassertReset(unsigned int cluster_num,
|
||||
unsigned int reset_type)
|
||||
{
|
||||
unsigned long ihostx_config_root;
|
||||
unsigned int pll_rst_ctrl;
|
||||
|
||||
ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
|
||||
pll_rst_ctrl = mmio_read_32(ihostx_config_root + A72_CRM_PLL_PWR_ON);
|
||||
|
||||
// PLL reset
|
||||
if (reset_type & PLL_RESET_TYPE_PLL) {
|
||||
pll_rst_ctrl |= (0x1 << A72_CRM_PLL_PWR_ON__PLL0_RESETB_R);
|
||||
}
|
||||
|
||||
// post-div channel reset
|
||||
if (reset_type & PLL_RESET_TYPE_POST) {
|
||||
pll_rst_ctrl |= (0x1 << A72_CRM_PLL_PWR_ON__PLL0_POST_RESETB_R);
|
||||
}
|
||||
|
||||
mmio_write_32(ihostx_config_root + A72_CRM_PLL_PWR_ON, pll_rst_ctrl);
|
||||
}
|
||||
|
||||
static void ARMCOE_crm_pllUpdate(unsigned int cluster_num, unsigned int type)
|
||||
{
|
||||
unsigned long ihostx_config_root;
|
||||
unsigned int pll_cmd;
|
||||
|
||||
ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
|
||||
pll_cmd = mmio_read_32(ihostx_config_root + A72_CRM_PLL_CMD);
|
||||
|
||||
// VCO update
|
||||
if (type & PLL_VCO) {
|
||||
pll_cmd |= BIT(A72_CRM_PLL_CMD__UPDATE_PLL0_FREQUENCY_VCO_R);
|
||||
}
|
||||
// post-div channel update
|
||||
if (type & PLL_POSTDIV) {
|
||||
pll_cmd |= BIT(A72_CRM_PLL_CMD__UPDATE_PLL0_FREQUENCY_POST_R);
|
||||
}
|
||||
|
||||
mmio_write_32(ihostx_config_root+A72_CRM_PLL_CMD, pll_cmd);
|
||||
}
|
||||
|
||||
static void insert_delay(unsigned int delay)
|
||||
{
|
||||
volatile unsigned int index;
|
||||
|
||||
for (index = 0; index < delay; index++)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns 1 if PLL locked within certain interval
|
||||
*/
|
||||
static unsigned int ARMCOE_crm_pllIsLocked(unsigned int cluster_num)
|
||||
{
|
||||
unsigned long ihostx_config_root;
|
||||
unsigned int lock_status;
|
||||
unsigned int i;
|
||||
|
||||
ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
|
||||
|
||||
/* wait a while for pll to lock before returning from this function */
|
||||
for (i = 0; i < 1500; i++) {
|
||||
insert_delay(256);
|
||||
lock_status = mmio_read_32(ihostx_config_root +
|
||||
A72_CRM_PLL_STATUS);
|
||||
if (lock_status & BIT(A72_CRM_PLL_STATUS__PLL0_LOCK_R))
|
||||
return 1;
|
||||
}
|
||||
|
||||
ERROR("PLL of Cluster #%u failed to lock\n", cluster_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ihost PLL Variable Frequency Configuration
|
||||
*
|
||||
* Frequency Limit {VCO,ARM} (GHz):
|
||||
* 0 - no limit,
|
||||
* 1 - {3.0,1.5},
|
||||
* 2 - {4.0,2.0},
|
||||
* 3 - {5.0,2.5}
|
||||
*/
|
||||
uint32_t bcm_set_ihost_pll_freq(uint32_t cluster_num, int ihost_pll_freq_sel)
|
||||
{
|
||||
NOTICE("cluster: %u, freq_sel:0x%x\n", cluster_num, ihost_pll_freq_sel);
|
||||
|
||||
//bypass PLL
|
||||
ARMCOE_crm_pllSetMode(cluster_num, PLL_MODE_BYPASS);
|
||||
//assert reset
|
||||
ARMCOE_crm_pllAssertReset(cluster_num,
|
||||
PLL_RESET_TYPE_PLL | PLL_RESET_TYPE_POST);
|
||||
//set ndiv_int for different freq
|
||||
ARMCOE_crm_pllFreqSet(cluster_num, ihost_pll_freq_sel, 0x1);
|
||||
//de-assert reset
|
||||
ARMCOE_crm_pllDeassertReset(cluster_num, PLL_RESET_TYPE_PLL);
|
||||
ARMCOE_crm_pllUpdate(cluster_num, PLL_VCO);
|
||||
//waiting for PLL lock
|
||||
ARMCOE_crm_pllIsLocked(cluster_num);
|
||||
ARMCOE_crm_pllDeassertReset(cluster_num, PLL_RESET_TYPE_POST);
|
||||
//disable bypass PLL
|
||||
ARMCOE_crm_pllSetMode(cluster_num, PLL_MODE_VCO);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t bcm_get_ihost_pll_freq(uint32_t cluster_num)
|
||||
{
|
||||
unsigned long ihostx_config_root;
|
||||
uint32_t ndiv_int;
|
||||
uint32_t ihost_pll_freq_sel;
|
||||
|
||||
ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
|
||||
ndiv_int = mmio_read_32(ihostx_config_root+A72_CRM_PLL0_CTRL3) & 0x3FF;
|
||||
|
||||
if (ndiv_int == 0x78) {
|
||||
ihost_pll_freq_sel = ARM_FREQ_3G;
|
||||
} else if (ndiv_int == 0x3c) {
|
||||
ihost_pll_freq_sel = ARM_FREQ_1P5G;
|
||||
} else if (ndiv_int == 0x1e) {
|
||||
ihost_pll_freq_sel = ARM_FREQ_750M;
|
||||
} else {
|
||||
/* return unlimit otherwise*/
|
||||
ihost_pll_freq_sel = 0;
|
||||
}
|
||||
return ihost_pll_freq_sel;
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#define ICFG_IPROC_IOPAD_CTRL_4 (IPROC_ROOT + 0x9c0)
|
||||
#define ICFG_IPROC_IOPAD_CTRL_5 (IPROC_ROOT + 0x9c4)
|
||||
#define ICFG_IPROC_IOPAD_CTRL_6 (IPROC_ROOT + 0x9c8)
|
||||
#define ICFG_IPROC_IOPAD_CTRL_7 (IPROC_ROOT + 0x9cc)
|
||||
|
||||
#define IOPAD_CTRL4_SDIO0_CD_IND_R 30
|
||||
#define IOPAD_CTRL4_SDIO0_CD_SRC_R 31
|
||||
#define IOPAD_CTRL4_SDIO0_CD_HYS_R 29
|
||||
#define IOPAD_CTRL4_SDIO0_CD_PULL_R 28
|
||||
#define IOPAD_CTRL4_SDIO0_CD_DRIVE_R 24
|
||||
#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_SRC_R 23
|
||||
#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_HYS_R 21
|
||||
#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_DRIVE_R 17
|
||||
|
||||
#define IOPAD_CTRL4_SDIO0_DATA0_SRC_R 15
|
||||
#define IOPAD_CTRL4_SDIO0_DATA0_HYS_R 13
|
||||
#define IOPAD_CTRL4_SDIO0_DATA0_DRIVE_R 9
|
||||
#define IOPAD_CTRL4_SDIO0_DATA1_SRC_R 7
|
||||
#define IOPAD_CTRL4_SDIO0_DATA1_HYS_R 5
|
||||
#define IOPAD_CTRL4_SDIO0_DATA1_DRIVE_R 1
|
||||
|
||||
#define IOPAD_CTRL5_SDIO0_DATA2_SRC_R 31
|
||||
#define IOPAD_CTRL5_SDIO0_DATA2_HYS_R 29
|
||||
#define IOPAD_CTRL5_SDIO0_DATA2_DRIVE_R 25
|
||||
#define IOPAD_CTRL5_SDIO0_DATA3_SRC_R 23
|
||||
#define IOPAD_CTRL5_SDIO0_DATA3_IND_R 22
|
||||
#define IOPAD_CTRL5_SDIO0_DATA3_HYS_R 21
|
||||
#define IOPAD_CTRL5_SDIO0_DATA3_DRIVE_R 17
|
||||
#define IOPAD_CTRL5_SDIO0_DATA4_SRC_R 15
|
||||
#define IOPAD_CTRL5_SDIO0_DATA4_HYS_R 13
|
||||
#define IOPAD_CTRL5_SDIO0_DATA4_DRIVE_R 9
|
||||
#define IOPAD_CTRL5_SDIO0_DATA5_SRC_R 7
|
||||
#define IOPAD_CTRL5_SDIO0_DATA5_HYS_R 5
|
||||
#define IOPAD_CTRL5_SDIO0_DATA5_DRIVE_R 1
|
||||
|
||||
#define IOPAD_CTRL6_SDIO0_DATA6_SRC_R 31
|
||||
#define IOPAD_CTRL6_SDIO0_DATA6_HYS_R 29
|
||||
#define IOPAD_CTRL6_SDIO0_DATA6_DRIVE_R 25
|
||||
#define IOPAD_CTRL6_SDIO0_DATA7_SRC_R 23
|
||||
#define IOPAD_CTRL6_SDIO0_DATA7_HYS_R 21
|
||||
#define IOPAD_CTRL6_SDIO0_DATA7_DRIVE_R 17
|
||||
|
||||
void emmc_soft_reset(void)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
|
||||
val = (BIT(IOPAD_CTRL6_SDIO0_DATA7_SRC_R) |
|
||||
BIT(IOPAD_CTRL6_SDIO0_DATA7_HYS_R) |
|
||||
BIT(IOPAD_CTRL6_SDIO0_DATA7_DRIVE_R) |
|
||||
BIT(IOPAD_CTRL6_SDIO0_DATA6_SRC_R) |
|
||||
BIT(IOPAD_CTRL6_SDIO0_DATA6_HYS_R) |
|
||||
BIT(IOPAD_CTRL6_SDIO0_DATA6_DRIVE_R));
|
||||
|
||||
mmio_write_32(ICFG_IPROC_IOPAD_CTRL_6, val);
|
||||
|
||||
val = (BIT(IOPAD_CTRL5_SDIO0_DATA3_SRC_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA3_HYS_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA3_DRIVE_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA4_SRC_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA4_HYS_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA4_DRIVE_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA5_SRC_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA5_HYS_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA5_DRIVE_R));
|
||||
|
||||
mmio_write_32(ICFG_IPROC_IOPAD_CTRL_5, val);
|
||||
|
||||
val = (BIT(IOPAD_CTRL4_SDIO0_DATA0_SRC_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_DATA0_HYS_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_DATA0_DRIVE_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_DATA1_SRC_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_DATA1_HYS_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_DATA1_DRIVE_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA2_SRC_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA2_HYS_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA2_DRIVE_R));
|
||||
|
||||
mmio_write_32(ICFG_IPROC_IOPAD_CTRL_6, val);
|
||||
|
||||
val = (BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_SRC_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_HYS_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_DRIVE_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_CD_SRC_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_CD_HYS_R));
|
||||
|
||||
/*
|
||||
* set pull-down, clear pull-up=0
|
||||
* bit 12: pull-down bit 11: pull-up
|
||||
* Note: In emulation, this pull-down setting was not
|
||||
* sufficient. Board design likely requires pull down on
|
||||
* this pin for eMMC.
|
||||
*/
|
||||
|
||||
val |= BIT(IOPAD_CTRL4_SDIO0_CD_PULL_R);
|
||||
|
||||
mmio_write_32(ICFG_IPROC_IOPAD_CTRL_4, val);
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2019 - 2021, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SR_USB_H
|
||||
#define SR_USB_H
|
||||
|
||||
#define CDRU_PM_RESET_N_R BIT(CDRU_MISC_RESET_CONTROL__CDRU_PM_RESET_N_R)
|
||||
#define CDRU_USBSS_RESET_N BIT(CDRU_MISC_RESET_CONTROL__CDRU_USBSS_RESET_N)
|
||||
#define CDRU_MISC_CLK_USBSS \
|
||||
BIT(CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_USBSS_CLK_EN_R)
|
||||
|
||||
#define RESCAL_I_RSTB BIT(26)
|
||||
#define RESCAL_I_PWRDNB BIT(27)
|
||||
|
||||
#define DRDU3_U3PHY_CTRL 0x68500014
|
||||
#define PHY_RESET BIT(1)
|
||||
#define POR_RESET BIT(28)
|
||||
#define MDIO_RESET BIT(29)
|
||||
|
||||
#define DRDU3_PWR_CTRL 0x6850002c
|
||||
#define POWER_CTRL_OVRD BIT(2)
|
||||
|
||||
#define USB3H_U3PHY_CTRL 0x68510014
|
||||
#define USB3H_U3SOFT_RST_N BIT(30)
|
||||
|
||||
#define USB3H_PWR_CTRL 0x68510028
|
||||
|
||||
#define USB3_PHY_MDIO_BLOCK_BASE_REG 0x1f
|
||||
#define BDC_AXI_SOFT_RST_N_OFFSET 0
|
||||
#define XHC_AXI_SOFT_RST_N_OFFSET 1
|
||||
#define MDIO_BUS_ID 3
|
||||
#define USB3H_PHY_ID 5
|
||||
#define USB3DRD_PHY_ID 2
|
||||
|
||||
#define USB3_PHY_RXPMD_BLOCK_BASE 0x8020
|
||||
#define USB3_PHY_RXPMD_REG1 0x1
|
||||
#define USB3_PHY_RXPMD_REG2 0x2
|
||||
#define USB3_PHY_RXPMD_REG5 0x5
|
||||
#define USB3_PHY_RXPMD_REG7 0x7
|
||||
|
||||
#define USB3_PHY_TXPMD_BLOCK_BASE 0x8040
|
||||
#define USB3_PHY_TXPMD_REG1 0x1
|
||||
#define USB3_PHY_TXPMD_REG2 0x2
|
||||
|
||||
#define USB3_PHY_ANA_BLOCK_BASE 0x8090
|
||||
#define USB3_PHY_ANA_REG0 0x0
|
||||
#define USB3_PHY_ANA_REG1 0x1
|
||||
#define USB3_PHY_ANA_REG2 0x2
|
||||
#define USB3_PHY_ANA_REG5 0x5
|
||||
#define USB3_PHY_ANA_REG8 0x8
|
||||
#define USB3_PHY_ANA_REG11 0xb
|
||||
|
||||
#define USB3_PHY_AEQ_BLOCK_BASE 0x80e0
|
||||
#define USB3_PHY_AEQ_REG1 0x1
|
||||
#define USB3_PHY_AEQ_REG3 0x3
|
||||
|
||||
#ifdef USB_DMA_COHERENT
|
||||
#define DRDU3_U3XHC_SOFT_RST_N BIT(31)
|
||||
#define DRDU3_U3BDC_SOFT_RST_N BIT(30)
|
||||
|
||||
#define DRDU3_SOFT_RESET_CTRL 0x68500030
|
||||
#define DRDU3_XHC_AXI_SOFT_RST_N BIT(1)
|
||||
#define DRDU3_BDC_AXI_SOFT_RST_N BIT(0)
|
||||
|
||||
#define DRDU2_PHY_CTRL 0x6852000c
|
||||
#define DRDU2_U2SOFT_RST_N BIT(29)
|
||||
|
||||
#define USB3H_SOFT_RESET_CTRL 0x6851002c
|
||||
#define USB3H_XHC_AXI_SOFT_RST_N BIT(1)
|
||||
|
||||
#define DRDU2_SOFT_RESET_CTRL 0x68520020
|
||||
#define DRDU2_BDC_AXI_SOFT_RST_N BIT(0)
|
||||
|
||||
#define DRD2U3H_XHC_REGS_AXIWRA 0x68511c08
|
||||
#define DRD2U3H_XHC_REGS_AXIRDA 0x68511c0c
|
||||
#define DRDU2D_BDC_REGS_AXIWRA 0x68521c08
|
||||
#define DRDU2D_BDC_REGS_AXIRDA 0x68521c0c
|
||||
#define DRDU3H_XHC_REGS_AXIWRA 0x68501c08
|
||||
#define DRDU3H_XHC_REGS_AXIRDA 0x68501c0c
|
||||
#define DRDU3D_BDC_REGS_AXIWRA 0x68502c08
|
||||
#define DRDU3D_BDC_REGS_AXIRDA 0x68502c0c
|
||||
/* cacheable write-back, allocate on both reads and writes */
|
||||
#define USBAXI_AWCACHE 0xf
|
||||
#define USBAXI_ARCACHE 0xf
|
||||
/* non-secure */
|
||||
#define USBAXI_AWPROT 0x8
|
||||
#define USBAXI_ARPROT 0x8
|
||||
#define USBAXIWR_SA_VAL ((USBAXI_AWCACHE << 4 | USBAXI_AWPROT) << 0)
|
||||
#define USBAXIWR_SA_MASK ((0xf << 4 | 0xf) << 0)
|
||||
#define USBAXIWR_UA_VAL ((USBAXI_AWCACHE << 4 | USBAXI_AWPROT) << 16)
|
||||
#define USBAXIWR_UA_MASK ((0xf << 4 | 0xf) << 0)
|
||||
#define USBAXIRD_SA_VAL ((USBAXI_ARCACHE << 4 | USBAXI_ARPROT) << 0)
|
||||
#define USBAXIRD_SA_MASK ((0xf << 4 | 0xf) << 0)
|
||||
#define USBAXIRD_UA_VAL ((USBAXI_ARCACHE << 4 | USBAXI_ARPROT) << 16)
|
||||
#define USBAXIRD_UA_MASK ((0xf << 4 | 0xf) << 0)
|
||||
#endif /* USB_DMA_COHERENT */
|
||||
|
||||
#define ICFG_DRDU3_SID_CTRL 0x6850001c
|
||||
#define ICFG_USB3H_SID_CTRL 0x6851001c
|
||||
#define ICFG_DRDU2_SID_CTRL 0x68520010
|
||||
#define ICFG_USB_SID_SHIFT 5
|
||||
#define ICFG_USB_SID_AWADDR_OFFSET 0x0
|
||||
#define ICFG_USB_SID_ARADDR_OFFSET 0x4
|
||||
|
||||
#define USBIC_GPV_BASE 0x68600000
|
||||
#define USBIC_GPV_SECURITY0 (USBIC_GPV_BASE + 0x8)
|
||||
#define USBIC_GPV_SECURITY0_FIELD BIT(0)
|
||||
#define USBIC_GPV_SECURITY1 (USBIC_GPV_BASE + 0xc)
|
||||
#define USBIC_GPV_SECURITY1_FIELD (BIT(0) | BIT(1))
|
||||
#define USBIC_GPV_SECURITY2 (USBIC_GPV_BASE + 0x10)
|
||||
#define USBIC_GPV_SECURITY2_FIELD (BIT(0) | BIT(1))
|
||||
#define USBIC_GPV_SECURITY4 (USBIC_GPV_BASE + 0x18)
|
||||
#define USBIC_GPV_SECURITY4_FIELD BIT(0)
|
||||
#define USBIC_GPV_SECURITY10 (USBIC_GPV_BASE + 0x30)
|
||||
#define USBIC_GPV_SECURITY10_FIELD (0x7 << 0)
|
||||
|
||||
#define USBSS_TZPCDECPROT_BASE 0x68540800
|
||||
#define USBSS_TZPCDECPROT0set (USBSS_TZPCDECPROT_BASE + 0x4)
|
||||
#define USBSS_TZPCDECPROT0clr (USBSS_TZPCDECPROT_BASE + 0x8)
|
||||
#define DECPROT0_USBSS_DRD2U3H BIT(3)
|
||||
#define DECPROT0_USBSS_DRDU2H BIT(2)
|
||||
#define DECPROT0_USBSS_DRDU3D BIT(1)
|
||||
#define DECPROT0_USBSS_DRDU2D BIT(0)
|
||||
#define USBSS_TZPCDECPROT0 \
|
||||
(DECPROT0_USBSS_DRD2U3H | \
|
||||
DECPROT0_USBSS_DRDU2H | \
|
||||
DECPROT0_USBSS_DRDU3D | \
|
||||
DECPROT0_USBSS_DRDU2D)
|
||||
|
||||
int32_t usb_device_init(unsigned int);
|
||||
|
||||
#endif /* SR_USB_H */
|
||||
+375
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright (c) 2017 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <sr_utils.h>
|
||||
#include <swreg.h>
|
||||
|
||||
#define MIN_VOLT 760000
|
||||
#define MAX_VOLT 1060000
|
||||
|
||||
#define BSTI_WRITE 0x1
|
||||
#define BSTI_READ 0x2
|
||||
#define BSTI_COMMAND_TA 0x2
|
||||
#define BSTI_COMMAND_DATA 0xFF
|
||||
#define BSTI_CONTROL_VAL 0x81
|
||||
#define BSTI_CONTROL_BUSY 0x100
|
||||
#define BSTI_TOGGLE_BIT 0x2
|
||||
#define BSTI_CONFI_DONE_MASK 0xFFFFFFFD
|
||||
#define BSTI_REG_DATA_MASK 0xFFFF
|
||||
#define BSTI_CMD(sb, op, pa, ra, ta, data) \
|
||||
((((sb) & 0x3) << 30) | (((op) & 0x3) << 28) | \
|
||||
(((pa) & 0x1F) << 23) | (((ra) & 0x1F) << 18) | \
|
||||
(((ta) & 0x3) << 16) | (data))
|
||||
|
||||
#define PHY_REG0 0x0
|
||||
#define PHY_REG1 0x1
|
||||
#define PHY_REG4 0x4
|
||||
#define PHY_REG5 0x5
|
||||
#define PHY_REG6 0x6
|
||||
#define PHY_REG7 0x7
|
||||
#define PHY_REGC 0xc
|
||||
|
||||
#define IHOST_VDDC_DATA 0x560
|
||||
#define DDR_CORE_DATA 0x2560
|
||||
#define UPDATE_POS_EDGE(data, set) ((data) | ((set) << 1))
|
||||
|
||||
/*
|
||||
* Formula for SR A2 reworked board:
|
||||
* step = ((vol/(1.4117 * 0.98)) - 500000)/3125
|
||||
* where,
|
||||
* vol - input voltage
|
||||
* 500000 - Reference voltage
|
||||
* 3125 - one step value
|
||||
*/
|
||||
#define A2_VOL_REF 500000
|
||||
#define ONE_STEP_VALUE 3125
|
||||
#define VOL_DIV(vol) (((vol*10000ull)/(14117*98ull)) * 100ull)
|
||||
#define STEP_VALUE(vol) \
|
||||
((((((VOL_DIV(vol)) - A2_VOL_REF) / ONE_STEP_VALUE) & 0xFF) << 8) | 4)
|
||||
|
||||
#define B0_VOL_REF ((500000/100)*98)
|
||||
#define B0_ONE_STEP_VALUE 3125
|
||||
/*
|
||||
* Formula for SR B0 chip for IHOST12/03 and VDDC_CORE
|
||||
* step = ((vol/1.56) - (500000 * 0.98))/3125
|
||||
* where,
|
||||
* vol - input voltage
|
||||
* 500000 - Reference voltage
|
||||
* 3125 - one step value
|
||||
*/
|
||||
#define B0_VOL_DIV(vol) (((vol)*100ull)/156)
|
||||
#define B0_STEP_VALUE(vol) \
|
||||
((((((B0_VOL_DIV(vol)) - B0_VOL_REF) / B0_ONE_STEP_VALUE) \
|
||||
& 0xFF) << 8) | 4)
|
||||
|
||||
/*
|
||||
* Formula for SR B0 chip for DDR-CORE
|
||||
* step = ((vol/1) - (500000 * 0.98))/3125
|
||||
* where,
|
||||
* vol - input voltage
|
||||
* 500000 - Reference voltage
|
||||
* 3125 - one step value
|
||||
*/
|
||||
#define B0_DDR_VDDC_VOL_DIV(vol) ((vol)/1)
|
||||
#define B0_DDR_VDDC_STEP_VALUE(vol) \
|
||||
((((((B0_DDR_VDDC_VOL_DIV(vol)) - B0_VOL_REF) / B0_ONE_STEP_VALUE) \
|
||||
& 0xFF) << 8) | 4)
|
||||
|
||||
#define MAX_SWREG_CNT 8
|
||||
#define MAX_ADDR_PER_SWREG 16
|
||||
#define MAX_REG_ADDR 0xF
|
||||
#define MIN_REG_ADDR 0x0
|
||||
|
||||
static const char *sw_reg_name[MAX_SWREG_CNT] = {
|
||||
"DDR_VDDC",
|
||||
"IHOST03",
|
||||
"IHOST12",
|
||||
"IHOST_ARRAY",
|
||||
"DDRIO_SLAVE",
|
||||
"VDDC_CORE",
|
||||
"VDDC1",
|
||||
"DDRIO_MASTER"
|
||||
};
|
||||
|
||||
/* firmware values for all SWREG for 3.3V input operation */
|
||||
static const uint16_t swreg_fm_data_bx[MAX_SWREG_CNT][MAX_ADDR_PER_SWREG] = {
|
||||
/* DDR logic: Power Domains independent of 12v or 3p3v */
|
||||
{0x25E0, 0x2D54, 0x0EC6, 0x01EC, 0x28BB, 0x1144, 0x0200, 0x69C0,
|
||||
0x0010, 0x0EDF, 0x90D7, 0x8000, 0x820C, 0x0003, 0x0001, 0x0000},
|
||||
|
||||
/* ihost03, 3p3V */
|
||||
{0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80,
|
||||
0x003F, 0x0FFF, 0x90D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000},
|
||||
|
||||
/* ihost12 3p3v */
|
||||
{0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80,
|
||||
0x003F, 0x0FFF, 0x90D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000},
|
||||
|
||||
/* ihost array */
|
||||
{0x25E0, 0x2D94, 0x0EC6, 0x01EC, 0x2ABB, 0x1144, 0x0340, 0x69C0,
|
||||
0x0010, 0x0EDF, 0x90D7, 0x8000, 0x860C, 0x0003, 0x0001, 0x0000},
|
||||
|
||||
/* ddr io slave : 3p3v */
|
||||
{0x0560, 0x4438, 0x0000, 0x001F, 0x8028, 0x4444, 0x0300, 0x4380,
|
||||
0x003F, 0x0FFF, 0x10D7, 0x8000, 0xA70C, 0x0003, 0x0001, 0x0000},
|
||||
|
||||
/* core master 3p3v */
|
||||
{0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80,
|
||||
0x003F, 0x0FFF, 0x90D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000},
|
||||
|
||||
/* core slave 3p3v */
|
||||
{0x0560, 0x4438, 0x0000, 0x001F, 0x8028, 0x4444, 0x0300, 0x4380,
|
||||
0x003F, 0x0FFF, 0x10D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000},
|
||||
|
||||
/* ddr io master : 3p3v */
|
||||
{0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80,
|
||||
0x003F, 0x0FFF, 0x90D7, 0x8000, 0xA70C, 0x0003, 0x0001, 0x0000},
|
||||
};
|
||||
|
||||
#define FM_DATA swreg_fm_data_bx
|
||||
|
||||
static int swreg_poll(void)
|
||||
{
|
||||
uint32_t data;
|
||||
int retry = 100;
|
||||
|
||||
do {
|
||||
data = mmio_read_32(BSTI_CONTROL_OFFSET);
|
||||
if ((data & BSTI_CONTROL_BUSY) != BSTI_CONTROL_BUSY)
|
||||
return 0;
|
||||
retry--;
|
||||
udelay(1);
|
||||
} while (retry > 0);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int write_swreg_config(enum sw_reg reg_id, uint32_t addr, uint32_t data)
|
||||
{
|
||||
uint32_t cmd;
|
||||
int ret;
|
||||
|
||||
cmd = BSTI_CMD(0x1, BSTI_WRITE, reg_id, addr, BSTI_COMMAND_TA, data);
|
||||
mmio_write_32(BSTI_CONTROL_OFFSET, BSTI_CONTROL_VAL);
|
||||
mmio_write_32(BSTI_COMMAND_OFFSET, cmd);
|
||||
ret = swreg_poll();
|
||||
if (ret) {
|
||||
ERROR("Failed to write swreg %s addr 0x%x\n",
|
||||
sw_reg_name[reg_id-1], addr);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int read_swreg_config(enum sw_reg reg_id, uint32_t addr, uint32_t *data)
|
||||
{
|
||||
uint32_t cmd;
|
||||
int ret;
|
||||
|
||||
cmd = BSTI_CMD(0x1, BSTI_READ, reg_id, addr, BSTI_COMMAND_TA, PHY_REG0);
|
||||
mmio_write_32(BSTI_CONTROL_OFFSET, BSTI_CONTROL_VAL);
|
||||
mmio_write_32(BSTI_COMMAND_OFFSET, cmd);
|
||||
ret = swreg_poll();
|
||||
if (ret) {
|
||||
ERROR("Failed to read swreg %s addr 0x%x\n",
|
||||
sw_reg_name[reg_id-1], addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*data = mmio_read_32(BSTI_COMMAND_OFFSET);
|
||||
*data &= BSTI_REG_DATA_MASK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int swreg_config_done(enum sw_reg reg_id)
|
||||
{
|
||||
uint32_t read_data;
|
||||
int ret;
|
||||
|
||||
ret = read_swreg_config(reg_id, PHY_REG0, &read_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
read_data &= BSTI_CONFI_DONE_MASK;
|
||||
read_data |= BSTI_TOGGLE_BIT;
|
||||
ret = write_swreg_config(reg_id, PHY_REG0, read_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = read_swreg_config(reg_id, PHY_REG0, &read_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
read_data &= BSTI_CONFI_DONE_MASK;
|
||||
ret = write_swreg_config(reg_id, PHY_REG0, read_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef DUMP_SWREG
|
||||
static void dump_swreg_firmware(void)
|
||||
{
|
||||
enum sw_reg reg_id;
|
||||
uint32_t data;
|
||||
int addr;
|
||||
int ret;
|
||||
|
||||
for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) {
|
||||
INFO("SWREG: %s\n", sw_reg_name[reg_id - 1]);
|
||||
for (addr = MIN_REG_ADDR; addr <= MAX_REG_ADDR; addr++) {
|
||||
ret = read_swreg_config(reg_id, addr, &data);
|
||||
if (ret)
|
||||
ERROR("Failed to read offset %d\n", addr);
|
||||
INFO("\t0x%x: 0x%04x\n", addr, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int set_swreg(enum sw_reg reg_id, uint32_t micro_volts)
|
||||
{
|
||||
uint32_t step, programmed_step;
|
||||
uint32_t data = IHOST_VDDC_DATA;
|
||||
int ret;
|
||||
|
||||
if ((micro_volts > MAX_VOLT) || (micro_volts < MIN_VOLT)) {
|
||||
ERROR("input voltage out-of-range\n");
|
||||
ret = -EINVAL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ret = read_swreg_config(reg_id, PHY_REGC, &programmed_step);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
if (reg_id == DDR_VDDC)
|
||||
step = B0_DDR_VDDC_STEP_VALUE(micro_volts);
|
||||
else
|
||||
step = B0_STEP_VALUE(micro_volts);
|
||||
|
||||
if ((step >> 8) != (programmed_step >> 8)) {
|
||||
ret = write_swreg_config(reg_id, PHY_REGC, step);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
if (reg_id == DDR_VDDC)
|
||||
data = DDR_CORE_DATA;
|
||||
|
||||
ret = write_swreg_config(reg_id, PHY_REG0,
|
||||
UPDATE_POS_EDGE(data, 1));
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = write_swreg_config(reg_id, PHY_REG0,
|
||||
UPDATE_POS_EDGE(data, 0));
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
INFO("%s voltage updated to %duV\n", sw_reg_name[reg_id-1],
|
||||
micro_volts);
|
||||
return ret;
|
||||
|
||||
failed:
|
||||
/*
|
||||
* Stop booting if voltages are not set
|
||||
* correctly. Booting will fail at random point
|
||||
* if we continue with wrong voltage settings.
|
||||
*/
|
||||
ERROR("Failed to set %s voltage to %duV\n", sw_reg_name[reg_id-1],
|
||||
micro_volts);
|
||||
assert(0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Update SWREG firmware for all power doman for A2 chip */
|
||||
int swreg_firmware_update(void)
|
||||
{
|
||||
enum sw_reg reg_id;
|
||||
uint32_t data;
|
||||
int addr;
|
||||
int ret;
|
||||
|
||||
/* write firmware values */
|
||||
for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) {
|
||||
/* write higher location first */
|
||||
for (addr = MAX_REG_ADDR; addr >= MIN_REG_ADDR; addr--) {
|
||||
ret = write_swreg_config(reg_id, addr,
|
||||
FM_DATA[reg_id - 1][addr]);
|
||||
if (ret)
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* trigger SWREG firmware update */
|
||||
for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) {
|
||||
/*
|
||||
* Slave regulator doesn't have to be updated,
|
||||
* Updating Master is enough
|
||||
*/
|
||||
if ((reg_id == DDRIO_SLAVE) || (reg_id == VDDC1))
|
||||
continue;
|
||||
|
||||
ret = swreg_config_done(reg_id);
|
||||
if (ret) {
|
||||
ERROR("Failed to trigger SWREG firmware update for %s\n"
|
||||
, sw_reg_name[reg_id-1]);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) {
|
||||
/*
|
||||
* IHOST_ARRAY will be used on some boards like STRATUS and
|
||||
* there will not be any issue even if it is updated on other
|
||||
* boards where it is not used.
|
||||
*/
|
||||
if (reg_id == IHOST_ARRAY)
|
||||
continue;
|
||||
|
||||
for (addr = MIN_REG_ADDR; addr <= MAX_REG_ADDR; addr++) {
|
||||
ret = read_swreg_config(reg_id, addr, &data);
|
||||
if (ret || (!ret &&
|
||||
(data != FM_DATA[reg_id - 1][addr]))) {
|
||||
ERROR("swreg fm update failed: %s at off %d\n",
|
||||
sw_reg_name[reg_id - 1], addr);
|
||||
ERROR("Read val: 0x%x, expected val: 0x%x\n",
|
||||
data, FM_DATA[reg_id - 1][addr]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INFO("Updated SWREG firmware\n");
|
||||
|
||||
#ifdef DUMP_SWREG
|
||||
dump_swreg_firmware();
|
||||
#endif
|
||||
return ret;
|
||||
|
||||
exit:
|
||||
/*
|
||||
* Stop booting if swreg firmware update fails.
|
||||
* Booting will fail at random point if we
|
||||
* continue with wrong voltage settings.
|
||||
*/
|
||||
ERROR("Failed to update firmware for %s SWREG\n",
|
||||
sw_reg_name[reg_id-1]);
|
||||
assert(0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (c) 2019 - 2021, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <mdio.h>
|
||||
#include <platform_usb.h>
|
||||
#include <sr_utils.h>
|
||||
#include "sr_usb.h"
|
||||
#include <usbh_xhci_regs.h>
|
||||
|
||||
static uint32_t usb_func = USB3_DRD | USB3H_USB2DRD;
|
||||
|
||||
static void usb_pm_rescal_init(void)
|
||||
{
|
||||
uint32_t data;
|
||||
uint32_t try;
|
||||
|
||||
mmio_setbits_32(CDRU_MISC_RESET_CONTROL, CDRU_PM_RESET_N_R);
|
||||
/* release reset */
|
||||
mmio_setbits_32(CDRU_CHIP_TOP_SPARE_REG0, RESCAL_I_RSTB);
|
||||
udelay(10U);
|
||||
/* power up */
|
||||
mmio_setbits_32(CDRU_CHIP_TOP_SPARE_REG0,
|
||||
RESCAL_I_RSTB | RESCAL_I_PWRDNB);
|
||||
try = 1000U;
|
||||
do {
|
||||
udelay(1U);
|
||||
data = mmio_read_32(CDRU_CHIP_TOP_SPARE_REG1);
|
||||
try--;
|
||||
} while ((data & RESCAL_I_PWRDNB) == 0x0U && (try != 0U));
|
||||
|
||||
if (try == 0U) {
|
||||
ERROR("CDRU_CHIP_TOP_SPARE_REG1: 0x%x\n", data);
|
||||
}
|
||||
|
||||
INFO("USB and PM Rescal Init done..\n");
|
||||
}
|
||||
|
||||
const unsigned int xhc_portsc_reg_offset[MAX_USB_PORTS] = {
|
||||
XHC_PORTSC1_OFFSET,
|
||||
XHC_PORTSC2_OFFSET,
|
||||
XHC_PORTSC3_OFFSET,
|
||||
};
|
||||
|
||||
static void usb3h_usb2drd_init(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
INFO("USB3H + USB 2DRD init\n");
|
||||
mmio_clrbits_32(USB3H_U3PHY_CTRL, POR_RESET);
|
||||
val = mmio_read_32(USB3H_PWR_CTRL);
|
||||
val &= ~(0x3U << POWER_CTRL_OVRD);
|
||||
val |= (1U << POWER_CTRL_OVRD);
|
||||
mmio_write_32(USB3H_PWR_CTRL, val);
|
||||
mmio_setbits_32(USB3H_U3PHY_CTRL, PHY_RESET);
|
||||
/* Phy to come out of reset */
|
||||
udelay(2U);
|
||||
mmio_clrbits_32(USB3H_U3PHY_CTRL, MDIO_RESET);
|
||||
|
||||
/* MDIO in reset */
|
||||
udelay(2U);
|
||||
mmio_setbits_32(USB3H_U3PHY_CTRL, MDIO_RESET);
|
||||
|
||||
/* After MDIO reset release */
|
||||
udelay(2U);
|
||||
|
||||
/* USB 3.0 phy Analog Block Initialization */
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG,
|
||||
USB3_PHY_ANA_BLOCK_BASE);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_ANA_REG0, 0x4646U);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_ANA_REG1, 0x80c9U);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_ANA_REG2, 0x88a6U);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_ANA_REG5, 0x7c12U);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_ANA_REG8, 0x1d07U);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_ANA_REG11, 0x25cU);
|
||||
|
||||
/* USB 3.0 phy RXPMD Block initialization*/
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG,
|
||||
USB3_PHY_RXPMD_BLOCK_BASE);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_RXPMD_REG1, 0x4052U);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_RXPMD_REG2, 0x4cU);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_RXPMD_REG5, 0x7U);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_RXPMD_REG7, 0x173U);
|
||||
|
||||
/* USB 3.0 phy AEQ Block initialization*/
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG,
|
||||
USB3_PHY_AEQ_BLOCK_BASE);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_AEQ_REG1, 0x3000U);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_AEQ_REG3, 0x2c70U);
|
||||
|
||||
/* USB 3.0 phy TXPMD Block initialization*/
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG,
|
||||
USB3_PHY_TXPMD_BLOCK_BASE);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_TXPMD_REG1, 0x100fU);
|
||||
mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_TXPMD_REG2, 0x238cU);
|
||||
}
|
||||
|
||||
static void usb3drd_init(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
INFO("USB3DRD init\n");
|
||||
mmio_clrbits_32(DRDU3_U3PHY_CTRL, POR_RESET);
|
||||
val = mmio_read_32(DRDU3_PWR_CTRL);
|
||||
val &= ~(0x3U << POWER_CTRL_OVRD);
|
||||
val |= (1U << POWER_CTRL_OVRD);
|
||||
mmio_write_32(DRDU3_PWR_CTRL, val);
|
||||
mmio_setbits_32(DRDU3_U3PHY_CTRL, PHY_RESET);
|
||||
/* Phy to come out of reset */
|
||||
udelay(2U);
|
||||
mmio_clrbits_32(DRDU3_U3PHY_CTRL, MDIO_RESET);
|
||||
|
||||
/* MDIO in reset */
|
||||
udelay(2U);
|
||||
mmio_setbits_32(DRDU3_U3PHY_CTRL, MDIO_RESET);
|
||||
|
||||
/* After MDIO reset release */
|
||||
udelay(2U);
|
||||
|
||||
/* USB 3.0 DRD phy Analog Block Initialization */
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG,
|
||||
USB3_PHY_ANA_BLOCK_BASE);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_ANA_REG0, 0x4646U);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_ANA_REG1, 0x80c9U);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_ANA_REG2, 0x88a6U);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_ANA_REG5, 0x7c12U);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_ANA_REG8, 0x1d07U);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_ANA_REG11, 0x25cU);
|
||||
|
||||
/* USB 3.0 DRD phy RXPMD Block initialization*/
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG,
|
||||
USB3_PHY_RXPMD_BLOCK_BASE);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_RXPMD_REG1, 0x4052U);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_RXPMD_REG2, 0x4cU);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_RXPMD_REG5, 0x7U);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_RXPMD_REG7, 0x173U);
|
||||
|
||||
/* USB 3.0 DRD phy AEQ Block initialization*/
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG,
|
||||
USB3_PHY_AEQ_BLOCK_BASE);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_AEQ_REG1, 0x3000U);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_AEQ_REG3, 0x2c70U);
|
||||
|
||||
/* USB 3.0 DRD phy TXPMD Block initialization*/
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG,
|
||||
USB3_PHY_TXPMD_BLOCK_BASE);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_TXPMD_REG1, 0x100fU);
|
||||
mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_TXPMD_REG2, 0x238cU);
|
||||
}
|
||||
|
||||
static void usb3_phy_init(void)
|
||||
{
|
||||
usb_pm_rescal_init();
|
||||
|
||||
if ((usb_func & USB3H_USB2DRD) != 0U) {
|
||||
usb3h_usb2drd_init();
|
||||
}
|
||||
|
||||
if ((usb_func & USB3_DRD) != 0U) {
|
||||
usb3drd_init();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USB_DMA_COHERENT
|
||||
void usb_enable_coherence(void)
|
||||
{
|
||||
if (usb_func & USB3H_USB2DRD) {
|
||||
mmio_setbits_32(USB3H_SOFT_RESET_CTRL,
|
||||
USB3H_XHC_AXI_SOFT_RST_N);
|
||||
mmio_setbits_32(DRDU2_SOFT_RESET_CTRL,
|
||||
DRDU2_BDC_AXI_SOFT_RST_N);
|
||||
mmio_setbits_32(USB3H_U3PHY_CTRL, USB3H_U3SOFT_RST_N);
|
||||
mmio_setbits_32(DRDU2_PHY_CTRL, DRDU2_U2SOFT_RST_N);
|
||||
|
||||
mmio_clrsetbits_32(DRD2U3H_XHC_REGS_AXIWRA,
|
||||
(USBAXIWR_UA_MASK | USBAXIWR_SA_MASK),
|
||||
(USBAXIWR_UA_VAL | USBAXIWR_SA_VAL));
|
||||
|
||||
mmio_clrsetbits_32(DRD2U3H_XHC_REGS_AXIRDA,
|
||||
(USBAXIRD_UA_MASK | USBAXIRD_SA_MASK),
|
||||
(USBAXIRD_UA_VAL | USBAXIRD_SA_VAL));
|
||||
|
||||
mmio_clrsetbits_32(DRDU2D_BDC_REGS_AXIWRA,
|
||||
(USBAXIWR_UA_MASK | USBAXIWR_SA_MASK),
|
||||
(USBAXIWR_UA_VAL | USBAXIWR_SA_VAL));
|
||||
|
||||
mmio_clrsetbits_32(DRDU2D_BDC_REGS_AXIRDA,
|
||||
(USBAXIRD_UA_MASK | USBAXIRD_SA_MASK),
|
||||
(USBAXIRD_UA_VAL | USBAXIRD_SA_VAL));
|
||||
|
||||
}
|
||||
|
||||
if (usb_func & USB3_DRD) {
|
||||
mmio_setbits_32(DRDU3_SOFT_RESET_CTRL,
|
||||
(DRDU3_XHC_AXI_SOFT_RST_N |
|
||||
DRDU3_BDC_AXI_SOFT_RST_N));
|
||||
mmio_setbits_32(DRDU3_U3PHY_CTRL,
|
||||
(DRDU3_U3XHC_SOFT_RST_N |
|
||||
DRDU3_U3BDC_SOFT_RST_N));
|
||||
|
||||
mmio_clrsetbits_32(DRDU3H_XHC_REGS_AXIWRA,
|
||||
(USBAXIWR_UA_MASK | USBAXIWR_SA_MASK),
|
||||
(USBAXIWR_UA_VAL | USBAXIWR_SA_VAL));
|
||||
|
||||
mmio_clrsetbits_32(DRDU3H_XHC_REGS_AXIRDA,
|
||||
(USBAXIRD_UA_MASK | USBAXIRD_SA_MASK),
|
||||
(USBAXIRD_UA_VAL | USBAXIRD_SA_VAL));
|
||||
|
||||
mmio_clrsetbits_32(DRDU3D_BDC_REGS_AXIWRA,
|
||||
(USBAXIWR_UA_MASK | USBAXIWR_SA_MASK),
|
||||
(USBAXIWR_UA_VAL | USBAXIWR_SA_VAL));
|
||||
|
||||
mmio_clrsetbits_32(DRDU3D_BDC_REGS_AXIRDA,
|
||||
(USBAXIRD_UA_MASK | USBAXIRD_SA_MASK),
|
||||
(USBAXIRD_UA_VAL | USBAXIRD_SA_VAL));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void xhci_phy_init(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
INFO("usb init start\n");
|
||||
mmio_setbits_32(CDRU_MISC_CLK_ENABLE_CONTROL,
|
||||
CDRU_MISC_CLK_USBSS);
|
||||
|
||||
mmio_setbits_32(CDRU_MISC_RESET_CONTROL, CDRU_USBSS_RESET_N);
|
||||
|
||||
if (usb_func & USB3_DRD) {
|
||||
VERBOSE(" - configure stream_id = 0x6800 for DRDU3\n");
|
||||
val = SR_SID_VAL(0x3U, 0x1U, 0x0U) << ICFG_USB_SID_SHIFT;
|
||||
mmio_write_32(ICFG_DRDU3_SID_CTRL + ICFG_USB_SID_AWADDR_OFFSET,
|
||||
val);
|
||||
mmio_write_32(ICFG_DRDU3_SID_CTRL + ICFG_USB_SID_ARADDR_OFFSET,
|
||||
val);
|
||||
|
||||
/*
|
||||
* DRDU3 Device USB Space, DRDU3 Host USB Space,
|
||||
* DRDU3 SS Config
|
||||
*/
|
||||
mmio_setbits_32(USBIC_GPV_SECURITY10,
|
||||
USBIC_GPV_SECURITY10_FIELD);
|
||||
}
|
||||
|
||||
if (usb_func & USB3H_USB2DRD) {
|
||||
VERBOSE(" - configure stream_id = 0x6801 for USB3H\n");
|
||||
val = SR_SID_VAL(0x3U, 0x1U, 0x1U) << ICFG_USB_SID_SHIFT;
|
||||
mmio_write_32(ICFG_USB3H_SID_CTRL + ICFG_USB_SID_AWADDR_OFFSET,
|
||||
val);
|
||||
mmio_write_32(ICFG_USB3H_SID_CTRL + ICFG_USB_SID_ARADDR_OFFSET,
|
||||
val);
|
||||
|
||||
VERBOSE(" - configure stream_id = 0x6802 for DRDU2\n");
|
||||
val = SR_SID_VAL(0x3U, 0x1U, 0x2U) << ICFG_USB_SID_SHIFT;
|
||||
mmio_write_32(ICFG_DRDU2_SID_CTRL + ICFG_USB_SID_AWADDR_OFFSET,
|
||||
val);
|
||||
mmio_write_32(ICFG_DRDU2_SID_CTRL + ICFG_USB_SID_ARADDR_OFFSET,
|
||||
val);
|
||||
|
||||
/* DRDU2 APB Bridge:DRDU2 USB Device, USB3H SS Config */
|
||||
mmio_setbits_32(USBIC_GPV_SECURITY1, USBIC_GPV_SECURITY1_FIELD);
|
||||
|
||||
/*
|
||||
* USB3H APB Bridge:DRDU2 Host + USB3 Host USB Space,
|
||||
* USB3H SS Config
|
||||
*/
|
||||
mmio_setbits_32(USBIC_GPV_SECURITY2, USBIC_GPV_SECURITY2_FIELD);
|
||||
}
|
||||
|
||||
/* Configure Host masters as non-Secure */
|
||||
mmio_setbits_32(USBSS_TZPCDECPROT0set, USBSS_TZPCDECPROT0);
|
||||
|
||||
/* CCN Slave on USBIC */
|
||||
mmio_setbits_32(USBIC_GPV_SECURITY0, USBIC_GPV_SECURITY0_FIELD);
|
||||
|
||||
/* SLAVE_8:IDM Register Space */
|
||||
mmio_setbits_32(USBIC_GPV_SECURITY4, USBIC_GPV_SECURITY4_FIELD);
|
||||
|
||||
usb3_phy_init();
|
||||
#ifdef USB_DMA_COHERENT
|
||||
usb_enable_coherence();
|
||||
#endif
|
||||
|
||||
usb_device_init(usb_func);
|
||||
|
||||
INFO("PLAT USB: init done.\n");
|
||||
}
|
||||
+601
@@ -0,0 +1,601 @@
|
||||
/*
|
||||
* Copyright (c) 2019 - 2021, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <platform_usb.h>
|
||||
#include <usb_phy.h>
|
||||
|
||||
#define USB_PHY_ALREADY_STARTED (-2)
|
||||
#define USB_MAX_DEVICES 2
|
||||
#define USB3H_USB2DRD_PHY 0
|
||||
#define USB3_DRD_PHY 1
|
||||
|
||||
/* Common bit fields for all the USB2 phy */
|
||||
#define USB2_PHY_ISO DRDU2_U2PHY_ISO
|
||||
#define USB2_AFE_PLL_PWRDWNB DRDU2_U2AFE_PLL_PWRDWNB
|
||||
#define USB2_AFE_BG_PWRDWNB DRDU2_U2AFE_BG_PWRDWNB
|
||||
#define USB2_AFE_LDO_PWRDWNB DRDU2_U2AFE_LDO_PWRDWNB
|
||||
#define USB2_CTRL_CORERDY DRDU2_U2CTRL_CORERDY
|
||||
|
||||
#define USB2_PHY_PCTL_MASK DRDU2_U2PHY_PCTL_MASK
|
||||
#define USB2_PHY_PCTL_OFFSET DRDU2_U2PHY_PCTL_OFFSET
|
||||
#define USB2_PHY_PCTL_VAL U2PHY_PCTL_VAL
|
||||
|
||||
#define USB2_PLL_RESETB DRDU2_U2PLL_RESETB
|
||||
#define USB2_PHY_RESETB DRDU2_U2PHY_RESETB
|
||||
|
||||
static usb_phy_port_t usb_phy_port[2U][MAX_NR_PORTS];
|
||||
|
||||
static usb_phy_t usb_phy_info[2U] = {
|
||||
{DRDU2_U2PLL_NDIV_FRAC, USB3H_PIPE_CTRL, 0U, USB3H_DRDU2_PHY},
|
||||
{0U, 0U, DRDU3_PIPE_CTRL, DRDU3_PHY}
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
void *pcd_id;
|
||||
} usb_platform_dev;
|
||||
|
||||
/* index 0: USB3H + USB2 DRD, 1: USB3 DRD */
|
||||
static usb_platform_dev xhci_devices_configs[USB_MAX_DEVICES] = {
|
||||
{&usb_phy_info[0U]},
|
||||
{&usb_phy_info[1U]}
|
||||
};
|
||||
|
||||
static int32_t pll_lock_check(uint32_t address, uint32_t bit)
|
||||
{
|
||||
uint32_t retry;
|
||||
uint32_t data;
|
||||
|
||||
retry = PLL_LOCK_RETRY_COUNT;
|
||||
do {
|
||||
data = mmio_read_32(address);
|
||||
if ((data & bit) != 0U) {
|
||||
return 0;
|
||||
}
|
||||
udelay(1);
|
||||
} while (--retry != 0);
|
||||
|
||||
ERROR("%s(): FAIL (0x%08x)\n", __func__, address);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* USB2 PHY using external FSM bringup sequence
|
||||
* Total #3 USB2 phys. All phys has the same
|
||||
* bringup sequence. Register bit fields for
|
||||
* some of the PHY's are different.
|
||||
* Bit fields which are different are passed using
|
||||
* struct u2_phy_ext_fsm with bit-fields and register addr.
|
||||
*/
|
||||
|
||||
static void u2_phy_ext_fsm_power_on(struct u2_phy_ext_fsm *u2_phy)
|
||||
{
|
||||
mmio_setbits_32(u2_phy->phy_ctrl_reg, USB2_PHY_ISO);
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(10U);
|
||||
|
||||
mmio_setbits_32(u2_phy->phy_ctrl_reg, u2_phy->phy_iddq);
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(10U);
|
||||
|
||||
mmio_clrbits_32(u2_phy->phy_ctrl_reg,
|
||||
(USB2_AFE_BG_PWRDWNB |
|
||||
USB2_AFE_PLL_PWRDWNB |
|
||||
USB2_AFE_LDO_PWRDWNB |
|
||||
USB2_CTRL_CORERDY));
|
||||
|
||||
mmio_clrsetbits_32(u2_phy->phy_ctrl_reg,
|
||||
(USB2_PHY_PCTL_MASK << USB2_PHY_PCTL_OFFSET),
|
||||
(USB2_PHY_PCTL_VAL << USB2_PHY_PCTL_OFFSET));
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(160U);
|
||||
|
||||
mmio_setbits_32(u2_phy->phy_ctrl_reg, USB2_CTRL_CORERDY);
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(50U);
|
||||
|
||||
mmio_setbits_32(u2_phy->phy_ctrl_reg, USB2_AFE_BG_PWRDWNB);
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(200U);
|
||||
|
||||
mmio_setbits_32(u2_phy->pwr_ctrl_reg, u2_phy->pwr_onin);
|
||||
mmio_setbits_32(u2_phy->phy_ctrl_reg, USB2_AFE_LDO_PWRDWNB);
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(10U);
|
||||
|
||||
mmio_setbits_32(u2_phy->pwr_ctrl_reg, u2_phy->pwr_okin);
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(10U);
|
||||
|
||||
mmio_setbits_32(u2_phy->phy_ctrl_reg, USB2_AFE_PLL_PWRDWNB);
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(10U);
|
||||
|
||||
mmio_clrbits_32(u2_phy->phy_ctrl_reg, USB2_PHY_ISO);
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(10U);
|
||||
mmio_clrbits_32(u2_phy->phy_ctrl_reg, u2_phy->phy_iddq);
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(1U);
|
||||
|
||||
mmio_setbits_32(u2_phy->pll_ctrl_reg, USB2_PLL_RESETB);
|
||||
mmio_setbits_32(u2_phy->phy_ctrl_reg, USB2_PHY_RESETB);
|
||||
|
||||
}
|
||||
|
||||
static int32_t usb3h_u2_phy_power_on(uint32_t base)
|
||||
{
|
||||
int32_t status;
|
||||
struct u2_phy_ext_fsm u2_phy;
|
||||
|
||||
u2_phy.pll_ctrl_reg = base + USB3H_U2PLL_CTRL;
|
||||
u2_phy.phy_ctrl_reg = base + USB3H_U2PHY_CTRL;
|
||||
u2_phy.phy_iddq = USB3H_U2PHY_IDDQ;
|
||||
u2_phy.pwr_ctrl_reg = base + USB3H_PWR_CTRL;
|
||||
u2_phy.pwr_okin = USB3H_PWR_CTRL_U2PHY_DFE_SWITCH_PWROKIN;
|
||||
u2_phy.pwr_onin = USB3H_PWR_CTRL_U2PHY_DFE_SWITCH_PWRONIN;
|
||||
|
||||
u2_phy_ext_fsm_power_on(&u2_phy);
|
||||
|
||||
status = pll_lock_check(base + USB3H_U2PLL_CTRL, USB3H_U2PLL_LOCK);
|
||||
if (status != 0) {
|
||||
/* re-try by toggling the PLL reset */
|
||||
mmio_clrbits_32(base + USB3H_U2PLL_CTRL,
|
||||
(uint32_t)USB3H_U2PLL_RESETB);
|
||||
mmio_setbits_32(base + USB3H_U2PLL_CTRL, USB3H_U2PLL_RESETB);
|
||||
status = pll_lock_check(base + USB3H_U2PLL_CTRL,
|
||||
USB3H_U2PLL_LOCK);
|
||||
if (status != 0)
|
||||
ERROR("%s() re-try PLL lock FAIL (0x%08x)\n", __func__,
|
||||
base + USB3H_U2PLL_CTRL);
|
||||
}
|
||||
|
||||
mmio_clrsetbits_32(base + USB3H_U2PHY_CTRL,
|
||||
(USB3H_U2PHY_PCTL_MASK << USB3H_U2PHY_PCTL_OFFSET),
|
||||
(U2PHY_PCTL_NON_DRV_LOW << USB3H_U2PHY_PCTL_OFFSET));
|
||||
return status;
|
||||
}
|
||||
|
||||
static int32_t usb3h_u3_phy_power_on(uint32_t base)
|
||||
{
|
||||
int32_t status;
|
||||
|
||||
/* Set pctl with mode and soft reset */
|
||||
mmio_clrsetbits_32(base + USB3H_U3PHY_CTRL,
|
||||
(USB3H_U3PHY_PCTL_MASK << USB3H_U3PHY_PCTL_OFFSET),
|
||||
(U3PHY_PCTL_VAL << USB3H_U3PHY_PCTL_OFFSET));
|
||||
|
||||
mmio_clrbits_32(base + USB3H_U3PHY_PLL_CTRL,
|
||||
(uint32_t) USB3H_U3SSPLL_SUSPEND_EN);
|
||||
mmio_setbits_32(base + USB3H_U3PHY_PLL_CTRL, USB3H_U3PLL_SEQ_START);
|
||||
mmio_setbits_32(base + USB3H_U3PHY_PLL_CTRL, USB3H_U3PLL_RESETB);
|
||||
|
||||
/* Time to stabilize the PLL Control */
|
||||
mdelay(1U);
|
||||
|
||||
status = pll_lock_check(base + USB3H_U3PHY_PLL_CTRL,
|
||||
USB3H_U3PLL_SS_LOCK);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int32_t drdu3_u2_phy_power_on(uint32_t base)
|
||||
{
|
||||
int32_t status;
|
||||
struct u2_phy_ext_fsm u2_phy;
|
||||
|
||||
u2_phy.pll_ctrl_reg = base + DRDU3_U2PLL_CTRL;
|
||||
u2_phy.phy_ctrl_reg = base + DRDU3_U2PHY_CTRL;
|
||||
u2_phy.phy_iddq = DRDU3_U2PHY_IDDQ;
|
||||
u2_phy.pwr_ctrl_reg = base + DRDU3_PWR_CTRL;
|
||||
u2_phy.pwr_okin = DRDU3_U2PHY_DFE_SWITCH_PWROKIN;
|
||||
u2_phy.pwr_onin = DRDU3_U2PHY_DFE_SWITCH_PWRONIN;
|
||||
|
||||
u2_phy_ext_fsm_power_on(&u2_phy);
|
||||
|
||||
status = pll_lock_check(base + DRDU3_U2PLL_CTRL, DRDU3_U2PLL_LOCK);
|
||||
if (status != 0) {
|
||||
/* re-try by toggling the PLL reset */
|
||||
mmio_clrbits_32(base + DRDU3_U2PLL_CTRL,
|
||||
(uint32_t)DRDU2_U2PLL_RESETB);
|
||||
mmio_setbits_32(base + DRDU3_U2PLL_CTRL, DRDU3_U2PLL_RESETB);
|
||||
|
||||
status = pll_lock_check(base + DRDU3_U2PLL_CTRL,
|
||||
DRDU3_U2PLL_LOCK);
|
||||
if (status != 0) {
|
||||
ERROR("%s() re-try PLL lock FAIL (0x%08x)\n", __func__,
|
||||
base + DRDU3_U2PLL_CTRL);
|
||||
}
|
||||
}
|
||||
mmio_clrsetbits_32(base + DRDU3_U2PHY_CTRL,
|
||||
(DRDU3_U2PHY_PCTL_MASK << DRDU3_U2PHY_PCTL_OFFSET),
|
||||
(U2PHY_PCTL_NON_DRV_LOW << DRDU3_U2PHY_PCTL_OFFSET));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int32_t drdu3_u3_phy_power_on(uint32_t base)
|
||||
{
|
||||
int32_t status;
|
||||
|
||||
/* Set pctl with mode and soft reset */
|
||||
mmio_clrsetbits_32(base + DRDU3_U3PHY_CTRL,
|
||||
(DRDU3_U3PHY_PCTL_MASK << DRDU3_U3PHY_PCTL_OFFSET),
|
||||
(U3PHY_PCTL_VAL << DRDU3_U3PHY_PCTL_OFFSET));
|
||||
|
||||
mmio_clrbits_32(base + DRDU3_U3PHY_PLL_CTRL,
|
||||
(uint32_t) DRDU3_U3SSPLL_SUSPEND_EN);
|
||||
mmio_setbits_32(base + DRDU3_U3PHY_PLL_CTRL, DRDU3_U3PLL_SEQ_START);
|
||||
mmio_setbits_32(base + DRDU3_U3PHY_PLL_CTRL, DRDU3_U3PLL_RESETB);
|
||||
|
||||
/* Time to stabilize the PLL Control */
|
||||
mdelay(1U);
|
||||
|
||||
status = pll_lock_check(base + DRDU3_U3PHY_PLL_CTRL,
|
||||
DRDU3_U3PLL_SS_LOCK);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int32_t drdu2_u2_phy_power_on(uint32_t base)
|
||||
{
|
||||
int32_t status;
|
||||
struct u2_phy_ext_fsm u2_phy;
|
||||
|
||||
u2_phy.pll_ctrl_reg = base + DRDU2_U2PLL_CTRL;
|
||||
u2_phy.phy_ctrl_reg = base + DRDU2_PHY_CTRL;
|
||||
u2_phy.phy_iddq = DRDU2_U2IDDQ;
|
||||
u2_phy.pwr_ctrl_reg = base + DRDU2_PWR_CTRL;
|
||||
u2_phy.pwr_okin = DRDU2_U2PHY_DFE_SWITCH_PWROKIN_I;
|
||||
u2_phy.pwr_onin = DRDU2_U2PHY_DFE_SWITCH_PWRONIN_I;
|
||||
|
||||
u2_phy_ext_fsm_power_on(&u2_phy);
|
||||
|
||||
status = pll_lock_check(base + DRDU2_U2PLL_CTRL, DRDU2_U2PLL_LOCK);
|
||||
if (status != 0) {
|
||||
/* re-try by toggling the PLL reset */
|
||||
mmio_clrbits_32(base + DRDU2_U2PLL_CTRL,
|
||||
(uint32_t)DRDU2_U2PLL_RESETB);
|
||||
mmio_setbits_32(base + DRDU2_U2PLL_CTRL, DRDU2_U2PLL_RESETB);
|
||||
|
||||
status = pll_lock_check(base + DRDU2_U2PLL_CTRL,
|
||||
DRDU2_U2PLL_LOCK);
|
||||
if (status != 0)
|
||||
ERROR("%s() re-try PLL lock FAIL (0x%08x)\n", __func__,
|
||||
base + DRDU2_U2PLL_CTRL);
|
||||
}
|
||||
mmio_clrsetbits_32(base + DRDU2_PHY_CTRL,
|
||||
(DRDU2_U2PHY_PCTL_MASK << DRDU2_U2PHY_PCTL_OFFSET),
|
||||
(U2PHY_PCTL_NON_DRV_LOW << DRDU2_U2PHY_PCTL_OFFSET));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void u3h_u2drd_phy_reset(usb_phy_port_t *phy_port)
|
||||
{
|
||||
usb_phy_t *phy = phy_port->p;
|
||||
|
||||
switch (phy_port->port_id) {
|
||||
case USB3HS_PORT:
|
||||
mmio_clrbits_32(phy->usb3hreg + USB3H_U2PHY_CTRL,
|
||||
(uint32_t) USB3H_U2CTRL_CORERDY);
|
||||
mmio_setbits_32(phy->usb3hreg + USB3H_U2PHY_CTRL,
|
||||
USB3H_U2CTRL_CORERDY);
|
||||
break;
|
||||
case DRDU2_PORT:
|
||||
mmio_clrbits_32(phy->drdu2reg + DRDU2_PHY_CTRL,
|
||||
(uint32_t) DRDU2_U2CTRL_CORERDY);
|
||||
mmio_setbits_32(phy->drdu2reg + DRDU2_PHY_CTRL,
|
||||
DRDU2_U2CTRL_CORERDY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void u3drd_phy_reset(usb_phy_port_t *phy_port)
|
||||
{
|
||||
usb_phy_t *phy = phy_port->p;
|
||||
|
||||
if (phy_port->port_id == DRD3HS_PORT) {
|
||||
mmio_clrbits_32(phy->drdu3reg + DRDU3_U2PHY_CTRL,
|
||||
(uint32_t) DRDU3_U2CTRL_CORERDY);
|
||||
mmio_setbits_32(phy->drdu3reg + DRDU3_U2PHY_CTRL,
|
||||
DRDU3_U2CTRL_CORERDY);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t u3h_u2drd_phy_power_on(usb_phy_port_t *phy_port)
|
||||
{
|
||||
usb_phy_t *phy = phy_port->p;
|
||||
int32_t status;
|
||||
|
||||
switch (phy_port->port_id) {
|
||||
case USB3SS_PORT:
|
||||
mmio_clrbits_32(phy->usb3hreg + USB3H_PHY_PWR_CTRL,
|
||||
(uint32_t) USB3H_DISABLE_USB30_P0);
|
||||
status = usb3h_u3_phy_power_on(phy->usb3hreg);
|
||||
if (status != 0) {
|
||||
goto err_usb3h_phy_on;
|
||||
}
|
||||
break;
|
||||
case USB3HS_PORT:
|
||||
mmio_clrbits_32(phy->usb3hreg + USB3H_PHY_PWR_CTRL,
|
||||
(uint32_t) USB3H_DISABLE_EUSB_P1);
|
||||
mmio_setbits_32(AXI_DEBUG_CTRL,
|
||||
AXI_DBG_CTRL_SSPHY_DRD_MODE_DISABLE);
|
||||
mmio_setbits_32(USB3H_DEBUG_CTRL,
|
||||
USB3H_DBG_CTRL_SSPHY_DRD_MODE_DISABLE);
|
||||
|
||||
mmio_clrbits_32(phy->usb3hreg + USB3H_PWR_CTRL,
|
||||
USB3H_PWR_CTRL_U2PHY_DFE_SWITCH_PWRONIN);
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(10U);
|
||||
mmio_clrbits_32(phy->usb3hreg + USB3H_PWR_CTRL,
|
||||
USB3H_PWR_CTRL_U2PHY_DFE_SWITCH_PWROKIN);
|
||||
status = usb3h_u2_phy_power_on(phy->usb3hreg);
|
||||
if (status != 0) {
|
||||
goto err_usb3h_phy_on;
|
||||
}
|
||||
break;
|
||||
case DRDU2_PORT:
|
||||
mmio_clrbits_32(phy->usb3hreg + USB3H_PHY_PWR_CTRL,
|
||||
(uint32_t) USB3H_DISABLE_EUSB_P0);
|
||||
mmio_setbits_32(AXI_DEBUG_CTRL,
|
||||
AXI_DBG_CTRL_SSPHY_DRD_MODE_DISABLE);
|
||||
mmio_setbits_32(USB3H_DEBUG_CTRL,
|
||||
USB3H_DBG_CTRL_SSPHY_DRD_MODE_DISABLE);
|
||||
|
||||
mmio_clrbits_32(phy->usb3hreg + DRDU2_PWR_CTRL,
|
||||
DRDU2_U2PHY_DFE_SWITCH_PWRONIN_I);
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(10U);
|
||||
mmio_clrbits_32(phy->usb3hreg + DRDU2_PWR_CTRL,
|
||||
DRDU2_U2PHY_DFE_SWITCH_PWROKIN_I);
|
||||
|
||||
status = drdu2_u2_phy_power_on(phy->drdu2reg);
|
||||
if (status != 0) {
|
||||
mmio_setbits_32(phy->usb3hreg + USB3H_PHY_PWR_CTRL,
|
||||
USB3H_DISABLE_EUSB_P0);
|
||||
goto err_drdu2_phy_on;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Device Mode */
|
||||
if (phy_port->port_id == DRDU2_PORT) {
|
||||
mmio_write_32(phy->drdu2reg + DRDU2_SOFT_RESET_CTRL,
|
||||
DRDU2_BDC_AXI_SOFT_RST_N);
|
||||
mmio_setbits_32(phy->drdu2reg + DRDU2_PHY_CTRL,
|
||||
DRDU2_U2SOFT_RST_N);
|
||||
}
|
||||
/* Host Mode */
|
||||
mmio_write_32(phy->usb3hreg + USB3H_SOFT_RESET_CTRL,
|
||||
USB3H_XHC_AXI_SOFT_RST_N);
|
||||
mmio_setbits_32(phy->usb3hreg + USB3H_U3PHY_CTRL, USB3H_U3SOFT_RST_N);
|
||||
|
||||
return 0U;
|
||||
err_usb3h_phy_on:mmio_setbits_32(phy->usb3hreg + USB3H_PHY_PWR_CTRL,
|
||||
(USB3H_DISABLE_EUSB_P1 |
|
||||
USB3H_DISABLE_USB30_P0));
|
||||
err_drdu2_phy_on:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int32_t u3drd_phy_power_on(usb_phy_port_t *phy_port)
|
||||
{
|
||||
usb_phy_t *phy = phy_port->p;
|
||||
int32_t status;
|
||||
|
||||
switch (phy_port->port_id) {
|
||||
case DRD3SS_PORT:
|
||||
mmio_clrbits_32(phy->drdu3reg + DRDU3_PHY_PWR_CTRL,
|
||||
(uint32_t) DRDU3_DISABLE_USB30_P0);
|
||||
|
||||
status = drdu3_u3_phy_power_on(phy->drdu3reg);
|
||||
if (status != 0) {
|
||||
goto err_drdu3_phy_on;
|
||||
}
|
||||
break;
|
||||
case DRD3HS_PORT:
|
||||
mmio_clrbits_32(phy->drdu3reg + DRDU3_PHY_PWR_CTRL,
|
||||
(uint32_t) DRDU3_DISABLE_EUSB_P0);
|
||||
mmio_setbits_32(AXI_DEBUG_CTRL,
|
||||
AXI_DBG_CTRL_SSPHY_DRD_MODE_DISABLE);
|
||||
mmio_setbits_32(USB3H_DEBUG_CTRL,
|
||||
USB3H_DBG_CTRL_SSPHY_DRD_MODE_DISABLE);
|
||||
|
||||
mmio_clrbits_32(phy->drdu3reg + DRDU3_PWR_CTRL,
|
||||
DRDU3_U2PHY_DFE_SWITCH_PWRONIN);
|
||||
/* Delay as per external FSM spec */
|
||||
udelay(10U);
|
||||
mmio_clrbits_32(phy->drdu3reg + DRDU3_PWR_CTRL,
|
||||
DRDU3_U2PHY_DFE_SWITCH_PWROKIN);
|
||||
|
||||
status = drdu3_u2_phy_power_on(phy->drdu3reg);
|
||||
if (status != 0) {
|
||||
goto err_drdu3_phy_on;
|
||||
}
|
||||
|
||||
/* Host Mode */
|
||||
mmio_setbits_32(phy->drdu3reg + DRDU3_SOFT_RESET_CTRL,
|
||||
DRDU3_XHC_AXI_SOFT_RST_N);
|
||||
mmio_setbits_32(phy->drdu3reg + DRDU3_U3PHY_CTRL,
|
||||
DRDU3_U3XHC_SOFT_RST_N);
|
||||
/* Device Mode */
|
||||
mmio_setbits_32(phy->drdu3reg + DRDU3_SOFT_RESET_CTRL,
|
||||
DRDU3_BDC_AXI_SOFT_RST_N);
|
||||
mmio_setbits_32(phy->drdu3reg + DRDU3_U3PHY_CTRL,
|
||||
DRDU3_U3BDC_SOFT_RST_N);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0U;
|
||||
err_drdu3_phy_on:mmio_setbits_32(phy->drdu3reg + DRDU3_PHY_PWR_CTRL,
|
||||
(DRDU3_DISABLE_EUSB_P0 |
|
||||
DRDU3_DISABLE_USB30_P0));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void u3h_u2drd_phy_power_off(usb_phy_port_t *phy_port)
|
||||
{
|
||||
usb_phy_t *p = phy_port->p;
|
||||
|
||||
switch (phy_port->port_id) {
|
||||
case USB3SS_PORT:
|
||||
mmio_setbits_32(p->usb3hreg + USB3H_PHY_PWR_CTRL,
|
||||
USB3H_DISABLE_USB30_P0);
|
||||
break;
|
||||
case USB3HS_PORT:
|
||||
mmio_setbits_32(p->usb3hreg + USB3H_PHY_PWR_CTRL,
|
||||
USB3H_DISABLE_EUSB_P1);
|
||||
break;
|
||||
case DRDU2_PORT:
|
||||
mmio_setbits_32(p->usb3hreg + USB3H_PHY_PWR_CTRL,
|
||||
USB3H_DISABLE_EUSB_P0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void u3drd_phy_power_off(usb_phy_port_t *phy_port)
|
||||
{
|
||||
usb_phy_t *p = phy_port->p;
|
||||
|
||||
switch (phy_port->port_id) {
|
||||
case DRD3SS_PORT:
|
||||
mmio_setbits_32(p->drdu3reg + DRDU3_PHY_PWR_CTRL,
|
||||
DRDU3_DISABLE_USB30_P0);
|
||||
break;
|
||||
case DRD3HS_PORT:
|
||||
mmio_setbits_32(p->drdu3reg + DRDU3_PHY_PWR_CTRL,
|
||||
DRDU3_DISABLE_EUSB_P0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t usb_info_fill(usb_phy_t *phy_info)
|
||||
{
|
||||
int32_t index;
|
||||
|
||||
if (phy_info->initialized != 0U) {
|
||||
return USB_PHY_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
if (phy_info->phy_id == USB3H_DRDU2_PHY) {
|
||||
phy_info->phy_port = usb_phy_port[USB3H_DRDU2_PHY - 1U];
|
||||
phy_info->ports_enabled = 0x7U;
|
||||
} else {
|
||||
phy_info->phy_port = usb_phy_port[DRDU3_PHY - 1U];
|
||||
phy_info->ports_enabled = 0x3U;
|
||||
}
|
||||
|
||||
for (index = MAX_NR_PORTS - 1U; index > -1; index--) {
|
||||
phy_info->phy_port[index].enabled = (phy_info->ports_enabled
|
||||
>> index) & 0x1U;
|
||||
phy_info->phy_port[index].p = phy_info;
|
||||
phy_info->phy_port[index].port_id = index;
|
||||
}
|
||||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
int32_t usb_phy_init(usb_platform_dev *device)
|
||||
{
|
||||
int32_t status;
|
||||
usb_phy_t *phy_info;
|
||||
uint32_t index;
|
||||
|
||||
phy_info = (usb_phy_t *)device->pcd_id;
|
||||
|
||||
status = usb_info_fill(phy_info);
|
||||
if (status != 0) {
|
||||
return (status == USB_PHY_ALREADY_STARTED) ? 0 : status;
|
||||
}
|
||||
|
||||
for (index = 0U; index < MAX_NR_PORTS; index++) {
|
||||
if (phy_info->phy_port[index].enabled != 0U) {
|
||||
switch (phy_info->phy_id) {
|
||||
case USB3H_DRDU2_PHY:
|
||||
status =
|
||||
u3h_u2drd_phy_power_on(&phy_info->
|
||||
phy_port[index]);
|
||||
break;
|
||||
default:
|
||||
status =
|
||||
u3drd_phy_power_on(&phy_info->
|
||||
phy_port[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
phy_info->initialized = !status;
|
||||
return status;
|
||||
}
|
||||
|
||||
void usb_phy_shutdown(usb_platform_dev *device)
|
||||
{
|
||||
usb_phy_t *phy_info;
|
||||
uint32_t index;
|
||||
|
||||
phy_info = (usb_phy_t *)device->pcd_id;
|
||||
|
||||
phy_info->initialized = 0U;
|
||||
|
||||
for (index = 0U; index < MAX_NR_PORTS; index++) {
|
||||
if (phy_info->phy_port[index].enabled != 0U) {
|
||||
switch (phy_info->phy_id) {
|
||||
case USB3H_DRDU2_PHY:
|
||||
u3h_u2drd_phy_power_off(&phy_info->
|
||||
phy_port[index]);
|
||||
break;
|
||||
case DRDU3_PHY:
|
||||
u3drd_phy_power_off(&phy_info->phy_port[index]);
|
||||
break;
|
||||
default:
|
||||
INFO("%s: invalid phy id 0x%x\n", __func__,
|
||||
phy_info->phy_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t usb_xhci_init(usb_platform_dev *device)
|
||||
{
|
||||
int32_t status;
|
||||
|
||||
status = usb_phy_init(device);
|
||||
if (status == USB_PHY_ALREADY_STARTED) {
|
||||
status = 0U;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int32_t usb_device_init(unsigned int usb_func)
|
||||
{
|
||||
int32_t status;
|
||||
int32_t devices_initialized = 0U;
|
||||
|
||||
if ((usb_func & USB3H_USB2DRD) != 0U) {
|
||||
status = usb_xhci_init(
|
||||
&xhci_devices_configs[USB3H_USB2DRD_PHY]);
|
||||
if (status == 0) {
|
||||
devices_initialized++;
|
||||
} else {
|
||||
ERROR("%s(): USB3H_USB2DRD init failure\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
if ((usb_func & USB3_DRD) != 0U) {
|
||||
status = usb_xhci_init(&xhci_devices_configs[USB3_DRD_PHY]);
|
||||
if (status == 0) {
|
||||
devices_initialized++;
|
||||
} else {
|
||||
ERROR("%s(): USB3_DRD init failure\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
return devices_initialized;
|
||||
}
|
||||
Reference in New Issue
Block a user