173
bdk/soc/actmon.c
Normal file
173
bdk/soc/actmon.c
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Activity Monitor driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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/>.
|
||||
*/
|
||||
|
||||
#include "actmon.h"
|
||||
#include "clock.h"
|
||||
#include "t210.h"
|
||||
|
||||
/* Global registers */
|
||||
#define ACTMON_GLB_STATUS 0x0
|
||||
#define ACTMON_MCCPU_MON_ACT BIT(8)
|
||||
#define ACTMON_MCALL_MON_ACT BIT(9)
|
||||
#define ACTMON_CPU_FREQ_MON_ACT BIT(10)
|
||||
#define ACTMON_APB_MON_ACT BIT(12)
|
||||
#define ACTMON_AHB_MON_ACT BIT(13)
|
||||
#define ACTMON_BPMP_MON_ACT BIT(14)
|
||||
#define ACTMON_CPU_MON_ACT BIT(15)
|
||||
#define ACTMON_MCCPU_INTR BIT(25)
|
||||
#define ACTMON_MCALL_INTR BIT(26)
|
||||
#define ACTMON_CPU_FREQ_INTR BIT(27)
|
||||
#define ACTMON_APB_INTR BIT(28)
|
||||
#define ACTMON_AHB_INTR BIT(29)
|
||||
#define ACTMON_BPMP_INTR BIT(30)
|
||||
#define ACTMON_CPU_INTR BIT(31)
|
||||
#define ACTMON_GLB_PERIOD_CTRL 0x4
|
||||
#define ACTMON_GLB_PERIOD_USEC BIT(8)
|
||||
#define ACTMON_GLB_PERIOD_SAMPLE(n) (((n) - 1) & 0xFF)
|
||||
|
||||
/* Device Registers */
|
||||
#define ACTMON_DEV_BASE ACTMON_BASE + 0x80
|
||||
#define ACTMON_DEV_SIZE 0x40
|
||||
/* CTRL */
|
||||
#define ACTMON_DEV_CTRL_K_VAL(k) (((k) & 7) << 10)
|
||||
#define ACTMON_DEV_CTRL_ENB_PERIODIC BIT(18)
|
||||
#define ACTMON_DEV_CTRL_AT_END_EN BIT(19)
|
||||
#define ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN BIT(20)
|
||||
#define ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN BIT(21)
|
||||
#define ACTMON_DEV_CTRL_WHEN_OVERFLOW_EN BIT(22)
|
||||
#define ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_NUM(n) (((n) & 7) << 23)
|
||||
#define ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_NUM(n) (((n) & 7) << 26)
|
||||
#define ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN BIT(29)
|
||||
#define ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN BIT(30)
|
||||
#define ACTMON_DEV_CTRL_ENB BIT(31)
|
||||
/* INTR_STATUS */
|
||||
#define ACTMON_DEV_ISTS_AVG_ABOVE_WMARK BIT(24)
|
||||
#define ACTMON_DEV_ISTS_AVG_BELOW_WMARK BIT(25)
|
||||
#define ACTMON_DEV_ISTS_WHEN_OVERFLOW BIT(26)
|
||||
#define ACTMON_DEV_ISTS_AT_END BIT(29)
|
||||
#define ACTMON_DEV_ISTS_CONSECUTIVE_LOWER BIT(30)
|
||||
#define ACTMON_DEV_ISTS_CONSECUTIVE_UPPER BIT(31)
|
||||
|
||||
/* Histogram Registers */
|
||||
#define ACTMON_HISTOGRAM_CONFIG 0x300
|
||||
#define ACTMON_HIST_CFG_ACTIVE BIT(0)
|
||||
#define ACTMON_HIST_CFG_LINEAR_MODE BIT(1)
|
||||
#define ACTMON_HIST_CFG_NO_UNDERFLOW_BUCKET BIT(2)
|
||||
#define ACTMON_HIST_CFG_STALL_ON_SINGLE_SATURATE BIT(3)
|
||||
#define ACTMON_HIST_CFG_SHIFT(s) (((s) & 0x1F) << 4)
|
||||
#define ACTMON_HIST_CFG_SOURCE(s) (((s) & 0xF) << 12)
|
||||
#define ACTMON_HISTOGRAM_CTRL 0x304
|
||||
#define ACTMON_HIST_CTRL_CLEAR_ALL BIT(0)
|
||||
#define ACTMON_HISTOGRAM_DATA_BASE 0x380
|
||||
#define ACTMON_HISTOGRAM_DATA_NUM 32
|
||||
|
||||
#define ACTMON_FREQ 19200000
|
||||
|
||||
typedef struct _actmon_dev_reg_t
|
||||
{
|
||||
vu32 ctrl;
|
||||
vu32 upper_wnark;
|
||||
vu32 lower_wmark;
|
||||
vu32 init_avg;
|
||||
vu32 avg_upper_wmark;
|
||||
vu32 avg_lower_wmark;
|
||||
vu32 count_weight;
|
||||
vu32 count;
|
||||
vu32 avg_count;
|
||||
vu32 intr_status;
|
||||
vu32 ctrl2;
|
||||
vu32 unk[5];
|
||||
} actmon_dev_reg_t;
|
||||
|
||||
u32 sample_period = 0;
|
||||
|
||||
void actmon_hist_enable(actmon_hist_src_t src)
|
||||
{
|
||||
ACTMON(ACTMON_HISTOGRAM_CONFIG) = ACTMON_HIST_CFG_SOURCE(src) | ACTMON_HIST_CFG_ACTIVE;
|
||||
ACTMON(ACTMON_HISTOGRAM_CTRL) = ACTMON_HIST_CTRL_CLEAR_ALL;
|
||||
}
|
||||
|
||||
void actmon_hist_disable()
|
||||
{
|
||||
ACTMON(ACTMON_HISTOGRAM_CONFIG) = 0;
|
||||
}
|
||||
|
||||
void actmon_hist_get(u32 *histogram)
|
||||
{
|
||||
if (histogram)
|
||||
{
|
||||
for (u32 i = 0; i < ACTMON_HISTOGRAM_DATA_NUM; i++)
|
||||
histogram[i] = ACTMON(ACTMON_HISTOGRAM_DATA_BASE + i * sizeof(u32));
|
||||
}
|
||||
}
|
||||
|
||||
void actmon_dev_enable(actmon_dev_t dev)
|
||||
{
|
||||
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
|
||||
|
||||
regs->init_avg = 0;
|
||||
regs->count_weight = 5;
|
||||
|
||||
regs->ctrl = ACTMON_DEV_CTRL_ENB | ACTMON_DEV_CTRL_ENB_PERIODIC;
|
||||
}
|
||||
|
||||
void actmon_dev_disable(actmon_dev_t dev)
|
||||
{
|
||||
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
|
||||
|
||||
regs->ctrl = 0;
|
||||
}
|
||||
|
||||
u32 actmon_dev_get_load(actmon_dev_t dev)
|
||||
{
|
||||
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
|
||||
|
||||
// Get load-based sampling. 1 decimal point precision.
|
||||
u32 load = regs->count / (ACTMON_FREQ / 1000);
|
||||
|
||||
return load;
|
||||
}
|
||||
|
||||
u32 actmon_dev_get_load_avg(actmon_dev_t dev)
|
||||
{
|
||||
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
|
||||
|
||||
// Get load-based sampling. 1 decimal point precision.
|
||||
u32 avg_load = regs->avg_count / (ACTMON_FREQ / 1000);
|
||||
|
||||
return avg_load;
|
||||
}
|
||||
|
||||
void atmon_dev_all_disable()
|
||||
{
|
||||
// TODO: do a global reset?
|
||||
}
|
||||
|
||||
void actmon_init()
|
||||
{
|
||||
clock_enable_actmon();
|
||||
|
||||
// Set period to 200ms.
|
||||
ACTMON(ACTMON_GLB_PERIOD_CTRL) &= ~ACTMON_GLB_PERIOD_USEC;
|
||||
ACTMON(ACTMON_GLB_PERIOD_CTRL) |= ACTMON_GLB_PERIOD_SAMPLE(200);
|
||||
}
|
||||
|
||||
void actmon_end()
|
||||
{
|
||||
clock_disable_actmon();
|
||||
}
|
||||
62
bdk/soc/actmon.h
Normal file
62
bdk/soc/actmon.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Activity Monitor driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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 __ACTMON_H_
|
||||
#define __ACTMON_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
typedef enum _actmon_dev_t
|
||||
{
|
||||
ACTMON_DEV_CPU,
|
||||
ACTMON_DEV_BPMP,
|
||||
ACTMON_DEV_AHB,
|
||||
ACTMON_DEV_APB,
|
||||
ACTMON_DEV_CPU_FREQ,
|
||||
ACTMON_DEV_MC_ALL,
|
||||
ACTMON_DEV_MC_CPU,
|
||||
|
||||
ACTMON_DEV_NUM,
|
||||
} actmon_dev_t;
|
||||
|
||||
typedef enum _actmon_hist_src_t
|
||||
{
|
||||
ACTMON_HIST_SRC_NONE = 0,
|
||||
ACTMON_HIST_SRC_AHB = 1,
|
||||
ACTMON_HIST_SRC_APB = 2,
|
||||
ACTMON_HIST_SRC_BPMP = 3,
|
||||
ACTMON_HIST_SRC_CPU = 4,
|
||||
ACTMON_HIST_SRC_MC_ALL = 5,
|
||||
ACTMON_HIST_SRC_MC_CPU = 6,
|
||||
ACTMON_HIST_SRC_CPU_FREQ = 7,
|
||||
ACTMON_HIST_SRC_NA = 8,
|
||||
ACTMON_HIST_SRC_APB_MMIO = 9,
|
||||
} actmon_hist_src_t;
|
||||
|
||||
void actmon_hist_enable(actmon_hist_src_t src);
|
||||
void actmon_hist_disable();
|
||||
void actmon_hist_get(u32 *histogram);
|
||||
void actmon_dev_enable(actmon_dev_t dev);
|
||||
void actmon_dev_disable(actmon_dev_t dev);
|
||||
u32 actmon_dev_get_load(actmon_dev_t dev);
|
||||
u32 actmon_dev_get_load_avg(actmon_dev_t dev);
|
||||
void atmon_dev_all_disable();
|
||||
void actmon_init();
|
||||
void actmon_end();
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -18,9 +18,9 @@
|
||||
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <memory_map.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define BPMP_MMU_CACHE_LINE_SIZE 0x20
|
||||
|
||||
@@ -134,7 +134,7 @@ void bpmp_mmu_maintenance(u32 op, bool force)
|
||||
// This is a blocking operation.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MAINT_REQ) = MAINT_REQ_WAY_BITMAP(0xF) | op;
|
||||
|
||||
while(!(BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT) & INT_MAINT_DONE))
|
||||
while (!(BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT) & INT_MAINT_DONE))
|
||||
;
|
||||
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT);
|
||||
@@ -150,8 +150,8 @@ void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply)
|
||||
if (entry->enable)
|
||||
{
|
||||
mmu_entry->start_addr = ALIGN(entry->start_addr, BPMP_MMU_CACHE_LINE_SIZE);
|
||||
mmu_entry->end_addr = ALIGN_DOWN(entry->end_addr, BPMP_MMU_CACHE_LINE_SIZE);
|
||||
mmu_entry->attr = entry->attr;
|
||||
mmu_entry->end_addr = ALIGN_DOWN(entry->end_addr, BPMP_MMU_CACHE_LINE_SIZE);
|
||||
mmu_entry->attr = entry->attr;
|
||||
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) |= BIT(idx);
|
||||
|
||||
@@ -166,9 +166,9 @@ void bpmp_mmu_enable()
|
||||
return;
|
||||
|
||||
// Init BPMP MMU.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_INIT;
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_INIT;
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_FALLBACK_ENTRY) = MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC; // RWX for non-defined regions.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CFG) = MMU_CFG_SEQ_EN | MMU_CFG_TLB_EN | MMU_CFG_ABORT_STORE_LAST;
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CFG) = MMU_CFG_SEQ_EN | MMU_CFG_TLB_EN | MMU_CFG_ABORT_STORE_LAST;
|
||||
|
||||
// Init BPMP MMU entries.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) = 0;
|
||||
@@ -206,6 +206,7 @@ void bpmp_mmu_disable()
|
||||
const u8 pll_divn[] = {
|
||||
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
|
||||
85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB.
|
||||
88, // BPMP_CLK_HIGH2_BOOST: 563MHz 38% - 141MHz APB.
|
||||
90, // BPMP_CLK_SUPER_BOOST: 576MHz 41% - 144MHz APB.
|
||||
92 // BPMP_CLK_HYPER_BOOST: 589MHz 44% - 147MHz APB.
|
||||
// Do not use for public releases!
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -47,12 +47,14 @@ typedef enum
|
||||
{
|
||||
BPMP_CLK_NORMAL, // 408MHz 0% - 136MHz APB.
|
||||
BPMP_CLK_HIGH_BOOST, // 544MHz 33% - 136MHz APB.
|
||||
BPMP_CLK_HIGH2_BOOST, // 563MHz 38% - 141MHz APB.
|
||||
BPMP_CLK_SUPER_BOOST, // 576MHz 41% - 144MHz APB.
|
||||
BPMP_CLK_HYPER_BOOST, // 589MHz 44% - 147MHz APB.
|
||||
//BPMP_CLK_DEV_BOOST, // 608MHz 49% - 152MHz APB.
|
||||
BPMP_CLK_MAX
|
||||
} bpmp_freq_t;
|
||||
|
||||
#define BPMP_CLK_LOWEST_BOOST BPMP_CLK_HIGH2_BOOST
|
||||
#define BPMP_CLK_LOWER_BOOST BPMP_CLK_SUPER_BOOST
|
||||
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -15,6 +15,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <memory_map.h>
|
||||
#include <soc/ccplex.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/i2c.h>
|
||||
@@ -51,7 +52,7 @@ void _ccplex_enable_power_t210b01()
|
||||
void ccplex_boot_cpu0(u32 entry)
|
||||
{
|
||||
// Set ACTIVE_CLUSER to FAST.
|
||||
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE;
|
||||
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW;
|
||||
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
||||
_ccplex_enable_power_t210();
|
||||
@@ -62,12 +63,12 @@ void ccplex_boot_cpu0(u32 entry)
|
||||
|
||||
// Configure MSELECT source and enable clock to 102MHz.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_MSELECT);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_MSELECT);
|
||||
|
||||
// Configure initial CPU clock frequency and enable clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; // PLLX_OUT0_LJ.
|
||||
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
|
||||
|
||||
clock_enable_coresight();
|
||||
|
||||
@@ -81,9 +82,9 @@ void ccplex_boot_cpu0(u32 entry)
|
||||
// Enable CPU0 rail.
|
||||
pmc_enable_partition(POWER_RAIL_CE0, ENABLE);
|
||||
|
||||
// Request and wait for RAM repair.
|
||||
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1;
|
||||
while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & 2))
|
||||
// Request and wait for RAM repair. Needed for the Fast cluster.
|
||||
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = RAM_REPAIR_REQ;
|
||||
while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & RAM_REPAIR_STS))
|
||||
;
|
||||
|
||||
EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0;
|
||||
@@ -91,6 +92,7 @@ void ccplex_boot_cpu0(u32 entry)
|
||||
// Set reset vector.
|
||||
SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN;
|
||||
SB(SB_AA64_RESET_HIGH) = 0;
|
||||
|
||||
// Non-secure reset vector write disable.
|
||||
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
|
||||
(void)SB(SB_CSR);
|
||||
@@ -99,7 +101,7 @@ void ccplex_boot_cpu0(u32 entry)
|
||||
// MC(MC_TZ_SECURITY_CTRL) = 1;
|
||||
|
||||
// Clear MSELECT reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT);
|
||||
// Clear NONCPU reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;
|
||||
// Clear CPU0 reset.
|
||||
|
||||
202
bdk/soc/clock.c
202
bdk/soc/clock.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -17,9 +17,10 @@
|
||||
|
||||
#include <soc/clock.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
typedef struct _clock_osc_t
|
||||
{
|
||||
@@ -59,46 +60,65 @@ static const clock_t _clock_i2c[] = {
|
||||
};
|
||||
|
||||
static clock_t _clock_se = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, 0 // 408MHz.
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, 0 // 408MHz. Default: 408MHz. Max: 627.2 MHz.
|
||||
};
|
||||
|
||||
static clock_t _clock_tzram = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, 0
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, 0
|
||||
};
|
||||
|
||||
static clock_t _clock_host1x = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, 3 // 163.2MHz.
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, 3 // 163.2MHz. Max: 408MHz.
|
||||
};
|
||||
static clock_t _clock_tsec = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, 2 // 204MHz.
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, 2 // 204MHz. Max: 408MHz.
|
||||
};
|
||||
static clock_t _clock_nvdec = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, 0 // 408 MHz. Max: 716.8/979.2MHz.
|
||||
};
|
||||
static clock_t _clock_nvjpg = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, 0 // 408 MHz. Max: 627.2/652.8MHz.
|
||||
};
|
||||
static clock_t _clock_vic = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, 0 // 408 MHz. Max: 627.2/652.8MHz.
|
||||
};
|
||||
static clock_t _clock_sor_safe = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0
|
||||
};
|
||||
static clock_t _clock_sor0 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, 0
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, 0
|
||||
};
|
||||
static clock_t _clock_sor1 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, 2 //204MHz.
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, 2 // 204MHz.
|
||||
};
|
||||
static clock_t _clock_kfuse = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, 0
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, 0
|
||||
};
|
||||
|
||||
static clock_t _clock_cl_dvfs = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, 0
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, 0
|
||||
};
|
||||
static clock_t _clock_coresight = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, 4 // 136MHz.
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, 4 // 136MHz.
|
||||
};
|
||||
|
||||
static clock_t _clock_pwm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, 4 // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, 4 // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
|
||||
};
|
||||
|
||||
static clock_t _clock_sdmmc_legacy_tm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, 66
|
||||
};
|
||||
static clock_t _clock_apbdma = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_APBDMA, 0, 0 // Max: 204MHz.
|
||||
};
|
||||
static clock_t _clock_ahbdma = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, 0
|
||||
};
|
||||
static clock_t _clock_actmon = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, 0 // 19.2MHz.
|
||||
};
|
||||
static clock_t _clock_extperiph1 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, 0
|
||||
};
|
||||
static clock_t _clock_extperiph2 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, 202 // 4.0MHz
|
||||
};
|
||||
|
||||
void clock_enable(const clock_t *clk)
|
||||
{
|
||||
@@ -147,7 +167,9 @@ int clock_uart_use_src_div(u32 idx, u32 baud)
|
||||
{
|
||||
u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000;
|
||||
|
||||
if (baud == 1000000)
|
||||
if (baud == 3000000)
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 15;
|
||||
else if (baud == 1000000)
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 49;
|
||||
else
|
||||
{
|
||||
@@ -203,6 +225,36 @@ void clock_disable_tsec()
|
||||
clock_disable(&_clock_tsec);
|
||||
}
|
||||
|
||||
void clock_enable_nvdec()
|
||||
{
|
||||
clock_enable(&_clock_nvdec);
|
||||
}
|
||||
|
||||
void clock_disable_nvdec()
|
||||
{
|
||||
clock_disable(&_clock_nvdec);
|
||||
}
|
||||
|
||||
void clock_enable_nvjpg()
|
||||
{
|
||||
clock_enable(&_clock_nvjpg);
|
||||
}
|
||||
|
||||
void clock_disable_nvjpg()
|
||||
{
|
||||
clock_disable(&_clock_nvjpg);
|
||||
}
|
||||
|
||||
void clock_enable_vic()
|
||||
{
|
||||
clock_enable(&_clock_vic);
|
||||
}
|
||||
|
||||
void clock_disable_vic()
|
||||
{
|
||||
clock_disable(&_clock_vic);
|
||||
}
|
||||
|
||||
void clock_enable_sor_safe()
|
||||
{
|
||||
clock_enable(&_clock_sor_safe);
|
||||
@@ -279,6 +331,86 @@ void clock_disable_pwm()
|
||||
clock_disable(&_clock_pwm);
|
||||
}
|
||||
|
||||
void clock_enable_apbdma()
|
||||
{
|
||||
clock_enable(&_clock_apbdma);
|
||||
}
|
||||
|
||||
void clock_disable_apbdma()
|
||||
{
|
||||
clock_disable(&_clock_apbdma);
|
||||
}
|
||||
|
||||
void clock_enable_ahbdma()
|
||||
{
|
||||
clock_enable(&_clock_ahbdma);
|
||||
}
|
||||
|
||||
void clock_disable_ahbdma()
|
||||
{
|
||||
clock_disable(&_clock_ahbdma);
|
||||
}
|
||||
|
||||
void clock_enable_actmon()
|
||||
{
|
||||
clock_enable(&_clock_actmon);
|
||||
}
|
||||
|
||||
void clock_disable_actmon()
|
||||
{
|
||||
clock_disable(&_clock_actmon);
|
||||
}
|
||||
|
||||
void clock_enable_extperiph1()
|
||||
{
|
||||
clock_enable(&_clock_extperiph1);
|
||||
|
||||
PMC(APBDEV_PMC_CLK_OUT_CNTRL) |= PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(OSC_CAR) | PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN;
|
||||
usleep(5);
|
||||
}
|
||||
|
||||
void clock_disable_extperiph1()
|
||||
{
|
||||
PMC(APBDEV_PMC_CLK_OUT_CNTRL) &= ~((PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(OSC_CAR)) | PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN);
|
||||
clock_disable(&_clock_extperiph1);
|
||||
}
|
||||
|
||||
void clock_enable_extperiph2()
|
||||
{
|
||||
clock_enable(&_clock_extperiph2);
|
||||
|
||||
PMC(APBDEV_PMC_CLK_OUT_CNTRL) |= PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(OSC_CAR) | PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN;
|
||||
usleep(5);
|
||||
}
|
||||
|
||||
void clock_disable_extperiph2()
|
||||
{
|
||||
PMC(APBDEV_PMC_CLK_OUT_CNTRL) &= ~((PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(OSC_CAR)) | PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN);
|
||||
clock_disable(&_clock_extperiph2);
|
||||
}
|
||||
|
||||
void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210)
|
||||
{
|
||||
u32 plld_div = (divp << 20) | (divn << 11) | 1;
|
||||
|
||||
// N divider is fractional, so N = DIVN + 1/2 + PLLD_SDM_DIN/8192.
|
||||
u32 misc = 0x2D0000 | 0xFC00; // Clock enable and PLLD_SDM_DIN: -1024 -> DIVN + 0.375.
|
||||
if (lowpower && tegra_t210)
|
||||
misc = 0x2D0000 | 0x0AAA; // Clock enable and PLLD_SDM_DIN: 2730 -> DIVN + 0.833.
|
||||
|
||||
|
||||
// Set DISP1 clock source and parent clock.
|
||||
if (lowpower)
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 0x40000000; // PLLD_OUT0.
|
||||
|
||||
// Set dividers and enable PLLD.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = tegra_t210 ? 0x20 : 0; // Keep default PLLD_SETUP.
|
||||
|
||||
// Set PLLD_SDM_DIN and enable PLLD to DSI pads.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = misc;
|
||||
}
|
||||
|
||||
void clock_enable_pllx()
|
||||
{
|
||||
// Configure and enable PLLX if disabled.
|
||||
@@ -315,7 +447,7 @@ void clock_enable_pllc(u32 divn)
|
||||
|
||||
// Take PLLC out of reset and set basic misc parameters.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) =
|
||||
((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x80000 << 4); // PLLC_EXT_FRU.
|
||||
((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x8000 << 4); // PLLC_EXT_FRU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) |= 0xF0 << 8; // PLLC_FLL_LD_MEM.
|
||||
|
||||
// Disable PLL and IDDQ in case they are on.
|
||||
@@ -342,11 +474,11 @@ void clock_enable_pllc(u32 divn)
|
||||
void clock_disable_pllc()
|
||||
{
|
||||
// Disable PLLC and PLLC_OUT1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~(PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR);
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~PLLC_OUT1_RSTN_CLR;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) = PLLC_MISC_RESET;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLLCX_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) |= PLLCX_BASE_REF_DIS;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) |= PLLC_MISC1_IDDQ;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) |= PLLC_MISC_RESET;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) &= ~(0xFF << 8); // PLLC_FLL_LD_MEM.
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
@@ -409,9 +541,9 @@ void clock_enable_pllu()
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | PLLCX_BASE_ENABLE; // Enable.
|
||||
|
||||
// Wait for PLL to stabilize.
|
||||
u32 timeout = (u32)TMR(TIMERUS_CNTR_1US) + 1300;
|
||||
u32 timeout = get_tmr_us() + 1300;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & PLLCX_BASE_LOCK)) // PLL_LOCK.
|
||||
if ((u32)TMR(TIMERUS_CNTR_1US) > timeout)
|
||||
if (get_tmr_us() > timeout)
|
||||
break;
|
||||
usleep(10);
|
||||
|
||||
@@ -421,9 +553,9 @@ void clock_enable_pllu()
|
||||
|
||||
void clock_disable_pllu()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x2E00000; // Disable PLLU USB/HSIC/ICUSB/48M.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x40000000; // Disable PLLU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) &= ~0x20000000; // Enable reference clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x2E00000; // Disable PLLU USB/HSIC/ICUSB/48M.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~BIT(30); // Disable PLLU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) &= ~BIT(29); // Enable reference clock.
|
||||
}
|
||||
|
||||
void clock_enable_utmipll()
|
||||
@@ -588,10 +720,6 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
*pclock = 25500;
|
||||
divisor = 30; // 16 div.
|
||||
break;
|
||||
case 40800:
|
||||
*pclock = 40800;
|
||||
divisor = 18; // 10 div.
|
||||
break;
|
||||
case 50000:
|
||||
*pclock = 48000;
|
||||
divisor = 15; // 8.5 div.
|
||||
@@ -600,6 +728,10 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
*pclock = 51000;
|
||||
divisor = 14; // 8 div.
|
||||
break;
|
||||
case 81600: // Originally MMC_HS50 for GC FPGA at 40800 KHz, div 18 (real 10).
|
||||
*pclock = 81600;
|
||||
divisor = 8; // 5 div.
|
||||
break;
|
||||
case 100000:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||
*pclock = 99840;
|
||||
@@ -727,10 +859,10 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type)
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case SDHCI_TIMING_UHS_DDR50:
|
||||
*pclock = 40800;
|
||||
*pdivisor = 1;
|
||||
*pclock = 81600; // Originally MMC_HS50 for GC FPGA at 40800 KHz, div 1.
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
case SDHCI_TIMING_MMC_HS102: // Actual IO Freq: 99.84 MHz.
|
||||
case SDHCI_TIMING_MMC_DDR100: // Actual IO Freq: 99.84 MHz.
|
||||
*pclock = 200000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -117,7 +117,10 @@
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD 0x3A4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT 0x3B4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C4 0x3C4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_AHUB 0x3D0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON 0x3E8
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1 0x3EC
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2 0x3F0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SYS 0x400
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C
|
||||
@@ -153,8 +156,12 @@
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL 0x66C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_VIC 0x678
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC 0x698
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG 0x69C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC 0x6A0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_APE 0x6C0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK 0x6CC
|
||||
#define CLK_RST_CONTROLLER_SE_SUPER_CLK_DIVIDER 0x704
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE 0x710
|
||||
@@ -645,6 +652,12 @@ void clock_enable_host1x();
|
||||
void clock_disable_host1x();
|
||||
void clock_enable_tsec();
|
||||
void clock_disable_tsec();
|
||||
void clock_enable_nvdec();
|
||||
void clock_disable_nvdec();
|
||||
void clock_enable_nvjpg();
|
||||
void clock_disable_nvjpg();
|
||||
void clock_enable_vic();
|
||||
void clock_disable_vic();
|
||||
void clock_enable_sor_safe();
|
||||
void clock_disable_sor_safe();
|
||||
void clock_enable_sor0();
|
||||
@@ -659,12 +672,25 @@ void clock_enable_coresight();
|
||||
void clock_disable_coresight();
|
||||
void clock_enable_pwm();
|
||||
void clock_disable_pwm();
|
||||
void clock_enable_apbdma();
|
||||
void clock_disable_apbdma();
|
||||
void clock_enable_ahbdma();
|
||||
void clock_disable_ahbdma();
|
||||
void clock_enable_actmon();
|
||||
void clock_disable_actmon();
|
||||
void clock_enable_extperiph1();
|
||||
void clock_disable_extperiph1();
|
||||
void clock_enable_extperiph2();
|
||||
void clock_disable_extperiph2();
|
||||
|
||||
void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210);
|
||||
void clock_enable_pllx();
|
||||
void clock_enable_pllc(u32 divn);
|
||||
void clock_disable_pllc();
|
||||
void clock_enable_pllu();
|
||||
void clock_disable_pllu();
|
||||
void clock_enable_utmipll();
|
||||
|
||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 val);
|
||||
void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type);
|
||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
||||
|
||||
119
bdk/soc/fuse.c
119
bdk/soc/fuse.c
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 shuffle2
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <mem/heap.h>
|
||||
#include <sec/se.h>
|
||||
#include <sec/se_t210.h>
|
||||
#include <soc/fuse.h>
|
||||
@@ -26,8 +27,6 @@
|
||||
#include <soc/t210.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
extern boot_cfg_t b_cfg;
|
||||
|
||||
static const u32 evp_thunk_template[] = {
|
||||
0xe92d0007, // STMFD SP!, {R0-R2}
|
||||
0xe1a0200e, // MOV R2, LR
|
||||
@@ -44,12 +43,19 @@ static const u32 evp_thunk_template[] = {
|
||||
0xe3822001, // ORR R2, R2, #1
|
||||
0xe8bd0003, // LDMFD SP!, {R0,R1}
|
||||
0xe12fff12, // BX R2
|
||||
// idx: 15:
|
||||
0x001007b0, // off_1007EC DCD evp_thunk_template
|
||||
0x001007f8, // off_1007F0 DCD thunk_end
|
||||
0x40004c30, // off_1007F4 DCD iram_evp_thunks
|
||||
// thunk_end is here
|
||||
};
|
||||
static const u32 evp_thunk_template_len = sizeof(evp_thunk_template);
|
||||
|
||||
static const u32 evp_thunk_func_offsets_t210b01[] = {
|
||||
0x0010022c, // off_100268 DCD evp_thunk_template
|
||||
0x00100174, // off_10026C DCD thunk_end
|
||||
0x40004164, // off_100270 DCD iram_evp_thunks
|
||||
// thunk_end is here
|
||||
};
|
||||
|
||||
// treated as 12bit values
|
||||
static const u32 hash_vals[] = {1, 2, 4, 8, 0, 3, 5, 6, 7, 9, 10, 11};
|
||||
@@ -82,19 +88,26 @@ u32 fuse_read_odm_keygen_rev()
|
||||
|
||||
u32 fuse_read_dramid(bool raw_id)
|
||||
{
|
||||
u32 dramid = (fuse_read_odm(4) & 0xF8) >> 3;
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
u32 odm4 = fuse_read_odm(4);
|
||||
|
||||
u32 dramid = (odm4 & 0xF8) >> 3;
|
||||
|
||||
// Get extended dram id info.
|
||||
if (!tegra_t210)
|
||||
dramid |= (odm4 & 0x7000) >> 7;
|
||||
|
||||
if (raw_id)
|
||||
return dramid;
|
||||
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
||||
if (tegra_t210)
|
||||
{
|
||||
if (dramid > 6)
|
||||
dramid = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dramid > 28)
|
||||
if (dramid > 34)
|
||||
dramid = 8;
|
||||
}
|
||||
|
||||
@@ -130,9 +143,7 @@ u32 fuse_read_hw_type()
|
||||
|
||||
int fuse_set_sbk()
|
||||
{
|
||||
// Skip SBK/SSK if sept was run.
|
||||
bool sbk_skip = b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN || FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF;
|
||||
if (!sbk_skip)
|
||||
if (FUSE(FUSE_PRIVATE_KEY0) != 0xFFFFFFFF)
|
||||
{
|
||||
// Read SBK from fuses.
|
||||
u32 sbk[4] = {
|
||||
@@ -174,7 +185,8 @@ u32 fuse_read(u32 addr)
|
||||
|
||||
void fuse_read_array(u32 *words)
|
||||
{
|
||||
u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ? 256 : 192;
|
||||
u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ?
|
||||
FUSE_ARRAY_WORDS_NUM_T210B01 : FUSE_ARRAY_WORDS_NUM;
|
||||
|
||||
for (u32 i = 0; i < array_size; i++)
|
||||
words[i] = fuse_read(i);
|
||||
@@ -184,9 +196,8 @@ static u32 _parity32_even(u32 *words, u32 count)
|
||||
{
|
||||
u32 acc = words[0];
|
||||
for (u32 i = 1; i < count; i++)
|
||||
{
|
||||
acc ^= words[i];
|
||||
}
|
||||
|
||||
u32 lo = ((acc & 0xffff) ^ (acc >> 16)) & 0xff;
|
||||
u32 hi = ((acc & 0xffff) ^ (acc >> 16)) >> 8;
|
||||
u32 x = hi ^ lo;
|
||||
@@ -202,26 +213,26 @@ static int _patch_hash_one(u32 *word)
|
||||
u32 bits20_31 = *word & 0xfff00000;
|
||||
u32 parity_bit = _parity32_even(&bits20_31, 1);
|
||||
u32 hash = 0;
|
||||
|
||||
for (u32 i = 0; i < 12; i++)
|
||||
{
|
||||
if (*word & (1 << (20 + i)))
|
||||
{
|
||||
hash ^= hash_vals[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (hash == 0)
|
||||
{
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
*word ^= 1 << 24;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < ARRAY_SIZE(hash_vals); i++)
|
||||
{
|
||||
if (hash_vals[i] == hash)
|
||||
@@ -230,6 +241,7 @@ static int _patch_hash_one(u32 *word)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -250,9 +262,7 @@ static int _patch_hash_multi(u32 *words, u32 count)
|
||||
for (u32 bitpos = 0; bitpos < 32; bitpos++)
|
||||
{
|
||||
if ((w >> bitpos) & 1)
|
||||
{
|
||||
hash ^= 0x4000 + i * 32 + bitpos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,16 +274,14 @@ static int _patch_hash_multi(u32 *words, u32 count)
|
||||
if (hash == 0)
|
||||
{
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
words[0] ^= 0x8000;
|
||||
return 1;
|
||||
}
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
u32 bitcount = hash - 0x4000;
|
||||
if (bitcount < 16 || bitcount >= count * 32)
|
||||
{
|
||||
@@ -281,14 +289,11 @@ static int _patch_hash_multi(u32 *words, u32 count)
|
||||
for (u32 bitpos = 0; bitpos < 15; bitpos++)
|
||||
{
|
||||
if ((hash >> bitpos) & 1)
|
||||
{
|
||||
num_set++;
|
||||
}
|
||||
}
|
||||
if (num_set != 1)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
words[0] ^= hash;
|
||||
return 1;
|
||||
}
|
||||
@@ -306,24 +311,30 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
|
||||
|
||||
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
||||
word_count &= 0x7F;
|
||||
word_addr = 191;
|
||||
word_addr = FUSE_ARRAY_WORDS_NUM - 1;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
total_read += word_count;
|
||||
if (total_read >= ARRAY_SIZE(words))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < word_count; i++)
|
||||
{
|
||||
words[i] = fuse_read(word_addr--);
|
||||
// Parse extra T210B01 fuses when the difference is reached.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
|
||||
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
|
||||
(FUSE_ARRAY_WORDS_NUM_T210B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
|
||||
{
|
||||
word_addr = FUSE_ARRAY_WORDS_NUM_T210B01 - 1;
|
||||
}
|
||||
}
|
||||
|
||||
word0 = words[0];
|
||||
if (_patch_hash_multi(words, word_count) >= 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 ipatch_count = (words[0] >> 16) & 0xF;
|
||||
if (ipatch_count)
|
||||
{
|
||||
@@ -336,13 +347,14 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
|
||||
ipatch(addr, data);
|
||||
}
|
||||
}
|
||||
|
||||
words[0] = word0;
|
||||
if ((word0 >> 25) == 0)
|
||||
break;
|
||||
|
||||
if (_patch_hash_one(&word0) >= 2)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
word_count = word0 >> 25;
|
||||
}
|
||||
|
||||
@@ -358,29 +370,44 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
||||
u32 total_read = 0;
|
||||
int evp_thunk_written = 0;
|
||||
void *evp_thunk_dst_addr = 0;
|
||||
bool t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01;
|
||||
u32 *evp_thunk_tmp = (u32 *)malloc(sizeof(evp_thunk_template));
|
||||
|
||||
memcpy(evp_thunk_tmp, evp_thunk_template, sizeof(evp_thunk_template));
|
||||
memset(iram_evp_thunks, 0, *iram_evp_thunks_len);
|
||||
|
||||
if (t210b01)
|
||||
memcpy(&evp_thunk_tmp[15], evp_thunk_func_offsets_t210b01, sizeof(evp_thunk_func_offsets_t210b01));
|
||||
|
||||
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
||||
word_count &= 0x7F;
|
||||
word_addr = 191;
|
||||
word_addr = FUSE_ARRAY_WORDS_NUM - 1;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
total_read += word_count;
|
||||
if (total_read >= ARRAY_SIZE(words))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < word_count; i++)
|
||||
{
|
||||
words[i] = fuse_read(word_addr--);
|
||||
// Parse extra T210B01 fuses when the difference is reached.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
|
||||
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
|
||||
(FUSE_ARRAY_WORDS_NUM_T210B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
|
||||
{
|
||||
word_addr = FUSE_ARRAY_WORDS_NUM_T210B01 - 1;
|
||||
}
|
||||
}
|
||||
|
||||
word0 = words[0];
|
||||
if (_patch_hash_multi(words, word_count) >= 2)
|
||||
{
|
||||
free(evp_thunk_tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 ipatch_count = (words[0] >> 16) & 0xF;
|
||||
u32 insn_count = word_count - ipatch_count - 1;
|
||||
if (insn_count)
|
||||
@@ -389,10 +416,10 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
||||
{
|
||||
evp_thunk_dst_addr = (void *)iram_evp_thunks;
|
||||
|
||||
memcpy(evp_thunk_dst_addr, (void *)evp_thunk_template, evp_thunk_template_len);
|
||||
evp_thunk_dst_addr += evp_thunk_template_len;
|
||||
memcpy(evp_thunk_dst_addr, (void *)evp_thunk_tmp, sizeof(evp_thunk_template));
|
||||
evp_thunk_dst_addr += sizeof(evp_thunk_template);
|
||||
evp_thunk_written = 1;
|
||||
*iram_evp_thunks_len = evp_thunk_template_len;
|
||||
*iram_evp_thunks_len = sizeof(evp_thunk_template);
|
||||
|
||||
//write32(TEGRA_EXCEPTION_VECTORS_BASE + 0x208, iram_evp_thunks);
|
||||
}
|
||||
@@ -402,16 +429,22 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
||||
evp_thunk_dst_addr += thunk_patch_len;
|
||||
*iram_evp_thunks_len += thunk_patch_len;
|
||||
}
|
||||
|
||||
words[0] = word0;
|
||||
if ((word0 >> 25) == 0)
|
||||
break;
|
||||
|
||||
if (_patch_hash_one(&word0) >= 2)
|
||||
{
|
||||
free(evp_thunk_tmp);
|
||||
return 3;
|
||||
}
|
||||
|
||||
word_count = word0 >> 25;
|
||||
}
|
||||
|
||||
free(evp_thunk_tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -423,7 +456,7 @@ bool fuse_check_patched_rcm()
|
||||
|
||||
// Check if RCM is ipatched.
|
||||
u32 word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE) & 0x7F;
|
||||
u32 word_addr = 191;
|
||||
u32 word_addr = FUSE_ARRAY_WORDS_NUM - 1;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 shuffle2
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -37,6 +37,8 @@
|
||||
#define FUSE_DISABLEREGPROGRAM 0x2C
|
||||
#define FUSE_WRITE_ACCESS_SW 0x30
|
||||
#define FUSE_PWR_GOOD_SW 0x34
|
||||
|
||||
/*! Fuse Cached registers */
|
||||
#define FUSE_SKU_INFO 0x110
|
||||
#define FUSE_CPU_SPEEDO_0_CALIB 0x114
|
||||
#define FUSE_CPU_IDDQ_CALIB 0x118
|
||||
@@ -64,8 +66,10 @@
|
||||
#define FUSE_OPT_WAFER_ID 0x210
|
||||
#define FUSE_OPT_X_COORDINATE 0x214
|
||||
#define FUSE_OPT_Y_COORDINATE 0x218
|
||||
#define FUSE_OPT_OPS_RESERVED 0x220
|
||||
#define FUSE_GPU_IDDQ_CALIB 0x228
|
||||
#define FUSE_USB_CALIB_EXT 0x350
|
||||
#define FUSE_RESERVED_FIELD 0x354
|
||||
|
||||
#define FUSE_RESERVED_ODM28_T210B01 0x240
|
||||
|
||||
@@ -78,12 +82,15 @@
|
||||
/*! Fuse cache registers. */
|
||||
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
|
||||
|
||||
#define FUSE_ARRAY_WORDS_NUM 192
|
||||
#define FUSE_ARRAY_WORDS_NUM_T210B01 256
|
||||
|
||||
enum
|
||||
{
|
||||
FUSE_NX_HW_TYPE_ICOSA,
|
||||
FUSE_NX_HW_TYPE_IOWA,
|
||||
FUSE_NX_HW_TYPE_HOAG,
|
||||
FUSE_NX_HW_TYPE_AULA
|
||||
FUSE_NX_HW_TYPE_AULA
|
||||
};
|
||||
|
||||
enum
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -86,6 +86,19 @@ void gpio_write(u32 port, u32 pins, int high)
|
||||
(void)GPIO(port_offset); // Commit the write.
|
||||
}
|
||||
|
||||
void gpio_direction_input(u32 port, u32 pins)
|
||||
{
|
||||
gpio_output_enable(port, pins, GPIO_OUTPUT_DISABLE);
|
||||
gpio_config(port, pins, GPIO_MODE_GPIO);
|
||||
}
|
||||
|
||||
void gpio_direction_output(u32 port, u32 pins, int high)
|
||||
{
|
||||
gpio_output_enable(port, pins, GPIO_OUTPUT_ENABLE);
|
||||
gpio_config(port, pins, GPIO_MODE_GPIO);
|
||||
gpio_write(port, pins, high);
|
||||
}
|
||||
|
||||
int gpio_read(u32 port, u32 pins)
|
||||
{
|
||||
u32 port_offset = GPIO_IN_OFFSET(port);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -85,6 +85,8 @@
|
||||
|
||||
void gpio_config(u32 port, u32 pins, int mode);
|
||||
void gpio_output_enable(u32 port, u32 pins, int enable);
|
||||
void gpio_direction_input(u32 port, u32 pins);
|
||||
void gpio_direction_output(u32 port, u32 pins, int high);
|
||||
void gpio_write(u32 port, u32 pins, int high);
|
||||
int gpio_read(u32 port, u32 pins);
|
||||
int gpio_interrupt_status(u32 port, u32 pins);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <soc/hw_init.h>
|
||||
#include <display/di.h>
|
||||
#include <display/vic.h>
|
||||
#include <input/joycon.h>
|
||||
#include <input/touch.h>
|
||||
#include <sec/se.h>
|
||||
@@ -31,6 +32,7 @@
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/uart.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <mem/mc.h>
|
||||
#include <mem/minerva.h>
|
||||
@@ -39,7 +41,7 @@
|
||||
#include <power/max77620.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <power/regulator_5v.h>
|
||||
#include <storage/nx_sd.h>
|
||||
#include <storage/sd.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <thermal/fan.h>
|
||||
#include <thermal/tmp451.h>
|
||||
@@ -71,24 +73,24 @@ u32 hw_get_chip_id()
|
||||
static void _config_oscillators()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2.
|
||||
SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
|
||||
TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
|
||||
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength.
|
||||
SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
|
||||
TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
|
||||
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength.
|
||||
|
||||
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE; // Set LP0 OSC drive strength.
|
||||
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | PMC_OSC_EDPD_OVER_OSC_CTRL_OVER;
|
||||
PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
|
||||
PMC(APBDEV_PMC_SCRATCH188) = (PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF) | (4 << 23); // LP0 EMC2TMC_CFG_XM2COMP_PU_VREF_SEL_RANGE.
|
||||
PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
|
||||
PMC(APB_MISC_GP_ASDBGREG) = (PMC(APB_MISC_GP_ASDBGREG) & 0xFCFFFFFF) | (2 << 24); // CFG2TMC_RAM_SVOP_PDP.
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
|
||||
|
||||
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; // Enable SUPER_SDIV to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
|
||||
}
|
||||
|
||||
// The uart is skipped for Copper, Hoag and Calcio. Used in Icosa, Iowa and Aula.
|
||||
@@ -99,53 +101,39 @@ static void _config_gpios(bool nx_hoag)
|
||||
|
||||
if (!nx_hoag)
|
||||
{
|
||||
// Turn Joy-Con detect on. (GPIO mode and input logic for UARTB/C TX pins.)
|
||||
PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
|
||||
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
|
||||
|
||||
// Set pin mode for UARTB/C TX pins.
|
||||
#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
#endif
|
||||
#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_C
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
#endif
|
||||
|
||||
// Enable input logic for UARTB/C TX pins.
|
||||
gpio_output_enable(GPIO_PORT_G, GPIO_PIN_0, GPIO_OUTPUT_DISABLE);
|
||||
gpio_output_enable(GPIO_PORT_D, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);
|
||||
gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0);
|
||||
gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1);
|
||||
}
|
||||
|
||||
// Set Joy-Con IsAttached direction.
|
||||
// Set Joy-Con IsAttached pinmux. Shared with UARTB/UARTC TX.
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
|
||||
// Set Joy-Con IsAttached mode.
|
||||
gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO);
|
||||
gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO);
|
||||
|
||||
// Enable input logic for Joy-Con IsAttached pins.
|
||||
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
|
||||
gpio_output_enable(GPIO_PORT_H, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
|
||||
// Configure Joy-Con IsAttached pins. Shared with UARTB/UARTC TX.
|
||||
gpio_direction_input(GPIO_PORT_E, GPIO_PIN_6);
|
||||
gpio_direction_input(GPIO_PORT_H, GPIO_PIN_6);
|
||||
|
||||
pinmux_config_i2c(I2C_1);
|
||||
pinmux_config_i2c(I2C_5);
|
||||
pinmux_config_uart(UART_A);
|
||||
|
||||
// Configure volume up/down as inputs.
|
||||
gpio_config(GPIO_PORT_X, GPIO_PIN_6, GPIO_MODE_GPIO);
|
||||
gpio_config(GPIO_PORT_X, GPIO_PIN_7, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_X, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
|
||||
gpio_output_enable(GPIO_PORT_X, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
|
||||
gpio_direction_input(GPIO_PORT_X, GPIO_PIN_6 | GPIO_PIN_7);
|
||||
|
||||
// Configure HOME as inputs.
|
||||
// PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
// gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
// Configure HOME as input. (Shared with UARTB RTS).
|
||||
PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
gpio_direction_input(GPIO_PORT_Y, GPIO_PIN_1);
|
||||
|
||||
// Power button can be configured for hoag here. Only SKU where it's connected.
|
||||
}
|
||||
|
||||
static void _config_pmc_scratch()
|
||||
{
|
||||
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; // Unset Debug console from Customer Option.
|
||||
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset DATA_DQ_E_IVREF EMC_PMACRO_DATA_PAD_TX_CTRL
|
||||
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset WDT_DURING_BR.
|
||||
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
|
||||
}
|
||||
|
||||
@@ -178,8 +166,9 @@ static void _mbist_workaround()
|
||||
I2S(I2S5_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S5_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
|
||||
// Set SLCG overrides.
|
||||
DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= 4; // DSC_SLCG_OVERRIDE.
|
||||
VIC(0x8C) = 0xFFFFFFFF;
|
||||
VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0xFFFFFFFF;
|
||||
usleep(2);
|
||||
|
||||
// Set per-clock reset for APE/VIC/HOST1X/DISP1.
|
||||
@@ -246,9 +235,9 @@ static void _mbist_workaround()
|
||||
// Set child clock sources.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF; // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
}
|
||||
|
||||
static void _config_se_brom()
|
||||
@@ -263,7 +252,7 @@ static void _config_se_brom()
|
||||
// se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
||||
|
||||
// This memset needs to happen here, else TZRAM will behave weirdly later on.
|
||||
memset((void *)TZRAM_BASE, 0, SZ_64K);
|
||||
memset((void *)TZRAM_BASE, 0, TZRAM_SIZE);
|
||||
PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE;
|
||||
SE(SE_INT_STATUS_REG) = 0x1F; // Clear all SE interrupts.
|
||||
|
||||
@@ -291,6 +280,9 @@ static void _config_regulators(bool tegra_t210)
|
||||
max7762x_regulator_enable(REGULATOR_LDO2, false);
|
||||
sd_power_cycle_time_start = get_tmr_ms();
|
||||
|
||||
// Disable LCD DVDD.
|
||||
max7762x_regulator_enable(REGULATOR_LDO0, false);
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
|
||||
MAX77620_ONOFFCNFG1_RSVD | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
|
||||
@@ -327,7 +319,7 @@ static void _config_regulators(bool tegra_t210)
|
||||
|
||||
void hw_init()
|
||||
{
|
||||
// Get Chip ID.
|
||||
// Get Chip ID and SKU.
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
|
||||
|
||||
@@ -360,8 +352,14 @@ void hw_init()
|
||||
_config_gpios(nx_hoag);
|
||||
|
||||
#ifdef DEBUG_UART_PORT
|
||||
#if (DEBUG_UART_PORT == UART_B)
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
#elif (DEBUG_UART_PORT == UART_C)
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
#endif
|
||||
pinmux_config_uart(DEBUG_UART_PORT);
|
||||
clock_enable_uart(DEBUG_UART_PORT);
|
||||
uart_init(DEBUG_UART_PORT, DEBUG_UART_BAUDRATE);
|
||||
uart_init(DEBUG_UART_PORT, DEBUG_UART_BAUDRATE, UART_AO_TX_AO_RX);
|
||||
uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD);
|
||||
#endif
|
||||
|
||||
@@ -378,7 +376,7 @@ void hw_init()
|
||||
// Initialize I2C5, mandatory for PMIC.
|
||||
i2c_init(I2C_5);
|
||||
|
||||
//! TODO: Why? Device is NFC MCU on Lite.
|
||||
// Enable LDO8 on HOAG as it also powers I2C1 IO pads.
|
||||
if (nx_hoag)
|
||||
{
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO8, 2800000);
|
||||
@@ -391,35 +389,38 @@ void hw_init()
|
||||
// Initialize various regulators based on Erista/Mariko platform.
|
||||
_config_regulators(tegra_t210);
|
||||
|
||||
// Enable charger in case it's disabled.
|
||||
bq24193_enable_charger();
|
||||
|
||||
_config_pmc_scratch(); // Missing from 4.x+
|
||||
|
||||
// Set BPMP/SCLK to PLLP_OUT (408MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333;
|
||||
|
||||
// Disable TZRAM shutdown control and lock the regs.
|
||||
// Power on T210B01 shadow TZRAM and lock the reg.
|
||||
if (!tegra_t210)
|
||||
{
|
||||
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= 0xFFFFFFFE;
|
||||
PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = 3;
|
||||
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = 3;
|
||||
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= ~PMC_TZRAM_PWR_CNTRL_SD;
|
||||
PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
}
|
||||
|
||||
// Initialize External memory controller and configure DRAM parameters.
|
||||
sdram_init();
|
||||
|
||||
bpmp_mmu_enable();
|
||||
|
||||
// Enable HOST1X used by every display module (DC, VIC, NVDEC, NVENC, TSEC, etc).
|
||||
clock_enable_host1x();
|
||||
}
|
||||
|
||||
void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
||||
{
|
||||
// Disable BPMP max clock.
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
|
||||
// Scale down BPMP clock.
|
||||
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||
|
||||
#ifdef NYX
|
||||
// Disable temperature sensor, touchscreen, 5V regulators and Joy-Con.
|
||||
#ifdef BDK_HW_EXTRA_DEINIT
|
||||
// Disable temperature sensor, touchscreen, 5V regulators, Joy-Con and VIC.
|
||||
vic_end();
|
||||
tmp451_end();
|
||||
set_fan_duty(0);
|
||||
touch_power_off();
|
||||
@@ -427,14 +428,19 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
||||
regulator_5v_disable(REGULATOR_5V_ALL);
|
||||
#endif
|
||||
|
||||
// Flush/disable MMU cache and set DRAM clock to 204MHz.
|
||||
bpmp_mmu_disable();
|
||||
// set DRAM clock to 204MHz.
|
||||
minerva_change_freq(FREQ_204);
|
||||
nyx_str->mtc_cfg.init_done = 0;
|
||||
|
||||
// Flush/disable MMU cache.
|
||||
bpmp_mmu_disable();
|
||||
|
||||
// Re-enable clocks to Audio Processing Engine as a workaround to hanging.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
||||
if (tegra_t210)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
||||
}
|
||||
|
||||
// Do coreboot mitigations.
|
||||
if (coreboot)
|
||||
@@ -443,11 +449,9 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
||||
|
||||
clock_disable_cl_dvfs();
|
||||
|
||||
// Disable Joy-con GPIOs.
|
||||
// Disable Joy-con detect in order to restore UART TX.
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_SPIO);
|
||||
|
||||
// Reinstate SD controller power.
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) &= ~(PMC_NO_IOPOWER_SDMMC1_IO_EN);
|
||||
@@ -463,17 +467,11 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
display_backlight_brightness(brightness, 0);
|
||||
break;
|
||||
case BL_MAGIC_L4TLDR_SLD:
|
||||
// Do not disable display or backlight at all.
|
||||
break;
|
||||
default:
|
||||
display_end();
|
||||
}
|
||||
|
||||
// Enable clock to USBD and init SDMMC1 to avoid hangs with bad hw inits.
|
||||
if (bl_magic == BL_MAGIC_BROKEN_HWI)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD);
|
||||
sdmmc_init(&sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, 0);
|
||||
clock_disable_cl_dvfs();
|
||||
|
||||
msleep(200);
|
||||
clock_disable_host1x();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <utils/types.h>
|
||||
|
||||
#define BL_MAGIC_CRBOOT_SLD 0x30444C53 // SLD0, seamless display type 0.
|
||||
#define BL_MAGIC_BROKEN_HWI 0xBAADF00D // Broken hwinit.
|
||||
#define BL_MAGIC_L4TLDR_SLD 0x31444C53 // SLD1, seamless display type 1.
|
||||
|
||||
extern u32 hw_rst_status;
|
||||
extern u32 hw_rst_reason;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <soc/i2c.h>
|
||||
#include <utils/util.h>
|
||||
#include <soc/timer.h>
|
||||
|
||||
#define I2C_PACKET_PROT_I2C BIT(4)
|
||||
#define I2C_HEADER_CONT_XFER BIT(15)
|
||||
@@ -95,9 +95,9 @@ static void _i2c_load_cfg_wait(vu32 *base)
|
||||
base[I2C_CONFIG_LOAD] = BIT(5) | TIMEOUT_CONFIG_LOAD | MSTR_CONFIG_LOAD;
|
||||
for (u32 i = 0; i < 20; i++)
|
||||
{
|
||||
usleep(1);
|
||||
if (!(base[I2C_CONFIG_LOAD] & MSTR_CONFIG_LOAD))
|
||||
break;
|
||||
usleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,8 +205,8 @@ static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
||||
ARB_LOST | TX_FIFO_OVER | RX_FIFO_UNDER | TX_FIFO_DATA_REQ;
|
||||
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
|
||||
|
||||
// Set device address and recv mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
|
||||
// Set device address and send mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_WRITE;
|
||||
|
||||
// Set recv mode.
|
||||
base[I2C_CNFG] = DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_WRITE;
|
||||
@@ -362,9 +362,9 @@ void i2c_init(u32 i2c_idx)
|
||||
|
||||
for (u32 i = 0; i < 10; i++)
|
||||
{
|
||||
usleep(20000);
|
||||
if (base[I2C_INT_STATUS] & BUS_CLEAR_DONE)
|
||||
break;
|
||||
usleep(25);
|
||||
}
|
||||
|
||||
(vu32)base[I2C_BUS_CLEAR_STATUS];
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "irq.h"
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <gfx_utils.h>
|
||||
#include <mem/heap.h>
|
||||
@@ -26,6 +27,7 @@
|
||||
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
|
||||
extern void excp_reset();
|
||||
extern void irq_disable();
|
||||
extern void irq_enable_cpu_irq_exceptions();
|
||||
extern void irq_disable_cpu_irq_exceptions();
|
||||
@@ -69,7 +71,7 @@ static void _irq_disable_and_ack_all()
|
||||
{
|
||||
u32 enabled_irqs = ICTLR(ctrl_idx, PRI_ICTLR_COP_IER);
|
||||
ICTLR(ctrl_idx, PRI_ICTLR_COP_IER_CLR) = enabled_irqs;
|
||||
ICTLR(ctrl_idx, PRI_ICTLR_FIR_CLR) = enabled_irqs;
|
||||
ICTLR(ctrl_idx, PRI_ICTLR_FIR_CLR) = enabled_irqs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,10 +90,10 @@ void irq_free(u32 irq)
|
||||
{
|
||||
if (irqs[idx].irq == irq && irqs[idx].handler)
|
||||
{
|
||||
irqs[idx].irq = 0;
|
||||
irqs[idx].irq = 0;
|
||||
irqs[idx].handler = NULL;
|
||||
irqs[idx].data = NULL;
|
||||
irqs[idx].flags = 0;
|
||||
irqs[idx].data = NULL;
|
||||
irqs[idx].flags = 0;
|
||||
|
||||
_irq_disable_source(irq);
|
||||
}
|
||||
@@ -106,10 +108,10 @@ static void _irq_free_all()
|
||||
{
|
||||
_irq_disable_source(irqs[idx].irq);
|
||||
|
||||
irqs[idx].irq = 0;
|
||||
irqs[idx].irq = 0;
|
||||
irqs[idx].handler = NULL;
|
||||
irqs[idx].data = NULL;
|
||||
irqs[idx].flags = 0;
|
||||
irqs[idx].data = NULL;
|
||||
irqs[idx].flags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,10 +220,10 @@ irq_status_t irq_request(u32 irq, irq_handler_t handler, void *data, irq_flags_t
|
||||
DPRINTF("Registered handler, IRQ: %d, Slot: %d\n", irq, idx);
|
||||
DPRINTF("Handler: %08p, Flags: %x\n", (u32)handler, flags);
|
||||
|
||||
irqs[idx].irq = irq;
|
||||
irqs[idx].irq = irq;
|
||||
irqs[idx].handler = handler;
|
||||
irqs[idx].data = data;
|
||||
irqs[idx].flags = flags;
|
||||
irqs[idx].data = data;
|
||||
irqs[idx].flags = flags;
|
||||
|
||||
_irq_enable_source(irq);
|
||||
|
||||
@@ -270,4 +272,14 @@ void __attribute__ ((target("arm"), interrupt ("FIQ"))) fiq_handler()
|
||||
len--;
|
||||
}
|
||||
*/
|
||||
#ifdef BDK_WATCHDOG_FIQ_ENABLE
|
||||
// Set watchdog timeout status and disable WDT and its FIQ signal.
|
||||
watchdog_handle();
|
||||
|
||||
#ifdef BDK_RESTART_BL_ON_WDT
|
||||
// Restart bootloader.
|
||||
excp_reset();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
|
||||
void pinmux_config_uart(u32 idx)
|
||||
{
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_RTS(idx)) = 0;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
}
|
||||
|
||||
void pinmux_config_i2c(u32 idx)
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#define PINMUX_AUX_SDMMC3_DAT2 0x2C
|
||||
#define PINMUX_AUX_SDMMC3_DAT3 0x30
|
||||
#define PINMUX_AUX_SATA_LED_ACTIVE 0x4C
|
||||
#define PINMUX_AUX_GPIO_PA5_T210B01 PINMUX_AUX_SATA_LED_ACTIVE
|
||||
#define PINMUX_AUX_DMIC3_CLK 0xB4
|
||||
#define PINMUX_AUX_DMIC3_DAT 0xB8
|
||||
#define PINMUX_AUX_CAM_I2C_SCL 0xD4
|
||||
@@ -46,7 +47,9 @@
|
||||
#define PINMUX_AUX_UART2_TX 0xF4
|
||||
#define PINMUX_AUX_UART3_TX 0x104
|
||||
#define PINMUX_AUX_DAP4_DIN 0x148
|
||||
#define PINMUX_AUX_DAP4_DOUT 0x14C
|
||||
#define PINMUX_AUX_DAP4_SCLK 0x150
|
||||
#define PINMUX_AUX_CLK_32K_OUT 0x164
|
||||
#define PINMUX_AUX_GPIO_X1_AUD 0x18C
|
||||
#define PINMUX_AUX_GPIO_X3_AUD 0x190
|
||||
#define PINMUX_AUX_SPDIF_IN 0x1A4
|
||||
@@ -57,19 +60,26 @@
|
||||
#define PINMUX_AUX_AP_WAKE_NFC 0x1CC
|
||||
#define PINMUX_AUX_NFC_EN 0x1D0
|
||||
#define PINMUX_AUX_NFC_INT 0x1D4
|
||||
#define PINMUX_AUX_CAM_RST 0x1E0
|
||||
#define PINMUX_AUX_CAM1_PWDN 0x1EC
|
||||
#define PINMUX_AUX_CAM2_PWDN 0x1F0
|
||||
#define PINMUX_AUX_CAM1_STROBE 0x1F4
|
||||
#define PINMUX_AUX_LCD_BL_PWM 0x1FC
|
||||
#define PINMUX_AUX_LCD_BL_EN 0x200
|
||||
#define PINMUX_AUX_LCD_RST 0x204
|
||||
#define PINMUX_AUX_LCD_GPIO1 0x208
|
||||
#define PINMUX_AUX_LCD_GPIO2 0x20C
|
||||
#define PINMUX_AUX_TOUCH_CLK 0x218
|
||||
#define PINMUX_AUX_TOUCH_INT 0x220
|
||||
#define PINMUX_AUX_MOTION_INT 0x224
|
||||
#define PINMUX_AUX_ALS_PROX_INT 0x228
|
||||
#define PINMUX_AUX_BUTTON_POWER_ON 0x230
|
||||
#define PINMUX_AUX_BUTTON_HOME 0x240
|
||||
#define PINMUX_AUX_GPIO_PE6 0x248
|
||||
#define PINMUX_AUX_GPIO_PE7 0x24C
|
||||
#define PINMUX_AUX_GPIO_PH6 0x250
|
||||
#define PINMUX_AUX_GPIO_PK3 0x260
|
||||
#define PINMUX_AUX_GPIO_PK7 0x270
|
||||
#define PINMUX_AUX_GPIO_PZ1 0x280
|
||||
/* Only in T210B01 */
|
||||
#define PINMUX_AUX_SDMMC2_DAT0 0x294
|
||||
@@ -116,6 +126,8 @@
|
||||
#define PINMUX_DRIVE_3X (2 << 13)
|
||||
#define PINMUX_DRIVE_4X (3 << 13)
|
||||
|
||||
#define PINMUX_PREEMP BIT(15)
|
||||
|
||||
void pinmux_config_uart(u32 idx);
|
||||
void pinmux_config_i2c(u32 idx);
|
||||
|
||||
|
||||
@@ -16,31 +16,28 @@
|
||||
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
void pmc_scratch_lock(pmc_sec_lock_t lock_mask)
|
||||
{
|
||||
// Lock Private key disable, Fuse write enable, MC carveout, Warmboot PA id and Warmboot address.
|
||||
|
||||
// Happens on T210B01 LP0 always.
|
||||
if (lock_mask & PMC_SEC_LOCK_MISC)
|
||||
{
|
||||
PMC(APBDEV_PMC_SEC_DISABLE) |= 0x700FF0; // RW lock: 0-3.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0xFC000000; // RW lock: 21-23.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE3) |= 0x3F0FFF00; // RW lock: 28-33, 36-38.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE6) |= 0xC000000; // RW lock: 85.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE8) |= 0xFF00FF00; // RW lock: 108-111, 116-119.
|
||||
|
||||
// SE2 context.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
|
||||
{
|
||||
PMC(APBDEV_PMC_SEC_DISABLE9) |= 0x3FF; // RW lock: 120-124. (0xB38)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE10) = 0xFFFFFFFF; // RW lock: 135-150.
|
||||
}
|
||||
// Default: 0xFF00FF00: RW lock: 108-111, 116-119. Gets locked in LP0.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE8) |= 0xFF005500; // W lock: 108-111, RW lock: 116-119.
|
||||
}
|
||||
|
||||
// Happens on T210B01 LP0 always.
|
||||
if (lock_mask & PMC_SEC_LOCK_LP0_PARAMS)
|
||||
{
|
||||
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF; // RW lock: 8-15, 17-20.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF; // RW lock: 8-15, 17-20. L4T expects 8-15 as write locked only.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE4) |= 0x3F3FFFFF; // RW lock: 40-50, 52-54.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF; // RW lock: 56-71.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE6) |= 0xF3FFC00F; // RW lock: 72-73, 79-84, 86-87.
|
||||
@@ -60,6 +57,7 @@ void pmc_scratch_lock(pmc_sec_lock_t lock_mask)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE7) |= 0xFFC00000; // RW lock: 99-103.
|
||||
}
|
||||
|
||||
// HOS specific.
|
||||
if (lock_mask & PMC_SEC_LOCK_TZ_CMAC_W)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE8) |= 0x550000; // W lock: 112-115.
|
||||
|
||||
@@ -71,9 +69,34 @@ void pmc_scratch_lock(pmc_sec_lock_t lock_mask)
|
||||
|
||||
if (lock_mask & PMC_SEC_LOCK_TZ_KEK_R)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE3) |= 0xAA; // R lock: 24-27.
|
||||
// End of HOS specific.
|
||||
|
||||
if (lock_mask & PMC_SEC_LOCK_SE_SRK)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE) |= 0xFF000; // RW lock: 4-7
|
||||
|
||||
if (lock_mask & PMC_SEC_LOCK_SE2_SRK_B01)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE9) |= 0x3FC; // RW lock: 120-123 (T210B01). LP0 also sets global bits (b0-1).
|
||||
|
||||
if (lock_mask & PMC_SEC_LOCK_MISC_B01)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE10) = 0xFFFFFFFF; // RW lock: 135-150. Happens on T210B01 LP0 always.
|
||||
|
||||
if (lock_mask & PMC_SEC_LOCK_CARVEOUTS_L4T)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x5555; // W: 8-15 LP0 and Carveouts. Superseded by LP0 lock.
|
||||
|
||||
// NVTBOOT misses APBDEV_PMC_SCRATCH_WRITE_LOCK_DISABLE_STICKY. bit0: SCRATCH_WR_DIS_ON.
|
||||
// They could also use the NS write disable registers instead.
|
||||
if (lock_mask & PMC_SEC_LOCK_LP0_PARAMS_B01)
|
||||
{
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE0) |= 0xCBCFE0; // W lock: 5-11, 14-17, 19, 22-23.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE1) |= 0x583FF; // W lock: 24-33, 39-40, 42.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE2) |= 0x1BE; // W lock: 44-48, 50-51.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE3) = 0xFFFFFFFF; // W lock: 56-87.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE4) |= 0xFFFFFFF; // W lock: 88-115.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE5) |= 0xFFFFFFF8; // W lock: 123-151.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE6) = 0xFFFFFFFF; // W lock: 152-183.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE7) |= 0xFC00FFFF; // W lock: 184-199, 210-215.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE8) |= 0xF; // W lock: 216-219.
|
||||
}
|
||||
}
|
||||
|
||||
int pmc_enable_partition(pmc_power_rail_t part, u32 enable)
|
||||
|
||||
269
bdk/soc/pmc.h
269
bdk/soc/pmc.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -22,102 +22,183 @@
|
||||
#include <utils/types.h>
|
||||
|
||||
/*! PMC registers. */
|
||||
#define APBDEV_PMC_CNTRL 0x0
|
||||
#define PMC_CNTRL_MAIN_RST BIT(4)
|
||||
#define APBDEV_PMC_SEC_DISABLE 0x4
|
||||
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
|
||||
#define APBDEV_PMC_PWRGATE_STATUS 0x38
|
||||
#define APBDEV_PMC_NO_IOPOWER 0x44
|
||||
#define PMC_NO_IOPOWER_SDMMC1_IO_EN BIT(12)
|
||||
#define PMC_NO_IOPOWER_AUDIO_HV BIT(18)
|
||||
#define PMC_NO_IOPOWER_GPIO_IO_EN BIT(21)
|
||||
#define APBDEV_PMC_SCRATCH0 0x50
|
||||
#define PMC_SCRATCH0_MODE_WARMBOOT BIT(0)
|
||||
#define PMC_SCRATCH0_MODE_RCM BIT(1)
|
||||
#define PMC_SCRATCH0_MODE_PAYLOAD BIT(29)
|
||||
#define PMC_SCRATCH0_MODE_FASTBOOT BIT(30)
|
||||
#define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
|
||||
#define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | PMC_SCRATCH0_MODE_FASTBOOT | PMC_SCRATCH0_MODE_PAYLOAD)
|
||||
#define APBDEV_PMC_SCRATCH1 0x54
|
||||
#define APBDEV_PMC_SCRATCH20 0xA0
|
||||
#define APBDEV_PMC_SECURE_SCRATCH4 0xC0
|
||||
#define APBDEV_PMC_SECURE_SCRATCH5 0xC4
|
||||
#define APBDEV_PMC_PWR_DET_VAL 0xE4
|
||||
#define PMC_PWR_DET_SDMMC1_IO_EN BIT(12)
|
||||
#define PMC_PWR_DET_AUDIO_HV BIT(18)
|
||||
#define PMC_PWR_DET_GPIO_IO_EN BIT(21)
|
||||
#define APBDEV_PMC_DDR_PWR 0xE8
|
||||
#define APBDEV_PMC_USB_AO 0xF0
|
||||
#define APBDEV_PMC_CRYPTO_OP 0xF4
|
||||
#define PMC_CRYPTO_OP_SE_ENABLE 0
|
||||
#define PMC_CRYPTO_OP_SE_DISABLE 1
|
||||
#define APBDEV_PMC_SCRATCH33 0x120
|
||||
#define APBDEV_PMC_SCRATCH37 0x130
|
||||
#define PMC_SCRATCH37_KERNEL_PANIC_FLAG BIT(24)
|
||||
#define APBDEV_PMC_SCRATCH40 0x13C
|
||||
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
|
||||
#define PMC_OSC_EDPD_OVER_OSC_CTRL_OVER 0x400000
|
||||
#define APBDEV_PMC_CLK_OUT_CNTRL 0x1A8
|
||||
#define PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN BIT(2)
|
||||
#define APBDEV_PMC_RST_STATUS 0x1B4
|
||||
#define PMC_RST_STATUS_MASK 0x7
|
||||
#define PMC_RST_STATUS_POR 0
|
||||
#define PMC_RST_STATUS_WATCHDOG 1
|
||||
#define PMC_RST_STATUS_SENSOR 2
|
||||
#define PMC_RST_STATUS_SW_MAIN 3
|
||||
#define PMC_RST_STATUS_LP0 4
|
||||
#define PMC_RST_STATUS_AOTAG 5
|
||||
#define APBDEV_PMC_IO_DPD_REQ 0x1B8
|
||||
#define PMC_IO_DPD_REQ_DPD_OFF BIT(30)
|
||||
#define APBDEV_PMC_IO_DPD2_REQ 0x1C0
|
||||
#define APBDEV_PMC_VDDP_SEL 0x1CC
|
||||
#define APBDEV_PMC_DDR_CFG 0x1D0
|
||||
#define APBDEV_PMC_SECURE_SCRATCH6 0x224
|
||||
#define APBDEV_PMC_SECURE_SCRATCH7 0x228
|
||||
#define APBDEV_PMC_SCRATCH45 0x234
|
||||
#define APBDEV_PMC_SCRATCH46 0x238
|
||||
#define APBDEV_PMC_SCRATCH49 0x244
|
||||
#define APBDEV_PMC_TSC_MULT 0x2B4
|
||||
#define APBDEV_PMC_SEC_DISABLE2 0x2C4
|
||||
#define APBDEV_PMC_WEAK_BIAS 0x2C8
|
||||
#define APBDEV_PMC_REG_SHORT 0x2CC
|
||||
#define APBDEV_PMC_SEC_DISABLE3 0x2D8
|
||||
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
|
||||
#define PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT 0x10
|
||||
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
|
||||
#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4
|
||||
#define APBDEV_PMC_CNTRL2 0x440
|
||||
#define PMC_CNTRL2_HOLD_CKE_LOW_EN 0x1000
|
||||
#define APBDEV_PMC_IO_DPD3_REQ 0x45C
|
||||
#define APBDEV_PMC_IO_DPD4_REQ 0x464
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC
|
||||
#define APBDEV_PMC_DDR_CNTRL 0x4E4
|
||||
#define APBDEV_PMC_SEC_DISABLE4 0x5B0
|
||||
#define APBDEV_PMC_SEC_DISABLE5 0x5B4
|
||||
#define APBDEV_PMC_SEC_DISABLE6 0x5B8
|
||||
#define APBDEV_PMC_SEC_DISABLE7 0x5BC
|
||||
#define APBDEV_PMC_SEC_DISABLE8 0x5C0
|
||||
#define APBDEV_PMC_SEC_DISABLE9 0x5C4
|
||||
#define APBDEV_PMC_SEC_DISABLE10 0x5C8
|
||||
#define APBDEV_PMC_SCRATCH188 0x810
|
||||
#define APBDEV_PMC_SCRATCH190 0x818
|
||||
#define APBDEV_PMC_SCRATCH200 0x840
|
||||
#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8
|
||||
#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC
|
||||
#define APBDEV_PMC_TZRAM_NON_SEC_DISABLE 0xBF0
|
||||
#define APBDEV_PMC_CNTRL 0x0
|
||||
#define PMC_CNTRL_RTC_CLK_DIS BIT(1)
|
||||
#define PMC_CNTRL_RTC_RST BIT(2)
|
||||
#define PMC_CNTRL_MAIN_RST BIT(4)
|
||||
#define PMC_CNTRL_LATCHWAKE_EN BIT(5)
|
||||
#define PMC_CNTRL_BLINK_EN BIT(7)
|
||||
#define PMC_CNTRL_PWRREQ_OE BIT(9)
|
||||
#define PMC_CNTRL_SYSCLK_OE BIT(11)
|
||||
#define PMC_CNTRL_PWRGATE_DIS BIT(12)
|
||||
#define PMC_CNTRL_SIDE_EFFECT_LP0 BIT(14)
|
||||
#define PMC_CNTRL_CPUPWRREQ_OE BIT(16)
|
||||
#define PMC_CNTRL_FUSE_OVERRIDE BIT(18)
|
||||
#define PMC_CNTRL_SHUTDOWN_OE BIT(22)
|
||||
#define APBDEV_PMC_SEC_DISABLE 0x4
|
||||
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
|
||||
#define APBDEV_PMC_PWRGATE_STATUS 0x38
|
||||
#define APBDEV_PMC_NO_IOPOWER 0x44
|
||||
#define PMC_NO_IOPOWER_SDMMC1_IO_EN BIT(12)
|
||||
#define PMC_NO_IOPOWER_SDMMC4_IO_EN BIT(14)
|
||||
#define PMC_NO_IOPOWER_AUDIO_HV BIT(18)
|
||||
#define PMC_NO_IOPOWER_GPIO_IO_EN BIT(21)
|
||||
#define APBDEV_PMC_SCRATCH0 0x50
|
||||
#define PMC_SCRATCH0_MODE_WARMBOOT BIT(0)
|
||||
#define PMC_SCRATCH0_MODE_RCM BIT(1)
|
||||
#define PMC_SCRATCH0_MODE_PAYLOAD BIT(29)
|
||||
#define PMC_SCRATCH0_MODE_BOOTLOADER BIT(30)
|
||||
#define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
|
||||
#define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | \
|
||||
PMC_SCRATCH0_MODE_BOOTLOADER | \
|
||||
PMC_SCRATCH0_MODE_PAYLOAD)
|
||||
#define APBDEV_PMC_BLINK_TIMER 0x40
|
||||
#define PMC_BLINK_ON(n) ((n & 0x7FFF))
|
||||
#define PMC_BLINK_FORCE BIT(15)
|
||||
#define PMC_BLINK_OFF(n) ((u32)(n & 0xFFFF) << 16)
|
||||
#define APBDEV_PMC_SCRATCH1 0x54
|
||||
#define APBDEV_PMC_SCRATCH20 0xA0 // ODM data/config scratch.
|
||||
#define APBDEV_PMC_SECURE_SCRATCH4 0xC0
|
||||
#define APBDEV_PMC_SECURE_SCRATCH5 0xC4
|
||||
#define APBDEV_PMC_PWR_DET_VAL 0xE4
|
||||
#define PMC_PWR_DET_SDMMC1_IO_EN BIT(12)
|
||||
#define PMC_PWR_DET_AUDIO_HV BIT(18)
|
||||
#define PMC_PWR_DET_GPIO_IO_EN BIT(21)
|
||||
#define APBDEV_PMC_DDR_PWR 0xE8
|
||||
#define APBDEV_PMC_USB_AO 0xF0
|
||||
#define APBDEV_PMC_CRYPTO_OP 0xF4
|
||||
#define PMC_CRYPTO_OP_SE_ENABLE 0
|
||||
#define PMC_CRYPTO_OP_SE_DISABLE 1
|
||||
#define APBDEV_PMC_PLLP_WB0_OVERRIDE 0xF8
|
||||
#define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE_ENABLE BIT(11)
|
||||
#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12)
|
||||
#define APBDEV_PMC_SCRATCH33 0x120
|
||||
#define APBDEV_PMC_SCRATCH37 0x130
|
||||
#define PMC_SCRATCH37_KERNEL_PANIC_MAGIC 0x4E415054 // "TPAN"
|
||||
#define APBDEV_PMC_SCRATCH39 0x138
|
||||
#define APBDEV_PMC_SCRATCH40 0x13C
|
||||
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
|
||||
#define PMC_OSC_EDPD_OVER_OSC_CTRL_OVER BIT(22)
|
||||
#define APBDEV_PMC_CLK_OUT_CNTRL 0x1A8
|
||||
#define PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN BIT(2)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN BIT(10)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK3_FORCE_EN BIT(18)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(src) (((src) & 3) << 6)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(src) (((src) & 3) << 14)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK3_SRC_SEL(src) (((src) & 3) << 22)
|
||||
#define OSC_DIV1 0
|
||||
#define OSC_DIV2 1
|
||||
#define OSC_DIV4 2
|
||||
#define OSC_CAR 3
|
||||
#define APBDEV_PMC_RST_STATUS 0x1B4
|
||||
#define PMC_RST_STATUS_MASK 7
|
||||
#define PMC_RST_STATUS_POR 0
|
||||
#define PMC_RST_STATUS_WATCHDOG 1
|
||||
#define PMC_RST_STATUS_SENSOR 2
|
||||
#define PMC_RST_STATUS_SW_MAIN 3
|
||||
#define PMC_RST_STATUS_LP0 4
|
||||
#define PMC_RST_STATUS_AOTAG 5
|
||||
#define APBDEV_PMC_IO_DPD_REQ 0x1B8
|
||||
#define PMC_IO_DPD_REQ_DPD_OFF BIT(30)
|
||||
#define APBDEV_PMC_IO_DPD2_REQ 0x1C0
|
||||
#define APBDEV_PMC_VDDP_SEL 0x1CC
|
||||
#define APBDEV_PMC_DDR_CFG 0x1D0
|
||||
#define APBDEV_PMC_SECURE_SCRATCH6 0x224
|
||||
#define APBDEV_PMC_SECURE_SCRATCH7 0x228
|
||||
#define APBDEV_PMC_SCRATCH45 0x234
|
||||
#define APBDEV_PMC_SCRATCH46 0x238
|
||||
#define APBDEV_PMC_SCRATCH49 0x244
|
||||
#define APBDEV_PMC_SCRATCH52 0x250
|
||||
#define APBDEV_PMC_SCRATCH53 0x254
|
||||
#define APBDEV_PMC_SCRATCH54 0x258
|
||||
#define APBDEV_PMC_SCRATCH55 0x25C
|
||||
#define APBDEV_PMC_TSC_MULT 0x2B4
|
||||
#define APBDEV_PMC_STICKY_BITS 0x2C0
|
||||
#define PMC_STICKY_BITS_HDA_LPBK_DIS BIT(0)
|
||||
#define APBDEV_PMC_SEC_DISABLE2 0x2C4
|
||||
#define APBDEV_PMC_WEAK_BIAS 0x2C8
|
||||
#define APBDEV_PMC_REG_SHORT 0x2CC
|
||||
#define APBDEV_PMC_SEC_DISABLE3 0x2D8
|
||||
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
|
||||
#define PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT BIT(4)
|
||||
#define APBDEV_PMC_SECURE_SCRATCH22 0x338 // AArch32 reset address.
|
||||
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
|
||||
#define APBDEV_PMC_SECURE_SCRATCH34 0x368 // AArch64 reset address.
|
||||
#define APBDEV_PMC_SECURE_SCRATCH35 0x36C // AArch64 reset hi-address.
|
||||
#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4
|
||||
#define APBDEV_PMC_CNTRL2 0x440
|
||||
#define PMC_CNTRL2_WAKE_INT_EN BIT(0)
|
||||
#define PMC_CNTRL2_WAKE_DET_EN BIT(9)
|
||||
#define PMC_CNTRL2_SYSCLK_ORRIDE BIT(10)
|
||||
#define PMC_CNTRL2_HOLD_CKE_LOW_EN BIT(12)
|
||||
#define PMC_CNTRL2_ALLOW_PULSE_WAKE BIT(14)
|
||||
#define APBDEV_PMC_IO_DPD3_REQ 0x45C
|
||||
#define APBDEV_PMC_IO_DPD4_REQ 0x464
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC
|
||||
#define APBDEV_PMC_DDR_CNTRL 0x4E4
|
||||
#define APBDEV_PMC_SEC_DISABLE4 0x5B0
|
||||
#define APBDEV_PMC_SEC_DISABLE5 0x5B4
|
||||
#define APBDEV_PMC_SEC_DISABLE6 0x5B8
|
||||
#define APBDEV_PMC_SEC_DISABLE7 0x5BC
|
||||
#define APBDEV_PMC_SEC_DISABLE8 0x5C0
|
||||
#define APBDEV_PMC_SEC_DISABLE9 0x5C4
|
||||
#define APBDEV_PMC_SEC_DISABLE10 0x5C8
|
||||
#define APBDEV_PMC_SCRATCH188 0x810
|
||||
#define APBDEV_PMC_SCRATCH190 0x818
|
||||
#define APBDEV_PMC_SCRATCH200 0x840
|
||||
#define APBDEV_PMC_SCRATCH201 0x844
|
||||
#define APBDEV_PMC_SCRATCH250 0x908
|
||||
#define APBDEV_PMC_SECURE_SCRATCH108 0xB08
|
||||
#define APBDEV_PMC_SECURE_SCRATCH109 0xB0C
|
||||
#define APBDEV_PMC_SECURE_SCRATCH110 0xB10
|
||||
#define APBDEV_PMC_SECURE_SCRATCH112 0xB18
|
||||
#define APBDEV_PMC_SECURE_SCRATCH113 0xB1C
|
||||
#define APBDEV_PMC_SECURE_SCRATCH114 0xB20
|
||||
#define APBDEV_PMC_SECURE_SCRATCH119 0xB34
|
||||
|
||||
// Only in T210B01.
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE0 0xA48
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE1 0xA4C
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE2 0xA50
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE3 0xA54
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE4 0xA58
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE5 0xA5C
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE6 0xA60
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE7 0xA64
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE8 0xA68
|
||||
#define APBDEV_PMC_LED_BREATHING_CTRL 0xB48
|
||||
#define PMC_LED_BREATHING_CTRL_ENABLE BIT(0)
|
||||
#define PMC_LED_BREATHING_CTRL_COUNTER1_EN BIT(1)
|
||||
#define APBDEV_PMC_LED_BREATHING_SLOPE_STEPS 0xB4C
|
||||
#define APBDEV_PMC_LED_BREATHING_ON_COUNTER 0xB50
|
||||
#define APBDEV_PMC_LED_BREATHING_OFF_COUNTER1 0xB54
|
||||
#define APBDEV_PMC_LED_BREATHING_OFF_COUNTER0 0xB58
|
||||
#define PMC_LED_BREATHING_COUNTER_HZ 32768
|
||||
#define APBDEV_PMC_LED_BREATHING_STATUS 0xB5C
|
||||
#define PMC_LED_BREATHING_FSM_STATUS_MASK 0x7
|
||||
#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8
|
||||
#define PMC_TZRAM_PWR_CNTRL_SD BIT(0)
|
||||
#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC
|
||||
#define APBDEV_PMC_TZRAM_NON_SEC_DISABLE 0xBF0
|
||||
#define PMC_TZRAM_DISABLE_REG_WRITE BIT(0)
|
||||
#define PMC_TZRAM_DISABLE_REG_READ BIT(1)
|
||||
|
||||
typedef enum _pmc_sec_lock_t
|
||||
{
|
||||
PMC_SEC_LOCK_MISC = BIT(0),
|
||||
PMC_SEC_LOCK_LP0_PARAMS = BIT(1),
|
||||
PMC_SEC_LOCK_RST_VECTOR = BIT(2),
|
||||
PMC_SEC_LOCK_CARVEOUTS = BIT(3),
|
||||
PMC_SEC_LOCK_TZ_CMAC_W = BIT(4),
|
||||
PMC_SEC_LOCK_TZ_CMAC_R = BIT(5),
|
||||
PMC_SEC_LOCK_TZ_KEK_W = BIT(6),
|
||||
PMC_SEC_LOCK_TZ_KEK_R = BIT(7),
|
||||
PMC_SEC_LOCK_SE_SRK = BIT(8),
|
||||
PMC_SEC_LOCK_MISC = BIT(0),
|
||||
PMC_SEC_LOCK_LP0_PARAMS = BIT(1),
|
||||
PMC_SEC_LOCK_RST_VECTOR = BIT(2),
|
||||
PMC_SEC_LOCK_CARVEOUTS = BIT(3),
|
||||
PMC_SEC_LOCK_TZ_CMAC_W = BIT(4),
|
||||
PMC_SEC_LOCK_TZ_CMAC_R = BIT(5),
|
||||
PMC_SEC_LOCK_TZ_KEK_W = BIT(6),
|
||||
PMC_SEC_LOCK_TZ_KEK_R = BIT(7),
|
||||
PMC_SEC_LOCK_SE_SRK = BIT(8),
|
||||
PMC_SEC_LOCK_SE2_SRK_B01 = BIT(9),
|
||||
PMC_SEC_LOCK_MISC_B01 = BIT(10),
|
||||
PMC_SEC_LOCK_CARVEOUTS_L4T = BIT(11),
|
||||
PMC_SEC_LOCK_LP0_PARAMS_B01 = BIT(12),
|
||||
} pmc_sec_lock_t;
|
||||
|
||||
typedef enum _pmc_power_rail_t
|
||||
|
||||
251
bdk/soc/t210.h
251
bdk/soc/t210.h
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -26,8 +27,10 @@
|
||||
#define DISPLAY_A_BASE 0x54200000
|
||||
#define DSI_BASE 0x54300000
|
||||
#define VIC_BASE 0x54340000
|
||||
#define NVDEC_BASE 0x54480000
|
||||
#define TSEC_BASE 0x54500000
|
||||
#define SOR1_BASE 0x54580000
|
||||
#define MSELECT_BASE 0x50060000
|
||||
#define ICTLR_BASE 0x60004000
|
||||
#define TMR_BASE 0x60005000
|
||||
#define CLOCK_BASE 0x60006000
|
||||
@@ -35,6 +38,7 @@
|
||||
#define AHBDMA_BASE 0x60008000
|
||||
#define SYSREG_BASE 0x6000C000
|
||||
#define SB_BASE (SYSREG_BASE + 0x200)
|
||||
#define ACTMON_BASE 0x6000C800
|
||||
#define GPIO_BASE 0x6000D000
|
||||
#define GPIO_1_BASE (GPIO_BASE)
|
||||
#define GPIO_2_BASE (GPIO_BASE + 0x100)
|
||||
@@ -69,6 +73,8 @@
|
||||
#define I2S_BASE 0x702D1000
|
||||
#define ADMA_BASE 0x702E2000
|
||||
#define TZRAM_BASE 0x7C010000
|
||||
#define TZRAM_SIZE 0x10000
|
||||
#define TZRAM_T210B01_SIZE 0x3C000
|
||||
#define USB_BASE 0x7D000000
|
||||
#define USB_OTG_BASE USB_BASE
|
||||
#define USB1_BASE 0x7D004000
|
||||
@@ -80,8 +86,10 @@
|
||||
#define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off)
|
||||
#define DSI(off) _REG(DSI_BASE, off)
|
||||
#define VIC(off) _REG(VIC_BASE, off)
|
||||
#define NVDEC(off) _REG(NVDEC_BASE, off)
|
||||
#define TSEC(off) _REG(TSEC_BASE, off)
|
||||
#define SOR1(off) _REG(SOR1_BASE, off)
|
||||
#define MSELECT(off) _REG(MSELECT_BASE, off)
|
||||
#define ICTLR(cidx, off) _REG(ICTLR_BASE + (0x100 * (cidx)), off)
|
||||
#define TMR(off) _REG(TMR_BASE, off)
|
||||
#define CLOCK(off) _REG(CLOCK_BASE, off)
|
||||
@@ -89,6 +97,7 @@
|
||||
#define SYSREG(off) _REG(SYSREG_BASE, off)
|
||||
#define AHB_GIZMO(off) _REG(SYSREG_BASE, off)
|
||||
#define SB(off) _REG(SB_BASE, off)
|
||||
#define ACTMON(off) _REG(ACTMON_BASE, off)
|
||||
#define GPIO(off) _REG(GPIO_BASE, off)
|
||||
#define GPIO_1(off) _REG(GPIO_1_BASE, off)
|
||||
#define GPIO_2(off) _REG(GPIO_2_BASE, off)
|
||||
@@ -127,88 +136,91 @@
|
||||
#define TEST_REG(off) _REG(0x0, off)
|
||||
|
||||
/* HOST1X registers. */
|
||||
#define HOST1X_CH0_SYNC_BASE 0x2100
|
||||
#define HOST1X_CH0_SYNC_BASE 0x2100
|
||||
#define HOST1X_CH0_SYNC_SYNCPT_9 (HOST1X_CH0_SYNC_BASE + 0xFA4)
|
||||
#define HOST1X_CH0_SYNC_SYNCPT_160 (HOST1X_CH0_SYNC_BASE + 0x1200)
|
||||
|
||||
/*! EVP registers. */
|
||||
#define EVP_CPU_RESET_VECTOR 0x100
|
||||
#define EVP_COP_RESET_VECTOR 0x200
|
||||
#define EVP_COP_UNDEF_VECTOR 0x204
|
||||
#define EVP_COP_SWI_VECTOR 0x208
|
||||
#define EVP_CPU_RESET_VECTOR 0x100
|
||||
#define EVP_COP_RESET_VECTOR 0x200
|
||||
#define EVP_COP_UNDEF_VECTOR 0x204
|
||||
#define EVP_COP_SWI_VECTOR 0x208
|
||||
#define EVP_COP_PREFETCH_ABORT_VECTOR 0x20C
|
||||
#define EVP_COP_DATA_ABORT_VECTOR 0x210
|
||||
#define EVP_COP_RSVD_VECTOR 0x214
|
||||
#define EVP_COP_IRQ_VECTOR 0x218
|
||||
#define EVP_COP_FIQ_VECTOR 0x21C
|
||||
#define EVP_COP_IRQ_STS 0x220
|
||||
#define EVP_COP_DATA_ABORT_VECTOR 0x210
|
||||
#define EVP_COP_RSVD_VECTOR 0x214
|
||||
#define EVP_COP_IRQ_VECTOR 0x218
|
||||
#define EVP_COP_FIQ_VECTOR 0x21C
|
||||
#define EVP_COP_IRQ_STS 0x220
|
||||
|
||||
/*! Primary Interrupt Controller registers. */
|
||||
#define PRI_ICTLR_FIR 0x14
|
||||
#define PRI_ICTLR_FIR_SET 0x18
|
||||
#define PRI_ICTLR_FIR_CLR 0x1C
|
||||
#define PRI_ICTLR_CPU_IER 0x20
|
||||
#define PRI_ICTLR_CPU_IER_SET 0x24
|
||||
#define PRI_ICTLR_CPU_IER_CLR 0x28
|
||||
#define PRI_ICTLR_FIR 0x14
|
||||
#define PRI_ICTLR_FIR_SET 0x18
|
||||
#define PRI_ICTLR_FIR_CLR 0x1C
|
||||
#define PRI_ICTLR_CPU_IER 0x20
|
||||
#define PRI_ICTLR_CPU_IER_SET 0x24
|
||||
#define PRI_ICTLR_CPU_IER_CLR 0x28
|
||||
#define PRI_ICTLR_CPU_IEP_CLASS 0x2C
|
||||
#define PRI_ICTLR_COP_IER 0x30
|
||||
#define PRI_ICTLR_COP_IER_SET 0x34
|
||||
#define PRI_ICTLR_COP_IER_CLR 0x38
|
||||
#define PRI_ICTLR_COP_IER 0x30
|
||||
#define PRI_ICTLR_COP_IER_SET 0x34
|
||||
#define PRI_ICTLR_COP_IER_CLR 0x38
|
||||
#define PRI_ICTLR_COP_IEP_CLASS 0x3C
|
||||
|
||||
/*! AHB Gizmo registers. */
|
||||
#define AHB_ARBITRATION_PRIORITY_CTRL 0x8
|
||||
#define PRIORITY_CTRL_WEIGHT(x) (((x) & 7) << 29)
|
||||
#define PRIORITY_SELECT_USB BIT(6) // USB-OTG.
|
||||
#define PRIORITY_SELECT_USB2 BIT(18) // USB-HSIC.
|
||||
#define PRIORITY_SELECT_USB3 BIT(17) // XUSB.
|
||||
#define AHB_GIZMO_AHB_MEM 0x10
|
||||
#define AHB_MEM_ENB_FAST_REARBITRATE BIT(2)
|
||||
#define AHB_MEM_DONT_SPLIT_AHB_WR BIT(7)
|
||||
#define AHB_MEM_IMMEDIATE BIT(18)
|
||||
#define AHB_GIZMO_APB_DMA 0x14
|
||||
#define AHB_GIZMO_USB 0x20
|
||||
#define AHB_GIZMO_SDMMC4 0x48
|
||||
#define AHB_GIZMO_USB2 0x7C
|
||||
#define AHB_GIZMO_USB3 0x80
|
||||
#define AHB_GIZMO_IMMEDIATE BIT(18)
|
||||
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG3 0xE4
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG4 0xE8
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG1 0xF0
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG2 0xF4
|
||||
#define MST_ID(x) (((x) & 0x1F) << 26)
|
||||
#define MEM_PREFETCH_AHBDMA_MST_ID MST_ID(5)
|
||||
#define MEM_PREFETCH_USB_MST_ID MST_ID(6) // USB-OTG.
|
||||
#define MEM_PREFETCH_USB2_MST_ID MST_ID(18) // USB-HSIC.
|
||||
#define MEM_PREFETCH_USB3_MST_ID MST_ID(17) // XUSB.
|
||||
#define MEM_PREFETCH_ADDR_BNDRY(x) (((x) & 0xF) << 21)
|
||||
#define MEM_PREFETCH_ENABLE BIT(31)
|
||||
#define AHB_AHB_SPARE_REG 0x110
|
||||
#define AHB_ARBITRATION_PRIORITY_CTRL 0x8
|
||||
#define PRIORITY_CTRL_WEIGHT(x) (((x) & 7) << 29)
|
||||
#define PRIORITY_SELECT_USB BIT(6) // USB-OTG.
|
||||
#define PRIORITY_SELECT_USB2 BIT(18) // USB-HSIC.
|
||||
#define PRIORITY_SELECT_USB3 BIT(17) // XUSB.
|
||||
#define AHB_GIZMO_AHB_MEM 0x10
|
||||
#define AHB_MEM_ENB_FAST_REARBITRATE BIT(2)
|
||||
#define AHB_MEM_DONT_SPLIT_AHB_WR BIT(7)
|
||||
#define AHB_MEM_IMMEDIATE BIT(18)
|
||||
#define AHB_GIZMO_APB_DMA 0x14
|
||||
#define AHB_GIZMO_USB 0x20
|
||||
#define AHB_GIZMO_SDMMC4 0x48
|
||||
#define AHB_GIZMO_USB2 0x7C
|
||||
#define AHB_GIZMO_USB3 0x80
|
||||
#define AHB_GIZMO_IMMEDIATE BIT(18)
|
||||
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG3 0xE4
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG4 0xE8
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG1 0xF0
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG2 0xF4
|
||||
#define MST_ID(x) (((x) & 0x1F) << 26)
|
||||
#define MEM_PREFETCH_AHBDMA_MST_ID MST_ID(5)
|
||||
#define MEM_PREFETCH_USB_MST_ID MST_ID(6) // USB-OTG.
|
||||
#define MEM_PREFETCH_USB2_MST_ID MST_ID(18) // USB-HSIC.
|
||||
#define MEM_PREFETCH_USB3_MST_ID MST_ID(17) // XUSB.
|
||||
#define MEM_PREFETCH_ADDR_BNDRY(x) (((x) & 0xF) << 21)
|
||||
#define MEM_PREFETCH_ENABLE BIT(31)
|
||||
#define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID 0xFC
|
||||
#define MEM_WRQUE_SE_MST_ID BIT(14)
|
||||
#define AHB_AHB_SPARE_REG 0x110
|
||||
|
||||
/*! Misc registers. */
|
||||
#define APB_MISC_PP_STRAPPING_OPT_A 0x08
|
||||
#define APB_MISC_PP_PINMUX_GLOBAL 0x40
|
||||
#define APB_MISC_GP_HIDREV 0x804
|
||||
#define GP_HIDREV_MAJOR_T210 0x1
|
||||
#define GP_HIDREV_MAJOR_T210B01 0x2
|
||||
#define APB_MISC_GP_AUD_MCLK_CFGPADCTRL 0x8F4
|
||||
#define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34
|
||||
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
|
||||
#define APB_MISC_GP_EMMC2_PAD_CFGPADCTRL 0xA9C
|
||||
#define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4
|
||||
#define APB_MISC_PP_STRAPPING_OPT_A 0x8
|
||||
#define APB_MISC_PP_PINMUX_GLOBAL 0x40
|
||||
#define APB_MISC_GP_HIDREV 0x804
|
||||
#define GP_HIDREV_MAJOR_T210 0x1
|
||||
#define GP_HIDREV_MAJOR_T210B01 0x2
|
||||
#define APB_MISC_GP_ASDBGREG 0x810
|
||||
#define APB_MISC_GP_AUD_MCLK_CFGPADCTRL 0x8F4
|
||||
#define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34
|
||||
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
|
||||
#define APB_MISC_GP_EMMC2_PAD_CFGPADCTRL 0xA9C
|
||||
#define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4
|
||||
#define APB_MISC_GP_EMMC4_PAD_PUPD_CFGPADCTRL 0xABC
|
||||
#define APB_MISC_GP_DSI_PAD_CONTROL 0xAC0
|
||||
#define APB_MISC_GP_WIFI_EN_CFGPADCTRL 0xB64
|
||||
#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68
|
||||
#define APB_MISC_GP_DSI_PAD_CONTROL 0xAC0
|
||||
#define APB_MISC_GP_WIFI_EN_CFGPADCTRL 0xB64
|
||||
#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68
|
||||
|
||||
/*! Secure boot registers. */
|
||||
#define SB_CSR 0x0
|
||||
#define SB_CSR_NS_RST_VEC_WR_DIS BIT(1)
|
||||
#define SB_CSR_PIROM_DISABLE BIT(4)
|
||||
#define SB_AA64_RESET_LOW 0x30
|
||||
#define SB_AA64_RST_AARCH64_MODE_EN BIT(0)
|
||||
#define SB_AA64_RESET_HIGH 0x34
|
||||
#define SB_CSR 0x0
|
||||
#define SB_CSR_NS_RST_VEC_WR_DIS BIT(1)
|
||||
#define SB_CSR_PIROM_DISABLE BIT(4)
|
||||
#define SB_AA64_RESET_LOW 0x30
|
||||
#define SB_AA64_RST_AARCH64_MODE_EN BIT(0)
|
||||
#define SB_AA64_RESET_HIGH 0x34
|
||||
|
||||
/*! SOR registers. */
|
||||
#define SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB 0x1E8
|
||||
@@ -222,42 +234,22 @@
|
||||
#define APBDEV_RTC_MILLI_SECONDS 0x10
|
||||
|
||||
/*! SYSCTR0 registers. */
|
||||
#define SYSCTR0_CNTFID0 0x20
|
||||
#define SYSCTR0_CNTCR 0x00
|
||||
#define SYSCTR0_COUNTERID0 0xFE0
|
||||
#define SYSCTR0_COUNTERID1 0xFE4
|
||||
#define SYSCTR0_COUNTERID2 0xFE8
|
||||
#define SYSCTR0_COUNTERID3 0xFEC
|
||||
#define SYSCTR0_COUNTERID4 0xFD0
|
||||
#define SYSCTR0_COUNTERID5 0xFD4
|
||||
#define SYSCTR0_COUNTERID6 0xFD8
|
||||
#define SYSCTR0_COUNTERID7 0xFDC
|
||||
#define SYSCTR0_COUNTERID8 0xFF0
|
||||
#define SYSCTR0_COUNTERID9 0xFF4
|
||||
#define SYSCTR0_COUNTERID10 0xFF8
|
||||
#define SYSCTR0_COUNTERID11 0xFFC
|
||||
|
||||
/*! TMR registers. */
|
||||
#define TIMERUS_CNTR_1US (0x10 + 0x0)
|
||||
#define TIMERUS_USEC_CFG (0x10 + 0x4)
|
||||
#define TIMER_TMR8_TMR_PTV 0x78
|
||||
#define TIMER_TMR9_TMR_PTV 0x80
|
||||
#define TIMER_PER_EN BIT(30)
|
||||
#define TIMER_EN BIT(31)
|
||||
#define TIMER_TMR8_TMR_PCR 0x7C
|
||||
#define TIMER_TMR9_TMR_PCR 0x8C
|
||||
#define TIMER_INTR_CLR BIT(30)
|
||||
|
||||
#define TIMER_WDT4_CONFIG (0x100 + 0x80)
|
||||
#define TIMER_SRC(TMR) ((TMR) & 0xF)
|
||||
#define TIMER_PER(PER) (((PER) & 0xFF) << 4)
|
||||
#define TIMER_SYSRESET_EN BIT(14)
|
||||
#define TIMER_PMCRESET_EN BIT(15)
|
||||
#define TIMER_WDT4_COMMAND (0x108 + 0x80)
|
||||
#define TIMER_START_CNT BIT(0)
|
||||
#define TIMER_CNT_DISABLE BIT(1)
|
||||
#define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80)
|
||||
#define TIMER_MAGIC_PTRN 0xC45A
|
||||
#define SYSCTR0_CNTCR 0x00
|
||||
#define SYSCTR0_CNTFID0 0x20
|
||||
#define SYSCTR0_COUNTERS_BASE 0xFD0
|
||||
#define SYSCTR0_COUNTERS 12
|
||||
#define SYSCTR0_COUNTERID0 0xFE0
|
||||
#define SYSCTR0_COUNTERID1 0xFE4
|
||||
#define SYSCTR0_COUNTERID2 0xFE8
|
||||
#define SYSCTR0_COUNTERID3 0xFEC
|
||||
#define SYSCTR0_COUNTERID4 0xFD0
|
||||
#define SYSCTR0_COUNTERID5 0xFD4
|
||||
#define SYSCTR0_COUNTERID6 0xFD8
|
||||
#define SYSCTR0_COUNTERID7 0xFDC
|
||||
#define SYSCTR0_COUNTERID8 0xFF0
|
||||
#define SYSCTR0_COUNTERID9 0xFF4
|
||||
#define SYSCTR0_COUNTERID10 0xFF8
|
||||
#define SYSCTR0_COUNTERID11 0xFFC
|
||||
|
||||
/*! I2S registers. */
|
||||
#define I2S1_CG 0x88
|
||||
@@ -284,25 +276,42 @@
|
||||
#define EMC_SEPT_RUN BIT(31)
|
||||
|
||||
/*! Flow controller registers. */
|
||||
#define FLOW_CTLR_HALT_COP_EVENTS 0x4
|
||||
#define HALT_COP_GIC_IRQ BIT(9)
|
||||
#define HALT_COP_LIC_IRQ BIT(11)
|
||||
#define HALT_COP_SEC BIT(23)
|
||||
#define HALT_COP_MSEC BIT(24)
|
||||
#define HALT_COP_USEC BIT(25)
|
||||
#define HALT_COP_JTAG BIT(28)
|
||||
#define HALT_COP_WAIT_EVENT BIT(30)
|
||||
#define HALT_COP_STOP_UNTIL_IRQ BIT(31)
|
||||
#define HALT_COP_MAX_CNT 0xFF
|
||||
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
|
||||
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
|
||||
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
|
||||
#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24
|
||||
#define FLOW_CTLR_CPU0_CSR 0x8
|
||||
#define FLOW_CTLR_CPU1_CSR 0x18
|
||||
#define FLOW_CTLR_CPU2_CSR 0x20
|
||||
#define FLOW_CTLR_CPU3_CSR 0x28
|
||||
#define FLOW_CTLR_RAM_REPAIR 0x40
|
||||
#define FLOW_CTLR_HALT_COP_EVENTS 0x4
|
||||
#define HALT_COP_GIC_IRQ BIT(9)
|
||||
#define HALT_COP_LIC_IRQ BIT(11)
|
||||
#define HALT_COP_SEC BIT(23)
|
||||
#define HALT_COP_MSEC BIT(24)
|
||||
#define HALT_COP_USEC BIT(25)
|
||||
#define HALT_COP_JTAG BIT(28)
|
||||
#define HALT_COP_WAIT_EVENT BIT(30)
|
||||
#define HALT_COP_STOP_UNTIL_IRQ BIT(31)
|
||||
#define HALT_COP_MAX_CNT 0xFF
|
||||
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
|
||||
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
|
||||
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
|
||||
#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24
|
||||
#define FLOW_CTLR_CPU0_CSR 0x8
|
||||
#define FLOW_CTLR_CPU1_CSR 0x18
|
||||
#define FLOW_CTLR_CPU2_CSR 0x20
|
||||
#define FLOW_CTLR_CPU3_CSR 0x28
|
||||
#define FLOW_CTLR_RAM_REPAIR 0x40
|
||||
#define RAM_REPAIR_REQ BIT(0)
|
||||
#define RAM_REPAIR_STS BIT(1)
|
||||
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98
|
||||
#define CLUSTER_CTRL_ACTIVE_SLOW BIT(0)
|
||||
|
||||
/* MSelect registers */
|
||||
#define MSELECT_CONFIG 0x00
|
||||
#define MSELECT_CFG_ERR_RESP_EN_PCIE BIT(24)
|
||||
#define MSELECT_CFG_ERR_RESP_EN_GPU BIT(25)
|
||||
#define MSELECT_CFG_WRAP_TO_INCR_BPMP BIT(27)
|
||||
#define MSELECT_CFG_WRAP_TO_INCR_PCIE BIT(28)
|
||||
#define MSELECT_CFG_WRAP_TO_INCR_GPU BIT(29)
|
||||
|
||||
/* NVDEC registers */
|
||||
#define NVDEC_SA_KEYSLOT_FALCON 0x2100
|
||||
#define NVDEC_SA_KEYSLOT_TZ 0x2104
|
||||
#define NVDEC_SA_KEYSLOT_OTF 0x210C
|
||||
#define NVDEC_SA_KEYSLOT_GLOBAL_RW 0x2118
|
||||
#define NVDEC_VPR_ALL_OTF_GOTO_VPR 0x211C
|
||||
#endif
|
||||
|
||||
115
bdk/soc/timer.c
Normal file
115
bdk/soc/timer.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Timer/Watchdog driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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/>.
|
||||
*/
|
||||
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/irq.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
#define EXCP_TYPE_ADDR 0x4003FFF8
|
||||
#define EXCP_TYPE_WDT 0x544457 // "WDT".
|
||||
|
||||
u32 get_tmr_s()
|
||||
{
|
||||
(void)RTC(APBDEV_RTC_MILLI_SECONDS);
|
||||
return (u32)RTC(APBDEV_RTC_SECONDS);
|
||||
}
|
||||
|
||||
u32 get_tmr_ms()
|
||||
{
|
||||
// The registers must be read with the following order:
|
||||
// RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC)
|
||||
return (u32)(RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000));
|
||||
}
|
||||
|
||||
u32 get_tmr_us()
|
||||
{
|
||||
return (u32)TMR(TIMERUS_CNTR_1US);
|
||||
}
|
||||
|
||||
void msleep(u32 ms)
|
||||
{
|
||||
#ifdef USE_RTC_TIMER
|
||||
u32 start = (u32)RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000);
|
||||
// Casting to u32 is important!
|
||||
while (((u32)(RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000)) - start) <= ms)
|
||||
;
|
||||
#else
|
||||
bpmp_msleep(ms);
|
||||
#endif
|
||||
}
|
||||
|
||||
void usleep(u32 us)
|
||||
{
|
||||
#ifdef USE_RTC_TIMER
|
||||
u32 start = (u32)TMR(TIMERUS_CNTR_1US);
|
||||
|
||||
// Check if timer is at upper limits and use BPMP sleep so it doesn't wake up immediately.
|
||||
if ((start + us) < start)
|
||||
bpmp_usleep(us);
|
||||
else
|
||||
while ((u32)(TMR(TIMERUS_CNTR_1US) - start) <= us) // Casting to u32 is important!
|
||||
;
|
||||
#else
|
||||
bpmp_usleep(us);
|
||||
#endif
|
||||
}
|
||||
|
||||
void timer_usleep(u32 us)
|
||||
{
|
||||
TMR(TIMER_TMR8_TMR_PTV) = TIMER_EN | us;
|
||||
|
||||
irq_wait_event(IRQ_TMR8);
|
||||
|
||||
TMR(TIMER_TMR8_TMR_PCR) = TIMER_INTR_CLR;
|
||||
}
|
||||
|
||||
void watchdog_start(u32 us, u32 mode)
|
||||
{
|
||||
// WDT4 is for BPMP.
|
||||
TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;
|
||||
TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN | us;
|
||||
TMR(TIMER_WDT4_CONFIG) = TIMER_SRC(9) | TIMER_PER(1) | mode;
|
||||
TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT;
|
||||
}
|
||||
|
||||
void watchdog_end()
|
||||
{
|
||||
// WDT4 is for BPMP.
|
||||
TMR(TIMER_TMR9_TMR_PTV) = 0;
|
||||
TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;
|
||||
TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT; // Re-arm to clear any interrupts.
|
||||
TMR(TIMER_WDT4_COMMAND) = TIMER_CNT_DISABLE;
|
||||
TMR(TIMER_TMR9_TMR_PCR) = TIMER_INTR_CLR;
|
||||
}
|
||||
|
||||
void watchdog_handle()
|
||||
{
|
||||
// Disable watchdog and clear its interrupts.
|
||||
watchdog_end();
|
||||
|
||||
// Set watchdog magic.
|
||||
*(u32 *)EXCP_TYPE_ADDR = EXCP_TYPE_WDT;
|
||||
}
|
||||
|
||||
bool watchdog_fired()
|
||||
{
|
||||
// Return if watchdog got fired. User handles clearing.
|
||||
return (*(u32 *)EXCP_TYPE_ADDR == EXCP_TYPE_WDT);
|
||||
}
|
||||
62
bdk/soc/timer.h
Normal file
62
bdk/soc/timer.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Timer/Watchdog driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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 _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
// TMR registers.
|
||||
#define TIMERUS_CNTR_1US (0x10 + 0x0)
|
||||
#define TIMERUS_USEC_CFG (0x10 + 0x4)
|
||||
#define TIMER_TMR8_TMR_PTV 0x78
|
||||
#define TIMER_TMR9_TMR_PTV 0x80
|
||||
#define TIMER_PER_EN BIT(30)
|
||||
#define TIMER_EN BIT(31)
|
||||
#define TIMER_TMR8_TMR_PCR 0x7C
|
||||
#define TIMER_TMR9_TMR_PCR 0x8C
|
||||
#define TIMER_INTR_CLR BIT(30)
|
||||
|
||||
// WDT registers.
|
||||
#define TIMER_WDT4_CONFIG (0x100 + 0x80)
|
||||
#define TIMER_SRC(TMR) ((TMR) & 0xF)
|
||||
#define TIMER_PER(PER) (((PER) & 0xFF) << 4)
|
||||
#define TIMER_IRQENABL_EN BIT(12)
|
||||
#define TIMER_FIQENABL_EN BIT(13)
|
||||
#define TIMER_SYSRESET_EN BIT(14)
|
||||
#define TIMER_PMCRESET_EN BIT(15)
|
||||
#define TIMER_WDT4_COMMAND (0x108 + 0x80)
|
||||
#define TIMER_START_CNT BIT(0)
|
||||
#define TIMER_CNT_DISABLE BIT(1)
|
||||
#define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80)
|
||||
#define TIMER_MAGIC_PTRN 0xC45A
|
||||
|
||||
u32 get_tmr_us();
|
||||
u32 get_tmr_ms();
|
||||
u32 get_tmr_s();
|
||||
void usleep(u32 us);
|
||||
void msleep(u32 ms);
|
||||
|
||||
void timer_usleep(u32 us);
|
||||
|
||||
void watchdog_start(u32 us, u32 mode);
|
||||
void watchdog_end();
|
||||
void watchdog_handle();
|
||||
bool watchdog_fired();
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -17,45 +17,58 @@
|
||||
|
||||
#include <soc/uart.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
/* UART A, B, C, D and E. */
|
||||
static const u32 uart_baseoff[5] = { 0, 0x40, 0x200, 0x300, 0x400 };
|
||||
|
||||
void uart_init(u32 idx, u32 baud)
|
||||
void uart_init(u32 idx, u32 baud, u32 mode)
|
||||
{
|
||||
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
|
||||
|
||||
// Make sure no data is being sent.
|
||||
uart_wait_idle(idx, UART_TX_IDLE);
|
||||
if (!(mode & (UART_MCR_CTS_EN | UART_MCR_DTR)))
|
||||
uart_wait_xfer(idx, UART_TX_IDLE);
|
||||
|
||||
// Set clock.
|
||||
bool clk_type = clock_uart_use_src_div(idx, baud);
|
||||
|
||||
// 2 STOP bits for rates > 1M. (Reduced efficiency but less errors on high baudrates).
|
||||
u32 uart_lcr_stop = baud > 1000000 ? UART_LCR_STOP : 0;
|
||||
|
||||
// Misc settings.
|
||||
u32 div = clk_type ? ((8 * baud + 408000000) / (16 * baud)) : 1; // DIV_ROUND_CLOSEST.
|
||||
uart->UART_IER_DLAB = 0; // Disable interrupts.
|
||||
uart->UART_LCR = UART_LCR_DLAB | UART_LCR_WORD_LENGTH_8; // Enable DLAB & set 8n1 mode.
|
||||
uart->UART_THR_DLAB = (u8)div; // Divisor latch LSB.
|
||||
uart->UART_LCR = UART_LCR_DLAB | UART_LCR_WORD_LENGTH_8; // Enable DLAB & set 8n1 mode.
|
||||
uart->UART_THR_DLAB = (u8)div; // Divisor latch LSB.
|
||||
uart->UART_IER_DLAB = (u8)(div >> 8); // Divisor latch MSB.
|
||||
uart->UART_LCR = UART_LCR_WORD_LENGTH_8; // Disable DLAB.
|
||||
|
||||
// Disable DLAB and set STOP bits setting if applicable.
|
||||
uart->UART_LCR = uart_lcr_stop | UART_LCR_WORD_LENGTH_8;
|
||||
(void)uart->UART_SPR;
|
||||
|
||||
// Setup and flush fifo.
|
||||
// Enable fifo.
|
||||
uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO;
|
||||
(void)uart->UART_SPR;
|
||||
usleep(20);
|
||||
uart->UART_MCR = 0; // Disable hardware flow control.
|
||||
|
||||
// Disable hardware flow control.
|
||||
uart->UART_MCR = 0;
|
||||
usleep(96);
|
||||
|
||||
// Clear tx/rx fifos.
|
||||
uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | UART_IIR_FCR_TX_CLR | UART_IIR_FCR_RX_CLR;
|
||||
|
||||
// Set hardware flow control.
|
||||
uart->UART_MCR = mode;
|
||||
|
||||
// Wait 3 symbols for baudrate change.
|
||||
usleep(3 * ((baud + 999999) / baud));
|
||||
uart_wait_idle(idx, UART_TX_IDLE | UART_RX_IDLE);
|
||||
uart_wait_xfer(idx, UART_TX_IDLE | UART_RX_RDYR);
|
||||
}
|
||||
|
||||
void uart_wait_idle(u32 idx, u32 which)
|
||||
void uart_wait_xfer(u32 idx, u32 which)
|
||||
{
|
||||
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
|
||||
if (UART_TX_IDLE & which)
|
||||
@@ -63,10 +76,10 @@ void uart_wait_idle(u32 idx, u32 which)
|
||||
while (!(uart->UART_LSR & UART_LSR_TMTY))
|
||||
;
|
||||
}
|
||||
if (UART_RX_IDLE & which)
|
||||
if (UART_RX_RDYR & which)
|
||||
{
|
||||
while (uart->UART_LSR & UART_LSR_RDR)
|
||||
;
|
||||
(void)uart->UART_THR_DLAB;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,26 +98,31 @@ void uart_send(u32 idx, const u8 *buf, u32 len)
|
||||
u32 uart_recv(u32 idx, u8 *buf, u32 len)
|
||||
{
|
||||
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
|
||||
bool manual_mode = uart->UART_MCR & UART_MCR_RTS;
|
||||
u32 timeout = get_tmr_us() + 250;
|
||||
u32 i;
|
||||
|
||||
if (manual_mode)
|
||||
uart->UART_MCR &= ~UART_MCR_RTS;
|
||||
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
while (!(uart->UART_LSR & UART_LSR_RDR))
|
||||
{
|
||||
if (timeout < get_tmr_us())
|
||||
break;
|
||||
if (len && len < i)
|
||||
break;
|
||||
}
|
||||
if (timeout < get_tmr_us())
|
||||
if (len && len <= i)
|
||||
break;
|
||||
|
||||
while (!(uart->UART_LSR & UART_LSR_RDR))
|
||||
if (timeout < get_tmr_us())
|
||||
goto out;
|
||||
|
||||
buf[i] = uart->UART_THR_DLAB;
|
||||
timeout = get_tmr_us() + 250;
|
||||
}
|
||||
|
||||
return i ? (len ? (i - 1) : i) : 0;
|
||||
out:
|
||||
if (manual_mode)
|
||||
uart->UART_MCR |= UART_MCR_RTS;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void uart_invert(u32 idx, bool enable, u32 invert_mask)
|
||||
@@ -118,6 +136,14 @@ void uart_invert(u32 idx, bool enable, u32 invert_mask)
|
||||
(void)uart->UART_SPR;
|
||||
}
|
||||
|
||||
void uart_set_mode(u32 idx, u32 mode)
|
||||
{
|
||||
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
|
||||
|
||||
uart->UART_MCR = mode;
|
||||
(void)uart->UART_SPR;
|
||||
}
|
||||
|
||||
u32 uart_get_IIR(u32 idx)
|
||||
{
|
||||
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
|
||||
@@ -172,3 +198,24 @@ void uart_empty_fifo(u32 idx, u32 which)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_UART_PORT
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <utils/sprintf.h>
|
||||
|
||||
void uart_printf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
//! NOTE: Anything more and it will hang. Heap usage is out of the question.
|
||||
char text[256];
|
||||
|
||||
va_start(ap, fmt);
|
||||
s_vprintf(text, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
uart_send(DEBUG_UART_PORT, (u8 *)text, strlen(text));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -28,33 +28,33 @@
|
||||
|
||||
#define BAUD_115200 115200
|
||||
|
||||
#define UART_TX_IDLE 0x1
|
||||
#define UART_RX_IDLE 0x2
|
||||
#define UART_TX_IDLE BIT(0)
|
||||
#define UART_RX_RDYR BIT(1)
|
||||
|
||||
#define UART_TX_FIFO_FULL 0x100
|
||||
#define UART_RX_FIFO_EMPTY 0x200
|
||||
#define UART_TX_FIFO_FULL BIT(8)
|
||||
#define UART_RX_FIFO_EMPTY BIT(9)
|
||||
|
||||
#define UART_INVERT_RXD 0x01
|
||||
#define UART_INVERT_TXD 0x02
|
||||
#define UART_INVERT_CTS 0x04
|
||||
#define UART_INVERT_RTS 0x08
|
||||
#define UART_INVERT_RXD BIT(0)
|
||||
#define UART_INVERT_TXD BIT(1)
|
||||
#define UART_INVERT_CTS BIT(2)
|
||||
#define UART_INVERT_RTS BIT(3)
|
||||
|
||||
#define UART_IER_DLAB_IE_EORD 0x20
|
||||
#define UART_IER_DLAB_IE_EORD BIT(5)
|
||||
|
||||
#define UART_LCR_DLAB 0x80
|
||||
#define UART_LCR_STOP 0x4
|
||||
#define UART_LCR_WORD_LENGTH_8 0x3
|
||||
#define UART_LCR_STOP BIT(2)
|
||||
#define UART_LCR_DLAB BIT(7)
|
||||
|
||||
#define UART_LSR_RDR 0x1
|
||||
#define UART_LSR_THRE 0x20
|
||||
#define UART_LSR_TMTY 0x40
|
||||
#define UART_LSR_FIFOE 0x80
|
||||
#define UART_LSR_RDR BIT(0)
|
||||
#define UART_LSR_THRE BIT(5)
|
||||
#define UART_LSR_TMTY BIT(6)
|
||||
#define UART_LSR_FIFOE BIT(7)
|
||||
|
||||
#define UART_IIR_FCR_TX_CLR 0x4
|
||||
#define UART_IIR_FCR_RX_CLR 0x2
|
||||
#define UART_IIR_FCR_EN_FIFO 0x1
|
||||
#define UART_IIR_FCR_EN_FIFO BIT(0)
|
||||
#define UART_IIR_FCR_RX_CLR BIT(1)
|
||||
#define UART_IIR_FCR_TX_CLR BIT(2)
|
||||
|
||||
#define UART_IIR_NO_INT BIT(0)
|
||||
#define UART_IIR_NO_INT BIT(0)
|
||||
#define UART_IIR_INT_MASK 0xF
|
||||
/* Custom returned interrupt results. Actual interrupts are -1 */
|
||||
#define UART_IIR_NOI 0 // No interrupt.
|
||||
@@ -65,8 +65,10 @@
|
||||
#define UART_IIR_REDI 5 // Receiver end of data interrupt.
|
||||
#define UART_IIR_RDTI 7 // Receiver data timeout interrupt.
|
||||
|
||||
#define UART_MCR_RTS 0x2
|
||||
#define UART_MCR_DTR 0x1
|
||||
#define UART_MCR_DTR BIT(0)
|
||||
#define UART_MCR_RTS BIT(1)
|
||||
#define UART_MCR_CTS_EN BIT(5)
|
||||
#define UART_MCR_RTS_EN BIT(6)
|
||||
|
||||
typedef struct _uart_t
|
||||
{
|
||||
@@ -86,13 +88,29 @@ typedef struct _uart_t
|
||||
/* 0x3C */ vu32 UART_ASR;
|
||||
} uart_t;
|
||||
|
||||
void uart_init(u32 idx, u32 baud);
|
||||
void uart_wait_idle(u32 idx, u32 which);
|
||||
//! TODO: Commented out modes are not supported yet.
|
||||
typedef enum _uart_mode_t
|
||||
{
|
||||
UART_AO_TX_AO_RX = 0,
|
||||
//UART_MN_TX_AO_RX = UART_MCR_RTS | UART_MCR_DTR,
|
||||
UART_AO_TX_MN_RX = UART_MCR_RTS, // Up to 36 bytes read.
|
||||
//UART_MN_TX_AO_RX = UART_MCR_DTR,
|
||||
//UART_HW_TX_HW_RX = UART_MCR_RTS_EN | UART_MCR_CTS_EN,
|
||||
UART_AO_TX_HW_RX = UART_MCR_RTS_EN,
|
||||
//UART_HW_TX_AO_RX = UART_MCR_CTS_EN,
|
||||
} uart_mode_t;
|
||||
|
||||
void uart_init(u32 idx, u32 baud, u32 mode);
|
||||
void uart_wait_xfer(u32 idx, u32 which);
|
||||
void uart_send(u32 idx, const u8 *buf, u32 len);
|
||||
u32 uart_recv(u32 idx, u8 *buf, u32 len);
|
||||
void uart_invert(u32 idx, bool enable, u32 invert_mask);
|
||||
void uart_set_mode(u32 idx, u32 mode);
|
||||
u32 uart_get_IIR(u32 idx);
|
||||
void uart_set_IIR(u32 idx);
|
||||
void uart_empty_fifo(u32 idx, u32 which);
|
||||
#ifdef DEBUG_UART_PORT
|
||||
void uart_printf(const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user