Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a6eea1ebf | ||
|
|
22b32c2d3c | ||
|
|
ec6518ccbf | ||
|
|
3454c13e4a | ||
|
|
796a70aabc | ||
|
|
099588665a | ||
|
|
246486a46e | ||
|
|
22b1fda1d5 | ||
|
|
cd38dbc1ae | ||
|
|
029b32f722 | ||
|
|
cf9ec7683b | ||
|
|
a093a1fbba | ||
|
|
c9b22b2a36 |
19
.github/workflows/builder.yml
vendored
19
.github/workflows/builder.yml
vendored
@@ -1,19 +0,0 @@
|
|||||||
name: PCR builder
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container: devkitpro/devkita64_devkitarm
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
|
|
||||||
- name: Build PCR
|
|
||||||
run: make -j$(nproc)
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@master
|
|
||||||
with:
|
|
||||||
name: CommonProblemResolver
|
|
||||||
path: output/CommonProblemResolver.bin
|
|
||||||
52
.github/workflows/main.yml
vendored
Normal file
52
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [ created ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_and_release:
|
||||||
|
name: Build and release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: devkitpro/devkita64:latest
|
||||||
|
if: contains(github.event.comment.body, '/release-action')
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Update latest libnx
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory "*"
|
||||||
|
git clone --recurse-submodules https://github.com/zdm65477730/libnx.git
|
||||||
|
cd libnx
|
||||||
|
make install -j$(nproc)
|
||||||
|
shell: bash
|
||||||
|
- name: Checkout latest code
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
with:
|
||||||
|
ref: master
|
||||||
|
clean: true
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
submodules: recursive
|
||||||
|
- name: Setup ENV parameters
|
||||||
|
run: |
|
||||||
|
VER_FILE=Makefile
|
||||||
|
VERSION=$(awk '/^LPVERSION_MAJOR/{print $3}' $VER_FILE).$(awk '/^LPVERSION_MINOR/{print $3}' $VER_FILE).$(awk '/^LPVERSION_BUGFX/{print $3}' $VER_FILE)
|
||||||
|
echo "TAG=${VERSION}" >> "${GITHUB_ENV}"
|
||||||
|
echo "RELEASE_NAME=CommonProblemResolver ${VERSION}" >> "${GITHUB_ENV}"
|
||||||
|
shell: bash
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
export DEVKITPRO=/opt/devkitpro
|
||||||
|
make all
|
||||||
|
shell: bash
|
||||||
|
- name: Upload Release Asset
|
||||||
|
uses: softprops/action-gh-release@v2.0.9
|
||||||
|
with:
|
||||||
|
name: ${{ env.RELEASE_NAME }}
|
||||||
|
tag_name: ${{ env.TAG }}
|
||||||
|
draft: false
|
||||||
|
prerelease: false
|
||||||
|
generate_release_notes: yes
|
||||||
|
make_latest: true
|
||||||
|
files: |
|
||||||
|
output/CommonProblemResolver.bin
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
#include <input/als.h>
|
#include <input/als.h>
|
||||||
#include <input/joycon.h>
|
#include <input/joycon.h>
|
||||||
#include <input/touch.h>
|
#include <input/touch.h>
|
||||||
#include <mem/emc.h>
|
#include <mem/emc_t210.h>
|
||||||
#include <mem/heap.h>
|
#include <mem/heap.h>
|
||||||
#include <mem/mc.h>
|
#include <mem/mc.h>
|
||||||
#include <mem/minerva.h>
|
#include <mem/minerva.h>
|
||||||
@@ -49,6 +49,7 @@
|
|||||||
#include <soc/gpio.h>
|
#include <soc/gpio.h>
|
||||||
#include <soc/hw_init.h>
|
#include <soc/hw_init.h>
|
||||||
#include <soc/i2c.h>
|
#include <soc/i2c.h>
|
||||||
|
#include <soc/irq.h>
|
||||||
#include <soc/kfuse.h>
|
#include <soc/kfuse.h>
|
||||||
#include <soc/pinmux.h>
|
#include <soc/pinmux.h>
|
||||||
#include <soc/pmc.h>
|
#include <soc/pmc.h>
|
||||||
@@ -57,7 +58,7 @@
|
|||||||
#include <soc/uart.h>
|
#include <soc/uart.h>
|
||||||
#include <storage/emmc.h>
|
#include <storage/emmc.h>
|
||||||
#include <storage/mbr_gpt.h>
|
#include <storage/mbr_gpt.h>
|
||||||
#include <storage/mmc.h>
|
#include <storage/mmc_def.h>
|
||||||
#include <storage/nx_emmc_bis.h>
|
#include <storage/nx_emmc_bis.h>
|
||||||
#include <storage/ramdisk.h>
|
#include <storage/ramdisk.h>
|
||||||
#include <storage/sd.h>
|
#include <storage/sd.h>
|
||||||
@@ -71,6 +72,8 @@
|
|||||||
#include <utils/ini.h>
|
#include <utils/ini.h>
|
||||||
#include <utils/list.h>
|
#include <utils/list.h>
|
||||||
#include <utils/sprintf.h>
|
#include <utils/sprintf.h>
|
||||||
|
#include <utils/tegra_bct.h>
|
||||||
|
#include <utils/tegra_bit.h>
|
||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
#include <utils/util.h>
|
#include <utils/util.h>
|
||||||
|
|
||||||
|
|||||||
315
bdk/display/di.c
315
bdk/display/di.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2023 CTCaer
|
* Copyright (c) 2018-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
#include "di.h"
|
#include "di.h"
|
||||||
#include <power/max77620.h>
|
#include <power/max77620.h>
|
||||||
#include <power/max7762x.h>
|
#include <power/max7762x.h>
|
||||||
#include <mem/heap.h>
|
|
||||||
#include <soc/clock.h>
|
#include <soc/clock.h>
|
||||||
#include <soc/fuse.h>
|
#include <soc/fuse.h>
|
||||||
#include <soc/gpio.h>
|
#include <soc/gpio.h>
|
||||||
@@ -37,11 +36,31 @@
|
|||||||
extern volatile nyx_storage_t *nyx_str;
|
extern volatile nyx_storage_t *nyx_str;
|
||||||
|
|
||||||
static u32 _display_id = 0;
|
static u32 _display_id = 0;
|
||||||
static u32 _dsi_bl = -1;
|
static u32 _dsi_bl = -1;
|
||||||
static bool _nx_aula = false;
|
static bool _nx_aula = false;
|
||||||
|
|
||||||
static void _display_panel_and_hw_end(bool no_panel_deinit);
|
static void _display_panel_and_hw_end(bool no_panel_deinit);
|
||||||
|
|
||||||
|
void display_enable_interrupt(u32 intr)
|
||||||
|
{
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) |= intr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_disable_interrupt(u32 intr)
|
||||||
|
{
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) &= ~intr;
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = intr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_wait_interrupt(u32 intr)
|
||||||
|
{
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = intr;
|
||||||
|
|
||||||
|
// Interrupts are masked. Poll status register for checking if fired.
|
||||||
|
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & intr))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
|
static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
|
||||||
{
|
{
|
||||||
u32 end = get_tmr_us() + timeout;
|
u32 end = get_tmr_us() + timeout;
|
||||||
@@ -64,22 +83,18 @@ static void _display_dsi_wait_vblank(bool enable)
|
|||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
// Enable vblank interrupt.
|
// Enable vblank interrupt.
|
||||||
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = DC_CMD_INT_FRAME_END_INT;
|
display_enable_interrupt(DC_CMD_INT_FRAME_END_INT);
|
||||||
|
|
||||||
// Use the 4th line to transmit the host cmd packet.
|
// Use the 4th line to transmit the host cmd packet.
|
||||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4);
|
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4);
|
||||||
|
|
||||||
// Wait for vblank before starting the transfer.
|
// Wait for vblank before starting the transfer.
|
||||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
|
display_wait_interrupt(DC_CMD_INT_FRAME_END_INT);
|
||||||
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT))
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Wait for vblank before reseting sync points.
|
// Wait for vblank before resetting sync points.
|
||||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
|
display_wait_interrupt(DC_CMD_INT_FRAME_END_INT);
|
||||||
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT))
|
|
||||||
;
|
|
||||||
usleep(14);
|
usleep(14);
|
||||||
|
|
||||||
// Reset all states of syncpt block.
|
// Reset all states of syncpt block.
|
||||||
@@ -94,8 +109,7 @@ static void _display_dsi_wait_vblank(bool enable)
|
|||||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||||
|
|
||||||
// Disable and clear vblank interrupt.
|
// Disable and clear vblank interrupt.
|
||||||
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = 0;
|
display_disable_interrupt(DC_CMD_INT_FRAME_END_INT);
|
||||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +131,6 @@ static void _display_dsi_read_rx_fifo(u32 *data)
|
|||||||
|
|
||||||
int display_dsi_read(u8 cmd, u32 len, void *data)
|
int display_dsi_read(u8 cmd, u32 len, void *data)
|
||||||
{
|
{
|
||||||
int res = 0;
|
|
||||||
u32 fifo[DSI_STATUS_RX_FIFO_SIZE] = {0};
|
u32 fifo[DSI_STATUS_RX_FIFO_SIZE] = {0};
|
||||||
|
|
||||||
// Drain RX FIFO.
|
// Drain RX FIFO.
|
||||||
@@ -166,14 +179,13 @@ int display_dsi_read(u8 cmd, u32 len, void *data)
|
|||||||
|
|
||||||
case ACK_ERROR_RES:
|
case ACK_ERROR_RES:
|
||||||
default:
|
default:
|
||||||
res = 1;
|
return 1;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
res = 1;
|
return 1;
|
||||||
|
|
||||||
return res;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int display_dsi_vblank_read(u8 cmd, u32 len, void *data)
|
int display_dsi_vblank_read(u8 cmd, u32 len, void *data)
|
||||||
@@ -250,16 +262,9 @@ int display_dsi_vblank_read(u8 cmd, u32 len, void *data)
|
|||||||
|
|
||||||
void display_dsi_write(u8 cmd, u32 len, void *data)
|
void display_dsi_write(u8 cmd, u32 len, void *data)
|
||||||
{
|
{
|
||||||
static u8 *fifo8 = NULL;
|
|
||||||
static u32 *fifo32 = NULL;
|
|
||||||
u32 host_control;
|
u32 host_control;
|
||||||
|
u32 fifo32[DSI_STATUS_TX_FIFO_SIZE] = {0};
|
||||||
// Allocate fifo buffer.
|
u8 *fifo8 = (u8 *)fifo32;
|
||||||
if (!fifo32)
|
|
||||||
{
|
|
||||||
fifo32 = malloc(DSI_STATUS_RX_FIFO_SIZE * 8 * sizeof(u32));
|
|
||||||
fifo8 = (u8 *)fifo32;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare data for long write.
|
// Prepare data for long write.
|
||||||
if (len >= 2)
|
if (len >= 2)
|
||||||
@@ -304,15 +309,8 @@ void display_dsi_write(u8 cmd, u32 len, void *data)
|
|||||||
|
|
||||||
void display_dsi_vblank_write(u8 cmd, u32 len, void *data)
|
void display_dsi_vblank_write(u8 cmd, u32 len, void *data)
|
||||||
{
|
{
|
||||||
static u8 *fifo8 = NULL;
|
u32 fifo32[DSI_STATUS_TX_FIFO_SIZE] = {0};
|
||||||
static u32 *fifo32 = NULL;
|
u8 *fifo8 = (u8 *)fifo32;
|
||||||
|
|
||||||
// Allocate fifo buffer.
|
|
||||||
if (!fifo32)
|
|
||||||
{
|
|
||||||
fifo32 = malloc(DSI_STATUS_RX_FIFO_SIZE * 8 * sizeof(u32));
|
|
||||||
fifo8 = (u8 *)fifo32;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare data for long write.
|
// Prepare data for long write.
|
||||||
if (len >= 2)
|
if (len >= 2)
|
||||||
@@ -358,24 +356,10 @@ void display_init()
|
|||||||
// Get Chip ID.
|
// Get Chip ID.
|
||||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||||
|
|
||||||
// T210B01: Power on SD2 regulator for supplying LDO0.
|
// Enable DSI AVDD.
|
||||||
if (!tegra_t210)
|
|
||||||
{
|
|
||||||
// Set SD2 regulator voltage.
|
|
||||||
max7762x_regulator_set_voltage(REGULATOR_SD2, 1325000);
|
|
||||||
|
|
||||||
// Set slew rate and enable SD2 regulator.
|
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD2_CFG, (1 << MAX77620_SD_SR_SHIFT) | MAX77620_SD_CFG1_FSRADE_SD_ENABLE);
|
|
||||||
max7762x_regulator_enable(REGULATOR_SD2, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable LCD DVDD.
|
|
||||||
max7762x_regulator_set_voltage(REGULATOR_LDO0, 1200000);
|
max7762x_regulator_set_voltage(REGULATOR_LDO0, 1200000);
|
||||||
max7762x_regulator_enable(REGULATOR_LDO0, true);
|
max7762x_regulator_enable(REGULATOR_LDO0, true);
|
||||||
|
|
||||||
if (tegra_t210)
|
|
||||||
max77620_config_gpio(7, MAX77620_GPIO_OUTPUT_ENABLE); // T210: LD0 -> GPIO7 -> LCD.
|
|
||||||
|
|
||||||
// Enable Display Interface specific clocks.
|
// Enable Display Interface specific clocks.
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||||
@@ -383,12 +367,12 @@ void display_init()
|
|||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_DISP1);
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_DISP1);
|
||||||
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL);
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL);
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = 10; // Set PLLP_OUT3 and div 6 (17MHz).
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = CLK_SRC_DIV(6); // Set PLLP_OUT3 and div 6 (68MHz).
|
||||||
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP);
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP);
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz).
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = CLK_SRC_DIV(6); // Set PLLP_OUT and div 6 (68MHz).
|
||||||
|
|
||||||
// Bring every IO rail out of deep power down.
|
// Bring every IO rail out of deep power down. (Though no rail bit is set.)
|
||||||
PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
||||||
PMC(APBDEV_PMC_IO_DPD2_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
PMC(APBDEV_PMC_IO_DPD2_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
||||||
|
|
||||||
@@ -427,32 +411,25 @@ void display_init()
|
|||||||
APB_MISC(APB_MISC_GP_DSI_PAD_CONTROL) = 0;
|
APB_MISC(APB_MISC_GP_DSI_PAD_CONTROL) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set DISP1 clock source, parent clock and DSI/PCLK to low power mode.
|
// Set DISP1 clock source, parent clock and DSI/PCLK to command mode.
|
||||||
// T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-PCLK): 50.0 MHz. (PCLK: 16.66 MHz)
|
// T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-BCLK): 50.0 MHz. (PCLK: 16.66 MHz)
|
||||||
// T210B01: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 97.8 MHz, PLLD_OUT0 (DSI-PCLK): 48.9 MHz. (PCLK: 16.30 MHz)
|
// T210B01: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 97.8 MHz, PLLD_OUT0 (DSI-BCLK): 48.9 MHz. (PCLK: 16.30 MHz)
|
||||||
clock_enable_plld(3, 20, true, tegra_t210);
|
clock_enable_plld(3, 20, true, tegra_t210);
|
||||||
|
|
||||||
// Setup Display Interface initial window configuration.
|
// Setup Display Interface initial window configuration.
|
||||||
exec_cfg((u32 *)DISPLAY_A_BASE, _di_dc_setup_win_config, CFG_SIZE(_di_dc_setup_win_config));
|
reg_write_array((u32 *)DISPLAY_A_BASE, _di_dc_setup_win_config, ARRAY_SIZE(_di_dc_setup_win_config));
|
||||||
|
|
||||||
// Setup dsi init sequence packets.
|
// Setup dsi init sequence packets.
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_irq_pkt_config0, CFG_SIZE(_di_dsi_init_irq_pkt_config0));
|
reg_write_array((u32 *)DSI_BASE, _di_dsi_seq_pkt_reset_config0, ARRAY_SIZE(_di_dsi_seq_pkt_reset_config0));
|
||||||
if (tegra_t210)
|
DSI(_DSIREG(tegra_t210 ? DSI_INIT_SEQ_DATA_15 : DSI_INIT_SEQ_DATA_15_B01)) = 0;
|
||||||
DSI(_DSIREG(DSI_INIT_SEQ_DATA_15)) = 0;
|
reg_write_array((u32 *)DSI_BASE, _di_dsi_seq_pkt_reset_config1, ARRAY_SIZE(_di_dsi_seq_pkt_reset_config1));
|
||||||
else
|
|
||||||
DSI(_DSIREG(DSI_INIT_SEQ_DATA_15_B01)) = 0;
|
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_irq_pkt_config1, CFG_SIZE(_di_dsi_init_irq_pkt_config1));
|
|
||||||
|
|
||||||
// Reset pad trimmers for T210B01.
|
// Reset pad trimmers for T210B01.
|
||||||
if (!tegra_t210)
|
if (!tegra_t210)
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_pads_t210b01, CFG_SIZE(_di_dsi_init_pads_t210b01));
|
reg_write_array((u32 *)DSI_BASE, _di_dsi_init_pads_t210b01, ARRAY_SIZE(_di_dsi_init_pads_t210b01));
|
||||||
|
|
||||||
// Setup init sequence packets and timings.
|
// Setup init seq packet lengths, timings and power on DSI.
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_timing_pkt_config2, CFG_SIZE(_di_dsi_init_timing_pkt_config2));
|
reg_write_array((u32 *)DSI_BASE, _di_dsi_init_config, ARRAY_SIZE(_di_dsi_init_config));
|
||||||
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603; // DSI_THSPREPR: 1 : 3.
|
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_timing_pwrctrl_config, CFG_SIZE(_di_dsi_init_timing_pwrctrl_config));
|
|
||||||
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603; // DSI_THSPREPR: 1 : 3.
|
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_timing_pkt_config3, CFG_SIZE(_di_dsi_init_timing_pkt_config3));
|
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
|
|
||||||
// Enable LCD Reset.
|
// Enable LCD Reset.
|
||||||
@@ -490,9 +467,9 @@ void display_init()
|
|||||||
{
|
{
|
||||||
case PANEL_SAM_AMS699VC01:
|
case PANEL_SAM_AMS699VC01:
|
||||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
|
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
|
||||||
// Set color mode to natural. Stock is Saturated (0x00). (Reset value is 0x20).
|
// Set color mode to basic (natural). Stock is Saturated (0x00). (Reset value is 0x20).
|
||||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM,
|
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM,
|
||||||
MIPI_DCS_PRIV_SM_SET_COLOR_MODE | (DCS_SM_COLOR_MODE_NATURAL << 8), 0);
|
MIPI_DCS_PRIV_SM_SET_COLOR_MODE | (DCS_SM_COLOR_MODE_BASIC << 8), 0);
|
||||||
// Enable backlight and smooth PWM.
|
// Enable backlight and smooth PWM.
|
||||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM,
|
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM,
|
||||||
MIPI_DCS_SET_CONTROL_DISPLAY | ((DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL | DCS_CONTROL_DISPLAY_DIMMING_CTRL) << 8), 0);
|
MIPI_DCS_SET_CONTROL_DISPLAY | ((DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL | DCS_CONTROL_DISPLAY_DIMMING_CTRL) << 8), 0);
|
||||||
@@ -522,7 +499,7 @@ void display_init()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PANEL_JDI_XXX062M:
|
case PANEL_JDI_XXX062M:
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_panel_init_config_jdi, CFG_SIZE(_di_dsi_panel_init_config_jdi));
|
reg_write_array((u32 *)DSI_BASE, _di_dsi_panel_init_config_jdi, ARRAY_SIZE(_di_dsi_panel_init_config_jdi));
|
||||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
|
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -558,26 +535,29 @@ void display_init()
|
|||||||
// Unblank display.
|
// Unblank display.
|
||||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000);
|
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000);
|
||||||
|
|
||||||
// Setup final dsi clock.
|
// Switch to DSI HS mode.
|
||||||
// DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 468.0 MHz, PLLD_OUT0 (DSI): 234.0 MHz.
|
// DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 468.0 MHz, PLLD_OUT0 (DSI-BCLK): 234.0 MHz. (PCLK: 78 MHz)
|
||||||
clock_enable_plld(1, 24, false, tegra_t210);
|
clock_enable_plld(1, 24, false, tegra_t210);
|
||||||
|
|
||||||
// Finalize DSI init packet sequence configuration.
|
// Set HS PHY timing and finalize DSI packet sequence configuration.
|
||||||
DSI(_DSIREG(DSI_PAD_CONTROL_1)) = 0;
|
reg_write_array((u32 *)DSI_BASE, _di_dsi_seq_pkt_video_non_burst_no_eot_config, ARRAY_SIZE(_di_dsi_seq_pkt_video_non_burst_no_eot_config));
|
||||||
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
|
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_seq_pkt_final_config, CFG_SIZE(_di_dsi_init_seq_pkt_final_config));
|
|
||||||
|
|
||||||
// Set 1-by-1 pixel/clock and pixel clock to 234 / 3 = 78 MHz. For 60 Hz refresh rate.
|
// Set 1-by-1 pixel/clock and pixel clock to 234 / 3 = 78 MHz. For 60 Hz refresh rate.
|
||||||
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4); // 4: div3.
|
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4); // 4: div3.
|
||||||
|
|
||||||
// Set DSI mode.
|
// Set DSI mode to HOST.
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_mode_config, CFG_SIZE(_di_dsi_mode_config));
|
reg_write_array((u32 *)DSI_BASE, _di_dsi_host_mode_config, ARRAY_SIZE(_di_dsi_host_mode_config));
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
|
|
||||||
// Calibrate display communication pads.
|
/*
|
||||||
u32 loops = tegra_t210 ? 1 : 2; // Calibrate pads 2 times on T210B01.
|
* Calibrate display communication pads.
|
||||||
exec_cfg((u32 *)MIPI_CAL_BASE, _di_mipi_pad_cal_config, CFG_SIZE(_di_mipi_pad_cal_config));
|
* When switching to the 16ff pad brick, the clock lane termination control
|
||||||
for (u32 i = 0; i < loops; i++)
|
* is separated from data lane termination. This change of the mipi cal
|
||||||
|
* brings in a bug that the DSI pad clock termination code can't be loaded
|
||||||
|
* in one time calibration on T210B01. Trigger calibration twice.
|
||||||
|
*/
|
||||||
|
reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_pad_cal_config, ARRAY_SIZE(_di_mipi_pad_cal_config));
|
||||||
|
for (u32 i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
// Set MIPI bias pad config.
|
// Set MIPI bias pad config.
|
||||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0x10010;
|
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0x10010;
|
||||||
@@ -586,22 +566,25 @@ void display_init()
|
|||||||
// Set pad trimmers and set MIPI DSI cal offsets.
|
// Set pad trimmers and set MIPI DSI cal offsets.
|
||||||
if (tegra_t210)
|
if (tegra_t210)
|
||||||
{
|
{
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_pad_cal_config_t210, CFG_SIZE(_di_dsi_pad_cal_config_t210));
|
reg_write_array((u32 *)DSI_BASE, _di_dsi_pad_cal_config_t210, ARRAY_SIZE(_di_dsi_pad_cal_config_t210));
|
||||||
exec_cfg((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_offsets_config_t210, CFG_SIZE(_di_mipi_dsi_cal_offsets_config_t210));
|
reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_prod_config_t210, ARRAY_SIZE(_di_mipi_dsi_cal_prod_config_t210));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_pad_cal_config_t210b01, CFG_SIZE(_di_dsi_pad_cal_config_t210b01));
|
reg_write_array((u32 *)DSI_BASE, _di_dsi_pad_cal_config_t210b01, ARRAY_SIZE(_di_dsi_pad_cal_config_t210b01));
|
||||||
exec_cfg((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_offsets_config_t210b01, CFG_SIZE(_di_mipi_dsi_cal_offsets_config_t210b01));
|
reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_prod_config_t210b01, ARRAY_SIZE(_di_mipi_dsi_cal_prod_config_t210b01));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset all MIPI cal offsets and start calibration.
|
// Reset all unused MIPI cal offsets.
|
||||||
exec_cfg((u32 *)MIPI_CAL_BASE, _di_mipi_start_dsi_cal_config, CFG_SIZE(_di_mipi_start_dsi_cal_config));
|
reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_unused_config, ARRAY_SIZE(_di_mipi_dsi_cal_unused_config));
|
||||||
|
|
||||||
|
// Set Prescale/filter and start calibration.
|
||||||
|
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_CAL_CTRL)) = 0x2A000001;
|
||||||
}
|
}
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
|
|
||||||
// Enable video display controller.
|
// Enable video display controller.
|
||||||
exec_cfg((u32 *)DISPLAY_A_BASE, _di_dc_video_enable_config, CFG_SIZE(_di_dc_video_enable_config));
|
reg_write_array((u32 *)DISPLAY_A_BASE, _di_dc_video_enable_config, ARRAY_SIZE(_di_dc_video_enable_config));
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_backlight_pwm_init()
|
void display_backlight_pwm_init()
|
||||||
@@ -609,12 +592,15 @@ void display_backlight_pwm_init()
|
|||||||
if (_display_id == PANEL_SAM_AMS699VC01)
|
if (_display_id == PANEL_SAM_AMS699VC01)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Enable PWM clock.
|
||||||
clock_enable_pwm();
|
clock_enable_pwm();
|
||||||
|
|
||||||
// Enable PWM and set it to 25KHz PFM. 29.5KHz is stock.
|
// Enable PWM and set it to 25KHz PFM. 29.5KHz is stock.
|
||||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN;
|
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN;
|
||||||
|
|
||||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
|
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
|
||||||
|
usleep(2);
|
||||||
|
|
||||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode.
|
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,9 +621,9 @@ static void _display_dsi_backlight_brightness(u32 duty)
|
|||||||
u16 bl_ctrl = byte_swap_16((u16)candela);
|
u16 bl_ctrl = byte_swap_16((u16)candela);
|
||||||
display_dsi_vblank_write(MIPI_DCS_SET_BRIGHTNESS, 2, &bl_ctrl);
|
display_dsi_vblank_write(MIPI_DCS_SET_BRIGHTNESS, 2, &bl_ctrl);
|
||||||
|
|
||||||
// Wait for backlight to completely turn off. 6+1 frames.
|
// Wait for backlight to completely turn off. 6 frames.
|
||||||
if (!duty)
|
if (!duty)
|
||||||
usleep(120000);
|
usleep(100000);
|
||||||
|
|
||||||
_dsi_bl = duty;
|
_dsi_bl = duty;
|
||||||
}
|
}
|
||||||
@@ -681,7 +667,10 @@ void display_backlight_brightness(u32 brightness, u32 step_delay)
|
|||||||
|
|
||||||
u32 display_get_backlight_brightness()
|
u32 display_get_backlight_brightness()
|
||||||
{
|
{
|
||||||
return ((PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF);
|
if (_display_id != PANEL_SAM_AMS699VC01)
|
||||||
|
return ((PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF);
|
||||||
|
else
|
||||||
|
return _dsi_bl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _display_panel_and_hw_end(bool no_panel_deinit)
|
static void _display_panel_and_hw_end(bool no_panel_deinit)
|
||||||
@@ -698,22 +687,23 @@ static void _display_panel_and_hw_end(bool no_panel_deinit)
|
|||||||
DSI(_DSIREG(DSI_WR_DATA)) = (MIPI_DCS_SET_DISPLAY_OFF << 8) | MIPI_DSI_DCS_SHORT_WRITE;
|
DSI(_DSIREG(DSI_WR_DATA)) = (MIPI_DCS_SET_DISPLAY_OFF << 8) | MIPI_DSI_DCS_SHORT_WRITE;
|
||||||
|
|
||||||
// Wait for 5 frames (HOST1X_CH0_SYNC_SYNCPT_9).
|
// Wait for 5 frames (HOST1X_CH0_SYNC_SYNCPT_9).
|
||||||
// Not here.
|
// Not here. Wait for 1 frame manually.
|
||||||
|
usleep(20000);
|
||||||
|
|
||||||
// Propagate changes to all register buffers and disable host cmd packets during video.
|
// Propagate changes to all register buffers and disable host cmd packets during video.
|
||||||
DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX;
|
DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX_ACTIVE | WRITE_MUX_ACTIVE;
|
||||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||||
|
|
||||||
// De-initialize video controller.
|
// De-initialize video controller.
|
||||||
exec_cfg((u32 *)DISPLAY_A_BASE, _di_dc_video_disable_config, CFG_SIZE(_di_dc_video_disable_config));
|
reg_write_array((u32 *)DISPLAY_A_BASE, _di_dc_video_disable_config, ARRAY_SIZE(_di_dc_video_disable_config));
|
||||||
|
|
||||||
// Set DISP1 clock source, parent clock and DSI/PCLK to low power mode.
|
// Set DISP1 clock source, parent clock and DSI/PCLK to command mode.
|
||||||
// T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-PCLK): 50.0 MHz. (PCLK: 16.66 MHz)
|
// T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-BCLK): 50.0 MHz. (PCLK: 16.66 MHz)
|
||||||
// T210B01: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 97.8 MHz, PLLD_OUT0 (DSI-PCLK): 48.9 MHz. (PCLK: 16.30 MHz)
|
// T210B01: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 97.8 MHz, PLLD_OUT0 (DSI-BCLK): 48.9 MHz. (PCLK: 16.30 MHz)
|
||||||
clock_enable_plld(3, 20, true, hw_get_chip_id() == GP_HIDREV_MAJOR_T210);
|
clock_enable_plld(3, 20, true, hw_get_chip_id() == GP_HIDREV_MAJOR_T210);
|
||||||
|
|
||||||
// Set timings for lowpower clocks.
|
// Set timings for lowpower clocks.
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_timing_deinit_config, CFG_SIZE(_di_dsi_timing_deinit_config));
|
reg_write_array((u32 *)DSI_BASE, _di_dsi_timing_deinit_config, ARRAY_SIZE(_di_dsi_timing_deinit_config));
|
||||||
|
|
||||||
if (_display_id != PANEL_SAM_AMS699VC01)
|
if (_display_id != PANEL_SAM_AMS699VC01)
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
@@ -722,11 +712,12 @@ static void _display_panel_and_hw_end(bool no_panel_deinit)
|
|||||||
switch (_display_id)
|
switch (_display_id)
|
||||||
{
|
{
|
||||||
case PANEL_JDI_XXX062M:
|
case PANEL_JDI_XXX062M:
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_panel_deinit_config_jdi, CFG_SIZE(_di_dsi_panel_deinit_config_jdi));
|
reg_write_array((u32 *)DSI_BASE, _di_dsi_panel_deinit_config_jdi, ARRAY_SIZE(_di_dsi_panel_deinit_config_jdi));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PANEL_AUO_A062TAN01:
|
case PANEL_AUO_A062TAN01:
|
||||||
exec_cfg((u32 *)DSI_BASE, _di_dsi_panel_deinit_config_auo, CFG_SIZE(_di_dsi_panel_deinit_config_auo));
|
reg_write_array((u32 *)DSI_BASE, _di_dsi_panel_deinit_config_auo, ARRAY_SIZE(_di_dsi_panel_deinit_config_auo));
|
||||||
|
usleep(5000);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PANEL_INL_2J055IA_27A:
|
case PANEL_INL_2J055IA_27A:
|
||||||
@@ -781,6 +772,10 @@ skip_panel_deinit:
|
|||||||
{
|
{
|
||||||
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); // LCD AVDD -5.4V disable.
|
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); // LCD AVDD -5.4V disable.
|
||||||
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); // LCD AVDD +5.4V disable.
|
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); // LCD AVDD +5.4V disable.
|
||||||
|
|
||||||
|
// Make sure LCD PWM backlight pin is in PWM0 mode.
|
||||||
|
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM.
|
||||||
|
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = PINMUX_TRISTATE | PINMUX_PULL_DOWN | 1; // Set PWM0 mode.
|
||||||
}
|
}
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
|
|
||||||
@@ -795,14 +790,7 @@ skip_panel_deinit:
|
|||||||
DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);
|
DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);
|
||||||
DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;
|
DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;
|
||||||
|
|
||||||
// Switch LCD PWM backlight pin to special function mode and enable PWM0 mode.
|
// Disable DSI AVDD.
|
||||||
if (!_nx_aula)
|
|
||||||
{
|
|
||||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM.
|
|
||||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = PINMUX_TRISTATE | PINMUX_PULL_DOWN | 1; // Set PWM0 mode.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable LCD DVDD.
|
|
||||||
max7762x_regulator_enable(REGULATOR_LDO0, false);
|
max7762x_regulator_enable(REGULATOR_LDO0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -831,14 +819,15 @@ void display_set_decoded_panel_id(u32 id)
|
|||||||
|
|
||||||
void display_color_screen(u32 color)
|
void display_color_screen(u32 color)
|
||||||
{
|
{
|
||||||
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_one_color, CFG_SIZE(_di_win_one_color));
|
// Disable all windows.
|
||||||
|
reg_write_array((u32 *)DISPLAY_A_BASE, _di_win_one_color, ARRAY_SIZE(_di_win_one_color));
|
||||||
|
|
||||||
// Configure display to show single color.
|
// Configure display to show single color.
|
||||||
DISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0;
|
|
||||||
DISPLAY_A(_DIREG(DC_WIN_BD_WIN_OPTIONS)) = 0;
|
|
||||||
DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;
|
|
||||||
DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
|
DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
|
||||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ;
|
|
||||||
|
// Arm and activate changes.
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE | WIN_D_UPDATE;
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ | WIN_D_ACT_REQ;
|
||||||
usleep(35000); // Wait 2 frames. No need on Aula.
|
usleep(35000); // Wait 2 frames. No need on Aula.
|
||||||
|
|
||||||
if (_display_id != PANEL_SAM_AMS699VC01)
|
if (_display_id != PANEL_SAM_AMS699VC01)
|
||||||
@@ -847,58 +836,108 @@ void display_color_screen(u32 color)
|
|||||||
display_backlight_brightness(150, 0);
|
display_backlight_brightness(150, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *display_init_framebuffer_pitch()
|
u32 *display_init_window_a_pitch()
|
||||||
{
|
{
|
||||||
// Sanitize framebuffer area.
|
// Sanitize framebuffer area.
|
||||||
memset((u32 *)IPL_FB_ADDRESS, 0, IPL_FB_SZ);
|
memset((u32 *)IPL_FB_ADDRESS, 0, IPL_FB_SZ);
|
||||||
|
|
||||||
// This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
|
// This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
|
||||||
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_pitch, CFG_SIZE(_di_win_framebuffer_pitch));
|
reg_write_array((u32 *)DISPLAY_A_BASE, _di_winA_pitch, ARRAY_SIZE(_di_winA_pitch));
|
||||||
//usleep(35000); // Wait 2 frames. No need on Aula.
|
//usleep(35000); // Wait 2 frames. No need on Aula.
|
||||||
|
|
||||||
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *display_init_framebuffer_pitch_vic()
|
u32 *display_init_window_a_pitch_vic()
|
||||||
{
|
{
|
||||||
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
|
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
|
||||||
if (_display_id != PANEL_SAM_AMS699VC01)
|
if (_display_id != PANEL_SAM_AMS699VC01)
|
||||||
usleep(8000); // Wait half frame for PWM to apply.
|
usleep(8000); // Wait half frame for PWM to apply.
|
||||||
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_pitch_vic, CFG_SIZE(_di_win_framebuffer_pitch_vic));
|
reg_write_array((u32 *)DISPLAY_A_BASE, _di_winA_pitch_vic, ARRAY_SIZE(_di_winA_pitch_vic));
|
||||||
if (_display_id != PANEL_SAM_AMS699VC01)
|
if (_display_id != PANEL_SAM_AMS699VC01)
|
||||||
usleep(35000); // Wait 2 frames.
|
usleep(35000); // Wait 2 frames.
|
||||||
|
|
||||||
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *display_init_framebuffer_pitch_inv()
|
u32 *display_init_window_a_pitch_inv()
|
||||||
{
|
{
|
||||||
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
|
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
|
||||||
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_pitch_inv, CFG_SIZE(_di_win_framebuffer_pitch_inv));
|
reg_write_array((u32 *)DISPLAY_A_BASE, _di_winA_pitch_inv, ARRAY_SIZE(_di_winA_pitch_inv));
|
||||||
usleep(35000); // Wait 2 frames. No need on Aula.
|
usleep(35000); // Wait 2 frames. No need on Aula.
|
||||||
|
|
||||||
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *display_init_framebuffer_block()
|
u32 *display_init_window_a_block()
|
||||||
{
|
{
|
||||||
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280.
|
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280.
|
||||||
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_block, CFG_SIZE(_di_win_framebuffer_block));
|
reg_write_array((u32 *)DISPLAY_A_BASE, _di_winA_block, ARRAY_SIZE(_di_winA_block));
|
||||||
usleep(35000); // Wait 2 frames. No need on Aula.
|
usleep(35000); // Wait 2 frames. No need on Aula.
|
||||||
|
|
||||||
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *display_init_framebuffer_log()
|
u32 *display_init_window_d_console()
|
||||||
{
|
{
|
||||||
// This configures the framebuffer @ LOG_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
// This configures the framebuffer @ LOG_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||||
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_log, CFG_SIZE(_di_win_framebuffer_log));
|
reg_write_array((u32 *)DISPLAY_A_BASE, _di_winD_log, ARRAY_SIZE(_di_winD_log));
|
||||||
|
|
||||||
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_activate_console()
|
void display_window_disable(u32 window)
|
||||||
{
|
{
|
||||||
|
// Select window C.
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = BIT(WINDOW_SELECT + window);
|
||||||
|
|
||||||
|
// Disable window C.
|
||||||
|
DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0;
|
||||||
|
|
||||||
|
// Arm and activate changes.
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | BIT(WIN_UPDATE + window);
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | BIT(WIN_ACT_REQ + window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_set_framebuffer(u32 window, void *fb)
|
||||||
|
{
|
||||||
|
// Select window.
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = BIT(WINDOW_SELECT + window);
|
||||||
|
|
||||||
|
// Set new fb address.
|
||||||
|
DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)) = (u32)fb;
|
||||||
|
|
||||||
|
// Arm and activate changes.
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | BIT(WIN_UPDATE + window);
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | BIT(WIN_ACT_REQ + window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_move_framebuffer(u32 window, void *fb)
|
||||||
|
{
|
||||||
|
// Select window.
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = BIT(WINDOW_SELECT + window);
|
||||||
|
|
||||||
|
// Get current framebuffer address.
|
||||||
|
const void *fb_curr = (void *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
|
||||||
|
u32 win_size = DISPLAY_A(_DIREG(DC_WIN_PRESCALED_SIZE));
|
||||||
|
win_size = (win_size & 0x7FFF) * ((win_size >> 16) & 0x1FFF);
|
||||||
|
|
||||||
|
// Copy fb over.
|
||||||
|
memcpy(fb, fb_curr, win_size);
|
||||||
|
|
||||||
|
// Set new fb address.
|
||||||
|
DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)) = (u32)fb;
|
||||||
|
|
||||||
|
// Arm and activate changes.
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | BIT(WIN_UPDATE + window);
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | BIT(WIN_ACT_REQ + window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_window_d_console_enable()
|
||||||
|
{
|
||||||
|
// Only update active registers on vsync.
|
||||||
|
DISPLAY_A(_DIREG(DC_CMD_REG_ACT_CONTROL)) = DISPLAY_A(_DIREG(DC_CMD_REG_ACT_CONTROL)) & ~WIN_D_ACT_HCNTR_SEL;
|
||||||
|
|
||||||
// Select window D.
|
// Select window D.
|
||||||
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT;
|
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT;
|
||||||
|
|
||||||
@@ -927,12 +966,9 @@ void display_activate_console()
|
|||||||
// Arm and activate changes.
|
// Arm and activate changes.
|
||||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||||
|
|
||||||
// Re-select window A.
|
|
||||||
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_A_SELECT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_deactivate_console()
|
void display_window_d_console_disable()
|
||||||
{
|
{
|
||||||
// Select window D.
|
// Select window D.
|
||||||
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT;
|
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT;
|
||||||
@@ -950,18 +986,15 @@ void display_deactivate_console()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Disable window D.
|
// Disable window D.
|
||||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
|
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
|
||||||
DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0;
|
DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0;
|
||||||
|
|
||||||
// Arm and activate changes.
|
// Arm and activate changes.
|
||||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||||
|
|
||||||
// Re-select window A.
|
|
||||||
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_A_SELECT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_init_cursor(void *crs_fb, u32 size)
|
void display_cursor_init(void *crs_fb, u32 size)
|
||||||
{
|
{
|
||||||
// Setup cursor.
|
// Setup cursor.
|
||||||
DISPLAY_A(_DIREG(DC_DISP_CURSOR_START_ADDR)) = CURSOR_CLIPPING(CURSOR_CLIP_WIN_A) | size | ((u32)crs_fb >> 10);
|
DISPLAY_A(_DIREG(DC_DISP_CURSOR_START_ADDR)) = CURSOR_CLIPPING(CURSOR_CLIP_WIN_A) | size | ((u32)crs_fb >> 10);
|
||||||
@@ -977,7 +1010,7 @@ void display_init_cursor(void *crs_fb, u32 size)
|
|||||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_set_pos_cursor(u32 x, u32 y)
|
void display_cursor_set_pos(u32 x, u32 y)
|
||||||
{
|
{
|
||||||
// Set cursor position.
|
// Set cursor position.
|
||||||
DISPLAY_A(_DIREG(DC_DISP_CURSOR_POSITION)) = x | (y << 16);
|
DISPLAY_A(_DIREG(DC_DISP_CURSOR_POSITION)) = x | (y << 16);
|
||||||
@@ -987,7 +1020,7 @@ void display_set_pos_cursor(u32 x, u32 y)
|
|||||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_deinit_cursor()
|
void display_cursor_deinit()
|
||||||
{
|
{
|
||||||
DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = 0;
|
DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = 0;
|
||||||
DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) &= ~CURSOR_ENABLE;
|
DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) &= ~CURSOR_ENABLE;
|
||||||
|
|||||||
256
bdk/display/di.h
256
bdk/display/di.h
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2023 CTCaer
|
* Copyright (c) 2018-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -24,6 +24,11 @@
|
|||||||
#define DSI_VIDEO_DISABLED 0
|
#define DSI_VIDEO_DISABLED 0
|
||||||
#define DSI_VIDEO_ENABLED 1
|
#define DSI_VIDEO_ENABLED 1
|
||||||
|
|
||||||
|
#define WINDOW_A 0
|
||||||
|
#define WINDOW_B 1
|
||||||
|
#define WINDOW_C 2
|
||||||
|
#define WINDOW_D 3
|
||||||
|
|
||||||
/*! Display registers. */
|
/*! Display registers. */
|
||||||
#define _DIREG(reg) ((reg) * 4)
|
#define _DIREG(reg) ((reg) * 4)
|
||||||
|
|
||||||
@@ -43,8 +48,8 @@
|
|||||||
|
|
||||||
// DC_CMD non-shadowed command/sync registers.
|
// DC_CMD non-shadowed command/sync registers.
|
||||||
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
|
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
|
||||||
#define SYNCPT_GENERAL_INDX(x) (((x) & 0xff) << 0)
|
#define SYNCPT_GENERAL_INDX(x) (((x) & 0xFF) << 0)
|
||||||
#define SYNCPT_GENERAL_COND(x) (((x) & 0xff) << 8)
|
#define SYNCPT_GENERAL_COND(x) (((x) & 0xFF) << 8)
|
||||||
#define COND_REG_WR_SAFE 3
|
#define COND_REG_WR_SAFE 3
|
||||||
|
|
||||||
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
|
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
|
||||||
@@ -52,7 +57,7 @@
|
|||||||
#define SYNCPT_CNTRL_NO_STALL BIT(8)
|
#define SYNCPT_CNTRL_NO_STALL BIT(8)
|
||||||
|
|
||||||
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
|
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
|
||||||
#define SYNCPT_VSYNC_INDX(x) (((x) & 0xff) << 0)
|
#define SYNCPT_VSYNC_INDX(x) (((x) & 0xFF) << 0)
|
||||||
#define SYNCPT_VSYNC_ENABLE BIT(8)
|
#define SYNCPT_VSYNC_ENABLE BIT(8)
|
||||||
|
|
||||||
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
|
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
|
||||||
@@ -77,19 +82,24 @@
|
|||||||
#define DC_CMD_INT_ENABLE 0x39
|
#define DC_CMD_INT_ENABLE 0x39
|
||||||
#define DC_CMD_INT_FRAME_END_INT BIT(1)
|
#define DC_CMD_INT_FRAME_END_INT BIT(1)
|
||||||
#define DC_CMD_INT_V_BLANK_INT BIT(2)
|
#define DC_CMD_INT_V_BLANK_INT BIT(2)
|
||||||
|
#define DC_CMD_INT_POLARITY 0x3B
|
||||||
|
|
||||||
#define DC_CMD_STATE_ACCESS 0x40
|
#define DC_CMD_STATE_ACCESS 0x40
|
||||||
#define READ_MUX BIT(0)
|
#define READ_MUX_ASSEMBLY 0x0
|
||||||
#define WRITE_MUX BIT(2)
|
#define WRITE_MUX_ASSEMBLY 0x0
|
||||||
|
#define READ_MUX_ACTIVE BIT(0)
|
||||||
|
#define WRITE_MUX_ACTIVE BIT(2)
|
||||||
|
|
||||||
#define DC_CMD_STATE_CONTROL 0x41
|
#define DC_CMD_STATE_CONTROL 0x41
|
||||||
#define GENERAL_ACT_REQ BIT(0)
|
#define GENERAL_ACT_REQ BIT(0)
|
||||||
|
#define WIN_ACT_REQ 1
|
||||||
#define WIN_A_ACT_REQ BIT(1)
|
#define WIN_A_ACT_REQ BIT(1)
|
||||||
#define WIN_B_ACT_REQ BIT(2)
|
#define WIN_B_ACT_REQ BIT(2)
|
||||||
#define WIN_C_ACT_REQ BIT(3)
|
#define WIN_C_ACT_REQ BIT(3)
|
||||||
#define WIN_D_ACT_REQ BIT(4)
|
#define WIN_D_ACT_REQ BIT(4)
|
||||||
#define CURSOR_ACT_REQ BIT(7)
|
#define CURSOR_ACT_REQ BIT(7)
|
||||||
#define GENERAL_UPDATE BIT(8)
|
#define GENERAL_UPDATE BIT(8)
|
||||||
|
#define WIN_UPDATE 9
|
||||||
#define WIN_A_UPDATE BIT(9)
|
#define WIN_A_UPDATE BIT(9)
|
||||||
#define WIN_B_UPDATE BIT(10)
|
#define WIN_B_UPDATE BIT(10)
|
||||||
#define WIN_C_UPDATE BIT(11)
|
#define WIN_C_UPDATE BIT(11)
|
||||||
@@ -98,6 +108,7 @@
|
|||||||
#define NC_HOST_TRIG BIT(24)
|
#define NC_HOST_TRIG BIT(24)
|
||||||
|
|
||||||
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
|
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
|
||||||
|
#define WINDOW_SELECT 4
|
||||||
#define WINDOW_A_SELECT BIT(4)
|
#define WINDOW_A_SELECT BIT(4)
|
||||||
#define WINDOW_B_SELECT BIT(5)
|
#define WINDOW_B_SELECT BIT(5)
|
||||||
#define WINDOW_C_SELECT BIT(6)
|
#define WINDOW_C_SELECT BIT(6)
|
||||||
@@ -137,6 +148,31 @@
|
|||||||
#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
|
#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
|
||||||
#define LSC0_OUTPUT_POLARITY_LOW BIT(24)
|
#define LSC0_OUTPUT_POLARITY_LOW BIT(24)
|
||||||
|
|
||||||
|
// CMU registers.
|
||||||
|
#define DC_COM_CMU_CSC_KRR 0x32A
|
||||||
|
#define DC_COM_CMU_CSC_KGR 0x32B
|
||||||
|
#define DC_COM_CMU_CSC_KBR 0x32C
|
||||||
|
#define DC_COM_CMU_CSC_KRG 0x32D
|
||||||
|
#define DC_COM_CMU_CSC_KGG 0x32E
|
||||||
|
#define DC_COM_CMU_CSC_KBG 0x32F
|
||||||
|
#define DC_COM_CMU_CSC_KRB 0x330
|
||||||
|
#define DC_COM_CMU_CSC_KGB 0x331
|
||||||
|
#define DC_COM_CMU_CSC_KBB 0x332
|
||||||
|
#define DC_COM_CMU_LUT1 0x336
|
||||||
|
#define LUT1_ADDR(x) ((x) & 0xFF)
|
||||||
|
#define LUT1_DATA(x) (((x) & 0xFFF) << 16)
|
||||||
|
#define LUT1_READ_DATA(x) (((x) >> 16) & 0xFFF)
|
||||||
|
#define DC_COM_CMU_LUT2 0x337
|
||||||
|
#define LUT2_ADDR(x) ((x) & 0x3FF)
|
||||||
|
#define LUT2_DATA(x) (((x) & 0xFF) << 16)
|
||||||
|
#define LUT2_READ_DATA(x) (((x) >> 16) & 0xFF)
|
||||||
|
#define DC_COM_CMU_LUT1_READ 0x338
|
||||||
|
#define LUT1_READ_ADDR(x) (((x) & 0xFF) << 8)
|
||||||
|
#define LUT1_READ_EN BIT(0)
|
||||||
|
#define DC_COM_CMU_LUT2_READ 0x339
|
||||||
|
#define LUT2_READ_ADDR(x) (((x) & 0x3FF) << 8)
|
||||||
|
#define LUT2_READ_EN BIT(0)
|
||||||
|
|
||||||
#define DC_COM_DSC_TOP_CTL 0x33E
|
#define DC_COM_DSC_TOP_CTL 0x33E
|
||||||
|
|
||||||
// DC_DISP shadowed registers.
|
// DC_DISP shadowed registers.
|
||||||
@@ -153,30 +189,30 @@
|
|||||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
|
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
|
||||||
|
|
||||||
#define DC_DISP_DISP_TIMING_OPTIONS 0x405
|
#define DC_DISP_DISP_TIMING_OPTIONS 0x405
|
||||||
#define VSYNC_H_POSITION(x) (((x) & 0x1fff) << 0)
|
#define VSYNC_H_POSITION(x) (((x) & 0x1FFF) << 0)
|
||||||
|
|
||||||
#define DC_DISP_REF_TO_SYNC 0x406
|
#define DC_DISP_REF_TO_SYNC 0x406
|
||||||
#define H_REF_TO_SYNC(x) (((x) & 0x1fff) << 0) // Min 0 pixel clock.
|
#define H_REF_TO_SYNC(x) (((x) & 0x1FFF) << 0) // Min 0 pixel clock.
|
||||||
#define V_REF_TO_SYNC(x) (((x) & 0x1fff) << 16) // Min 1 line clock.
|
#define V_REF_TO_SYNC(x) (((x) & 0x1FFF) << 16) // Min 1 line clock.
|
||||||
|
|
||||||
#define DC_DISP_SYNC_WIDTH 0x407
|
#define DC_DISP_SYNC_WIDTH 0x407
|
||||||
#define H_SYNC_WIDTH(x) (((x) & 0x1fff) << 0) // Min 1 pixel clock.
|
#define H_SYNC_WIDTH(x) (((x) & 0x1FFF) << 0) // Min 1 pixel clock.
|
||||||
#define V_SYNC_WIDTH(x) (((x) & 0x1fff) << 16) // Min 1 line clock.
|
#define V_SYNC_WIDTH(x) (((x) & 0x1FFF) << 16) // Min 1 line clock.
|
||||||
|
|
||||||
#define DC_DISP_BACK_PORCH 0x408
|
#define DC_DISP_BACK_PORCH 0x408
|
||||||
#define H_BACK_PORCH(x) (((x) & 0x1fff) << 0)
|
#define H_BACK_PORCH(x) (((x) & 0x1FFF) << 0)
|
||||||
#define V_BACK_PORCH(x) (((x) & 0x1fff) << 16)
|
#define V_BACK_PORCH(x) (((x) & 0x1FFF) << 16)
|
||||||
|
|
||||||
#define DC_DISP_ACTIVE 0x409
|
#define DC_DISP_ACTIVE 0x409
|
||||||
#define H_DISP_ACTIVE(x) (((x) & 0x1fff) << 0) // Min 16 pixel clock.
|
#define H_DISP_ACTIVE(x) (((x) & 0x1FFF) << 0) // Min 16 pixel clock.
|
||||||
#define V_DISP_ACTIVE(x) (((x) & 0x1fff) << 16) // Min 16 line clock.
|
#define V_DISP_ACTIVE(x) (((x) & 0x1FFF) << 16) // Min 16 line clock.
|
||||||
|
|
||||||
#define DC_DISP_FRONT_PORCH 0x40A
|
#define DC_DISP_FRONT_PORCH 0x40A
|
||||||
#define H_FRONT_PORCH(x) (((x) & 0x1fff) << 0) // Min -=PS_=-H_REF_TO_SYNC + 1
|
#define H_FRONT_PORCH(x) (((x) & 0x1FFF) << 0) // Min -=PS_=-H_REF_TO_SYNC + 1
|
||||||
#define V_FRONT_PORCH(x) (((x) & 0x1fff) << 16) // Min -=PS_=-V_REF_TO_SYNC + 1
|
#define V_FRONT_PORCH(x) (((x) & 0x1FFF) << 16) // Min -=PS_=-V_REF_TO_SYNC + 1
|
||||||
|
|
||||||
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
|
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
|
||||||
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
|
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xFF)
|
||||||
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
|
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
|
||||||
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
|
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
|
||||||
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
|
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
|
||||||
@@ -207,11 +243,7 @@
|
|||||||
#define DISP_ORDER_BLUE_RED (1 << 9)
|
#define DISP_ORDER_BLUE_RED (1 << 9)
|
||||||
|
|
||||||
#define DC_DISP_DISP_COLOR_CONTROL 0x430
|
#define DC_DISP_DISP_COLOR_CONTROL 0x430
|
||||||
#define DITHER_CONTROL_MASK (3 << 8)
|
#define BASE_COLOR_SIZE_MASK (0xF << 0)
|
||||||
#define DITHER_CONTROL_DISABLE (0 << 8)
|
|
||||||
#define DITHER_CONTROL_ORDERED (2 << 8)
|
|
||||||
#define DITHER_CONTROL_ERRDIFF (3 << 8)
|
|
||||||
#define BASE_COLOR_SIZE_MASK (0xf << 0)
|
|
||||||
#define BASE_COLOR_SIZE_666 (0 << 0)
|
#define BASE_COLOR_SIZE_666 (0 << 0)
|
||||||
#define BASE_COLOR_SIZE_111 (1 << 0)
|
#define BASE_COLOR_SIZE_111 (1 << 0)
|
||||||
#define BASE_COLOR_SIZE_222 (2 << 0)
|
#define BASE_COLOR_SIZE_222 (2 << 0)
|
||||||
@@ -221,6 +253,13 @@
|
|||||||
#define BASE_COLOR_SIZE_565 (6 << 0)
|
#define BASE_COLOR_SIZE_565 (6 << 0)
|
||||||
#define BASE_COLOR_SIZE_332 (7 << 0)
|
#define BASE_COLOR_SIZE_332 (7 << 0)
|
||||||
#define BASE_COLOR_SIZE_888 (8 << 0)
|
#define BASE_COLOR_SIZE_888 (8 << 0)
|
||||||
|
#define DITHER_CONTROL_MASK (3 << 8)
|
||||||
|
#define DITHER_CONTROL_DISABLE (0 << 8)
|
||||||
|
#define DITHER_CONTROL_ORDERED (2 << 8)
|
||||||
|
#define DITHER_CONTROL_ERRDIFF (3 << 8)
|
||||||
|
#define DISP_COLOR_SWAP BIT(16)
|
||||||
|
#define BLANK_COLOR_WHITE BIT(17)
|
||||||
|
#define CMU_ENABLE BIT(20)
|
||||||
|
|
||||||
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
|
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
|
||||||
#define SC0_H_QUALIFIER_NONE BIT(0)
|
#define SC0_H_QUALIFIER_NONE BIT(0)
|
||||||
@@ -242,6 +281,7 @@
|
|||||||
#define CURSOR_COLOR(r,g,b) (((r) & 0xFF) | (((g) & 0xFF) << 8) | (((b) & 0xFF) << 16))
|
#define CURSOR_COLOR(r,g,b) (((r) & 0xFF) | (((g) & 0xFF) << 8) | (((b) & 0xFF) << 16))
|
||||||
|
|
||||||
#define DC_DISP_CURSOR_START_ADDR 0x43E
|
#define DC_DISP_CURSOR_START_ADDR 0x43E
|
||||||
|
#define DC_DISP_CURSOR_START_ADDR_NS 0x43F
|
||||||
#define CURSOR_CLIPPING(w) ((w) << 28)
|
#define CURSOR_CLIPPING(w) ((w) << 28)
|
||||||
#define CURSOR_CLIP_WIN_A 1
|
#define CURSOR_CLIP_WIN_A 1
|
||||||
#define CURSOR_CLIP_WIN_B 2
|
#define CURSOR_CLIP_WIN_B 2
|
||||||
@@ -253,6 +293,7 @@
|
|||||||
#define DC_DISP_CURSOR_POSITION 0x440
|
#define DC_DISP_CURSOR_POSITION 0x440
|
||||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
||||||
#define DC_DISP_CURSOR_START_ADDR_HI 0x4EC
|
#define DC_DISP_CURSOR_START_ADDR_HI 0x4EC
|
||||||
|
#define DC_DISP_CURSOR_START_ADDR_HI_NS 0x4ED
|
||||||
#define DC_DISP_BLEND_CURSOR_CONTROL 0x4F1
|
#define DC_DISP_BLEND_CURSOR_CONTROL 0x4F1
|
||||||
#define CURSOR_BLEND_2BIT (0 << 24)
|
#define CURSOR_BLEND_2BIT (0 << 24)
|
||||||
#define CURSOR_BLEND_R8G8B8A8 (1 << 24)
|
#define CURSOR_BLEND_R8G8B8A8 (1 << 24)
|
||||||
@@ -269,17 +310,22 @@
|
|||||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
||||||
|
|
||||||
#define DC_WINC_COLOR_PALETTE 0x500
|
#define DC_WINC_COLOR_PALETTE 0x500
|
||||||
#define DC_WINC_COLOR_PALETTE_IDX(off) (DC_WINC_COLOR_PALETTE + (off))
|
#define COLOR_PALETTE_IDX(off) (DC_WINC_COLOR_PALETTE + (off))
|
||||||
|
#define COLOR_PALETTE_RGB(rgb) (byte_swap_32(rgb) >> 8)
|
||||||
#define DC_WINC_PALETTE_COLOR_EXT 0x600
|
#define DC_WINC_PALETTE_COLOR_EXT 0x600
|
||||||
|
|
||||||
#define DC_WIN_CSC_YOF 0x611
|
#define DC_WINC_H_FILTER_P(p) (0x601 + (p))
|
||||||
#define DC_WIN_CSC_KYRGB 0x612
|
#define DC_WINC_V_FILTER_P(p) (0x619 + (p))
|
||||||
#define DC_WIN_CSC_KUR 0x613
|
#define DC_WINC_H_FILTER_HI_P(p) (0x629 + (p))
|
||||||
#define DC_WIN_CSC_KVR 0x614
|
|
||||||
#define DC_WIN_CSC_KUG 0x615
|
#define DC_WINC_CSC_YOF 0x611
|
||||||
#define DC_WIN_CSC_KVG 0x616
|
#define DC_WINC_CSC_KYRGB 0x612
|
||||||
#define DC_WIN_CSC_KUB 0x617
|
#define DC_WINC_CSC_KUR 0x613
|
||||||
#define DC_WIN_CSC_KVB 0x618
|
#define DC_WINC_CSC_KVR 0x614
|
||||||
|
#define DC_WINC_CSC_KUG 0x615
|
||||||
|
#define DC_WINC_CSC_KVG 0x616
|
||||||
|
#define DC_WINC_CSC_KUB 0x617
|
||||||
|
#define DC_WINC_CSC_KVB 0x618
|
||||||
#define DC_WIN_AD_WIN_OPTIONS 0xB80
|
#define DC_WIN_AD_WIN_OPTIONS 0xB80
|
||||||
#define DC_WIN_BD_WIN_OPTIONS 0xD80
|
#define DC_WIN_BD_WIN_OPTIONS 0xD80
|
||||||
#define DC_WIN_CD_WIN_OPTIONS 0xF80
|
#define DC_WIN_CD_WIN_OPTIONS 0xF80
|
||||||
@@ -290,15 +336,17 @@
|
|||||||
#define V_DIRECTION BIT(2)
|
#define V_DIRECTION BIT(2)
|
||||||
#define SCAN_COLUMN BIT(4)
|
#define SCAN_COLUMN BIT(4)
|
||||||
#define COLOR_EXPAND BIT(6)
|
#define COLOR_EXPAND BIT(6)
|
||||||
|
#define H_FILTER_ENABLE BIT(8)
|
||||||
|
#define V_FILTER_ENABLE BIT(10)
|
||||||
#define COLOR_PALETTE_ENABLE BIT(16)
|
#define COLOR_PALETTE_ENABLE BIT(16)
|
||||||
#define CSC_ENABLE BIT(18)
|
#define CSC_ENABLE BIT(18)
|
||||||
|
#define DV_ENABLE BIT(20)
|
||||||
#define WIN_ENABLE BIT(30)
|
#define WIN_ENABLE BIT(30)
|
||||||
|
#define H_FILTER_EXPAND BIT(31)
|
||||||
|
|
||||||
#define DC_WIN_BUFFER_CONTROL 0x702
|
#define DC_WIN_BUFFER_CONTROL 0x702
|
||||||
#define BUFFER_CONTROL_HOST 0
|
#define BUFFER_CONTROL_HOST 0
|
||||||
#define BUFFER_CONTROL_VI 1
|
#define BUFFER_CONTROL_VI 1
|
||||||
#define BUFFER_CONTROL_EPP 2
|
|
||||||
#define BUFFER_CONTROL_MPEGE 3
|
|
||||||
#define BUFFER_CONTROL_SB2D 4
|
#define BUFFER_CONTROL_SB2D 4
|
||||||
|
|
||||||
#define DC_WIN_COLOR_DEPTH 0x703
|
#define DC_WIN_COLOR_DEPTH 0x703
|
||||||
@@ -324,6 +372,10 @@
|
|||||||
#define WIN_COLOR_DEPTH_YUV422R 0x17
|
#define WIN_COLOR_DEPTH_YUV422R 0x17
|
||||||
#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
|
#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
|
||||||
#define WIN_COLOR_DEPTH_YUV422RA 0x19
|
#define WIN_COLOR_DEPTH_YUV422RA 0x19
|
||||||
|
#define WIN_COLOR_DEPTH_X1R5G5B5 0x1E
|
||||||
|
#define WIN_COLOR_DEPTH_R5G5B5X1 0x1F
|
||||||
|
#define WIN_COLOR_DEPTH_X1B5G5R5 0x20
|
||||||
|
#define WIN_COLOR_DEPTH_B5G5R5X1 0x21
|
||||||
#define WIN_COLOR_DEPTH_YCbCr444P 0x29
|
#define WIN_COLOR_DEPTH_YCbCr444P 0x29
|
||||||
#define WIN_COLOR_DEPTH_YCrCb420SP 0x2A
|
#define WIN_COLOR_DEPTH_YCrCb420SP 0x2A
|
||||||
#define WIN_COLOR_DEPTH_YCbCr420SP 0x2B
|
#define WIN_COLOR_DEPTH_YCbCr420SP 0x2B
|
||||||
@@ -338,33 +390,37 @@
|
|||||||
#define WIN_COLOR_DEPTH_YUV444SP 0x3C
|
#define WIN_COLOR_DEPTH_YUV444SP 0x3C
|
||||||
|
|
||||||
#define DC_WIN_POSITION 0x704
|
#define DC_WIN_POSITION 0x704
|
||||||
#define H_POSITION(x) (((x) & 0xffff) << 0) // Support negative.
|
#define H_POSITION(x) (((x) & 0xFFFF) << 0) // Support negative.
|
||||||
#define V_POSITION(x) (((x) & 0xffff) << 16) // Support negative.
|
#define V_POSITION(x) (((x) & 0xFFFF) << 16) // Support negative.
|
||||||
|
|
||||||
#define DC_WIN_SIZE 0x705
|
#define DC_WIN_SIZE 0x705
|
||||||
#define H_SIZE(x) (((x) & 0x1fff) << 0)
|
#define H_SIZE(x) (((x) & 0x1FFF) << 0)
|
||||||
#define V_SIZE(x) (((x) & 0x1fff) << 16)
|
#define V_SIZE(x) (((x) & 0x1FFF) << 16)
|
||||||
|
|
||||||
#define DC_WIN_PRESCALED_SIZE 0x706
|
#define DC_WIN_PRESCALED_SIZE 0x706
|
||||||
#define H_PRESCALED_SIZE(x) (((x) & 0x7fff) << 0)
|
#define H_PRESCALED_SIZE(x) (((x) & 0x7FFF) << 0)
|
||||||
#define V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)
|
#define V_PRESCALED_SIZE(x) (((x) & 0x1FFF) << 16)
|
||||||
|
|
||||||
#define DC_WIN_H_INITIAL_DDA 0x707
|
#define DC_WIN_H_INITIAL_DDA 0x707
|
||||||
#define DC_WIN_V_INITIAL_DDA 0x708
|
#define DC_WIN_V_INITIAL_DDA 0x708
|
||||||
|
|
||||||
#define DC_WIN_DDA_INC 0x709
|
#define DC_WIN_DDA_INC 0x709
|
||||||
#define H_DDA_INC(x) (((x) & 0xffff) << 0)
|
#define H_DDA_INC(x) (((x) & 0xFFFF) << 0)
|
||||||
#define V_DDA_INC(x) (((x) & 0xffff) << 16)
|
#define V_DDA_INC(x) (((x) & 0xFFFF) << 16)
|
||||||
|
|
||||||
#define DC_WIN_LINE_STRIDE 0x70A
|
#define DC_WIN_LINE_STRIDE 0x70A
|
||||||
#define LINE_STRIDE(x) (x)
|
#define LINE_STRIDE(x) (x)
|
||||||
#define UV_LINE_STRIDE(x) (((x) & 0xffff) << 16)
|
#define UV_LINE_STRIDE(x) (((x) & 0xFFFF) << 16)
|
||||||
|
|
||||||
#define DC_WIN_DV_CONTROL 0x70E
|
#define DC_WIN_DV_CONTROL 0x70E
|
||||||
|
#define DV_CTRL_R(r) (((r) & 7) << 16)
|
||||||
|
#define DV_CTRL_G(g) (((g) & 7) << 8)
|
||||||
|
#define DV_CTRL_B(b) (((b) & 7) << 0)
|
||||||
|
|
||||||
#define DC_WINBUF_BLEND_LAYER_CONTROL 0x716
|
#define DC_WINBUF_BLEND_LAYER_CONTROL 0x716
|
||||||
#define WIN_BLEND_DEPTH(x) (((x) & 0xff) << 0)
|
#define WIN_BLEND_DEPTH(x) (((x) & 0xFF) << 0)
|
||||||
#define WIN_K1(x) (((x) & 0xff) << 8)
|
#define WIN_K1(x) (((x) & 0xFF) << 8)
|
||||||
#define WIN_K2(x) (((x) & 0xff) << 16)
|
#define WIN_K2(x) (((x) & 0xFF) << 16)
|
||||||
#define WIN_BLEND_ENABLE (0 << 24)
|
#define WIN_BLEND_ENABLE (0 << 24)
|
||||||
#define WIN_BLEND_BYPASS (1 << 24)
|
#define WIN_BLEND_BYPASS (1 << 24)
|
||||||
|
|
||||||
@@ -395,8 +451,8 @@
|
|||||||
#define WIN_BLEND_FACT_DST_ALPHA_MATCH_SEL_K2 (3 << 12)
|
#define WIN_BLEND_FACT_DST_ALPHA_MATCH_SEL_K2 (3 << 12)
|
||||||
|
|
||||||
#define DC_WINBUF_BLEND_ALPHA_1BIT 0x719
|
#define DC_WINBUF_BLEND_ALPHA_1BIT 0x719
|
||||||
#define WIN_ALPHA_1BIT_WEIGHT0(x) (((x) & 0xff) << 0)
|
#define WIN_ALPHA_1BIT_WEIGHT0(x) (((x) & 0xFF) << 0)
|
||||||
#define WIN_ALPHA_1BIT_WEIGHT1(x) (((x) & 0xff) << 8)
|
#define WIN_ALPHA_1BIT_WEIGHT1(x) (((x) & 0xFF) << 8)
|
||||||
|
|
||||||
/*! The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). */
|
/*! The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). */
|
||||||
#define DC_WINBUF_START_ADDR 0x800
|
#define DC_WINBUF_START_ADDR 0x800
|
||||||
@@ -408,6 +464,8 @@
|
|||||||
#define BLOCK (2 << 0)
|
#define BLOCK (2 << 0)
|
||||||
#define BLOCK_HEIGHT(x) (((x) & 0x7) << 4)
|
#define BLOCK_HEIGHT(x) (((x) & 0x7) << 4)
|
||||||
|
|
||||||
|
#define DC_WINBUF_MEMFETCH_CONTROL 0x82B
|
||||||
|
|
||||||
/*! Display serial interface registers. */
|
/*! Display serial interface registers. */
|
||||||
#define _DSIREG(reg) ((reg) * 4)
|
#define _DSIREG(reg) ((reg) * 4)
|
||||||
|
|
||||||
@@ -462,6 +520,7 @@
|
|||||||
|
|
||||||
#define DSI_STATUS 0x15
|
#define DSI_STATUS 0x15
|
||||||
#define DSI_STATUS_RX_FIFO_SIZE 0x1F
|
#define DSI_STATUS_RX_FIFO_SIZE 0x1F
|
||||||
|
#define DSI_STATUS_TX_FIFO_SIZE 0x20 // Actual depth is 64.
|
||||||
|
|
||||||
#define DSI_INIT_SEQ_CONTROL 0x1A
|
#define DSI_INIT_SEQ_CONTROL 0x1A
|
||||||
#define DSI_INIT_SEQ_DATA_0 0x1B
|
#define DSI_INIT_SEQ_DATA_0 0x1B
|
||||||
@@ -486,8 +545,8 @@
|
|||||||
#define DSI_PKT_LEN_2_3 0x35
|
#define DSI_PKT_LEN_2_3 0x35
|
||||||
#define DSI_PKT_LEN_4_5 0x36
|
#define DSI_PKT_LEN_4_5 0x36
|
||||||
#define DSI_PKT_LEN_6_7 0x37
|
#define DSI_PKT_LEN_6_7 0x37
|
||||||
#define PKT0_LEN(x) (((x) & 0xffff) << 0)
|
#define PKT0_LEN(x) (((x) & 0xFFFF) << 0)
|
||||||
#define PKT1_LEN(x) (((x) & 0xffff) << 16)
|
#define PKT1_LEN(x) (((x) & 0xFFFF) << 16)
|
||||||
|
|
||||||
#define DSI_PHY_TIMING_0 0x3C
|
#define DSI_PHY_TIMING_0 0x3C
|
||||||
#define DSI_PHY_TIMING_1 0x3D
|
#define DSI_PHY_TIMING_1 0x3D
|
||||||
@@ -495,20 +554,20 @@
|
|||||||
#define DSI_BTA_TIMING 0x3F
|
#define DSI_BTA_TIMING 0x3F
|
||||||
|
|
||||||
#define DSI_TIMEOUT_0 0x44
|
#define DSI_TIMEOUT_0 0x44
|
||||||
#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
|
#define DSI_TIMEOUT_HTX(x) (((x) & 0xFFFF) << 0)
|
||||||
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
|
#define DSI_TIMEOUT_LRX(x) (((x) & 0xFFFF) << 16)
|
||||||
|
|
||||||
#define DSI_TIMEOUT_1 0x45
|
#define DSI_TIMEOUT_1 0x45
|
||||||
#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
|
#define DSI_TIMEOUT_TA(x) (((x) & 0xFFFF) << 0)
|
||||||
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
|
#define DSI_TIMEOUT_PR(x) (((x) & 0xFFFF) << 16)
|
||||||
|
|
||||||
#define DSI_TO_TALLY 0x46
|
#define DSI_TO_TALLY 0x46
|
||||||
|
|
||||||
#define DSI_PAD_CONTROL_0 0x4B
|
#define DSI_PAD_CONTROL_0 0x4B
|
||||||
#define DSI_PAD_CONTROL_VS1_PDIO_CLK BIT(8)
|
#define DSI_PAD_CONTROL_VS1_PDIO_CLK BIT(8)
|
||||||
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
|
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xF) << 0)
|
||||||
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK BIT(24)
|
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK BIT(24)
|
||||||
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
|
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xF) << 16)
|
||||||
|
|
||||||
#define DSI_PAD_CONTROL_CD 0x4C
|
#define DSI_PAD_CONTROL_CD 0x4C
|
||||||
#define DSI_VIDEO_MODE_CONTROL 0x4E
|
#define DSI_VIDEO_MODE_CONTROL 0x4E
|
||||||
@@ -659,7 +718,7 @@
|
|||||||
#define MIPI_DCS_READ_DDB_CONTINUE 0xA8 // 0x100 size.
|
#define MIPI_DCS_READ_DDB_CONTINUE 0xA8 // 0x100 size.
|
||||||
|
|
||||||
/*! MIPI DCS Panel Private CMDs. */
|
/*! MIPI DCS Panel Private CMDs. */
|
||||||
#define MIPI_DCS_PRIV_SM_SET_COLOR_MODE 0xA0
|
#define MIPI_DCS_PRIV_SM_SET_COLOR_MODE 0xA0 // 43 bytes.
|
||||||
#define MIPI_DCS_PRIV_SM_SET_REG_OFFSET 0xB0
|
#define MIPI_DCS_PRIV_SM_SET_REG_OFFSET 0xB0
|
||||||
#define MIPI_DCS_PRIV_SM_SET_ELVSS 0xB1 // OLED backlight tuning. Byte7: PWM transition time in frames.
|
#define MIPI_DCS_PRIV_SM_SET_ELVSS 0xB1 // OLED backlight tuning. Byte7: PWM transition time in frames.
|
||||||
#define MIPI_DCS_PRIV_SET_POWER_CONTROL 0xB1
|
#define MIPI_DCS_PRIV_SET_POWER_CONTROL 0xB1
|
||||||
@@ -669,8 +728,9 @@
|
|||||||
#define MIPI_DCS_PRIV_UNK_D6 0xD6
|
#define MIPI_DCS_PRIV_UNK_D6 0xD6
|
||||||
#define MIPI_DCS_PRIV_UNK_D8 0xD8
|
#define MIPI_DCS_PRIV_UNK_D8 0xD8
|
||||||
#define MIPI_DCS_PRIV_UNK_D9 0xD9
|
#define MIPI_DCS_PRIV_UNK_D9 0xD9
|
||||||
|
#define MIPI_DCS_PRIV_SM_DISPLAY_ID 0xDD
|
||||||
// LVL1 LVL2 LVL3 UNK0 UNK1
|
// LVL1 LVL2 LVL3 UNK0 UNK1
|
||||||
#define MIPI_DCS_PRIV_SM_SET_REGS_LOCK 0xE2 // Samsung: Lock (default): 5A5A A5A5 A5A5 A500 A500. Unlock: A5A5 5A5A 5A5A UNK UNK.
|
#define MIPI_DCS_PRIV_SM_SET_REGS_LOCK 0xE2 // Samsung: Lock (default): 5A5A A5A5 A5A5 A500 A500. Lock/Unlock: A5/5A. LVL1 group is normal registers.
|
||||||
#define MIPI_DCS_PRIV_READ_EXTC_CMD_SPI 0xFE // Read EXTC Command In SPI. 1 byte. 0-6: EXT_SPI_CNT, 7:EXT_SP.
|
#define MIPI_DCS_PRIV_READ_EXTC_CMD_SPI 0xFE // Read EXTC Command In SPI. 1 byte. 0-6: EXT_SPI_CNT, 7:EXT_SP.
|
||||||
#define MIPI_DCS_PRIV_SET_EXTC_CMD_REG 0xFF // EXTC Command Set enable register. 5 bytes. Pass: FF 98 06 04, PAGE.
|
#define MIPI_DCS_PRIV_SET_EXTC_CMD_REG 0xFF // EXTC Command Set enable register. 5 bytes. Pass: FF 98 06 04, PAGE.
|
||||||
|
|
||||||
@@ -707,19 +767,21 @@
|
|||||||
|
|
||||||
#define DCS_CONTROL_DISPLAY_SM_FLASHLIGHT BIT(2)
|
#define DCS_CONTROL_DISPLAY_SM_FLASHLIGHT BIT(2)
|
||||||
#define DCS_CONTROL_DISPLAY_BACKLIGHT_CTRL BIT(2)
|
#define DCS_CONTROL_DISPLAY_BACKLIGHT_CTRL BIT(2)
|
||||||
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL BIT(3)
|
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL BIT(3) // Transition fading.
|
||||||
#define DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL BIT(5)
|
#define DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL BIT(5)
|
||||||
|
#define DCS_CONTROL_DISPLAY_HBM_CTRL0 BIT(6)
|
||||||
|
#define DCS_CONTROL_DISPLAY_HBM_CTRL1 BIT(7)
|
||||||
|
|
||||||
#define DCS_SM_COLOR_MODE_SATURATED 0x00 // Disabled. Similar to vivid but over-saturated. Wide gamut?
|
#define DCS_SM_COLOR_MODE_SATURATED 0x00 // Disabled. Based on Vivid but over-saturated.
|
||||||
#define DCS_SM_COLOR_MODE_WASHED 0x45
|
#define DCS_SM_COLOR_MODE_WASHED 0x45
|
||||||
#define DCS_SM_COLOR_MODE_BASIC 0x03
|
#define DCS_SM_COLOR_MODE_BASIC 0x03 // Real natural profile.
|
||||||
#define DCS_SM_COLOR_MODE_POR_RESET 0x20 // Reset value on power on.
|
#define DCS_SM_COLOR_MODE_POR_RESET 0x20 // Reset value on power on.
|
||||||
#define DCS_SM_COLOR_MODE_NATURAL 0x23 // Not actually natural..
|
#define DCS_SM_COLOR_MODE_NATURAL 0x23 // Not actually natural.. Extra saturation.
|
||||||
#define DCS_SM_COLOR_MODE_VIVID 0x65
|
#define DCS_SM_COLOR_MODE_VIVID 0x65 // Saturated.
|
||||||
#define DCS_SM_COLOR_MODE_NIGHT0 0x43 // Based on washed out.
|
#define DCS_SM_COLOR_MODE_NIGHT0 0x43 // Based on Washed Out.
|
||||||
#define DCS_SM_COLOR_MODE_NIGHT1 0x15 // Based on basic.
|
#define DCS_SM_COLOR_MODE_NIGHT1 0x15 // Based on Basic.
|
||||||
#define DCS_SM_COLOR_MODE_NIGHT2 0x35 // Based on natural.
|
#define DCS_SM_COLOR_MODE_NIGHT2 0x35 // Based on Natural.
|
||||||
#define DCS_SM_COLOR_MODE_NIGHT3 0x75 // Based on vivid.
|
#define DCS_SM_COLOR_MODE_NIGHT3 0x75 // Based on Vivid.
|
||||||
|
|
||||||
#define DCS_SM_COLOR_MODE_ENABLE BIT(0)
|
#define DCS_SM_COLOR_MODE_ENABLE BIT(0)
|
||||||
|
|
||||||
@@ -732,9 +794,10 @@
|
|||||||
* [10] 96 [09]: JDI LAM062M109A
|
* [10] 96 [09]: JDI LAM062M109A
|
||||||
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
|
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
|
||||||
* [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1)
|
* [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1)
|
||||||
* [20] 96 [0F]: InnoLux P062CCA-AZ3 (Rev XX) [UNCONFIRMED MODEL+REV]
|
* [20] 96 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||||
* [20] 97 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
|
* [20] 97 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||||
* [20] 98 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
|
* [20] 98 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||||
|
* [20] 99 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||||
* [30] 93 [0F]: AUO A062TAN00 (59.06A33.000)
|
* [30] 93 [0F]: AUO A062TAN00 (59.06A33.000)
|
||||||
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
|
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
|
||||||
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
|
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
|
||||||
@@ -779,24 +842,44 @@
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PANEL_JDI_XXX062M = 0x10,
|
PANEL_JDI_XXX062M = 0x10,
|
||||||
PANEL_JDI_LAM062M109A = 0x0910,
|
PANEL_JDI_LAM062M109A = 0x0910, // SI.
|
||||||
PANEL_JDI_LPM062M326A = 0x2610,
|
PANEL_JDI_LPM062M326A = 0x2610, // LTPS.
|
||||||
PANEL_INL_P062CCA_AZ1 = 0x0F20,
|
PANEL_INL_P062CCA_AZ1 = 0x0F20,
|
||||||
PANEL_AUO_A062TAN01 = 0x0F30,
|
PANEL_AUO_A062TAN01 = 0x0F30,
|
||||||
PANEL_INL_2J055IA_27A = 0x1020,
|
PANEL_INL_2J055IA_27A = 0x1020,
|
||||||
PANEL_AUO_A055TAN01 = 0x1030,
|
PANEL_AUO_A055TAN01 = 0x1030,
|
||||||
PANEL_SHP_LQ055T1SW10 = 0x1040,
|
PANEL_SHP_LQ055T1SW10 = 0x1040,
|
||||||
PANEL_SAM_AMS699VC01 = 0x2050
|
PANEL_SAM_AMS699VC01 = 0x2050,
|
||||||
|
|
||||||
|
// Found on 6/2" clones. Unknown markings. Clone of AUO A062TAN01.
|
||||||
|
// Quality seems JDI like. Has bad low backlight scaling. ID: [83] 94 [0F]. Sometimes reports [30] 94 [0F]. Both IDs have correct CRC16.
|
||||||
|
PANEL_OEM_CLONE_6_2 = 0x0F83,
|
||||||
|
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
|
||||||
|
PANEL_OEM_CLONE_5_5 = 0x00B3,
|
||||||
|
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
|
||||||
|
PANEL_OEM_CLONE = 0x0000
|
||||||
|
//0x0F40 [40] 94 [0F], 5.5" clone
|
||||||
};
|
};
|
||||||
|
|
||||||
void display_init();
|
void display_init();
|
||||||
void display_backlight_pwm_init();
|
void display_backlight_pwm_init();
|
||||||
void display_end();
|
void display_end();
|
||||||
|
|
||||||
|
/*! Interrupt management. */
|
||||||
|
void display_enable_interrupt(u32 intr);
|
||||||
|
void display_disable_interrupt(u32 intr);
|
||||||
|
void display_wait_interrupt(u32 intr);
|
||||||
|
|
||||||
/*! Get/Set Display panel ID. */
|
/*! Get/Set Display panel ID. */
|
||||||
u16 display_get_decoded_panel_id();
|
u16 display_get_decoded_panel_id();
|
||||||
void display_set_decoded_panel_id(u32 id);
|
void display_set_decoded_panel_id(u32 id);
|
||||||
|
|
||||||
|
/*! MIPI DCS register management */
|
||||||
|
int display_dsi_read(u8 cmd, u32 len, void *data);
|
||||||
|
int display_dsi_vblank_read(u8 cmd, u32 len, void *data);
|
||||||
|
void display_dsi_write(u8 cmd, u32 len, void *data);
|
||||||
|
void display_dsi_vblank_write(u8 cmd, u32 len, void *data);
|
||||||
|
|
||||||
/*! Show one single color on the display. */
|
/*! Show one single color on the display. */
|
||||||
void display_color_screen(u32 color);
|
void display_color_screen(u32 color);
|
||||||
|
|
||||||
@@ -805,21 +888,22 @@ void display_backlight(bool enable);
|
|||||||
void display_backlight_brightness(u32 brightness, u32 step_delay);
|
void display_backlight_brightness(u32 brightness, u32 step_delay);
|
||||||
u32 display_get_backlight_brightness();
|
u32 display_get_backlight_brightness();
|
||||||
|
|
||||||
/*! Init display in full 720x1280 resolution (B8G8R8A8, line stride 720, framebuffer size = 720*1280*4 bytes). */
|
u32 *display_init_window_a_pitch();
|
||||||
u32 *display_init_framebuffer_pitch();
|
u32 *display_init_window_a_pitch_vic();
|
||||||
u32 *display_init_framebuffer_pitch_vic();
|
u32 *display_init_window_a_pitch_inv();
|
||||||
u32 *display_init_framebuffer_pitch_inv();
|
u32 *display_init_window_a_block();
|
||||||
u32 *display_init_framebuffer_block();
|
u32 *display_init_window_d_console();
|
||||||
u32 *display_init_framebuffer_log();
|
|
||||||
void display_activate_console();
|
|
||||||
void display_deactivate_console();
|
|
||||||
void display_init_cursor(void *crs_fb, u32 size);
|
|
||||||
void display_set_pos_cursor(u32 x, u32 y);
|
|
||||||
void display_deinit_cursor();
|
|
||||||
|
|
||||||
int display_dsi_read(u8 cmd, u32 len, void *data);
|
void display_window_disable(u32 window);
|
||||||
int display_dsi_vblank_read(u8 cmd, u32 len, void *data);
|
|
||||||
void display_dsi_write(u8 cmd, u32 len, void *data);
|
void display_set_framebuffer(u32 window, void *fb);
|
||||||
void display_dsi_vblank_write(u8 cmd, u32 len, void *data);
|
void display_move_framebuffer(u32 window, void *fb);
|
||||||
|
|
||||||
|
void display_window_d_console_enable();
|
||||||
|
void display_window_d_console_disable();
|
||||||
|
|
||||||
|
void display_cursor_init(void *crs_fb, u32 size);
|
||||||
|
void display_cursor_set_pos(u32 x, u32 y);
|
||||||
|
void display_cursor_deinit();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2022 CTCaer
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -16,37 +16,35 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Display A config.
|
// Display A config.
|
||||||
static const cfg_op_t _di_dc_setup_win_config[] = {
|
static const reg_cfg_t _di_dc_setup_win_config[] = {
|
||||||
{DC_CMD_STATE_ACCESS, 0},
|
{DC_CMD_STATE_ACCESS, READ_MUX_ASSEMBLY | WRITE_MUX_ASSEMBLY},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||||
{DC_CMD_REG_ACT_CONTROL, WIN_A_ACT_HCNTR_SEL | WIN_B_ACT_HCNTR_SEL | WIN_C_ACT_HCNTR_SEL},
|
{DC_CMD_REG_ACT_CONTROL, WIN_A_ACT_HCNTR_SEL | WIN_B_ACT_HCNTR_SEL | WIN_C_ACT_HCNTR_SEL | WIN_D_ACT_HCNTR_SEL},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT},
|
|
||||||
{DC_DISP_DC_MCCIF_FIFOCTRL, 0},
|
{DC_DISP_DC_MCCIF_FIFOCTRL, 0},
|
||||||
{DC_DISP_DISP_MEM_HIGH_PRIORITY, 0},
|
{DC_DISP_DISP_MEM_HIGH_PRIORITY, 0},
|
||||||
{DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0},
|
{DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0},
|
||||||
{DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE},
|
{DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE},
|
||||||
{DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL},
|
{DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL},
|
||||||
{DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | SYNCPT_VSYNC_INDX(9)},
|
{DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | SYNCPT_VSYNC_INDX(9)},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE | WIN_D_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ | WIN_D_ACT_REQ},
|
||||||
{DC_CMD_STATE_ACCESS, 0},
|
|
||||||
|
|
||||||
/* Setup Windows A/B/C */
|
/* Setup Windows A/B/C */
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT},
|
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT | WINDOW_D_SELECT},
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
{DC_WIN_WIN_OPTIONS, 0},
|
||||||
{DC_WIN_DV_CONTROL, 0},
|
{DC_WIN_DV_CONTROL, 0},
|
||||||
/* Setup default YUV colorspace conversion coefficients */
|
/* Setup default YUV colorspace conversion coefficients */
|
||||||
{DC_WIN_CSC_YOF, 0xF0},
|
{DC_WINC_CSC_YOF, 0xF0},
|
||||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
{DC_WINC_CSC_KYRGB, 0x12A},
|
||||||
{DC_WIN_CSC_KUR, 0},
|
{DC_WINC_CSC_KUR, 0},
|
||||||
{DC_WIN_CSC_KVR, 0x198},
|
{DC_WINC_CSC_KVR, 0x198},
|
||||||
{DC_WIN_CSC_KUG, 0x39B},
|
{DC_WINC_CSC_KUG, 0x39B},
|
||||||
{DC_WIN_CSC_KVG, 0x32F},
|
{DC_WINC_CSC_KVG, 0x32F},
|
||||||
{DC_WIN_CSC_KUB, 0x204},
|
{DC_WINC_CSC_KUB, 0x204},
|
||||||
{DC_WIN_CSC_KVB, 0},
|
{DC_WINC_CSC_KVB, 0},
|
||||||
/* End of color coefficients */
|
/* End of color coefficients */
|
||||||
|
|
||||||
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||||
@@ -55,21 +53,18 @@ static const cfg_op_t _di_dc_setup_win_config[] = {
|
|||||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||||
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
||||||
{DC_COM_CRC_CONTROL, 0},
|
{DC_COM_CRC_CONTROL, 0},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE | WIN_D_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ | WIN_D_ACT_REQ},
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT},
|
|
||||||
{DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_BYPASS | WIN_BLEND_DEPTH(255)},
|
{DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_BYPASS | WIN_BLEND_DEPTH(255)},
|
||||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT},
|
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{DC_DISP_DISP_WIN_OPTIONS, 0},
|
{DC_DISP_DISP_WIN_OPTIONS, 0},
|
||||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
|
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE | WIN_D_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ | WIN_D_ACT_REQ}
|
||||||
};
|
};
|
||||||
|
|
||||||
// DSI Init config.
|
// DSI Init config.
|
||||||
static const cfg_op_t _di_dsi_init_irq_pkt_config0[] = {
|
static const reg_cfg_t _di_dsi_seq_pkt_reset_config0[] = {
|
||||||
{DSI_WR_DATA, 0},
|
{DSI_WR_DATA, 0},
|
||||||
{DSI_INT_ENABLE, 0},
|
{DSI_INT_ENABLE, 0},
|
||||||
{DSI_INT_STATUS, 0},
|
{DSI_INT_STATUS, 0},
|
||||||
@@ -79,7 +74,7 @@ static const cfg_op_t _di_dsi_init_irq_pkt_config0[] = {
|
|||||||
{DSI_INIT_SEQ_DATA_2, 0},
|
{DSI_INIT_SEQ_DATA_2, 0},
|
||||||
{DSI_INIT_SEQ_DATA_3, 0}
|
{DSI_INIT_SEQ_DATA_3, 0}
|
||||||
};
|
};
|
||||||
static const cfg_op_t _di_dsi_init_irq_pkt_config1[] = {
|
static const reg_cfg_t _di_dsi_seq_pkt_reset_config1[] = {
|
||||||
{DSI_DCS_CMDS, 0},
|
{DSI_DCS_CMDS, 0},
|
||||||
{DSI_PKT_SEQ_0_LO, 0},
|
{DSI_PKT_SEQ_0_LO, 0},
|
||||||
{DSI_PKT_SEQ_1_LO, 0},
|
{DSI_PKT_SEQ_1_LO, 0},
|
||||||
@@ -95,7 +90,7 @@ static const cfg_op_t _di_dsi_init_irq_pkt_config1[] = {
|
|||||||
{DSI_PKT_SEQ_5_HI, 0},
|
{DSI_PKT_SEQ_5_HI, 0},
|
||||||
{DSI_CONTROL, 0}
|
{DSI_CONTROL, 0}
|
||||||
};
|
};
|
||||||
static const cfg_op_t _di_dsi_init_pads_t210b01[] = {
|
static const reg_cfg_t _di_dsi_init_pads_t210b01[] = {
|
||||||
{DSI_PAD_CONTROL_1, 0},
|
{DSI_PAD_CONTROL_1, 0},
|
||||||
{DSI_PAD_CONTROL_2, 0},
|
{DSI_PAD_CONTROL_2, 0},
|
||||||
{DSI_PAD_CONTROL_3, 0},
|
{DSI_PAD_CONTROL_3, 0},
|
||||||
@@ -104,39 +99,47 @@ static const cfg_op_t _di_dsi_init_pads_t210b01[] = {
|
|||||||
{DSI_PAD_CONTROL_6_B01, 0},
|
{DSI_PAD_CONTROL_6_B01, 0},
|
||||||
{DSI_PAD_CONTROL_7_B01, 0}
|
{DSI_PAD_CONTROL_7_B01, 0}
|
||||||
};
|
};
|
||||||
static const cfg_op_t _di_dsi_init_timing_pkt_config2[] = {
|
static const reg_cfg_t _di_dsi_init_config[] = {
|
||||||
{DSI_PAD_CONTROL_CD, 0},
|
{DSI_PAD_CONTROL_CD, 0},
|
||||||
{DSI_SOL_DELAY, 24},
|
{DSI_SOL_DELAY, 24},
|
||||||
{DSI_MAX_THRESHOLD, 480},
|
{DSI_MAX_THRESHOLD, 480},
|
||||||
{DSI_TRIGGER, 0},
|
{DSI_TRIGGER, 0},
|
||||||
{DSI_INIT_SEQ_CONTROL, 0},
|
{DSI_INIT_SEQ_CONTROL, 0},
|
||||||
|
|
||||||
{DSI_PKT_LEN_0_1, 0},
|
{DSI_PKT_LEN_0_1, 0},
|
||||||
{DSI_PKT_LEN_2_3, 0},
|
{DSI_PKT_LEN_2_3, 0},
|
||||||
{DSI_PKT_LEN_4_5, 0},
|
{DSI_PKT_LEN_4_5, 0},
|
||||||
{DSI_PKT_LEN_6_7, 0},
|
{DSI_PKT_LEN_6_7, 0},
|
||||||
{DSI_PAD_CONTROL_1, 0}
|
|
||||||
};
|
{DSI_PAD_CONTROL_1, 0},
|
||||||
static const cfg_op_t _di_dsi_init_timing_pwrctrl_config[] = {
|
|
||||||
|
/* DSI PHY timings */
|
||||||
|
{DSI_PHY_TIMING_0, 0x6070603},
|
||||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||||
{DSI_PHY_TIMING_2, 0x30109},
|
{DSI_PHY_TIMING_2, 0x30109},
|
||||||
{DSI_BTA_TIMING, 0x190A14},
|
{DSI_BTA_TIMING, 0x190A14},
|
||||||
|
/* DSI timeout */
|
||||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
||||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
|
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
|
||||||
{DSI_TO_TALLY, 0},
|
{DSI_TO_TALLY, 0},
|
||||||
{DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Enable
|
|
||||||
|
{DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Power up.
|
||||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||||
{DSI_POWER_CONTROL, 0},
|
{DSI_POWER_CONTROL, 0},
|
||||||
{DSI_POWER_CONTROL, 0},
|
{DSI_POWER_CONTROL, 0},
|
||||||
{DSI_PAD_CONTROL_1, 0}
|
{DSI_PAD_CONTROL_1, 0},
|
||||||
};
|
|
||||||
static const cfg_op_t _di_dsi_init_timing_pkt_config3[] = {
|
/* DSI PHY timings */
|
||||||
|
{DSI_PHY_TIMING_0, 0x6070603},
|
||||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||||
{DSI_PHY_TIMING_2, 0x30118},
|
{DSI_PHY_TIMING_2, 0x30118},
|
||||||
{DSI_BTA_TIMING, 0x190A14},
|
{DSI_BTA_TIMING, 0x190A14},
|
||||||
|
/* DSI timeout */
|
||||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
||||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||||
{DSI_TO_TALLY, 0},
|
{DSI_TO_TALLY, 0},
|
||||||
|
|
||||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||||
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||||
@@ -148,7 +151,7 @@ static const cfg_op_t _di_dsi_init_timing_pkt_config3[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// DSI panel JDI config.
|
// DSI panel JDI config.
|
||||||
static const cfg_op_t _di_dsi_panel_init_config_jdi[] = {
|
static const reg_cfg_t _di_dsi_panel_init_config_jdi[] = {
|
||||||
{DSI_WR_DATA, 0x0439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
{DSI_WR_DATA, 0x0439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||||
@@ -194,14 +197,21 @@ static const cfg_op_t _di_dsi_panel_init_config_jdi[] = {
|
|||||||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||||
};
|
};
|
||||||
|
|
||||||
// DSI packet config.
|
// DSI HS packet config.
|
||||||
static const cfg_op_t _di_dsi_init_seq_pkt_final_config[] = {
|
static const reg_cfg_t _di_dsi_seq_pkt_video_non_burst_no_eot_config[] = {
|
||||||
|
{DSI_PAD_CONTROL_1, 0},
|
||||||
|
|
||||||
|
/* DSI PHY timings */
|
||||||
|
{DSI_PHY_TIMING_0, 0x6070603},
|
||||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||||
{DSI_PHY_TIMING_2, 0x30172},
|
{DSI_PHY_TIMING_2, 0x30172},
|
||||||
{DSI_BTA_TIMING, 0x190A14},
|
{DSI_BTA_TIMING, 0x190A14},
|
||||||
|
/* DSI timeout */
|
||||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},
|
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},
|
||||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
|
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
|
||||||
{DSI_TO_TALLY, 0},
|
{DSI_TO_TALLY, 0},
|
||||||
|
|
||||||
|
/* DSI packet sequence */
|
||||||
{DSI_PKT_SEQ_0_LO, 0x40000208},
|
{DSI_PKT_SEQ_0_LO, 0x40000208},
|
||||||
{DSI_PKT_SEQ_2_LO, 0x40000308},
|
{DSI_PKT_SEQ_2_LO, 0x40000308},
|
||||||
{DSI_PKT_SEQ_4_LO, 0x40000308},
|
{DSI_PKT_SEQ_4_LO, 0x40000308},
|
||||||
@@ -218,7 +228,7 @@ static const cfg_op_t _di_dsi_init_seq_pkt_final_config[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// DSI mode config.
|
// DSI mode config.
|
||||||
static const cfg_op_t _di_dsi_mode_config[] = {
|
static const reg_cfg_t _di_dsi_host_mode_config[] = {
|
||||||
{DSI_TRIGGER, 0},
|
{DSI_TRIGGER, 0},
|
||||||
{DSI_CONTROL, 0},
|
{DSI_CONTROL, 0},
|
||||||
{DSI_SOL_DELAY, 6},
|
{DSI_SOL_DELAY, 6},
|
||||||
@@ -232,7 +242,7 @@ static const cfg_op_t _di_dsi_mode_config[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// MIPI CAL config.
|
// MIPI CAL config.
|
||||||
static const cfg_op_t _di_mipi_pad_cal_config[] = {
|
static const reg_cfg_t _di_mipi_pad_cal_config[] = {
|
||||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
|
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
|
||||||
{MIPI_CAL_CIL_MIPI_CAL_STATUS, 0xF3F10000},
|
{MIPI_CAL_CIL_MIPI_CAL_STATUS, 0xF3F10000},
|
||||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG0, 0},
|
{MIPI_CAL_MIPI_BIAS_PAD_CFG0, 0},
|
||||||
@@ -240,13 +250,13 @@ static const cfg_op_t _di_mipi_pad_cal_config[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// DSI pad config.
|
// DSI pad config.
|
||||||
static const cfg_op_t _di_dsi_pad_cal_config_t210[] = {
|
static const reg_cfg_t _di_dsi_pad_cal_config_t210[] = {
|
||||||
{DSI_PAD_CONTROL_1, 0},
|
{DSI_PAD_CONTROL_1, 0},
|
||||||
{DSI_PAD_CONTROL_2, 0},
|
{DSI_PAD_CONTROL_2, 0},
|
||||||
{DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
|
{DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
|
||||||
{DSI_PAD_CONTROL_4, 0}
|
{DSI_PAD_CONTROL_4, 0}
|
||||||
};
|
};
|
||||||
static const cfg_op_t _di_dsi_pad_cal_config_t210b01[] = {
|
static const reg_cfg_t _di_dsi_pad_cal_config_t210b01[] = {
|
||||||
{DSI_PAD_CONTROL_1, 0},
|
{DSI_PAD_CONTROL_1, 0},
|
||||||
{DSI_PAD_CONTROL_2, 0},
|
{DSI_PAD_CONTROL_2, 0},
|
||||||
{DSI_PAD_CONTROL_3, 0},
|
{DSI_PAD_CONTROL_3, 0},
|
||||||
@@ -257,19 +267,19 @@ static const cfg_op_t _di_dsi_pad_cal_config_t210b01[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// MIPI CAL config.
|
// MIPI CAL config.
|
||||||
static const cfg_op_t _di_mipi_dsi_cal_offsets_config_t210[] = {
|
static const reg_cfg_t _di_mipi_dsi_cal_prod_config_t210[] = {
|
||||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200200},
|
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200200},
|
||||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200200},
|
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200200},
|
||||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x200002},
|
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x200002},
|
||||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x200002}
|
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x200002}
|
||||||
};
|
};
|
||||||
static const cfg_op_t _di_mipi_dsi_cal_offsets_config_t210b01[] = {
|
static const reg_cfg_t _di_mipi_dsi_cal_prod_config_t210b01[] = {
|
||||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200006},
|
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200006},
|
||||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200006},
|
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200006},
|
||||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x260000},
|
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x260000},
|
||||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x260000}
|
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x260000}
|
||||||
};
|
};
|
||||||
static const cfg_op_t _di_mipi_start_dsi_cal_config[] = {
|
static const reg_cfg_t _di_mipi_dsi_cal_unused_config[] = {
|
||||||
{MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0},
|
{MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0},
|
||||||
{MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0},
|
{MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0},
|
||||||
{MIPI_CAL_CILC_MIPI_CAL_CONFIG, 0},
|
{MIPI_CAL_CILC_MIPI_CAL_CONFIG, 0},
|
||||||
@@ -280,48 +290,11 @@ static const cfg_op_t _di_mipi_start_dsi_cal_config[] = {
|
|||||||
{MIPI_CAL_DSID_MIPI_CAL_CONFIG, 0},
|
{MIPI_CAL_DSID_MIPI_CAL_CONFIG, 0},
|
||||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0},
|
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0},
|
||||||
{MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2, 0},
|
{MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2, 0},
|
||||||
{MIPI_CAL_DSID_MIPI_CAL_CONFIG_2, 0},
|
{MIPI_CAL_DSID_MIPI_CAL_CONFIG_2, 0}
|
||||||
{MIPI_CAL_MIPI_CAL_CTRL, 0x2A000001} // Set Prescale and filter and start calibration.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Display A enable config.
|
// Display A enable config.
|
||||||
static const cfg_op_t _di_dc_video_enable_config[] = {
|
static const reg_cfg_t _di_dc_video_enable_config[] = {
|
||||||
{DC_CMD_STATE_ACCESS, 0},
|
|
||||||
|
|
||||||
/* Setup Windows A/B/C */
|
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT},
|
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{DC_WIN_DV_CONTROL, 0},
|
|
||||||
/* Setup default YUV colorspace conversion coefficients */
|
|
||||||
{DC_WIN_CSC_YOF, 0xF0},
|
|
||||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
|
||||||
{DC_WIN_CSC_KUR, 0},
|
|
||||||
{DC_WIN_CSC_KVR, 0x198},
|
|
||||||
{DC_WIN_CSC_KUG, 0x39B},
|
|
||||||
{DC_WIN_CSC_KVG, 0x32F},
|
|
||||||
{DC_WIN_CSC_KUB, 0x204},
|
|
||||||
{DC_WIN_CSC_KVB, 0},
|
|
||||||
/* End of color coefficients */
|
|
||||||
|
|
||||||
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
|
||||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
|
||||||
{DC_COM_PIN_OUTPUT_POLARITY(1), LSC0_OUTPUT_POLARITY_LOW},
|
|
||||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
|
||||||
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
|
||||||
{DC_COM_CRC_CONTROL, 0},
|
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT},
|
|
||||||
{DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_BYPASS | WIN_BLEND_DEPTH(255)},
|
|
||||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT},
|
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{DC_DISP_DISP_WIN_OPTIONS, 0},
|
|
||||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
|
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
|
||||||
{DC_CMD_STATE_ACCESS, 0},
|
|
||||||
|
|
||||||
/* Set panel timings */
|
/* Set panel timings */
|
||||||
{DC_DISP_DISP_TIMING_OPTIONS, VSYNC_H_POSITION(0)},
|
{DC_DISP_DISP_TIMING_OPTIONS, VSYNC_H_POSITION(0)},
|
||||||
{DC_DISP_REF_TO_SYNC, V_REF_TO_SYNC(1) | H_REF_TO_SYNC(0)},
|
{DC_DISP_REF_TO_SYNC, V_REF_TO_SYNC(1) | H_REF_TO_SYNC(0)},
|
||||||
@@ -334,59 +307,60 @@ static const cfg_op_t _di_dc_video_enable_config[] = {
|
|||||||
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
||||||
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
||||||
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
|
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
|
||||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
|
||||||
{DC_DISP_DISP_CLOCK_CONTROL, 0},
|
{DC_DISP_DISP_CLOCK_CONTROL, 0},
|
||||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT},
|
/* Start continuous display. */
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{DC_DISP_DISP_WIN_OPTIONS, 0},
|
|
||||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
|
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||||
{DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX},
|
|
||||||
{DC_DISP_FRONT_PORCH, V_FRONT_PORCH(10) | H_FRONT_PORCH(136)},
|
|
||||||
{DC_CMD_STATE_ACCESS, 0},
|
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||||
{DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
|
{DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
|
||||||
|
{DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||||
{DC_CMD_STATE_ACCESS, 0},
|
|
||||||
{DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)},
|
{DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)}, // 4: div3.
|
||||||
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
|
||||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Display A disable config.
|
// Display A disable config.
|
||||||
static const cfg_op_t _di_dc_video_disable_config[] = {
|
static const reg_cfg_t _di_dc_video_disable_config[] = {
|
||||||
{DC_DISP_FRONT_PORCH, V_FRONT_PORCH(10) | H_FRONT_PORCH(136)},
|
|
||||||
{DC_CMD_INT_MASK, 0},
|
{DC_CMD_INT_MASK, 0},
|
||||||
{DC_CMD_STATE_ACCESS, 0},
|
{DC_CMD_STATE_ACCESS, READ_MUX_ASSEMBLY | WRITE_MUX_ASSEMBLY},
|
||||||
{DC_CMD_INT_ENABLE, 0},
|
{DC_CMD_INT_ENABLE, 0},
|
||||||
{DC_CMD_CONT_SYNCPT_VSYNC, 0},
|
{DC_CMD_CONT_SYNCPT_VSYNC, 0},
|
||||||
|
|
||||||
|
/* Stop display. */
|
||||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
|
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||||
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||||
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||||
|
{DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
|
||||||
{DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
|
{DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||||
// LCD panels should sleep for 40ms here.
|
// TODO: LCD panels should sleep for 40ms here.
|
||||||
{DC_CMD_DISPLAY_POWER_CONTROL, 0},
|
{DC_CMD_DISPLAY_POWER_CONTROL, 0},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||||
};
|
};
|
||||||
|
|
||||||
// DSI deinit config.
|
// DSI deinit config.
|
||||||
static const cfg_op_t _di_dsi_timing_deinit_config[] = {
|
static const reg_cfg_t _di_dsi_timing_deinit_config[] = {
|
||||||
{DSI_POWER_CONTROL, 0},
|
{DSI_POWER_CONTROL, 0},
|
||||||
{DSI_PAD_CONTROL_1, 0},
|
{DSI_PAD_CONTROL_1, 0},
|
||||||
{DSI_PHY_TIMING_0, 0x6070601}, //mariko changes
|
|
||||||
|
/* DSI PHY timings */
|
||||||
|
{DSI_PHY_TIMING_0, 0x6070603},
|
||||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||||
{DSI_PHY_TIMING_2, 0x30118},
|
{DSI_PHY_TIMING_2, 0x30118},
|
||||||
{DSI_BTA_TIMING, 0x190A14},
|
{DSI_BTA_TIMING, 0x190A14},
|
||||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },
|
/* DSI timeout */
|
||||||
|
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
||||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||||
{DSI_TO_TALLY, 0},
|
{DSI_TO_TALLY, 0},
|
||||||
|
|
||||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||||
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||||
@@ -397,7 +371,7 @@ static const cfg_op_t _di_dsi_timing_deinit_config[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// DSI panel JDI deinit config.
|
// DSI panel JDI deinit config.
|
||||||
static const cfg_op_t _di_dsi_panel_deinit_config_jdi[] = {
|
static const reg_cfg_t _di_dsi_panel_deinit_config_jdi[] = {
|
||||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||||
@@ -423,7 +397,7 @@ static const cfg_op_t _di_dsi_panel_deinit_config_jdi[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// DSI panel AUO deinit config.
|
// DSI panel AUO deinit config.
|
||||||
static const cfg_op_t _di_dsi_panel_deinit_config_auo[] = {
|
static const reg_cfg_t _di_dsi_panel_deinit_config_auo[] = {
|
||||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||||
@@ -464,24 +438,24 @@ static const cfg_op_t _di_dsi_panel_deinit_config_auo[] = {
|
|||||||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const cfg_op_t _di_init_config_invert[] = {
|
/*
|
||||||
|
static const reg_cfg_t _di_init_config_invert[] = {
|
||||||
{DSI_WR_DATA, 0x239},
|
{DSI_WR_DATA, 0x239},
|
||||||
{DSI_WR_DATA, 0x02C1}, // INV_EN.
|
{DSI_WR_DATA, 0x02C1}, // INV_EN.
|
||||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
// Display A Window A one color config.
|
// Display A Window A one color config.
|
||||||
static const cfg_op_t _di_win_one_color[] = {
|
static const reg_cfg_t _di_win_one_color[] = {
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT},
|
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT | WINDOW_D_SELECT},
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
{DC_WIN_WIN_OPTIONS, 0},
|
||||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} // Continuous display.
|
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} // Continuous display.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Display A Window A linear pitch config.
|
// Display A Window A linear pitch config.
|
||||||
static const cfg_op_t _di_win_framebuffer_pitch[] = {
|
static const reg_cfg_t _di_winA_pitch[] = {
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT | WINDOW_B_SELECT},
|
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
{DC_WIN_WIN_OPTIONS, 0},
|
||||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||||
@@ -500,14 +474,12 @@ static const cfg_op_t _di_win_framebuffer_pitch[] = {
|
|||||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
|
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
|
||||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Display A Window A linear pitch + Win D support config.
|
// Display A Window A linear pitch + Win D support config.
|
||||||
static const cfg_op_t _di_win_framebuffer_pitch_vic[] = {
|
static const reg_cfg_t _di_winA_pitch_vic[] = {
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT | WINDOW_C_SELECT | WINDOW_B_SELECT},
|
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
{DC_WIN_WIN_OPTIONS, 0},
|
||||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||||
@@ -526,14 +498,12 @@ static const cfg_op_t _di_win_framebuffer_pitch_vic[] = {
|
|||||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
|
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
|
||||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Display A Window A linear pitch inverse + Win D support config.
|
// Display A Window A linear pitch inverse + Win D support config.
|
||||||
static const cfg_op_t _di_win_framebuffer_pitch_inv[] = {
|
static const reg_cfg_t _di_winA_pitch_inv[] = {
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT | WINDOW_C_SELECT | WINDOW_B_SELECT},
|
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
{DC_WIN_WIN_OPTIONS, 0},
|
||||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||||
@@ -552,14 +522,12 @@ static const cfg_op_t _di_win_framebuffer_pitch_inv[] = {
|
|||||||
{DC_WINBUF_ADDR_V_OFFSET, 1279}, // Linear: 1279, Block: 0.
|
{DC_WINBUF_ADDR_V_OFFSET, 1279}, // Linear: 1279, Block: 0.
|
||||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | V_DIRECTION}, // Enable window AD.
|
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | V_DIRECTION}, // Enable window AD.
|
||||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Display A Window A block linear config.
|
// Display A Window A block linear config.
|
||||||
static const cfg_op_t _di_win_framebuffer_block[] = {
|
static const reg_cfg_t _di_winA_block[] = {
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT | WINDOW_C_SELECT | WINDOW_B_SELECT},
|
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
{DC_WIN_WIN_OPTIONS, 0},
|
||||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||||
@@ -578,12 +546,12 @@ static const cfg_op_t _di_win_framebuffer_block[] = {
|
|||||||
{DC_WINBUF_ADDR_V_OFFSET, 0}, // Linear: 1279, Block: 0.
|
{DC_WINBUF_ADDR_V_OFFSET, 0}, // Linear: 1279, Block: 0.
|
||||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | SCAN_COLUMN | H_DIRECTION}, // Enable window AD. | SCAN_COLUMN | H_DIRECTION.
|
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | SCAN_COLUMN | H_DIRECTION}, // Enable window AD. | SCAN_COLUMN | H_DIRECTION.
|
||||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Display A Window D config.
|
// Display A Window D config.
|
||||||
static const cfg_op_t _di_win_framebuffer_log[] = {
|
static const reg_cfg_t _di_winD_log[] = {
|
||||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
|
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
{DC_WIN_WIN_OPTIONS, 0},
|
||||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8},
|
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8},
|
||||||
@@ -601,6 +569,6 @@ static const cfg_op_t _di_win_framebuffer_log[] = {
|
|||||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||||
{DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_ENABLE | WIN_K1(200) | WIN_BLEND_DEPTH(0)},
|
{DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_ENABLE | WIN_K1(200) | WIN_BLEND_DEPTH(0)},
|
||||||
{DC_WINBUF_BLEND_MATCH_SELECT, WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_K1 | WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_NEG_K1},
|
{DC_WINBUF_BLEND_MATCH_SELECT, WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_K1 | WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_NEG_K1},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_D_UPDATE},
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_D_UPDATE},
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_D_ACT_REQ}
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_D_ACT_REQ},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* VIC driver for Tegra X1
|
* VIC driver for Tegra X1
|
||||||
*
|
*
|
||||||
* Copyright (c) 2018-2023 CTCaer
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -390,7 +390,7 @@ static int _vic_wait_idle()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vic_set_surface(vic_surface_t *sfc)
|
void vic_set_surface(const vic_surface_t *sfc)
|
||||||
{
|
{
|
||||||
u32 flip_x = 0;
|
u32 flip_x = 0;
|
||||||
u32 flip_y = 0;
|
u32 flip_y = 0;
|
||||||
@@ -406,6 +406,9 @@ void vic_set_surface(vic_surface_t *sfc)
|
|||||||
// Get format alpha type.
|
// Get format alpha type.
|
||||||
switch (sfc->pix_fmt)
|
switch (sfc->pix_fmt)
|
||||||
{
|
{
|
||||||
|
case VIC_PIX_FORMAT_L8:
|
||||||
|
case VIC_PIX_FORMAT_X1B5G5R5:
|
||||||
|
case VIC_PIX_FORMAT_B5G5R5X1:
|
||||||
case VIC_PIX_FORMAT_X8B8G8R8:
|
case VIC_PIX_FORMAT_X8B8G8R8:
|
||||||
case VIC_PIX_FORMAT_X8R8G8B8:
|
case VIC_PIX_FORMAT_X8R8G8B8:
|
||||||
case VIC_PIX_FORMAT_B8G8R8X8:
|
case VIC_PIX_FORMAT_B8G8R8X8:
|
||||||
@@ -536,14 +539,8 @@ int vic_compose()
|
|||||||
|
|
||||||
int vic_init()
|
int vic_init()
|
||||||
{
|
{
|
||||||
// Ease the stress to APB.
|
|
||||||
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
|
||||||
|
|
||||||
clock_enable_vic();
|
clock_enable_vic();
|
||||||
|
|
||||||
// Restore sys clock.
|
|
||||||
bpmp_clk_rate_set(prev_fid);
|
|
||||||
|
|
||||||
// Load Fetch Control Engine microcode.
|
// Load Fetch Control Engine microcode.
|
||||||
for (u32 i = 0; i < sizeof(vic_fce_ucode) / sizeof(u32); i++)
|
for (u32 i = 0; i < sizeof(vic_fce_ucode) / sizeof(u32); i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ typedef enum _vic_rotation_t
|
|||||||
|
|
||||||
typedef enum _vic_pix_format_t
|
typedef enum _vic_pix_format_t
|
||||||
{
|
{
|
||||||
|
VIC_PIX_FORMAT_L8 = 1, // 8-bit LUT.
|
||||||
|
VIC_PIX_FORMAT_X1B5G5R5 = 21, // 16-bit XBGR.
|
||||||
|
VIC_PIX_FORMAT_B5G5R5X1 = 23, // 16-bit BGRX.
|
||||||
|
|
||||||
VIC_PIX_FORMAT_A8B8G8R8 = 31, // 32-bit ABGR.
|
VIC_PIX_FORMAT_A8B8G8R8 = 31, // 32-bit ABGR.
|
||||||
VIC_PIX_FORMAT_A8R8G8B8 = 32, // 32-bit ARGB.
|
VIC_PIX_FORMAT_A8R8G8B8 = 32, // 32-bit ARGB.
|
||||||
VIC_PIX_FORMAT_B8G8R8A8 = 33, // 32-bit BGRA.
|
VIC_PIX_FORMAT_B8G8R8A8 = 33, // 32-bit BGRA.
|
||||||
@@ -42,7 +46,6 @@ typedef enum _vic_pix_format_t
|
|||||||
VIC_PIX_FORMAT_X8R8G8B8 = 36, // 32-bit XRGB.
|
VIC_PIX_FORMAT_X8R8G8B8 = 36, // 32-bit XRGB.
|
||||||
VIC_PIX_FORMAT_B8G8R8X8 = 37, // 32-bit BGRX.
|
VIC_PIX_FORMAT_B8G8R8X8 = 37, // 32-bit BGRX.
|
||||||
VIC_PIX_FORMAT_R8G8B8X8 = 38, // 32-bit RGBX.
|
VIC_PIX_FORMAT_R8G8B8X8 = 38, // 32-bit RGBX.
|
||||||
|
|
||||||
} vic_pix_format_t;
|
} vic_pix_format_t;
|
||||||
|
|
||||||
typedef struct _vic_surface_t
|
typedef struct _vic_surface_t
|
||||||
@@ -55,7 +58,7 @@ typedef struct _vic_surface_t
|
|||||||
u32 rotation;
|
u32 rotation;
|
||||||
} vic_surface_t;
|
} vic_surface_t;
|
||||||
|
|
||||||
void vic_set_surface(vic_surface_t *sfc);
|
void vic_set_surface(const vic_surface_t *sfc);
|
||||||
int vic_compose();
|
int vic_compose();
|
||||||
int vic_init();
|
int vic_init();
|
||||||
void vic_end();
|
void vic_end();
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_MKFS 1
|
#define FF_USE_MKFS 0
|
||||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
#if FF_USE_MKFS
|
#if FF_USE_MKFS
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ typedef struct _opt_win_cal_t
|
|||||||
} opt_win_cal_t;
|
} opt_win_cal_t;
|
||||||
|
|
||||||
// Nintendo Switch Icosa/Iowa Optical Window calibration.
|
// Nintendo Switch Icosa/Iowa Optical Window calibration.
|
||||||
const opt_win_cal_t opt_win_cal_default[] = {
|
static const opt_win_cal_t opt_win_cal_default[] = {
|
||||||
{ 500, 5002, 7502 },
|
{ 500, 5002, 7502 },
|
||||||
{ 754, 2250, 2000 },
|
{ 754, 2250, 2000 },
|
||||||
{ 1029, 1999, 1667 },
|
{ 1029, 1999, 1667 },
|
||||||
@@ -54,14 +54,14 @@ const opt_win_cal_t opt_win_cal_default[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Nintendo Switch Aula Optical Window calibration.
|
// Nintendo Switch Aula Optical Window calibration.
|
||||||
const opt_win_cal_t opt_win_cal_aula[] = {
|
static const opt_win_cal_t opt_win_cal_aula[] = {
|
||||||
{ 231, 9697, 30300 },
|
{ 231, 9697, 30300 },
|
||||||
{ 993, 3333, 2778 },
|
{ 993, 3333, 2778 },
|
||||||
{ 1478, 1621, 1053 },
|
{ 1478, 1621, 1053 },
|
||||||
{ 7500, 81, 10 }
|
{ 7500, 81, 10 }
|
||||||
};
|
};
|
||||||
|
|
||||||
const u32 als_gain_idx_tbl[4] = { 1, 2, 64, 128 };
|
static const u32 als_gain_idx_tbl[4] = { 1, 2, 64, 128 };
|
||||||
|
|
||||||
void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
|
void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
|
||||||
{
|
{
|
||||||
@@ -70,8 +70,6 @@ void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
|
|||||||
|
|
||||||
if (!cycle)
|
if (!cycle)
|
||||||
cycle = 1;
|
cycle = 1;
|
||||||
else if (cycle > 255)
|
|
||||||
cycle = 255;
|
|
||||||
|
|
||||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
|
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
|
||||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle));
|
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle));
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Joy-Con UART driver for Nintendo Switch
|
* Joy-Con UART driver for Nintendo Switch
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019-2023 CTCaer
|
* Copyright (c) 2019-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -22,7 +22,6 @@
|
|||||||
#include <gfx_utils.h>
|
#include <gfx_utils.h>
|
||||||
#include <power/max17050.h>
|
#include <power/max17050.h>
|
||||||
#include <power/regulator_5v.h>
|
#include <power/regulator_5v.h>
|
||||||
#include <soc/bpmp.h>
|
|
||||||
#include <soc/clock.h>
|
#include <soc/clock.h>
|
||||||
#include <soc/fuse.h>
|
#include <soc/fuse.h>
|
||||||
#include <soc/gpio.h>
|
#include <soc/gpio.h>
|
||||||
@@ -43,7 +42,9 @@
|
|||||||
#define JC_HORI_INPUT_RPT 0x00
|
#define JC_HORI_INPUT_RPT 0x00
|
||||||
|
|
||||||
#define JC_WIRED_CMD_GET_INFO 0x01
|
#define JC_WIRED_CMD_GET_INFO 0x01
|
||||||
#define JC_WIRED_CMD_CHRG_CFG 0x02
|
#define JC_WIRED_CMD_SET_CHARGER 0x02
|
||||||
|
#define JC_WIRED_CMD_GET_CHARGER 0x03
|
||||||
|
#define JC_WIRED_CMD_BATT_VOLT 0x06
|
||||||
#define JC_WIRED_CMD_WAKE_REASON 0x07
|
#define JC_WIRED_CMD_WAKE_REASON 0x07
|
||||||
#define JC_WIRED_CMD_HID_CONN 0x10
|
#define JC_WIRED_CMD_HID_CONN 0x10
|
||||||
#define JC_WIRED_CMD_HID_DISC 0x11
|
#define JC_WIRED_CMD_HID_DISC 0x11
|
||||||
@@ -102,10 +103,10 @@ enum
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
JC_BATT_EMTPY = 0,
|
JC_BATT_EMTPY = 0,
|
||||||
JC_BATT_CRIT = 2,
|
JC_BATT_CRIT = 1,
|
||||||
JC_BATT_LOW = 4,
|
JC_BATT_LOW = 2,
|
||||||
JC_BATT_MID = 6,
|
JC_BATT_MID = 3,
|
||||||
JC_BATT_FULL = 8
|
JC_BATT_FULL = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u8 sio_init[] = {
|
static const u8 sio_init[] = {
|
||||||
@@ -221,8 +222,8 @@ typedef struct _jc_hid_in_rpt_t
|
|||||||
{
|
{
|
||||||
u8 cmd;
|
u8 cmd;
|
||||||
u8 pkt_id;
|
u8 pkt_id;
|
||||||
u8 conn_info:4;
|
u8 conn_info:4; // Connection detect.
|
||||||
u8 batt_info:4;
|
u8 batt_info:4; // Power info.
|
||||||
u8 btn_right;
|
u8 btn_right;
|
||||||
u8 btn_shared;
|
u8 btn_shared;
|
||||||
u8 btn_left;
|
u8 btn_left;
|
||||||
@@ -232,7 +233,7 @@ typedef struct _jc_hid_in_rpt_t
|
|||||||
u8 stick_h_right;
|
u8 stick_h_right;
|
||||||
u8 stick_m_right;
|
u8 stick_m_right;
|
||||||
u8 stick_v_right;
|
u8 stick_v_right;
|
||||||
u8 vib_decider; // right:8, left:8. (bit3 en, bit2-0 buffer avail).
|
u8 vib_decider; // right:4, left:4 (bit3 en, bit2-0 buffer avail).
|
||||||
u8 submcd_ack;
|
u8 submcd_ack;
|
||||||
u8 subcmd;
|
u8 subcmd;
|
||||||
u8 subcmd_data[];
|
u8 subcmd_data[];
|
||||||
@@ -304,7 +305,7 @@ typedef struct _jc_sio_hid_in_rpt_t
|
|||||||
u8 stick_h_right;
|
u8 stick_h_right;
|
||||||
u8 stick_m_right;
|
u8 stick_m_right;
|
||||||
u8 stick_v_right;
|
u8 stick_v_right;
|
||||||
u8 siaxis_rpt_num; // Max 15.
|
u8 siaxis_rpt; // bit0-3: report num. bit4-7: imu type.
|
||||||
// Each report is 800 us?
|
// Each report is 800 us?
|
||||||
jc_hid_in_sixaxis_rpt_t sixaxis[15];
|
jc_hid_in_sixaxis_rpt_t sixaxis[15];
|
||||||
} jc_sio_hid_in_rpt_t;
|
} jc_sio_hid_in_rpt_t;
|
||||||
@@ -315,9 +316,10 @@ typedef struct _joycon_ctxt_t
|
|||||||
u8 uart;
|
u8 uart;
|
||||||
u8 type;
|
u8 type;
|
||||||
u8 state;
|
u8 state;
|
||||||
u8 mac[6];
|
|
||||||
u32 last_received_time;
|
u32 last_received_time;
|
||||||
u32 last_status_req_time;
|
u32 last_status_req_time;
|
||||||
|
u8 mac[6];
|
||||||
|
u8 pkt_id;
|
||||||
u8 rumble_sent;
|
u8 rumble_sent;
|
||||||
u8 connected;
|
u8 connected;
|
||||||
u8 detected;
|
u8 detected;
|
||||||
@@ -328,11 +330,10 @@ static joycon_ctxt_t jc_l = {0};
|
|||||||
static joycon_ctxt_t jc_r = {0};
|
static joycon_ctxt_t jc_r = {0};
|
||||||
|
|
||||||
static bool jc_init_done = false;
|
static bool jc_init_done = false;
|
||||||
static u32 hid_pkt_inc = 0;
|
|
||||||
|
|
||||||
static jc_gamepad_rpt_t jc_gamepad;
|
static jc_gamepad_rpt_t jc_gamepad;
|
||||||
|
|
||||||
static u8 _jc_crc(u8 *data, u16 len, u8 init)
|
static u8 _jc_crc(const u8 *data, u16 len, u8 init)
|
||||||
{
|
{
|
||||||
u8 crc = init;
|
u8 crc = init;
|
||||||
for (u16 i = 0; i < len; i++)
|
for (u16 i = 0; i < len; i++)
|
||||||
@@ -405,12 +406,16 @@ static void _jc_detect()
|
|||||||
if (!jc_gamepad.sio_mode)
|
if (!jc_gamepad.sio_mode)
|
||||||
{
|
{
|
||||||
// Turn on Joy-Con detect. (UARTB/C TX). UART CTS also if HW flow control and irq is enabled.
|
// Turn on Joy-Con detect. (UARTB/C TX). UART CTS also if HW flow control and irq is enabled.
|
||||||
PINMUX_AUX(PINMUX_AUX_UART2_TX) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
PINMUX_AUX(PINMUX_AUX_UART2_TX) = PINMUX_INPUT_ENABLE;
|
||||||
PINMUX_AUX(PINMUX_AUX_UART3_TX) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
PINMUX_AUX(PINMUX_AUX_UART3_TX) = PINMUX_INPUT_ENABLE;
|
||||||
gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0);
|
gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0);
|
||||||
gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1);
|
gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1);
|
||||||
usleep(20);
|
usleep(20);
|
||||||
|
|
||||||
|
//! HW BUG: Unlatch gpio buffer.
|
||||||
|
(void)gpio_read(GPIO_PORT_H, GPIO_PIN_6);
|
||||||
|
(void)gpio_read(GPIO_PORT_E, GPIO_PIN_6);
|
||||||
|
|
||||||
// Read H6/E6 which are shared with UART TX pins.
|
// Read H6/E6 which are shared with UART TX pins.
|
||||||
jc_r.detected = !gpio_read(GPIO_PORT_H, GPIO_PIN_6);
|
jc_r.detected = !gpio_read(GPIO_PORT_H, GPIO_PIN_6);
|
||||||
jc_l.detected = !gpio_read(GPIO_PORT_E, GPIO_PIN_6);
|
jc_l.detected = !gpio_read(GPIO_PORT_E, GPIO_PIN_6);
|
||||||
@@ -442,7 +447,7 @@ static void _jc_conn_check()
|
|||||||
if (jc_l.connected)
|
if (jc_l.connected)
|
||||||
_jc_power_supply(UART_C, false);
|
_jc_power_supply(UART_C, false);
|
||||||
|
|
||||||
hid_pkt_inc = 0;
|
jc_l.pkt_id = 0;
|
||||||
|
|
||||||
jc_l.connected = false;
|
jc_l.connected = false;
|
||||||
jc_l.rumble_sent = false;
|
jc_l.rumble_sent = false;
|
||||||
@@ -459,7 +464,7 @@ static void _jc_conn_check()
|
|||||||
if (jc_r.connected)
|
if (jc_r.connected)
|
||||||
_jc_power_supply(UART_B, false);
|
_jc_power_supply(UART_B, false);
|
||||||
|
|
||||||
hid_pkt_inc = 0;
|
jc_r.pkt_id = 0;
|
||||||
|
|
||||||
jc_r.connected = false;
|
jc_r.connected = false;
|
||||||
jc_r.rumble_sent = false;
|
jc_r.rumble_sent = false;
|
||||||
@@ -478,7 +483,7 @@ static void _joycon_send_raw(u8 uart_port, const u8 *buf, u16 size)
|
|||||||
uart_wait_xfer(uart_port, UART_TX_IDLE);
|
uart_wait_xfer(uart_port, UART_TX_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u16 _jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u16 size, bool crc)
|
static u16 _jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, const u8 *data, u16 size, bool crc)
|
||||||
{
|
{
|
||||||
out->uart_hdr.magic[0] = 0x19;
|
out->uart_hdr.magic[0] = 0x19;
|
||||||
out->uart_hdr.magic[1] = 0x01;
|
out->uart_hdr.magic[1] = 0x01;
|
||||||
@@ -498,7 +503,7 @@ static u16 _jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data,
|
|||||||
return sizeof(jc_wired_hdr_t);
|
return sizeof(jc_wired_hdr_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u16 _jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size, bool crc)
|
static u16 _jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, const u8 *payload, u16 size, bool crc)
|
||||||
{
|
{
|
||||||
u16 pkt_size = _jc_packet_add_uart_hdr(rpt, JC_WIRED_HID, NULL, 0, crc);
|
u16 pkt_size = _jc_packet_add_uart_hdr(rpt, JC_WIRED_HID, NULL, 0, crc);
|
||||||
pkt_size += size;
|
pkt_size += size;
|
||||||
@@ -513,25 +518,21 @@ static u16 _jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size,
|
|||||||
return pkt_size;
|
return pkt_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _jc_send_hid_output_rpt(u8 uart, u8 *payload, u16 size, bool crc)
|
static void _jc_send_hid_output_rpt(joycon_ctxt_t *jc, jc_hid_out_rpt_t *hid_pkt, u16 size, bool crc)
|
||||||
{
|
{
|
||||||
u8 rpt[0x50];
|
u8 rpt[0x50];
|
||||||
memset(rpt, 0, sizeof(rpt));
|
memset(rpt, 0, sizeof(rpt));
|
||||||
|
|
||||||
u32 rpt_size = _jc_hid_output_rpt_craft((jc_wired_hdr_t *)rpt, payload, size, crc);
|
hid_pkt->pkt_id = (jc->pkt_id++ & 0xF);
|
||||||
|
u32 rpt_size = _jc_hid_output_rpt_craft((jc_wired_hdr_t *)rpt, (u8 *)hid_pkt, size, crc);
|
||||||
|
|
||||||
_joycon_send_raw(uart, rpt, rpt_size);
|
_joycon_send_raw(jc->uart, rpt, rpt_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 _jc_hid_pkt_id_incr()
|
static void _jc_send_hid_cmd(joycon_ctxt_t *jc, u8 subcmd, const u8 *data, u16 size)
|
||||||
{
|
{
|
||||||
return (hid_pkt_inc++ & 0xF);
|
static const u8 rumble_neutral[8] = { 0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40 };
|
||||||
}
|
static const u8 rumble_init[8] = { 0xc2, 0xc8, 0x03, 0x72, 0xc2, 0xc8, 0x03, 0x72 };
|
||||||
|
|
||||||
static void _jc_send_hid_cmd(u8 uart, u8 subcmd, u8 *data, u16 size)
|
|
||||||
{
|
|
||||||
const u8 rumble_neutral[8] = { 0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40 };
|
|
||||||
const u8 rumble_init[8] = { 0xc2, 0xc8, 0x03, 0x72, 0xc2, 0xc8, 0x03, 0x72 };
|
|
||||||
|
|
||||||
u8 temp[0x30] = {0};
|
u8 temp[0x30] = {0};
|
||||||
|
|
||||||
@@ -545,47 +546,43 @@ static void _jc_send_hid_cmd(u8 uart, u8 subcmd, u8 *data, u16 size)
|
|||||||
|
|
||||||
// Enable rumble.
|
// Enable rumble.
|
||||||
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
||||||
hid_pkt->pkt_id = _jc_hid_pkt_id_incr();
|
|
||||||
hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL;
|
hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL;
|
||||||
hid_pkt->subcmd_data[0] = 1;
|
hid_pkt->subcmd_data[0] = 1;
|
||||||
if (send_r_rumble)
|
if (send_r_rumble)
|
||||||
_jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10, false);
|
_jc_send_hid_output_rpt(&jc_r, hid_pkt, 0x10, false);
|
||||||
if (send_l_rumble)
|
if (send_l_rumble)
|
||||||
_jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10, false);
|
_jc_send_hid_output_rpt(&jc_l, hid_pkt, 0x10, false);
|
||||||
|
|
||||||
// Send rumble.
|
// Send rumble.
|
||||||
hid_pkt->cmd = JC_HID_RUMBLE_RPT;
|
hid_pkt->cmd = JC_HID_RUMBLE_RPT;
|
||||||
hid_pkt->pkt_id = _jc_hid_pkt_id_incr();
|
|
||||||
memcpy(hid_pkt->rumble, rumble_init, sizeof(rumble_init));
|
memcpy(hid_pkt->rumble, rumble_init, sizeof(rumble_init));
|
||||||
if (send_r_rumble)
|
if (send_r_rumble)
|
||||||
_jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 10, false);
|
_jc_send_hid_output_rpt(&jc_r, hid_pkt, 10, false);
|
||||||
if (send_l_rumble)
|
if (send_l_rumble)
|
||||||
_jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 10, false);
|
_jc_send_hid_output_rpt(&jc_l, hid_pkt, 10, false);
|
||||||
|
|
||||||
msleep(15);
|
msleep(15);
|
||||||
|
|
||||||
// Disable rumble.
|
// Disable rumble.
|
||||||
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
||||||
hid_pkt->pkt_id = _jc_hid_pkt_id_incr();
|
|
||||||
hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL;
|
hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL;
|
||||||
hid_pkt->subcmd_data[0] = 0;
|
hid_pkt->subcmd_data[0] = 0;
|
||||||
memcpy(hid_pkt->rumble, rumble_neutral, sizeof(rumble_neutral));
|
memcpy(hid_pkt->rumble, rumble_neutral, sizeof(rumble_neutral));
|
||||||
if (send_r_rumble)
|
if (send_r_rumble)
|
||||||
_jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10, false);
|
_jc_send_hid_output_rpt(&jc_r, hid_pkt, 0x10, false);
|
||||||
if (send_l_rumble)
|
if (send_l_rumble)
|
||||||
_jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10, false);
|
_jc_send_hid_output_rpt(&jc_l, hid_pkt, 0x10, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool crc_needed = (jc_l.uart == uart) ? (jc_l.type & JC_ID_HORI) : (jc_r.type & JC_ID_HORI);
|
bool crc_needed = jc->type & JC_ID_HORI;
|
||||||
|
|
||||||
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
||||||
hid_pkt->pkt_id = _jc_hid_pkt_id_incr();
|
|
||||||
hid_pkt->subcmd = subcmd;
|
hid_pkt->subcmd = subcmd;
|
||||||
if (data)
|
if (data)
|
||||||
memcpy(hid_pkt->subcmd_data, data, size);
|
memcpy(hid_pkt->subcmd_data, data, size);
|
||||||
|
|
||||||
_jc_send_hid_output_rpt(uart, (u8 *)hid_pkt, sizeof(jc_hid_out_rpt_t) + size, crc_needed);
|
_jc_send_hid_output_rpt(jc, hid_pkt, sizeof(jc_hid_out_rpt_t) + size, crc_needed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,13 +591,13 @@ static void _jc_charging_decider(u8 batt, u8 uart)
|
|||||||
u32 system_batt_enough = max17050_get_cached_batt_volt() > 4000;
|
u32 system_batt_enough = max17050_get_cached_batt_volt() > 4000;
|
||||||
|
|
||||||
// Power supply control based on battery levels and charging.
|
// Power supply control based on battery levels and charging.
|
||||||
if ((batt >> 1 << 1) < JC_BATT_LOW) // Level without checking charging.
|
if ((batt >> 1) < JC_BATT_LOW) // Level without checking charging.
|
||||||
_jc_power_supply(uart, true);
|
_jc_power_supply(uart, true);
|
||||||
else if (batt > (system_batt_enough ? JC_BATT_FULL : JC_BATT_MID)) // Addresses the charging bit.
|
else if (batt > (system_batt_enough ? JC_BATT_FULL : JC_BATT_MID) << 1) // Addresses the charging bit.
|
||||||
_jc_power_supply(uart, false);
|
_jc_power_supply(uart, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
|
static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8 *packet, int size)
|
||||||
{
|
{
|
||||||
u32 btn_tmp;
|
u32 btn_tmp;
|
||||||
jc_hid_in_rpt_t *hid_pkt = (jc_hid_in_rpt_t *)packet;
|
jc_hid_in_rpt_t *hid_pkt = (jc_hid_in_rpt_t *)packet;
|
||||||
@@ -608,7 +605,14 @@ static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
|
|||||||
switch (hid_pkt->cmd)
|
switch (hid_pkt->cmd)
|
||||||
{
|
{
|
||||||
case JC_HORI_INPUT_RPT:
|
case JC_HORI_INPUT_RPT:
|
||||||
|
if (!(jc->type & JC_ID_HORI))
|
||||||
|
return;
|
||||||
|
|
||||||
case JC_HID_INPUT_RPT:
|
case JC_HID_INPUT_RPT:
|
||||||
|
// Discard incomplete hid packets.
|
||||||
|
if (size < 12)
|
||||||
|
break;
|
||||||
|
|
||||||
btn_tmp = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
|
btn_tmp = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
|
||||||
|
|
||||||
if (jc->type & JC_ID_L)
|
if (jc->type & JC_ID_L)
|
||||||
@@ -668,8 +672,12 @@ static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _jc_parse_wired_init(joycon_ctxt_t *jc, const u8* data, u32 size)
|
static void _jc_parse_wired_init(joycon_ctxt_t *jc, const u8 *data, int size)
|
||||||
{
|
{
|
||||||
|
// Discard empty packets.
|
||||||
|
if (size <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (data[0])
|
switch (data[0])
|
||||||
{
|
{
|
||||||
case JC_WIRED_CMD_GET_INFO:
|
case JC_WIRED_CMD_GET_INFO:
|
||||||
@@ -692,13 +700,13 @@ static void _jc_parse_wired_init(joycon_ctxt_t *jc, const u8* data, u32 size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _jc_uart_pkt_parse(joycon_ctxt_t *jc, const jc_wired_hdr_t *pkt, size_t size)
|
static void _jc_uart_pkt_parse(joycon_ctxt_t *jc, const jc_wired_hdr_t *pkt, int size)
|
||||||
{
|
{
|
||||||
switch (pkt->cmd)
|
switch (pkt->cmd)
|
||||||
{
|
{
|
||||||
case JC_HORI_INPUT_RPT_CMD:
|
case JC_HORI_INPUT_RPT_CMD:
|
||||||
case JC_WIRED_HID:
|
case JC_WIRED_HID:
|
||||||
_jc_parse_wired_hid(jc, pkt->payload, (pkt->data[0] << 8) | pkt->data[1]);
|
_jc_parse_wired_hid(jc, pkt->payload, size - sizeof(jc_wired_hdr_t));
|
||||||
break;
|
break;
|
||||||
case JC_WIRED_INIT_REPLY:
|
case JC_WIRED_INIT_REPLY:
|
||||||
_jc_parse_wired_init(jc, pkt->data, size - sizeof(jc_uart_hdr_t) - 1);
|
_jc_parse_wired_init(jc, pkt->data, size - sizeof(jc_uart_hdr_t) - 1);
|
||||||
@@ -713,11 +721,15 @@ static void _jc_uart_pkt_parse(joycon_ctxt_t *jc, const jc_wired_hdr_t *pkt, siz
|
|||||||
jc->last_received_time = get_tmr_ms();
|
jc->last_received_time = get_tmr_ms();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _jc_sio_parse_payload(joycon_ctxt_t *jc, u8 cmd, const u8* payload, u32 size)
|
static void _jc_sio_parse_payload(joycon_ctxt_t *jc, u8 cmd, const u8 *payload, int size)
|
||||||
{
|
{
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case JC_SIO_CMD_STATUS:
|
case JC_SIO_CMD_STATUS:
|
||||||
|
// Discard incomplete packets.
|
||||||
|
if (size < 12)
|
||||||
|
break;
|
||||||
|
|
||||||
jc_sio_hid_in_rpt_t *hid_pkt = (jc_sio_hid_in_rpt_t *)payload;
|
jc_sio_hid_in_rpt_t *hid_pkt = (jc_sio_hid_in_rpt_t *)payload;
|
||||||
jc_gamepad.buttons = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
|
jc_gamepad.buttons = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
|
||||||
jc_gamepad.home = !gpio_read(GPIO_PORT_V, GPIO_PIN_3);
|
jc_gamepad.home = !gpio_read(GPIO_PORT_V, GPIO_PIN_3);
|
||||||
@@ -738,7 +750,7 @@ static void _jc_sio_parse_payload(joycon_ctxt_t *jc, u8 cmd, const u8* payload,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _jc_sio_uart_pkt_parse(joycon_ctxt_t *jc, const jc_sio_in_rpt_t *pkt, u32 size)
|
static void _jc_sio_uart_pkt_parse(joycon_ctxt_t *jc, const jc_sio_in_rpt_t *pkt, int size)
|
||||||
{
|
{
|
||||||
if (pkt->crc_hdr != _jc_crc((u8 *)pkt, sizeof(jc_sio_in_rpt_t) - 1, 0))
|
if (pkt->crc_hdr != _jc_crc((u8 *)pkt, sizeof(jc_sio_in_rpt_t) - 1, 0))
|
||||||
return;
|
return;
|
||||||
@@ -755,7 +767,7 @@ static void _jc_sio_uart_pkt_parse(joycon_ctxt_t *jc, const jc_sio_in_rpt_t *pkt
|
|||||||
break;
|
break;
|
||||||
case JC_SIO_CMD_IAP_VER:
|
case JC_SIO_CMD_IAP_VER:
|
||||||
case JC_SIO_CMD_STATUS:
|
case JC_SIO_CMD_STATUS:
|
||||||
_jc_sio_parse_payload(jc, cmd, pkt->payload, pkt->payload_size);
|
_jc_sio_parse_payload(jc, cmd, pkt->payload, size - sizeof(jc_sio_in_rpt_t));
|
||||||
break;
|
break;
|
||||||
case JC_SIO_CMD_UNK02:
|
case JC_SIO_CMD_UNK02:
|
||||||
case JC_SIO_CMD_UNK20:
|
case JC_SIO_CMD_UNK20:
|
||||||
@@ -782,7 +794,7 @@ static void _jc_rcv_pkt(joycon_ctxt_t *jc)
|
|||||||
jc_wired_hdr_t *jc_pkt = (jc_wired_hdr_t *)jc->buf;
|
jc_wired_hdr_t *jc_pkt = (jc_wired_hdr_t *)jc->buf;
|
||||||
if (!jc->sio_mode && !memcmp(jc_pkt->uart_hdr.magic, "\x19\x81\x03", 3))
|
if (!jc->sio_mode && !memcmp(jc_pkt->uart_hdr.magic, "\x19\x81\x03", 3))
|
||||||
{
|
{
|
||||||
_jc_uart_pkt_parse(jc, jc_pkt, jc_pkt->uart_hdr.total_size_lsb + sizeof(jc_uart_hdr_t));
|
_jc_uart_pkt_parse(jc, jc_pkt, len);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -791,7 +803,7 @@ static void _jc_rcv_pkt(joycon_ctxt_t *jc)
|
|||||||
jc_sio_in_rpt_t *sio_pkt = (jc_sio_in_rpt_t *)(jc->buf);
|
jc_sio_in_rpt_t *sio_pkt = (jc_sio_in_rpt_t *)(jc->buf);
|
||||||
if (jc->sio_mode && sio_pkt->cmd == JC_SIO_INPUT_RPT && (sio_pkt->ack & JC_SIO_CMD_ACK) == JC_SIO_CMD_ACK)
|
if (jc->sio_mode && sio_pkt->cmd == JC_SIO_INPUT_RPT && (sio_pkt->ack & JC_SIO_CMD_ACK) == JC_SIO_CMD_ACK)
|
||||||
{
|
{
|
||||||
_jc_sio_uart_pkt_parse(jc, sio_pkt, sio_pkt->payload_size + sizeof(jc_sio_in_rpt_t));
|
_jc_sio_uart_pkt_parse(jc, sio_pkt, len);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -802,7 +814,7 @@ static bool _jc_send_init_rumble(joycon_ctxt_t *jc)
|
|||||||
// Send init rumble or request nx pad status report.
|
// Send init rumble or request nx pad status report.
|
||||||
if ((jc_r.connected && !jc_r.rumble_sent) || (jc_l.connected && !jc_l.rumble_sent))
|
if ((jc_r.connected && !jc_r.rumble_sent) || (jc_l.connected && !jc_l.rumble_sent))
|
||||||
{
|
{
|
||||||
_jc_send_hid_cmd(jc->uart, JC_HID_SUBCMD_SND_RUMBLE, NULL, 0);
|
_jc_send_hid_cmd(jc, JC_HID_SUBCMD_SND_RUMBLE, NULL, 0);
|
||||||
|
|
||||||
if (jc_l.connected)
|
if (jc_l.connected)
|
||||||
jc_l.rumble_sent = true;
|
jc_l.rumble_sent = true;
|
||||||
@@ -840,10 +852,10 @@ static void _jc_req_nx_pad_status(joycon_ctxt_t *jc)
|
|||||||
else
|
else
|
||||||
_joycon_send_raw(jc->uart, hori_pad_status, sizeof(hori_pad_status));
|
_joycon_send_raw(jc->uart, hori_pad_status, sizeof(hori_pad_status));
|
||||||
|
|
||||||
jc->last_status_req_time = get_tmr_ms() + 15;
|
jc->last_status_req_time = get_tmr_ms() + (!jc->sio_mode ? 15 : 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _jc_validate_pairing_info(u8 *buf, bool *is_hos)
|
static bool _jc_validate_pairing_info(const u8 *buf, bool *is_hos)
|
||||||
{
|
{
|
||||||
u8 crc = 0;
|
u8 crc = 0;
|
||||||
for (u32 i = 0; i < 0x22; i++)
|
for (u32 i = 0; i < 0x22; i++)
|
||||||
@@ -912,13 +924,13 @@ retry:
|
|||||||
{
|
{
|
||||||
if (!jc_l_found)
|
if (!jc_l_found)
|
||||||
{
|
{
|
||||||
_jc_send_hid_cmd(jc_l.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_l, 5);
|
_jc_send_hid_cmd(&jc_l, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_l, 5);
|
||||||
jc_l.last_status_req_time = get_tmr_ms() + 15;
|
jc_l.last_status_req_time = get_tmr_ms() + 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!jc_r_found)
|
if (!jc_r_found)
|
||||||
{
|
{
|
||||||
_jc_send_hid_cmd(jc_r.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_r, 5);
|
_jc_send_hid_cmd(&jc_r, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_r, 5);
|
||||||
jc_r.last_status_req_time = get_tmr_ms() + 15;
|
jc_r.last_status_req_time = get_tmr_ms() + 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1109,7 +1121,7 @@ static void _jc_init_conn(joycon_ctxt_t *jc)
|
|||||||
|
|
||||||
// Initialize the controller.
|
// Initialize the controller.
|
||||||
u32 retries = 10;
|
u32 retries = 10;
|
||||||
while (!jc->connected)
|
while (!jc->connected && retries)
|
||||||
{
|
{
|
||||||
_joycon_send_raw(jc->uart, sio_init, sizeof(sio_init));
|
_joycon_send_raw(jc->uart, sio_init, sizeof(sio_init));
|
||||||
msleep(5);
|
msleep(5);
|
||||||
@@ -1194,17 +1206,11 @@ void jc_init_hw()
|
|||||||
pinmux_config_uart(UART_B);
|
pinmux_config_uart(UART_B);
|
||||||
pinmux_config_uart(UART_C);
|
pinmux_config_uart(UART_C);
|
||||||
|
|
||||||
// Ease the stress to APB.
|
|
||||||
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
|
||||||
|
|
||||||
// Enable UART B and C clocks.
|
// Enable UART B and C clocks.
|
||||||
if (!jc_gamepad.sio_mode)
|
if (!jc_gamepad.sio_mode)
|
||||||
clock_enable_uart(UART_B);
|
clock_enable_uart(UART_B);
|
||||||
clock_enable_uart(UART_C);
|
clock_enable_uart(UART_C);
|
||||||
|
|
||||||
// Restore OC.
|
|
||||||
bpmp_clk_rate_set(prev_fid);
|
|
||||||
|
|
||||||
jc_init_done = true;
|
jc_init_done = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1224,12 +1230,12 @@ void jc_deinit()
|
|||||||
u8 data = HCI_STATE_SLEEP;
|
u8 data = HCI_STATE_SLEEP;
|
||||||
if (jc_r.connected && !(jc_r.type & JC_ID_HORI))
|
if (jc_r.connected && !(jc_r.type & JC_ID_HORI))
|
||||||
{
|
{
|
||||||
_jc_send_hid_cmd(UART_B, JC_HID_SUBCMD_HCI_STATE, &data, 1);
|
_jc_send_hid_cmd(&jc_r, JC_HID_SUBCMD_HCI_STATE, &data, 1);
|
||||||
_jc_rcv_pkt(&jc_r);
|
_jc_rcv_pkt(&jc_r);
|
||||||
}
|
}
|
||||||
if (jc_l.connected && !(jc_l.type & JC_ID_HORI))
|
if (jc_l.connected && !(jc_l.type & JC_ID_HORI))
|
||||||
{
|
{
|
||||||
_jc_send_hid_cmd(UART_C, JC_HID_SUBCMD_HCI_STATE, &data, 1);
|
_jc_send_hid_cmd(&jc_l, JC_HID_SUBCMD_HCI_STATE, &data, 1);
|
||||||
_jc_rcv_pkt(&jc_l);
|
_jc_rcv_pkt(&jc_l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,34 +43,34 @@ typedef struct _jc_gamepad_rpt_t
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
// Joy-Con (R).
|
// Joy-Con (R).
|
||||||
u32 y:1;
|
/*00*/ u32 y:1;
|
||||||
u32 x:1;
|
/*01*/ u32 x:1;
|
||||||
u32 b:1;
|
/*02*/ u32 b:1;
|
||||||
u32 a:1;
|
/*03*/ u32 a:1;
|
||||||
u32 sr_r:1;
|
/*04*/ u32 sr_r:1;
|
||||||
u32 sl_r:1;
|
/*05*/ u32 sl_r:1;
|
||||||
u32 r:1;
|
/*06*/ u32 r:1;
|
||||||
u32 zr:1;
|
/*07*/ u32 zr:1;
|
||||||
|
|
||||||
// Shared
|
// Shared
|
||||||
u32 minus:1;
|
/*08*/ u32 minus:1;
|
||||||
u32 plus:1;
|
/*09*/ u32 plus:1;
|
||||||
u32 r3:1;
|
/*10*/ u32 r3:1;
|
||||||
u32 l3:1;
|
/*11*/ u32 l3:1;
|
||||||
u32 home:1;
|
/*12*/ u32 home:1;
|
||||||
u32 cap:1;
|
/*13*/ u32 cap:1;
|
||||||
u32 pad:1;
|
/*14*/ u32 pad:1;
|
||||||
u32 wired:1;
|
/*15*/ u32 wired:1;
|
||||||
|
|
||||||
// Joy-Con (L).
|
// Joy-Con (L).
|
||||||
u32 down:1;
|
/*16*/ u32 down:1;
|
||||||
u32 up:1;
|
/*17*/ u32 up:1;
|
||||||
u32 right:1;
|
/*18*/ u32 right:1;
|
||||||
u32 left:1;
|
/*19*/ u32 left:1;
|
||||||
u32 sr_l:1;
|
/*20*/ u32 sr_l:1;
|
||||||
u32 sl_l:1;
|
/*21*/ u32 sl_l:1;
|
||||||
u32 l:1;
|
/*22*/ u32 l:1;
|
||||||
u32 zl:1;
|
/*23*/ u32 zl:1;
|
||||||
};
|
};
|
||||||
u32 buttons;
|
u32 buttons;
|
||||||
};
|
};
|
||||||
@@ -90,6 +90,16 @@ typedef struct _jc_gamepad_rpt_t
|
|||||||
jc_bt_conn_t bt_conn_r;
|
jc_bt_conn_t bt_conn_r;
|
||||||
} jc_gamepad_rpt_t;
|
} jc_gamepad_rpt_t;
|
||||||
|
|
||||||
|
typedef struct _jc_calib_t
|
||||||
|
{
|
||||||
|
u16 x_max:12;
|
||||||
|
u16 y_max:12;
|
||||||
|
u16 x_center:12;
|
||||||
|
u16 y_center:12;
|
||||||
|
u16 x_min:12;
|
||||||
|
u16 y_min:12;
|
||||||
|
} __attribute__((packed)) jc_calib_t;
|
||||||
|
|
||||||
void jc_init_hw();
|
void jc_init_hw();
|
||||||
void jc_deinit();
|
void jc_deinit();
|
||||||
jc_gamepad_rpt_t *joycon_poll();
|
jc_gamepad_rpt_t *joycon_poll();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller
|
* Touch driver for Nintendo Switch's STM FingerTip S (FTM4CD60DA1BE/FTM4CD50TA1BE) touch controller
|
||||||
*
|
*
|
||||||
* Copyright (c) 2018 langerhans
|
* Copyright (c) 2018 langerhans
|
||||||
* Copyright (c) 2018-2023 CTCaer
|
* Copyright (c) 2018-2023 CTCaer
|
||||||
@@ -39,7 +39,7 @@ static touch_panel_info_t _panels[] =
|
|||||||
{ 1, 0, 1, 1, "GiS GGM6 B2X" },// 1.
|
{ 1, 0, 1, 1, "GiS GGM6 B2X" },// 1.
|
||||||
{ 2, 0, 0, 0, "NISSHA NBF-K9A" },// 3.
|
{ 2, 0, 0, 0, "NISSHA NBF-K9A" },// 3.
|
||||||
{ 3, 1, 0, 0, "GiS 5.5\"" },// 4.
|
{ 3, 1, 0, 0, "GiS 5.5\"" },// 4.
|
||||||
{ 4, 0, 0, 1, "Samsung BH2109" },// 5?
|
{ 4, 0, 0, 1, "Samsung TSP" },// 5?
|
||||||
{ -1, 1, 0, 1, "GiS VA 6.2\"" } // 2.
|
{ -1, 1, 0, 1, "GiS VA 6.2\"" } // 2.
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -401,23 +401,29 @@ static int touch_init()
|
|||||||
|
|
||||||
int touch_power_on()
|
int touch_power_on()
|
||||||
{
|
{
|
||||||
// Enable LDO6 for touchscreen AVDD supply.
|
|
||||||
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
|
|
||||||
max7762x_regulator_enable(REGULATOR_LDO6, true);
|
|
||||||
|
|
||||||
// Configure touchscreen VDD GPIO.
|
|
||||||
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
|
|
||||||
gpio_direction_output(GPIO_PORT_J, GPIO_PIN_7, GPIO_HIGH);
|
|
||||||
|
|
||||||
// Configure Touscreen and GCAsic shared GPIO.
|
// Configure Touscreen and GCAsic shared GPIO.
|
||||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SDA) = PINMUX_LPDR | PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 2;
|
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SDA) = PINMUX_LPDR | PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 2;
|
||||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SCL) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_TRISTATE | PINMUX_PULL_DOWN | 2;
|
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SCL) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_TRISTATE | PINMUX_PULL_DOWN | 2; // Unused.
|
||||||
gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO); // GC detect.
|
gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO); // GC detect.
|
||||||
|
|
||||||
|
// Configure touchscreen Touch Reset pin.
|
||||||
|
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
|
||||||
|
gpio_direction_output(GPIO_PORT_J, GPIO_PIN_7, GPIO_LOW);
|
||||||
|
usleep(20);
|
||||||
|
|
||||||
|
// Enable LDO6 for touchscreen AVDD and DVDD supply.
|
||||||
|
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
|
||||||
|
max7762x_regulator_enable(REGULATOR_LDO6, true);
|
||||||
|
|
||||||
// Initialize I2C3.
|
// Initialize I2C3.
|
||||||
pinmux_config_i2c(I2C_3);
|
pinmux_config_i2c(I2C_3);
|
||||||
clock_enable_i2c(I2C_3);
|
clock_enable_i2c(I2C_3);
|
||||||
i2c_init(I2C_3);
|
i2c_init(I2C_3);
|
||||||
|
usleep(1000);
|
||||||
|
|
||||||
|
// Set Touch Reset pin.
|
||||||
|
gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_HIGH);
|
||||||
|
usleep(10000);
|
||||||
|
|
||||||
// Wait for the touchscreen module to get ready.
|
// Wait for the touchscreen module to get ready.
|
||||||
touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL);
|
touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL);
|
||||||
|
|||||||
@@ -20,33 +20,33 @@
|
|||||||
|
|
||||||
#include "blz.h"
|
#include "blz.h"
|
||||||
|
|
||||||
const blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter)
|
const blz_footer *blz_get_footer(const u8 *comp_data, u32 comp_data_size, blz_footer *out_footer)
|
||||||
{
|
{
|
||||||
if (compDataLen < sizeof(blz_footer))
|
if (comp_data_size < sizeof(blz_footer))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const blz_footer *srcFooter = (const blz_footer*)&compData[compDataLen - sizeof(blz_footer)];
|
const blz_footer *src_footer = (const blz_footer *)&comp_data[comp_data_size - sizeof(blz_footer)];
|
||||||
if (outFooter != NULL)
|
if (out_footer)
|
||||||
memcpy(outFooter, srcFooter, sizeof(blz_footer)); // Must be a memcpy because no umaligned accesses on ARMv4.
|
memcpy(out_footer, src_footer, sizeof(blz_footer)); // Must be a memcpy because no unaligned accesses on ARMv4.
|
||||||
|
|
||||||
return srcFooter;
|
return src_footer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// From https://github.com/SciresM/hactool/blob/master/kip.c which is exactly how kernel does it, thanks SciresM!
|
// From https://github.com/SciresM/hactool/blob/master/kip.c which is exactly how kernel does it, thanks SciresM!
|
||||||
int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer)
|
int blz_uncompress_inplace(u8 *data, u32 comp_size, const blz_footer *footer)
|
||||||
{
|
{
|
||||||
u32 addl_size = footer->addl_size;
|
u32 addl_size = footer->addl_size;
|
||||||
u32 header_size = footer->header_size;
|
u32 header_size = footer->header_size;
|
||||||
u32 cmp_and_hdr_size = footer->cmp_and_hdr_size;
|
u32 cmp_and_hdr_size = footer->cmp_and_hdr_size;
|
||||||
|
|
||||||
unsigned char* cmp_start = &dataBuf[compSize] - cmp_and_hdr_size;
|
u8 *cmp_start = &data[comp_size] - cmp_and_hdr_size;
|
||||||
u32 cmp_ofs = cmp_and_hdr_size - header_size;
|
u32 cmp_ofs = cmp_and_hdr_size - header_size;
|
||||||
u32 out_ofs = cmp_and_hdr_size + addl_size;
|
u32 out_ofs = cmp_and_hdr_size + addl_size;
|
||||||
|
|
||||||
while (out_ofs)
|
while (out_ofs)
|
||||||
{
|
{
|
||||||
unsigned char control = cmp_start[--cmp_ofs];
|
u8 control = cmp_start[--cmp_ofs];
|
||||||
for (unsigned int i=0; i<8; i++)
|
for (u32 i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
if (control & 0x80)
|
if (control & 0x80)
|
||||||
{
|
{
|
||||||
@@ -54,45 +54,48 @@ int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const
|
|||||||
return 0; // Out of bounds.
|
return 0; // Out of bounds.
|
||||||
|
|
||||||
cmp_ofs -= 2;
|
cmp_ofs -= 2;
|
||||||
u16 seg_val = ((unsigned int)(cmp_start[cmp_ofs + 1]) << 8) | cmp_start[cmp_ofs];
|
u16 seg_val = ((u32)(cmp_start[cmp_ofs + 1]) << 8) | cmp_start[cmp_ofs];
|
||||||
u32 seg_size = ((seg_val >> 12) & 0xF) + 3;
|
u32 seg_size = ((seg_val >> 12) & 0xF) + 3;
|
||||||
u32 seg_ofs = (seg_val & 0x0FFF) + 3;
|
u32 seg_ofs = (seg_val & 0x0FFF) + 3;
|
||||||
if (out_ofs < seg_size) // Kernel restricts segment copy to stay in bounds.
|
|
||||||
|
// Kernel restricts segment copy to stay in bounds.
|
||||||
|
if (out_ofs < seg_size)
|
||||||
seg_size = out_ofs;
|
seg_size = out_ofs;
|
||||||
|
|
||||||
out_ofs -= seg_size;
|
out_ofs -= seg_size;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < seg_size; j++)
|
for (u32 j = 0; j < seg_size; j++)
|
||||||
cmp_start[out_ofs + j] = cmp_start[out_ofs + j + seg_ofs];
|
cmp_start[out_ofs + j] = cmp_start[out_ofs + j + seg_ofs];
|
||||||
}
|
}
|
||||||
else
|
else // Copy directly.
|
||||||
{
|
{
|
||||||
// Copy directly.
|
|
||||||
if (cmp_ofs < 1)
|
if (cmp_ofs < 1)
|
||||||
return 0; //out of bounds
|
return 0; // Out of bounds.
|
||||||
|
|
||||||
cmp_start[--out_ofs] = cmp_start[--cmp_ofs];
|
cmp_start[--out_ofs] = cmp_start[--cmp_ofs];
|
||||||
}
|
}
|
||||||
|
|
||||||
control <<= 1;
|
control <<= 1;
|
||||||
if (out_ofs == 0) // Blz works backwards, so if it reaches byte 0, it's done.
|
|
||||||
|
if (!out_ofs) // Blz works backwards, so if it reaches byte 0, it's done.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize)
|
int blz_uncompress_srcdest(const u8 *comp_data, u32 comp_data_size, u8 *dst_data, u32 dst_size)
|
||||||
{
|
{
|
||||||
blz_footer footer;
|
blz_footer footer;
|
||||||
const blz_footer *compFooterPtr = blz_get_footer(compData, compDataLen, &footer);
|
const blz_footer *comp_footer = blz_get_footer(comp_data, comp_data_size, &footer);
|
||||||
if (compFooterPtr == NULL)
|
if (!comp_footer)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Decompression must be done in-place, so need to copy the relevant compressed data first.
|
// Decompression happens in-place, so need to copy the relevant compressed data first.
|
||||||
unsigned int numCompBytes = (const unsigned char*)(compFooterPtr)-compData;
|
u32 comp_bytes = (const u8 *)comp_footer - comp_data;
|
||||||
memcpy(dstData, compData, numCompBytes);
|
memcpy(dst_data, comp_data, comp_bytes);
|
||||||
memset(&dstData[numCompBytes], 0, dstSize - numCompBytes);
|
memset(&dst_data[comp_bytes], 0, dst_size - comp_bytes);
|
||||||
|
|
||||||
return blz_uncompress_inplace(dstData, compDataLen, &footer);
|
return blz_uncompress_inplace(dst_data, comp_data_size, &footer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ typedef struct _blz_footer
|
|||||||
u32 addl_size;
|
u32 addl_size;
|
||||||
} blz_footer;
|
} blz_footer;
|
||||||
|
|
||||||
// Returns pointer to footer in compData if present, additionally copies it to outFooter if not NULL.
|
// Returns pointer to footer in comp_data if present, additionally copies it to out_footer if not NULL.
|
||||||
const blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter);
|
const blz_footer *blz_get_footer(const u8 *comp_data, u32 comp_data_size, blz_footer *out_footer);
|
||||||
// Returns 0 on failure.
|
// Returns 0 on failure.
|
||||||
int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer);
|
int blz_uncompress_inplace(u8 *data, u32 comp_size, const blz_footer *footer);
|
||||||
// Returns 0 on failure.
|
// Returns 0 on failure.
|
||||||
int blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize);
|
int blz_uncompress_srcdest(const u8 *comp_data, u32 comp_data_size, u8 *dst_data, u32 dst_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -92,22 +92,12 @@
|
|||||||
# define LZ4_FORCE_O2_INLINE_GCC_PPC64LE static
|
# define LZ4_FORCE_O2_INLINE_GCC_PPC64LE static
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
|
|
||||||
# define expect(expr,value) (__builtin_expect ((expr),(value)) )
|
|
||||||
#else
|
|
||||||
# define expect(expr,value) (expr)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define likely(expr) expect((expr) != 0, 1)
|
|
||||||
#define unlikely(expr) expect((expr) != 0, 0)
|
|
||||||
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
* Memory routines
|
* Memory routines
|
||||||
**************************************/
|
**************************************/
|
||||||
#include <mem/heap.h> /* malloc, calloc, free */
|
#include <mem/heap.h> /* malloc, calloc, free */
|
||||||
#define ALLOC(s) malloc(s)
|
#define ALLOC(s) malloc(s)
|
||||||
#define ALLOC_AND_ZERO(s) calloc(1,s)
|
#define ALLOC_AND_ZERO(s) zalloc(s)
|
||||||
#define FREEMEM free
|
#define FREEMEM free
|
||||||
#include <string.h> /* memset, memcpy */
|
#include <string.h> /* memset, memcpy */
|
||||||
#define MEM_INIT memset
|
#define MEM_INIT memset
|
||||||
|
|||||||
@@ -61,27 +61,7 @@ DRESULT disk_set_info (BYTE pdrv, BYTE cmd, void *buff);
|
|||||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||||
#define SET_SECTOR_OFFSET 5 /* Set media logical offset */
|
#define SET_SECTOR_OFFSET 5 /* Set media logical offset */
|
||||||
|
#define SET_WRITE_PROTECT 6 /* Lock/Unlock media removal */
|
||||||
/* Generic command (Not used by FatFs) */
|
|
||||||
#define CTRL_POWER 5 /* Get/Set power status */
|
|
||||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
|
||||||
#define CTRL_EJECT 7 /* Eject media */
|
|
||||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
|
||||||
|
|
||||||
/* MMC/SDC specific ioctl command */
|
|
||||||
#define MMC_GET_TYPE 10 /* Get card type */
|
|
||||||
#define MMC_GET_CSD 11 /* Get CSD */
|
|
||||||
#define MMC_GET_CID 12 /* Get CID */
|
|
||||||
#define MMC_GET_OCR 13 /* Get OCR */
|
|
||||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
|
||||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
|
||||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
|
||||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
|
||||||
|
|
||||||
/* ATA/CF specific ioctl command */
|
|
||||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
|
||||||
#define ATA_GET_MODEL 21 /* Get model name */
|
|
||||||
#define ATA_GET_SN 22 /* Get serial number */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2021 CTCaer
|
* Copyright (c) 2018-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
#include "ff.h" /* Declarations of FatFs API */
|
#include "ff.h" /* Declarations of FatFs API */
|
||||||
#include "diskio.h" /* Declarations of device I/O functions */
|
#include "diskio.h" /* Declarations of device I/O functions */
|
||||||
#include <storage/mbr_gpt.h>
|
#include <storage/mbr_gpt.h>
|
||||||
|
#include <utils/util.h>
|
||||||
#include <gfx_utils.h>
|
#include <gfx_utils.h>
|
||||||
|
|
||||||
#define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
|
#define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
|
||||||
@@ -4698,13 +4699,20 @@ FRESULT f_lseek (
|
|||||||
|
|
||||||
DWORD *f_expand_cltbl (
|
DWORD *f_expand_cltbl (
|
||||||
FIL* fp, /* Pointer to the file object */
|
FIL* fp, /* Pointer to the file object */
|
||||||
UINT tblsz, /* Size of table */
|
UINT tblsz, /* Size of table (2 DWORDs + 2 DWORDs per fragment) */
|
||||||
FSIZE_t ofs /* File pointer from top of file */
|
FSIZE_t ofs /* File pointer from top of file */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Cluster table structure:
|
||||||
|
* Size (DWORD)
|
||||||
|
* Padding (DWORD)
|
||||||
|
* (Cluster Offset (DWORD) + Sequential clusters (DWORD)) * Fragments
|
||||||
|
*/
|
||||||
if (fp->flag & FA_WRITE) f_lseek(fp, ofs); /* Expand file if write is enabled */
|
if (fp->flag & FA_WRITE) f_lseek(fp, ofs); /* Expand file if write is enabled */
|
||||||
if (!fp->cltbl) { /* Allocate memory for cluster link table */
|
if (!fp->cltbl) { /* Allocate memory for cluster link table */
|
||||||
fp->cltbl = (DWORD *)ff_memalloc(tblsz);
|
fp->cltbl = (DWORD *)ff_memalloc(tblsz);
|
||||||
|
if (!fp->cltbl) return (void *)0;
|
||||||
fp->cltbl[0] = tblsz;
|
fp->cltbl[0] = tblsz;
|
||||||
}
|
}
|
||||||
if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */
|
if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */
|
||||||
@@ -6111,10 +6119,26 @@ FRESULT f_mkfs (
|
|||||||
for (i = 0, pau = 1; cst32[i] && cst32[i] <= n; i++, pau <<= 1) ; /* Get from table */
|
for (i = 0, pau = 1; cst32[i] && cst32[i] <= n; i++, pau <<= 1) ; /* Get from table */
|
||||||
}
|
}
|
||||||
n_clst = sz_vol / pau; /* Number of clusters */
|
n_clst = sz_vol / pau; /* Number of clusters */
|
||||||
sz_fat = (n_clst * 4 + 8 + ss - 1) / ss; /* FAT size [sector] */
|
while (1) {
|
||||||
sz_rsv = 32; /* Number of reserved sectors */
|
/* Do not account for reserved/root cluster on FAT size for better alignment. */
|
||||||
sz_dir = 0; /* No static directory */
|
sz_fat = (n_clst * 4 + ss - 1) / ss; /* FAT size [sector]. */
|
||||||
if (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED);
|
sz_rsv = 2048; /* Number of reserved sectors. Use 1MB for better performance (for flash memory media) */
|
||||||
|
sz_dir = 0; /* No static directory */
|
||||||
|
if (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED);
|
||||||
|
b_fat = b_vol + sz_rsv; /* FAT base */
|
||||||
|
b_data = b_fat + sz_fat * n_fats + sz_dir; /* Data base */
|
||||||
|
|
||||||
|
/* Align data base to erase block boundary (for flash memory media) */
|
||||||
|
n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */
|
||||||
|
b_fat += n; /* FAT32: Move FAT base */
|
||||||
|
/* Make sure FAT base is aligned to reserved size for performance (PRF2SAFE min cluster alignment) */
|
||||||
|
if ((b_fat & (sz_rsv - 1) || (n_fats == 2 && sz_fat & (sz_rsv - 1)))) {
|
||||||
|
n_clst++; /* FAT size must always be bigger than real free size */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sz_rsv += n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else { /* FAT volume */
|
} else { /* FAT volume */
|
||||||
if (pau == 0) { /* au auto-selection */
|
if (pau == 0) { /* au auto-selection */
|
||||||
n = sz_vol / 0x1000; /* Volume size in unit of 4KS */
|
n = sz_vol / 0x1000; /* Volume size in unit of 4KS */
|
||||||
@@ -6130,17 +6154,13 @@ FRESULT f_mkfs (
|
|||||||
sz_fat = (n + ss - 1) / ss; /* FAT size [sector] */
|
sz_fat = (n + ss - 1) / ss; /* FAT size [sector] */
|
||||||
sz_rsv = 1; /* Number of reserved sectors */
|
sz_rsv = 1; /* Number of reserved sectors */
|
||||||
sz_dir = (DWORD)n_rootdir * SZDIRE / ss; /* Rootdir size [sector] */
|
sz_dir = (DWORD)n_rootdir * SZDIRE / ss; /* Rootdir size [sector] */
|
||||||
}
|
b_fat = b_vol + sz_rsv; /* FAT base */
|
||||||
b_fat = b_vol + sz_rsv; /* FAT base */
|
b_data = b_fat + sz_fat * n_fats + sz_dir; /* Data base */
|
||||||
b_data = b_fat + sz_fat * n_fats + sz_dir; /* Data base */
|
|
||||||
|
|
||||||
/* Align data base to erase block boundary (for flash memory media) */
|
/* Align data base to erase block boundary (for flash memory media) */
|
||||||
n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */
|
n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */
|
||||||
if (fmt == FS_FAT32) { /* FAT32: Move FAT base */
|
|
||||||
sz_rsv += n; b_fat += n;
|
|
||||||
} else { /* FAT: Expand FAT size */
|
|
||||||
if (n % n_fats) { /* Adjust fractional error if needed */
|
if (n % n_fats) { /* Adjust fractional error if needed */
|
||||||
n--; sz_rsv++; b_fat++;
|
n--; sz_rsv++; b_fat++; /* FAT: Expand FAT size */
|
||||||
}
|
}
|
||||||
sz_fat += n / n_fats;
|
sz_fat += n / n_fats;
|
||||||
}
|
}
|
||||||
@@ -6183,7 +6203,7 @@ FRESULT f_mkfs (
|
|||||||
/* Create FAT VBR */
|
/* Create FAT VBR */
|
||||||
mem_set(buf, 0, ss);
|
mem_set(buf, 0, ss);
|
||||||
/* Boot jump code (x86), OEM name */
|
/* Boot jump code (x86), OEM name */
|
||||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.0.0", 11);
|
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.8.0", 11);
|
||||||
else mem_cpy(buf + BS_JmpBoot, "\xEB\xE9\x90\x00\x00\x00\x00\x00\x00\x00\x00", 11);
|
else mem_cpy(buf + BS_JmpBoot, "\xEB\xE9\x90\x00\x00\x00\x00\x00\x00\x00\x00", 11);
|
||||||
st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */
|
st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */
|
||||||
buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */
|
buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */
|
||||||
@@ -6240,21 +6260,10 @@ FRESULT f_mkfs (
|
|||||||
disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */
|
disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create PRF2SAFE info */
|
/* Clear PRF2SAFE info so PrFILE2 can recreate it and upgrade it if old */
|
||||||
if (fmt == FS_FAT32 && opt & FM_PRF2) {
|
if (fmt == FS_FAT32 && opt & FM_PRF2) {
|
||||||
mem_set(buf, 0, ss);
|
mem_set(buf, 0, ss);
|
||||||
st_dword(buf + 0, 0x32465250); /* Magic PRF2 */
|
disk_write(pdrv, buf, b_vol + 3, 1); /* Write PRF2SAFE info (VBR + 3) */
|
||||||
st_dword(buf + 4, 0x45464153); /* Magic SAFE */
|
|
||||||
buf[16] = 0x64; /* Record type */
|
|
||||||
st_dword(buf + 32, 0x03); /* Unknown. SYSTEM: 0x3F00. USER: 0x03. Volatile. */
|
|
||||||
if (sz_vol < 0x1000000) {
|
|
||||||
st_dword(buf + 36, 21 + 1); /* 22 Entries. */
|
|
||||||
st_dword(buf + 508, 0x90BB2F39); /* Sector CRC32 */
|
|
||||||
} else {
|
|
||||||
st_dword(buf + 36, 21 + 2); /* 23 Entries. */
|
|
||||||
st_dword(buf + 508, 0x5EA8AFC8); /* Sector CRC32 */
|
|
||||||
}
|
|
||||||
disk_write(pdrv, buf, b_vol + 3, 1); /* Write PRF2SAFE info (VBR + 3) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize FAT area */
|
/* Initialize FAT area */
|
||||||
|
|||||||
57
bdk/libs/fatfs/ffsystem.c
Normal file
57
bdk/libs/fatfs/ffsystem.c
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Sample Code of OS Dependent Functions for FatFs */
|
||||||
|
/* (C) ChaN, 2018 */
|
||||||
|
/* (C) CTCaer, 2018-2024 */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <bdk.h>
|
||||||
|
|
||||||
|
#include <libs/fatfs/ff.h>
|
||||||
|
|
||||||
|
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Allocate a memory block */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
|
||||||
|
UINT msize /* Number of bytes to allocate */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Ensure size is aligned to SDMMC block size.
|
||||||
|
return malloc(ALIGN(msize, SDMMC_DAT_BLOCKSIZE)); /* Allocate a new memory block with POSIX API */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Free a memory block */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void ff_memfree (
|
||||||
|
void* mblock /* Pointer to the memory block to free (nothing to do if null) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
free(mblock); /* Free the memory block with POSIX API */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FF_FS_NORTC == 0
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Get real time clock */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
DWORD get_fattime (
|
||||||
|
void
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtc_time_t time;
|
||||||
|
|
||||||
|
max77620_rtc_get_time_adjusted(&time);
|
||||||
|
|
||||||
|
return (((DWORD)(time.year - 1980) << 25) | ((DWORD)time.month << 21) | ((DWORD)time.day << 16) |
|
||||||
|
((DWORD)time.hour << 11) | ((DWORD)time.min << 5) | (time.sec >> 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
#ifndef LV_CONF_H
|
#ifndef LV_CONF_H
|
||||||
#define LV_CONF_H
|
#define LV_CONF_H
|
||||||
|
|
||||||
#include <utils/types.h>
|
#include <soc/timer.h>
|
||||||
#include <memory_map.h>
|
#include <memory_map.h>
|
||||||
/*===================
|
/*===================
|
||||||
Dynamic memory
|
Dynamic memory
|
||||||
@@ -116,8 +116,8 @@
|
|||||||
#define LV_INDEV_POINT_MARKER 0 /*Mark the pressed points (required: USE_LV_REAL_DRAW = 1)*/
|
#define LV_INDEV_POINT_MARKER 0 /*Mark the pressed points (required: USE_LV_REAL_DRAW = 1)*/
|
||||||
#define LV_INDEV_DRAG_LIMIT 10 /*Drag threshold in pixels */
|
#define LV_INDEV_DRAG_LIMIT 10 /*Drag threshold in pixels */
|
||||||
#define LV_INDEV_DRAG_THROW 20 /*Drag throw slow-down in [%]. Greater value means faster slow-down */
|
#define LV_INDEV_DRAG_THROW 20 /*Drag throw slow-down in [%]. Greater value means faster slow-down */
|
||||||
#define LV_INDEV_LONG_PRESS_TIME 400 /*Long press time in milliseconds*/
|
#define LV_INDEV_LONG_PRESS_TIME 5000 /*Long press time in milliseconds*/
|
||||||
#define LV_INDEV_LONG_PRESS_REP_TIME 1000 //Fix keyb /*Repeated trigger period in long press [ms] */
|
#define LV_INDEV_LONG_PRESS_REP_TIME 1000 //Fix lv_kb /*Repeated trigger period in long press [ms] */
|
||||||
|
|
||||||
/*Color settings*/
|
/*Color settings*/
|
||||||
#define LV_COLOR_DEPTH 32 /*Color depth: 1/8/16/32*/
|
#define LV_COLOR_DEPTH 32 /*Color depth: 1/8/16/32*/
|
||||||
@@ -147,10 +147,10 @@
|
|||||||
#define LV_COMPILER_VLA_SUPPORTED 1 /* 1: Variable length array is supported*/
|
#define LV_COMPILER_VLA_SUPPORTED 1 /* 1: Variable length array is supported*/
|
||||||
|
|
||||||
/*HAL settings*/
|
/*HAL settings*/
|
||||||
#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */
|
#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */
|
||||||
#if LV_TICK_CUSTOM == 1
|
#if LV_TICK_CUSTOM == 1
|
||||||
#define LV_TICK_CUSTOM_INCLUDE <utils/util.h> /*Header for the sys time function*/
|
#define LV_TICK_CUSTOM_INCLUDE <soc/timer.h> /*Header for the sys time function*/
|
||||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (get_tmr_ms()) /*Expression evaluating to current systime in ms*/
|
#define LV_TICK_CUSTOM_SYS_TIME_EXPR ((u32)get_tmr_ms()) /*Expression evaluating to current systime in ms*/
|
||||||
#endif /*LV_TICK_CUSTOM*/
|
#endif /*LV_TICK_CUSTOM*/
|
||||||
|
|
||||||
|
|
||||||
@@ -296,6 +296,9 @@
|
|||||||
|
|
||||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||||
#define USE_LV_MBOX 1
|
#define USE_LV_MBOX 1
|
||||||
|
#if USE_LV_MBOX != 0
|
||||||
|
# define LV_MBOX_CLOSE_ANIM_TIME 200 /*ms*/
|
||||||
|
#endif
|
||||||
|
|
||||||
/*Text area (dependencies: lv_label, lv_page)*/
|
/*Text area (dependencies: lv_label, lv_page)*/
|
||||||
#define USE_LV_TA 1
|
#define USE_LV_TA 1
|
||||||
|
|||||||
@@ -546,8 +546,8 @@ static void obj_to_foreground(lv_obj_t * obj)
|
|||||||
/*Move the last_top object to the foreground*/
|
/*Move the last_top object to the foreground*/
|
||||||
lv_obj_t * par = lv_obj_get_parent(last_top);
|
lv_obj_t * par = lv_obj_get_parent(last_top);
|
||||||
/*After list change it will be the new head*/
|
/*After list change it will be the new head*/
|
||||||
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
|
if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
|
||||||
lv_obj_invalidate(last_top);
|
lv_obj_invalidate(last_top); /*Only invalidate if not top*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -646,8 +646,8 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
|||||||
/*Move the last_top object to the foreground*/
|
/*Move the last_top object to the foreground*/
|
||||||
lv_obj_t * par = lv_obj_get_parent(last_top);
|
lv_obj_t * par = lv_obj_get_parent(last_top);
|
||||||
/*After list change it will be the new head*/
|
/*After list change it will be the new head*/
|
||||||
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
|
if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
|
||||||
lv_obj_invalidate(last_top);
|
lv_obj_invalidate(last_top); /*Only invalidate if not top*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Send a signal about the press*/
|
/*Send a signal about the press*/
|
||||||
|
|||||||
@@ -412,17 +412,17 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_COLOR_DEPTH == 32 // Concatenate into one 32-bit set.
|
#if LV_COLOR_DEPTH == 32 // Concatenate into one 32-bit set.
|
||||||
#define LV_COLOR_HEX(c) ((lv_color_t){.full = (c | 0xFF000000)})
|
#define LV_COLOR_HEX(c) ((lv_color_t){.full = ((c) | 0xFF000000)})
|
||||||
#else
|
#else
|
||||||
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)c >> 16) & 0xFF), \
|
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)(c) >> 16) & 0xFF), \
|
||||||
((uint32_t)((uint32_t)c >> 8) & 0xFF), \
|
((uint32_t)((uint32_t)(c) >> 8) & 0xFF), \
|
||||||
((uint32_t) c & 0xFF))
|
((uint32_t) (c) & 0xFF))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*Usage LV_COLOR_HEX3(0x16C) which means LV_COLOR_HEX(0x1166CC)*/
|
/*Usage LV_COLOR_HEX3(0x16C) which means LV_COLOR_HEX(0x1166CC)*/
|
||||||
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE((((c >> 4) & 0xF0) | ((c >> 8) & 0xF)), \
|
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE(((((c) >> 4) & 0xF0) | (((c) >> 8) & 0xF)), \
|
||||||
((uint32_t)(c & 0xF0) | ((c & 0xF0) >> 4)), \
|
((uint32_t)((c) & 0xF0) | (((c) & 0xF0) >> 4)), \
|
||||||
((uint32_t)(c & 0xF) | ((c & 0xF) << 4)))
|
((uint32_t)((c) & 0xF) | (((c) & 0xF) << 4)))
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -215,9 +215,12 @@ void lv_ll_clear(lv_ll_t * ll_p)
|
|||||||
* @param ll_ori_p pointer to the original (old) linked list
|
* @param ll_ori_p pointer to the original (old) linked list
|
||||||
* @param ll_new_p pointer to the new linked list
|
* @param ll_new_p pointer to the new linked list
|
||||||
* @param node pointer to a node
|
* @param node pointer to a node
|
||||||
|
* @return head changed
|
||||||
*/
|
*/
|
||||||
void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
bool lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
||||||
{
|
{
|
||||||
|
bool changed = ll_new_p->head != node;
|
||||||
|
|
||||||
lv_ll_rem(ll_ori_p, node);
|
lv_ll_rem(ll_ori_p, node);
|
||||||
|
|
||||||
/*Set node as head*/
|
/*Set node as head*/
|
||||||
@@ -232,6 +235,8 @@ void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
|||||||
if(ll_new_p->tail == NULL) { /*If there is no tail (first node) set the tail too*/
|
if(ll_new_p->tail == NULL) { /*If there is no tail (first node) set the tail too*/
|
||||||
ll_new_p->tail = node;
|
ll_new_p->tail = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -89,8 +89,9 @@ void lv_ll_clear(lv_ll_t * ll_p);
|
|||||||
* @param ll_ori_p pointer to the original (old) linked list
|
* @param ll_ori_p pointer to the original (old) linked list
|
||||||
* @param ll_new_p pointer to the new linked list
|
* @param ll_new_p pointer to the new linked list
|
||||||
* @param node pointer to a node
|
* @param node pointer to a node
|
||||||
|
* @return head changed
|
||||||
*/
|
*/
|
||||||
void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node);
|
bool lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return with head node of the linked list
|
* Return with head node of the linked list
|
||||||
|
|||||||
@@ -316,7 +316,8 @@ static bool lv_task_exec(lv_task_t * lv_task_p)
|
|||||||
lv_task_p->last_run = lv_tick_get();
|
lv_task_p->last_run = lv_tick_get();
|
||||||
task_deleted = false;
|
task_deleted = false;
|
||||||
task_created = false;
|
task_created = false;
|
||||||
lv_task_p->task(lv_task_p->param);
|
if (lv_task_p->task)
|
||||||
|
lv_task_p->task(lv_task_p->param);
|
||||||
|
|
||||||
/*Delete if it was a one shot lv_task*/
|
/*Delete if it was a one shot lv_task*/
|
||||||
if(task_deleted == false) { /*The task might be deleted by itself as well*/
|
if(task_deleted == false) { /*The task might be deleted by itself as well*/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2019 CTCaer
|
* Copyright (c) 2018-2022 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -32,13 +32,16 @@
|
|||||||
#define COLOR_HOS_TEAL_LIGHT (lv_color_hsv_to_rgb(_hue, 100, 72)) // 0x00B78F
|
#define COLOR_HOS_TEAL_LIGHT (lv_color_hsv_to_rgb(_hue, 100, 72)) // 0x00B78F
|
||||||
#define COLOR_HOS_TEAL (lv_color_hsv_to_rgb(_hue, 100, 64)) // 0x00A273
|
#define COLOR_HOS_TEAL (lv_color_hsv_to_rgb(_hue, 100, 64)) // 0x00A273
|
||||||
#define COLOR_HOS_ORANGE LV_COLOR_HEX(0xFF5500)
|
#define COLOR_HOS_ORANGE LV_COLOR_HEX(0xFF5500)
|
||||||
#define COLOR_HOS_BG_DARKER LV_COLOR_HEX(0x1B1B1B)
|
|
||||||
#define COLOR_HOS_BG_DARK LV_COLOR_HEX(0x222222)
|
|
||||||
#define COLOR_HOS_BG LV_COLOR_HEX(0x2D2D2D)
|
|
||||||
#define COLOR_HOS_BG_LIGHT LV_COLOR_HEX(0x3D3D3D)
|
|
||||||
#define COLOR_HOS_LIGHT_BORDER LV_COLOR_HEX(0x4D4D4D)
|
|
||||||
#define COLOR_HOS_TXT_WHITE LV_COLOR_HEX(0xFBFBFB)
|
#define COLOR_HOS_TXT_WHITE LV_COLOR_HEX(0xFBFBFB)
|
||||||
|
|
||||||
|
#define COLOR_BG_DARKER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color - 0x121212) : 0x0B0B0B) // 0x1B1B1B.
|
||||||
|
#define COLOR_BG_DARK LV_COLOR_HEX(theme_bg_color ? (theme_bg_color - 0x0B0B0B) : 0x121212) // 0x222222.
|
||||||
|
#define COLOR_BG LV_COLOR_HEX(theme_bg_color) // 0x2D2D2D.
|
||||||
|
#define COLOR_BG_LIGHT LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x101010) : 0x2D2D2D) // 0x3D3D3D.
|
||||||
|
#define COLOR_BG_LIGHTER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x191919) : 0x363636) // 0x464646.
|
||||||
|
#define COLOR_LIGHT_BORDER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x202020) : 0x3D3D3D) // 0x4D4D4D.
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
@@ -57,8 +60,9 @@ static lv_style_t def;
|
|||||||
static lv_style_t sb;
|
static lv_style_t sb;
|
||||||
|
|
||||||
/*Saved input parameters*/
|
/*Saved input parameters*/
|
||||||
static uint16_t _hue;
|
static uint16_t _hue;
|
||||||
static lv_font_t * _font;
|
static lv_font_t * _font;
|
||||||
|
uint32_t theme_bg_color;
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
@@ -80,18 +84,17 @@ static void basic_init(void)
|
|||||||
//def.image.opa = LV_OPA_COVER;
|
//def.image.opa = LV_OPA_COVER;
|
||||||
|
|
||||||
lv_style_copy(&bg, &def);
|
lv_style_copy(&bg, &def);
|
||||||
bg.body.main_color = COLOR_HOS_BG;
|
bg.body.main_color = COLOR_BG;
|
||||||
//bg.body.main_color = LV_COLOR_BLACK;
|
|
||||||
bg.body.grad_color = bg.body.main_color;
|
bg.body.grad_color = bg.body.main_color;
|
||||||
bg.body.radius = 0;
|
bg.body.radius = 0;
|
||||||
bg.body.empty = 1;
|
bg.body.empty = 1;
|
||||||
|
|
||||||
lv_style_copy(&panel, &def);
|
lv_style_copy(&panel, &def);
|
||||||
panel.body.radius = DEF_RADIUS;
|
panel.body.radius = DEF_RADIUS;
|
||||||
panel.body.main_color = COLOR_HOS_BG;
|
panel.body.main_color = COLOR_BG;
|
||||||
panel.body.grad_color = COLOR_HOS_BG;
|
panel.body.grad_color = COLOR_BG;
|
||||||
panel.body.border.width = 1;
|
panel.body.border.width = 1;
|
||||||
panel.body.border.color = COLOR_HOS_LIGHT_BORDER;
|
panel.body.border.color = COLOR_LIGHT_BORDER;
|
||||||
panel.body.border.opa = LV_OPA_COVER;
|
panel.body.border.opa = LV_OPA_COVER;
|
||||||
panel.body.shadow.color = COLOR_SHADOW_LIGHT;
|
panel.body.shadow.color = COLOR_SHADOW_LIGHT;
|
||||||
panel.body.shadow.type = LV_SHADOW_BOTTOM;
|
panel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||||
@@ -129,7 +132,7 @@ static void btn_init(void)
|
|||||||
static lv_style_t rel, pr, tgl_rel, tgl_pr, ina;
|
static lv_style_t rel, pr, tgl_rel, tgl_pr, ina;
|
||||||
|
|
||||||
lv_style_copy(&rel, &def);
|
lv_style_copy(&rel, &def);
|
||||||
rel.body.main_color = COLOR_HOS_BG_LIGHT;
|
rel.body.main_color = COLOR_BG_LIGHT;
|
||||||
rel.body.grad_color = rel.body.main_color;
|
rel.body.grad_color = rel.body.main_color;
|
||||||
rel.body.radius = 6;
|
rel.body.radius = 6;
|
||||||
rel.body.padding.hor = LV_DPI / 3;
|
rel.body.padding.hor = LV_DPI / 3;
|
||||||
@@ -139,7 +142,7 @@ static void btn_init(void)
|
|||||||
rel.body.shadow.type = LV_SHADOW_BOTTOM;
|
rel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||||
rel.body.shadow.width = 6;
|
rel.body.shadow.width = 6;
|
||||||
rel.body.border.width = 0;
|
rel.body.border.width = 0;
|
||||||
rel.body.border.color = COLOR_HOS_BG_LIGHT;
|
rel.body.border.color = COLOR_BG_LIGHT;
|
||||||
rel.body.border.part = LV_BORDER_FULL;
|
rel.body.border.part = LV_BORDER_FULL;
|
||||||
//rel.text.color = COLOR_HOS_TXT_WHITE;
|
//rel.text.color = COLOR_HOS_TXT_WHITE;
|
||||||
|
|
||||||
@@ -162,7 +165,7 @@ static void btn_init(void)
|
|||||||
tgl_pr.body.shadow.width = 0;
|
tgl_pr.body.shadow.width = 0;
|
||||||
|
|
||||||
lv_style_copy(&ina, &rel);
|
lv_style_copy(&ina, &rel);
|
||||||
ina.body.main_color = COLOR_HOS_BG_DARK;
|
ina.body.main_color = COLOR_BG_DARK;
|
||||||
ina.body.grad_color = ina.body.main_color;
|
ina.body.grad_color = ina.body.main_color;
|
||||||
//ina.body.shadow.width = 0;
|
//ina.body.shadow.width = 0;
|
||||||
ina.text.color = LV_COLOR_HEX(0x888888);
|
ina.text.color = LV_COLOR_HEX(0x888888);
|
||||||
@@ -207,7 +210,7 @@ static void img_init(void)
|
|||||||
img_light.image.intense = LV_OPA_80;
|
img_light.image.intense = LV_OPA_80;
|
||||||
|
|
||||||
lv_style_copy(&img_dark, &def);
|
lv_style_copy(&img_dark, &def);
|
||||||
img_dark.image.color = COLOR_HOS_BG_DARKER;
|
img_dark.image.color = COLOR_BG_DARKER;
|
||||||
img_dark.image.intense = LV_OPA_80;
|
img_dark.image.intense = LV_OPA_80;
|
||||||
|
|
||||||
|
|
||||||
@@ -250,7 +253,7 @@ static void bar_init(void)
|
|||||||
static lv_style_t bar_bg, bar_indic;
|
static lv_style_t bar_bg, bar_indic;
|
||||||
|
|
||||||
lv_style_copy(&bar_bg, &def);
|
lv_style_copy(&bar_bg, &def);
|
||||||
bar_bg.body.main_color = COLOR_HOS_LIGHT_BORDER;
|
bar_bg.body.main_color = COLOR_LIGHT_BORDER;
|
||||||
bar_bg.body.grad_color = bar_bg.body.main_color;
|
bar_bg.body.grad_color = bar_bg.body.main_color;
|
||||||
bar_bg.body.radius = 3;
|
bar_bg.body.radius = 3;
|
||||||
bar_bg.body.border.width = 0;
|
bar_bg.body.border.width = 0;
|
||||||
@@ -536,9 +539,9 @@ static void mbox_init(void)
|
|||||||
static lv_style_t bg;
|
static lv_style_t bg;
|
||||||
|
|
||||||
lv_style_copy(&bg, theme.panel);
|
lv_style_copy(&bg, theme.panel);
|
||||||
bg.body.main_color = LV_COLOR_HEX(0x464646);
|
bg.body.main_color = COLOR_BG_LIGHTER;
|
||||||
bg.body.grad_color = bg.body.main_color;
|
bg.body.grad_color = bg.body.main_color;
|
||||||
bg.body.shadow.color = COLOR_HOS_BG;
|
bg.body.shadow.color = COLOR_BG;
|
||||||
bg.body.shadow.type = LV_SHADOW_FULL;
|
bg.body.shadow.type = LV_SHADOW_FULL;
|
||||||
bg.body.shadow.width = 8;
|
bg.body.shadow.width = 8;
|
||||||
|
|
||||||
@@ -628,7 +631,7 @@ static void list_init(void)
|
|||||||
// pr.text.font = _font;
|
// pr.text.font = _font;
|
||||||
|
|
||||||
lv_style_copy(&tgl_rel, &pr);
|
lv_style_copy(&tgl_rel, &pr);
|
||||||
tgl_rel.body.main_color = COLOR_HOS_BG_LIGHT;
|
tgl_rel.body.main_color = COLOR_BG_LIGHT;
|
||||||
tgl_rel.body.grad_color = tgl_rel.body.main_color;
|
tgl_rel.body.grad_color = tgl_rel.body.main_color;
|
||||||
//tgl_rel.text.color = lv_color_hsv_to_rgb(_hue, 5, 95);
|
//tgl_rel.text.color = lv_color_hsv_to_rgb(_hue, 5, 95);
|
||||||
tgl_rel.text.color = COLOR_HOS_TEAL_LIGHTER;
|
tgl_rel.text.color = COLOR_HOS_TEAL_LIGHTER;
|
||||||
@@ -639,7 +642,7 @@ static void list_init(void)
|
|||||||
tgl_pr.body.border.width = 0;
|
tgl_pr.body.border.width = 0;
|
||||||
|
|
||||||
lv_style_copy(&ina, &pr);
|
lv_style_copy(&ina, &pr);
|
||||||
ina.body.main_color = COLOR_HOS_BG_DARK;
|
ina.body.main_color = COLOR_BG_DARK;
|
||||||
ina.body.grad_color = ina.body.main_color;
|
ina.body.grad_color = ina.body.main_color;
|
||||||
|
|
||||||
theme.list.sb = &sb;
|
theme.list.sb = &sb;
|
||||||
@@ -667,7 +670,7 @@ static void ddlist_init(void)
|
|||||||
bg.text.color = COLOR_HOS_TURQUOISE;
|
bg.text.color = COLOR_HOS_TURQUOISE;
|
||||||
|
|
||||||
lv_style_copy(&sel, &bg);
|
lv_style_copy(&sel, &bg);
|
||||||
sel.body.main_color = COLOR_HOS_BG_LIGHT;
|
sel.body.main_color = COLOR_BG_LIGHT;
|
||||||
sel.body.grad_color = sel.body.main_color;
|
sel.body.grad_color = sel.body.main_color;
|
||||||
|
|
||||||
theme.ddlist.bg = &bg;
|
theme.ddlist.bg = &bg;
|
||||||
@@ -713,7 +716,7 @@ static void tabview_init(void)
|
|||||||
indic.body.opa = LV_OPA_0;
|
indic.body.opa = LV_OPA_0;
|
||||||
|
|
||||||
lv_style_copy(&btn_bg, &def);
|
lv_style_copy(&btn_bg, &def);
|
||||||
btn_bg.body.main_color = COLOR_HOS_BG;
|
btn_bg.body.main_color = COLOR_BG;
|
||||||
btn_bg.body.grad_color = btn_bg.body.main_color;
|
btn_bg.body.grad_color = btn_bg.body.main_color;
|
||||||
btn_bg.body.radius = 0;
|
btn_bg.body.radius = 0;
|
||||||
btn_bg.body.empty = 1;
|
btn_bg.body.empty = 1;
|
||||||
@@ -734,7 +737,7 @@ static void tabview_init(void)
|
|||||||
rel.text.font = _font;
|
rel.text.font = _font;
|
||||||
|
|
||||||
lv_style_copy(&pr, &def);
|
lv_style_copy(&pr, &def);
|
||||||
pr.body.main_color = COLOR_HOS_BG_LIGHT;
|
pr.body.main_color = COLOR_BG_LIGHT;
|
||||||
pr.body.grad_color = pr.body.main_color;
|
pr.body.grad_color = pr.body.main_color;
|
||||||
pr.body.border.width = 0;
|
pr.body.border.width = 0;
|
||||||
pr.body.empty = 0;
|
pr.body.empty = 0;
|
||||||
@@ -750,7 +753,7 @@ static void tabview_init(void)
|
|||||||
tgl_rel.text.color = COLOR_HOS_TURQUOISE;
|
tgl_rel.text.color = COLOR_HOS_TURQUOISE;
|
||||||
|
|
||||||
lv_style_copy(&tgl_pr, &def);
|
lv_style_copy(&tgl_pr, &def);
|
||||||
tgl_pr.body.main_color = COLOR_HOS_BG_LIGHT;
|
tgl_pr.body.main_color = COLOR_BG_LIGHT;
|
||||||
tgl_pr.body.grad_color = tgl_pr.body.main_color;
|
tgl_pr.body.grad_color = tgl_pr.body.main_color;
|
||||||
tgl_pr.body.border.width = 0;
|
tgl_pr.body.border.width = 0;
|
||||||
tgl_pr.body.empty = 0;
|
tgl_pr.body.empty = 0;
|
||||||
@@ -797,7 +800,7 @@ static void win_init(void)
|
|||||||
static lv_style_t header, rel, pr;
|
static lv_style_t header, rel, pr;
|
||||||
|
|
||||||
lv_style_copy(&header, &def);
|
lv_style_copy(&header, &def);
|
||||||
header.body.main_color = COLOR_HOS_BG;
|
header.body.main_color = COLOR_BG;
|
||||||
header.body.grad_color = header.body.main_color;
|
header.body.grad_color = header.body.main_color;
|
||||||
header.body.radius = 0;
|
header.body.radius = 0;
|
||||||
header.body.border.width = 0;
|
header.body.border.width = 0;
|
||||||
@@ -843,10 +846,11 @@ static void win_init(void)
|
|||||||
* @param font pointer to a font (NULL to use the default)
|
* @param font pointer to a font (NULL to use the default)
|
||||||
* @return pointer to the initialized theme
|
* @return pointer to the initialized theme
|
||||||
*/
|
*/
|
||||||
lv_theme_t * lv_theme_hekate_init(uint16_t hue, lv_font_t * font)
|
lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t * font)
|
||||||
{
|
{
|
||||||
if(font == NULL) font = LV_FONT_DEFAULT;
|
if(font == NULL) font = LV_FONT_DEFAULT;
|
||||||
|
|
||||||
|
theme_bg_color = bg_color;
|
||||||
_hue = hue;
|
_hue = hue;
|
||||||
_font = font;
|
_font = font;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2019 CTCaer
|
* Copyright (c) 2018-2022 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -35,6 +35,14 @@ extern "C" {
|
|||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
|
#define COLOR_HOS_BG_BASE_DEFAULT 0x1B1B1B
|
||||||
|
#define COLOR_HOS_BG_BASE_BLACK 0x000000
|
||||||
|
|
||||||
|
#define COLOR_HOS_BG_DARKER 0x1B1B1B
|
||||||
|
#define COLOR_HOS_BG_DARK 0x222222
|
||||||
|
#define COLOR_HOS_BG 0x2D2D2D
|
||||||
|
#define COLOR_HOS_BG_LIGHT 0x3D3D3D
|
||||||
|
#define COLOR_HOS_LIGHT_BORDER 0x4D4D4D
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
@@ -44,13 +52,15 @@ extern "C" {
|
|||||||
* GLOBAL PROTOTYPES
|
* GLOBAL PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
|
extern uint32_t theme_bg_color;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the material theme
|
* Initialize the material theme
|
||||||
* @param hue [0..360] hue value from HSV color space to define the theme's base color
|
* @param hue [0..360] hue value from HSV color space to define the theme's base color
|
||||||
* @param font pointer to a font (NULL to use the default)
|
* @param font pointer to a font (NULL to use the default)
|
||||||
* @return pointer to the initialized theme
|
* @return pointer to the initialized theme
|
||||||
*/
|
*/
|
||||||
lv_theme_t * lv_theme_hekate_init(uint16_t hue, lv_font_t *font);
|
lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t *font);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a pointer to the theme
|
* Get a pointer to the theme
|
||||||
|
|||||||
@@ -70,89 +70,89 @@ typedef struct {
|
|||||||
allocation_table_header_t *header;
|
allocation_table_header_t *header;
|
||||||
} allocation_table_ctx_t;
|
} allocation_table_ctx_t;
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t allocation_table_entry_index_to_block(uint32_t entry_index) {
|
static inline __attribute__((always_inline)) uint32_t allocation_table_entry_index_to_block(uint32_t entry_index) {
|
||||||
return entry_index - 1;
|
return entry_index - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t allocation_table_block_to_entry_index(uint32_t block_index) {
|
static inline __attribute__((always_inline)) uint32_t allocation_table_block_to_entry_index(uint32_t block_index) {
|
||||||
return block_index + 1;
|
return block_index + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE int allocation_table_get_prev(allocation_table_entry_t *entry) {
|
static inline __attribute__((always_inline)) int allocation_table_get_prev(allocation_table_entry_t *entry) {
|
||||||
return entry->prev & 0x7FFFFFFF;
|
return entry->prev & 0x7FFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE int allocation_table_get_next(allocation_table_entry_t *entry) {
|
static inline __attribute__((always_inline)) int allocation_table_get_next(allocation_table_entry_t *entry) {
|
||||||
return entry->next & 0x7FFFFFFF;
|
return entry->next & 0x7FFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE int allocation_table_is_list_start(allocation_table_entry_t *entry) {
|
static inline __attribute__((always_inline)) int allocation_table_is_list_start(allocation_table_entry_t *entry) {
|
||||||
return entry->prev == 0x80000000;
|
return entry->prev == 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE int allocation_table_is_list_end(allocation_table_entry_t *entry) {
|
static inline __attribute__((always_inline)) int allocation_table_is_list_end(allocation_table_entry_t *entry) {
|
||||||
return (entry->next & 0x7FFFFFFF) == 0;
|
return (entry->next & 0x7FFFFFFF) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool allocation_table_is_multi_block_segment(allocation_table_entry_t *entry) {
|
static inline __attribute__((always_inline)) bool allocation_table_is_multi_block_segment(allocation_table_entry_t *entry) {
|
||||||
return entry->next & 0x80000000;
|
return entry->next & 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void allocation_table_make_multi_block_segment(allocation_table_entry_t *entry) {
|
static inline __attribute__((always_inline)) void allocation_table_make_multi_block_segment(allocation_table_entry_t *entry) {
|
||||||
entry->next |= 0x80000000;
|
entry->next |= 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void allocation_table_make_single_block_segment(allocation_table_entry_t *entry) {
|
static inline __attribute__((always_inline)) void allocation_table_make_single_block_segment(allocation_table_entry_t *entry) {
|
||||||
entry->next &= 0x7FFFFFFF;
|
entry->next &= 0x7FFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool allocation_table_is_single_block_segment(allocation_table_entry_t *entry) {
|
static inline __attribute__((always_inline)) bool allocation_table_is_single_block_segment(allocation_table_entry_t *entry) {
|
||||||
return (entry->next & 0x80000000) == 0;
|
return (entry->next & 0x80000000) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void allocation_table_make_list_start(allocation_table_entry_t *entry) {
|
static inline __attribute__((always_inline)) void allocation_table_make_list_start(allocation_table_entry_t *entry) {
|
||||||
entry->prev = 0x80000000;
|
entry->prev = 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool allocation_table_is_range_entry(allocation_table_entry_t *entry) {
|
static inline __attribute__((always_inline)) bool allocation_table_is_range_entry(allocation_table_entry_t *entry) {
|
||||||
return (entry->prev & 0x80000000) == 0x80000000 && entry->prev != 0x80000000;
|
return (entry->prev & 0x80000000) == 0x80000000 && entry->prev != 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void allocation_table_make_range_entry(allocation_table_entry_t *entry) {
|
static inline __attribute__((always_inline)) void allocation_table_make_range_entry(allocation_table_entry_t *entry) {
|
||||||
entry->prev |= 0x80000000;
|
entry->prev |= 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void allocation_table_set_next(allocation_table_entry_t *entry, int val) {
|
static inline __attribute__((always_inline)) void allocation_table_set_next(allocation_table_entry_t *entry, int val) {
|
||||||
entry->next = (entry->next & 0x80000000) | val;
|
entry->next = (entry->next & 0x80000000) | val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void allocation_table_set_prev(allocation_table_entry_t *entry, int val) {
|
static inline __attribute__((always_inline)) void allocation_table_set_prev(allocation_table_entry_t *entry, int val) {
|
||||||
entry->prev = val;
|
entry->prev = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void allocation_table_set_range(allocation_table_entry_t *entry, int start_index, int end_index) {
|
static inline __attribute__((always_inline)) void allocation_table_set_range(allocation_table_entry_t *entry, int start_index, int end_index) {
|
||||||
entry->next = end_index;
|
entry->next = end_index;
|
||||||
entry->prev = start_index;
|
entry->prev = start_index;
|
||||||
allocation_table_make_range_entry(entry);
|
allocation_table_make_range_entry(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE uint64_t allocation_table_query_size(uint32_t block_count) {
|
static inline __attribute__((always_inline)) uint64_t allocation_table_query_size(uint32_t block_count) {
|
||||||
return SAVE_FAT_ENTRY_SIZE * allocation_table_block_to_entry_index(block_count);
|
return SAVE_FAT_ENTRY_SIZE * allocation_table_block_to_entry_index(block_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE allocation_table_entry_t *save_allocation_table_read_entry(allocation_table_ctx_t *ctx, uint32_t entry_index) {
|
static inline __attribute__((always_inline)) allocation_table_entry_t *save_allocation_table_read_entry(allocation_table_ctx_t *ctx, uint32_t entry_index) {
|
||||||
return (allocation_table_entry_t *)((uint8_t *)ctx->base_storage + entry_index * SAVE_FAT_ENTRY_SIZE);
|
return (allocation_table_entry_t *)((uint8_t *)ctx->base_storage + entry_index * SAVE_FAT_ENTRY_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void save_allocation_table_write_entry(allocation_table_ctx_t *ctx, uint32_t entry_index, allocation_table_entry_t *entry) {
|
static inline __attribute__((always_inline)) void save_allocation_table_write_entry(allocation_table_ctx_t *ctx, uint32_t entry_index, allocation_table_entry_t *entry) {
|
||||||
memcpy((uint8_t *)ctx->base_storage + entry_index * SAVE_FAT_ENTRY_SIZE, entry, SAVE_FAT_ENTRY_SIZE);
|
memcpy((uint8_t *)ctx->base_storage + entry_index * SAVE_FAT_ENTRY_SIZE, entry, SAVE_FAT_ENTRY_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t save_allocation_table_get_free_list_entry_index(allocation_table_ctx_t *ctx) {
|
static inline __attribute__((always_inline)) uint32_t save_allocation_table_get_free_list_entry_index(allocation_table_ctx_t *ctx) {
|
||||||
return allocation_table_get_next(save_allocation_table_read_entry(ctx, ctx->free_list_entry_index));
|
return allocation_table_get_next(save_allocation_table_read_entry(ctx, ctx->free_list_entry_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t save_allocation_table_get_free_list_block_index(allocation_table_ctx_t *ctx) {
|
static inline __attribute__((always_inline)) uint32_t save_allocation_table_get_free_list_block_index(allocation_table_ctx_t *ctx) {
|
||||||
return allocation_table_entry_index_to_block(save_allocation_table_get_free_list_entry_index(ctx));
|
return allocation_table_entry_index_to_block(save_allocation_table_get_free_list_entry_index(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ typedef struct {
|
|||||||
uint64_t _length;
|
uint64_t _length;
|
||||||
} allocation_table_storage_ctx_t;
|
} allocation_table_storage_ctx_t;
|
||||||
|
|
||||||
static ALWAYS_INLINE void save_allocation_table_storage_get_size(allocation_table_storage_ctx_t *ctx, uint64_t *out_size) {
|
static inline __attribute__((always_inline)) void save_allocation_table_storage_get_size(allocation_table_storage_ctx_t *ctx, uint64_t *out_size) {
|
||||||
*out_size = ctx->_length;
|
*out_size = ctx->_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static ALWAYS_INLINE cache_block_t *cache_block_init(cached_storage_ctx_t *ctx) {
|
static inline __attribute__((always_inline)) cache_block_t *cache_block_init(cached_storage_ctx_t *ctx) {
|
||||||
cache_block_t *block = calloc(1, sizeof(cache_block_t));
|
cache_block_t *block = calloc(1, sizeof(cache_block_t));
|
||||||
block->buffer = malloc(ctx->block_size);
|
block->buffer = malloc(ctx->block_size);
|
||||||
block->index = -1;
|
block->index = -1;
|
||||||
|
|||||||
@@ -57,15 +57,15 @@ typedef struct {
|
|||||||
substorage base_storage;
|
substorage base_storage;
|
||||||
} duplex_storage_ctx_t;
|
} duplex_storage_ctx_t;
|
||||||
|
|
||||||
static ALWAYS_INLINE void save_bitmap_set_bit(void *buffer, uint64_t bit_offset) {
|
static inline __attribute__((always_inline)) void save_bitmap_set_bit(void *buffer, uint64_t bit_offset) {
|
||||||
*((uint8_t *)buffer + (bit_offset >> 3)) |= 1 << (bit_offset & 7);
|
*((uint8_t *)buffer + (bit_offset >> 3)) |= 1 << (bit_offset & 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void save_bitmap_clear_bit(void *buffer, uint64_t bit_offset) {
|
static inline __attribute__((always_inline)) void save_bitmap_clear_bit(void *buffer, uint64_t bit_offset) {
|
||||||
*((uint8_t *)buffer + (bit_offset >> 3)) &= ~(uint8_t)(1 << (bit_offset & 7));
|
*((uint8_t *)buffer + (bit_offset >> 3)) &= ~(uint8_t)(1 << (bit_offset & 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE uint8_t save_bitmap_check_bit(const void *buffer, uint64_t bit_offset) {
|
static inline __attribute__((always_inline)) uint8_t save_bitmap_check_bit(const void *buffer, uint64_t bit_offset) {
|
||||||
return *((uint8_t *)buffer + (bit_offset >> 3)) & (1 << (bit_offset & 7));
|
return *((uint8_t *)buffer + (bit_offset >> 3)) & (1 << (bit_offset & 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ typedef struct {
|
|||||||
uint32_t high;
|
uint32_t high;
|
||||||
} fs_int64_t;
|
} fs_int64_t;
|
||||||
|
|
||||||
static ALWAYS_INLINE void fs_int64_set(fs_int64_t *i, int64_t val) {
|
static inline __attribute__((always_inline)) void fs_int64_set(fs_int64_t *i, int64_t val) {
|
||||||
i->low = (uint32_t)((val & (uint64_t)(0x00000000FFFFFFFFul)) >> 0);
|
i->low = (uint32_t)((val & (uint64_t)(0x00000000FFFFFFFFul)) >> 0);
|
||||||
i->high = (uint32_t)((val & (uint64_t)(0xFFFFFFFF00000000ul)) >> 32);
|
i->high = (uint32_t)((val & (uint64_t)(0xFFFFFFFF00000000ul)) >> 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE const int64_t fs_int64_get(fs_int64_t *i) {
|
static inline __attribute__((always_inline)) const int64_t fs_int64_get(fs_int64_t *i) {
|
||||||
return ((int64_t)(i->high) << 32) | ((int64_t)i->low);
|
return ((int64_t)(i->high) << 32) | ((int64_t)i->low);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,52 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
u8 tmp1[0x40] = {0};
|
||||||
|
u8 tmp2[0x40 + src_size];
|
||||||
|
u8 tmp3[0x60] = {0};
|
||||||
|
memset(tmp2, 0, 0x40 + src_size);
|
||||||
|
|
||||||
|
u8 *secret = (u8 *)tmp1;
|
||||||
|
u8 *ipad = (u8 *)tmp2;
|
||||||
|
u8 *opad = (u8 *)tmp3;
|
||||||
|
|
||||||
|
if (key_size > 0x40)
|
||||||
|
{
|
||||||
|
if (!se_calc_sha256_oneshot(secret, key, key_size))
|
||||||
|
goto out;
|
||||||
|
memset(secret + 0x20, 0, 0x20);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(secret, key, key_size);
|
||||||
|
memset(secret + key_size, 0, 0x40 - key_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 *secret32 = (u32 *)secret;
|
||||||
|
u32 *ipad32 = (u32 *)ipad;
|
||||||
|
u32 *opad32 = (u32 *)opad;
|
||||||
|
for (u32 i = 0; i < 0x10; i++)
|
||||||
|
{
|
||||||
|
ipad32[i] = secret32[i] ^ 0x36363636;
|
||||||
|
opad32[i] = secret32[i] ^ 0x5C5C5C5C;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(ipad + 0x40, src, src_size);
|
||||||
|
if (!se_calc_sha256_oneshot(dst, ipad, 0x40 + src_size))
|
||||||
|
goto out;
|
||||||
|
memcpy(opad + 0x40, dst, 0x20);
|
||||||
|
if (!se_calc_sha256_oneshot(dst, opad, 0x60))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
res = 1;
|
||||||
|
|
||||||
|
out:;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
void save_hierarchical_integrity_verification_storage_control_area_query_size(ivfc_size_set_t *out, const ivfc_storage_control_input_param_t *input_param, int32_t layer_count, uint64_t data_size) {
|
void save_hierarchical_integrity_verification_storage_control_area_query_size(ivfc_size_set_t *out, const ivfc_storage_control_input_param_t *input_param, int32_t layer_count, uint64_t data_size) {
|
||||||
int64_t level_size[IVFC_MAX_LEVEL + 1];
|
int64_t level_size[IVFC_MAX_LEVEL + 1];
|
||||||
int32_t level = layer_count - 1;
|
int32_t level = layer_count - 1;
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ bool save_hierarchical_file_table_rename_file(hierarchical_save_file_table_ctx_t
|
|||||||
return save_fs_list_change_key(&ctx->file_table, &old_key, &new_key);
|
return save_fs_list_change_key(&ctx->file_table, &old_key, &new_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_is_sub_path(const char *path1, const char *path2) {
|
static inline __attribute__((always_inline)) bool save_is_sub_path(const char *path1, const char *path2) {
|
||||||
/* Check if either path is subpath of the other. */
|
/* Check if either path is subpath of the other. */
|
||||||
uint64_t path1_len = strlen(path1), path2_len = strlen(path2);
|
uint64_t path1_len = strlen(path1), path2_len = strlen(path2);
|
||||||
if (path1_len == 0 || path2_len == 0)
|
if (path1_len == 0 || path2_len == 0)
|
||||||
|
|||||||
@@ -50,13 +50,13 @@ void save_ivfc_storage_init(integrity_verification_storage_ctx_t *ctx, integrity
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* buffer must have size count + 0x20 for salt to by copied in at offset 0. */
|
/* buffer must have size count + 0x20 for salt to by copied in at offset 0. */
|
||||||
static ALWAYS_INLINE void save_ivfc_storage_do_hash(integrity_verification_storage_ctx_t *ctx, uint8_t *out_hash, void *buffer, uint64_t count) {
|
static inline __attribute__((always_inline)) void save_ivfc_storage_do_hash(integrity_verification_storage_ctx_t *ctx, uint8_t *out_hash, void *buffer, uint64_t count) {
|
||||||
memcpy(buffer, ctx->salt, sizeof(ctx->salt));
|
memcpy(buffer, ctx->salt, sizeof(ctx->salt));
|
||||||
se_calc_sha256_oneshot(out_hash, buffer, count + sizeof(ctx->salt));
|
se_calc_sha256_oneshot(out_hash, buffer, count + sizeof(ctx->salt));
|
||||||
out_hash[0x1F] |= 0x80;
|
out_hash[0x1F] |= 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool is_empty(const void *buffer, uint64_t count) {
|
static inline __attribute__((always_inline)) bool is_empty(const void *buffer, uint64_t count) {
|
||||||
bool empty = true;
|
bool empty = true;
|
||||||
const uint8_t *buf = (const uint8_t *)buffer;
|
const uint8_t *buf = (const uint8_t *)buffer;
|
||||||
for (uint64_t i = 0; i < count; i++) {
|
for (uint64_t i = 0; i < count; i++) {
|
||||||
|
|||||||
@@ -39,6 +39,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
VALIDITY_UNCHECKED = 0,
|
||||||
|
VALIDITY_INVALID,
|
||||||
|
VALIDITY_VALID
|
||||||
|
} validity_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
substorage hash_storage;
|
substorage hash_storage;
|
||||||
int integrity_check_level;
|
int integrity_check_level;
|
||||||
|
|||||||
@@ -71,11 +71,11 @@ typedef struct {
|
|||||||
uint8_t *free_blocks;
|
uint8_t *free_blocks;
|
||||||
} journal_map_ctx_t;
|
} journal_map_ctx_t;
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t save_journal_map_entry_make_physical_index(uint32_t index) {
|
static inline __attribute__((always_inline)) uint32_t save_journal_map_entry_make_physical_index(uint32_t index) {
|
||||||
return index | 0x80000000;
|
return index | 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t save_journal_map_entry_get_physical_index(uint32_t index) {
|
static inline __attribute__((always_inline)) uint32_t save_journal_map_entry_get_physical_index(uint32_t index) {
|
||||||
return index & 0x7FFFFFFF;
|
return index & 0x7FFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ typedef struct {
|
|||||||
bool _finished;
|
bool _finished;
|
||||||
} path_parser_ctx_t;
|
} path_parser_ctx_t;
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_path_parser_is_finished(path_parser_ctx_t *ctx) {
|
static inline __attribute__((always_inline)) bool save_path_parser_is_finished(path_parser_ctx_t *ctx) {
|
||||||
return ctx->_finished;
|
return ctx->_finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ remap_segment_ctx_t *save_remap_storage_init_segments(remap_storage_ctx_t *ctx)
|
|||||||
return segments;
|
return segments;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE remap_entry_ctx_t *save_remap_storage_get_map_entry(remap_storage_ctx_t *ctx, uint64_t offset) {
|
static inline __attribute__((always_inline)) remap_entry_ctx_t *save_remap_storage_get_map_entry(remap_storage_ctx_t *ctx, uint64_t offset) {
|
||||||
uint32_t segment_idx = save_remap_get_segment_from_virtual_offset(ctx->header, offset);
|
uint32_t segment_idx = save_remap_get_segment_from_virtual_offset(ctx->header, offset);
|
||||||
if (segment_idx < ctx->header->map_segment_count) {
|
if (segment_idx < ctx->header->map_segment_count) {
|
||||||
for (unsigned int i = 0; i < ctx->segments[segment_idx].entry_count; i++) {
|
for (unsigned int i = 0; i < ctx->segments[segment_idx].entry_count; i++) {
|
||||||
|
|||||||
@@ -89,11 +89,11 @@ typedef struct {
|
|||||||
substorage base_storage;
|
substorage base_storage;
|
||||||
} remap_storage_ctx_t;
|
} remap_storage_ctx_t;
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t save_remap_get_segment_from_virtual_offset(remap_header_t *header, uint64_t offset) {
|
static inline __attribute__((always_inline)) uint32_t save_remap_get_segment_from_virtual_offset(remap_header_t *header, uint64_t offset) {
|
||||||
return (uint32_t)(offset >> (64 - header->segment_bits));
|
return (uint32_t)(offset >> (64 - header->segment_bits));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE uint64_t save_remap_get_virtual_offset(remap_header_t *header, uint64_t segment) {
|
static inline __attribute__((always_inline)) uint64_t save_remap_get_virtual_offset(remap_header_t *header, uint64_t segment) {
|
||||||
return segment << (64 - header->segment_bits);
|
return segment << (64 - header->segment_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ static bool save_process_header(save_ctx_t *ctx) {
|
|||||||
|
|
||||||
uint8_t cmac[0x10] __attribute__((aligned(4)));
|
uint8_t cmac[0x10] __attribute__((aligned(4)));
|
||||||
se_aes_key_set(10, ctx->save_mac_key, 0x10);
|
se_aes_key_set(10, ctx->save_mac_key, 0x10);
|
||||||
se_aes_cmac(10, cmac, 0x10, &ctx->header.layout, sizeof(ctx->header.layout));
|
se_aes_cmac_128(10, cmac, &ctx->header.layout, sizeof(ctx->header.layout));
|
||||||
if (memcmp(cmac, &ctx->header.cmac, 0x10) == 0) {
|
if (memcmp(cmac, &ctx->header.cmac, 0x10) == 0) {
|
||||||
ctx->header_cmac_validity = VALIDITY_VALID;
|
ctx->header_cmac_validity = VALIDITY_VALID;
|
||||||
} else {
|
} else {
|
||||||
@@ -298,7 +298,7 @@ void save_free_contexts(save_ctx_t *ctx) {
|
|||||||
free(ctx->fat_storage);
|
free(ctx->fat_storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_flush(save_ctx_t *ctx) {
|
static inline __attribute__((always_inline)) bool save_flush(save_ctx_t *ctx) {
|
||||||
if (ctx->header.layout.version < VERSION_DISF_5) {
|
if (ctx->header.layout.version < VERSION_DISF_5) {
|
||||||
if (!save_cached_storage_flush(ctx->core_data_ivfc_storage.data_level)) {
|
if (!save_cached_storage_flush(ctx->core_data_ivfc_storage.data_level)) {
|
||||||
EPRINTF("Failed to flush cached storage!");
|
EPRINTF("Failed to flush cached storage!");
|
||||||
@@ -329,7 +329,7 @@ bool save_commit(save_ctx_t *ctx) {
|
|||||||
se_calc_sha256_oneshot(ctx->header.layout.hash, header + hashed_data_offset, hashed_data_size);
|
se_calc_sha256_oneshot(ctx->header.layout.hash, header + hashed_data_offset, hashed_data_size);
|
||||||
|
|
||||||
se_aes_key_set(10, ctx->save_mac_key, 0x10);
|
se_aes_key_set(10, ctx->save_mac_key, 0x10);
|
||||||
se_aes_cmac(10, ctx->header.cmac, 0x10, &ctx->header.layout, sizeof(ctx->header.layout));
|
se_aes_cmac_128(10, ctx->header.cmac, &ctx->header.layout, sizeof(ctx->header.layout));
|
||||||
|
|
||||||
if (substorage_write(&ctx->base_storage, &ctx->header, 0, sizeof(ctx->header)) != sizeof(ctx->header)) {
|
if (substorage_write(&ctx->base_storage, &ctx->header, 0, sizeof(ctx->header)) != sizeof(ctx->header)) {
|
||||||
EPRINTF("Failed to write save header!");
|
EPRINTF("Failed to write save header!");
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ typedef struct {
|
|||||||
|
|
||||||
static_assert(sizeof(save_data_creation_info_t) == 0x40, "Save data creation info size is wrong!");
|
static_assert(sizeof(save_data_creation_info_t) == 0x40, "Save data creation info size is wrong!");
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t save_calc_map_entry_storage_size(int32_t entry_count) {
|
static inline __attribute__((always_inline)) uint32_t save_calc_map_entry_storage_size(int32_t entry_count) {
|
||||||
int32_t val = entry_count < 1 ? entry_count : entry_count - 1;
|
int32_t val = entry_count < 1 ? entry_count : entry_count - 1;
|
||||||
return (entry_count + (val >> 1)) * sizeof(remap_entry_t);
|
return (entry_count + (val >> 1)) * sizeof(remap_entry_t);
|
||||||
}
|
}
|
||||||
@@ -107,47 +107,47 @@ bool save_create_system_save_data(save_ctx_t *ctx, uint32_t version, const char
|
|||||||
void save_free_contexts(save_ctx_t *ctx);
|
void save_free_contexts(save_ctx_t *ctx);
|
||||||
bool save_commit(save_ctx_t *ctx);
|
bool save_commit(save_ctx_t *ctx);
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_create_directory(save_ctx_t *ctx, const char *path) {
|
static inline __attribute__((always_inline)) bool save_create_directory(save_ctx_t *ctx, const char *path) {
|
||||||
return save_data_file_system_core_create_directory(&ctx->save_filesystem_core, path);
|
return save_data_file_system_core_create_directory(&ctx->save_filesystem_core, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_create_file(save_ctx_t *ctx, const char *path, uint64_t size) {
|
static inline __attribute__((always_inline)) bool save_create_file(save_ctx_t *ctx, const char *path, uint64_t size) {
|
||||||
return save_data_file_system_core_create_file(&ctx->save_filesystem_core, path, size);
|
return save_data_file_system_core_create_file(&ctx->save_filesystem_core, path, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_delete_directory(save_ctx_t *ctx, const char *path) {
|
static inline __attribute__((always_inline)) bool save_delete_directory(save_ctx_t *ctx, const char *path) {
|
||||||
return save_data_file_system_core_delete_directory(&ctx->save_filesystem_core,path);
|
return save_data_file_system_core_delete_directory(&ctx->save_filesystem_core,path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_delete_file(save_ctx_t *ctx, const char *path) {
|
static inline __attribute__((always_inline)) bool save_delete_file(save_ctx_t *ctx, const char *path) {
|
||||||
return save_data_file_system_core_delete_file(&ctx->save_filesystem_core, path);
|
return save_data_file_system_core_delete_file(&ctx->save_filesystem_core, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_open_directory(save_ctx_t *ctx, save_data_directory_ctx_t *directory, const char *path, open_directory_mode_t mode) {
|
static inline __attribute__((always_inline)) bool save_open_directory(save_ctx_t *ctx, save_data_directory_ctx_t *directory, const char *path, open_directory_mode_t mode) {
|
||||||
return save_data_file_system_core_open_directory(&ctx->save_filesystem_core, directory, path, mode);
|
return save_data_file_system_core_open_directory(&ctx->save_filesystem_core, directory, path, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_open_file(save_ctx_t *ctx, save_data_file_ctx_t *file, const char *path, open_mode_t mode) {
|
static inline __attribute__((always_inline)) bool save_open_file(save_ctx_t *ctx, save_data_file_ctx_t *file, const char *path, open_mode_t mode) {
|
||||||
return save_data_file_system_core_open_file(&ctx->save_filesystem_core, file, path, mode);
|
return save_data_file_system_core_open_file(&ctx->save_filesystem_core, file, path, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_rename_directory(save_ctx_t *ctx, const char *old_path, const char *new_path) {
|
static inline __attribute__((always_inline)) bool save_rename_directory(save_ctx_t *ctx, const char *old_path, const char *new_path) {
|
||||||
return save_data_file_system_core_rename_directory(&ctx->save_filesystem_core, old_path, new_path);
|
return save_data_file_system_core_rename_directory(&ctx->save_filesystem_core, old_path, new_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_rename_file(save_ctx_t *ctx, const char *old_path, const char *new_path) {
|
static inline __attribute__((always_inline)) bool save_rename_file(save_ctx_t *ctx, const char *old_path, const char *new_path) {
|
||||||
return save_data_file_system_core_rename_file(&ctx->save_filesystem_core, old_path, new_path);
|
return save_data_file_system_core_rename_file(&ctx->save_filesystem_core, old_path, new_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_get_entry_type(save_ctx_t *ctx, directory_entry_type_t *out_entry_type, const char *path) {
|
static inline __attribute__((always_inline)) bool save_get_entry_type(save_ctx_t *ctx, directory_entry_type_t *out_entry_type, const char *path) {
|
||||||
return save_data_file_system_core_get_entry_type(&ctx->save_filesystem_core, out_entry_type, path);
|
return save_data_file_system_core_get_entry_type(&ctx->save_filesystem_core, out_entry_type, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void save_get_free_space_size(save_ctx_t *ctx, uint64_t *out_free_space) {
|
static inline __attribute__((always_inline)) void save_get_free_space_size(save_ctx_t *ctx, uint64_t *out_free_space) {
|
||||||
return save_data_file_system_core_get_free_space_size(&ctx->save_filesystem_core, out_free_space);
|
return save_data_file_system_core_get_free_space_size(&ctx->save_filesystem_core, out_free_space);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void save_get_total_space_size(save_ctx_t *ctx, uint64_t *out_total_size) {
|
static inline __attribute__((always_inline)) void save_get_total_space_size(save_ctx_t *ctx, uint64_t *out_total_size) {
|
||||||
return save_data_file_system_core_get_total_space_size(&ctx->save_filesystem_core, out_total_size);
|
return save_data_file_system_core_get_total_space_size(&ctx->save_filesystem_core, out_total_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
OPEN_MODE_READ = 1,
|
||||||
|
OPEN_MODE_WRITE = 2,
|
||||||
|
OPEN_MODE_ALLOW_APPEND = 4,
|
||||||
|
OPEN_MODE_READ_WRITE = OPEN_MODE_READ | OPEN_MODE_WRITE,
|
||||||
|
OPEN_MODE_ALL = OPEN_MODE_READ | OPEN_MODE_WRITE | OPEN_MODE_ALLOW_APPEND
|
||||||
|
} open_mode_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
allocation_table_storage_ctx_t base_storage;
|
allocation_table_storage_ctx_t base_storage;
|
||||||
const char *path;
|
const char *path;
|
||||||
@@ -50,7 +59,7 @@ typedef struct {
|
|||||||
open_mode_t mode;
|
open_mode_t mode;
|
||||||
} save_data_file_ctx_t;
|
} save_data_file_ctx_t;
|
||||||
|
|
||||||
static ALWAYS_INLINE void save_data_file_get_size(save_data_file_ctx_t *ctx, uint64_t *out_size) {
|
static inline __attribute__((always_inline)) void save_data_file_get_size(save_data_file_ctx_t *ctx, uint64_t *out_size) {
|
||||||
*out_size = ctx->size;
|
*out_size = ctx->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||||||
#include <gfx_utils.h>
|
#include <gfx_utils.h>
|
||||||
#include <mem/heap.h>
|
#include <mem/heap.h>
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_data_file_system_core_open_fat_storage(save_data_file_system_core_ctx_t *ctx, allocation_table_storage_ctx_t *storage_ctx, uint32_t block_index) {
|
static inline __attribute__((always_inline)) bool save_data_file_system_core_open_fat_storage(save_data_file_system_core_ctx_t *ctx, allocation_table_storage_ctx_t *storage_ctx, uint32_t block_index) {
|
||||||
return save_allocation_table_storage_init(storage_ctx, ctx->base_storage, &ctx->allocation_table, (uint32_t)ctx->header->block_size, block_index);
|
return save_allocation_table_storage_init(storage_ctx, ctx->base_storage, &ctx->allocation_table, (uint32_t)ctx->header->block_size, block_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,20 +49,20 @@ typedef struct {
|
|||||||
hierarchical_save_file_table_ctx_t file_table;
|
hierarchical_save_file_table_ctx_t file_table;
|
||||||
} save_data_file_system_core_ctx_t;
|
} save_data_file_system_core_ctx_t;
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_data_file_system_core_rename_directory(save_data_file_system_core_ctx_t *ctx, const char *old_path, const char *new_path) {
|
static inline __attribute__((always_inline)) bool save_data_file_system_core_rename_directory(save_data_file_system_core_ctx_t *ctx, const char *old_path, const char *new_path) {
|
||||||
return save_hierarchical_file_table_rename_directory(&ctx->file_table, old_path, new_path);
|
return save_hierarchical_file_table_rename_directory(&ctx->file_table, old_path, new_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_data_file_system_core_rename_file(save_data_file_system_core_ctx_t *ctx, const char *old_path, const char *new_path) {
|
static inline __attribute__((always_inline)) bool save_data_file_system_core_rename_file(save_data_file_system_core_ctx_t *ctx, const char *old_path, const char *new_path) {
|
||||||
return save_hierarchical_file_table_rename_file(&ctx->file_table, old_path, new_path);
|
return save_hierarchical_file_table_rename_file(&ctx->file_table, old_path, new_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void save_data_file_system_core_get_free_space_size(save_data_file_system_core_ctx_t *ctx, uint64_t *out_free_space) {
|
static inline __attribute__((always_inline)) void save_data_file_system_core_get_free_space_size(save_data_file_system_core_ctx_t *ctx, uint64_t *out_free_space) {
|
||||||
uint32_t free_block_count = save_allocation_table_get_free_list_length(&ctx->allocation_table);
|
uint32_t free_block_count = save_allocation_table_get_free_list_length(&ctx->allocation_table);
|
||||||
*out_free_space = ctx->header->block_size * free_block_count;
|
*out_free_space = ctx->header->block_size * free_block_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void save_data_file_system_core_get_total_space_size(save_data_file_system_core_ctx_t *ctx, uint64_t *out_total_space) {
|
static inline __attribute__((always_inline)) void save_data_file_system_core_get_total_space_size(save_data_file_system_core_ctx_t *ctx, uint64_t *out_total_space) {
|
||||||
*out_total_space = ctx->header->block_size * ctx->header->block_count;
|
*out_total_space = ctx->header->block_size * ctx->header->block_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ void save_fs_list_init(save_filesystem_list_ctx_t *ctx) {
|
|||||||
ctx->used_list_head_index = 1;
|
ctx->used_list_head_index = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t save_fs_list_get_capacity(save_filesystem_list_ctx_t *ctx) {
|
static inline __attribute__((always_inline)) uint32_t save_fs_list_get_capacity(save_filesystem_list_ctx_t *ctx) {
|
||||||
uint32_t capacity;
|
uint32_t capacity;
|
||||||
if (save_allocation_table_storage_read(&ctx->storage, &capacity, 4, 4) != 4) {
|
if (save_allocation_table_storage_read(&ctx->storage, &capacity, 4, 4) != 4) {
|
||||||
EPRINTF("Failed to read FS list capacity!");
|
EPRINTF("Failed to read FS list capacity!");
|
||||||
@@ -52,7 +52,7 @@ static ALWAYS_INLINE uint32_t save_fs_list_get_capacity(save_filesystem_list_ctx
|
|||||||
return capacity;
|
return capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t save_fs_list_get_length(save_filesystem_list_ctx_t *ctx) {
|
static inline __attribute__((always_inline)) uint32_t save_fs_list_get_length(save_filesystem_list_ctx_t *ctx) {
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
if (save_allocation_table_storage_read(&ctx->storage, &length, 0, 4) != 4) {
|
if (save_allocation_table_storage_read(&ctx->storage, &length, 0, 4) != 4) {
|
||||||
EPRINTF("Failed to read FS list length!");
|
EPRINTF("Failed to read FS list length!");
|
||||||
@@ -61,11 +61,11 @@ static ALWAYS_INLINE uint32_t save_fs_list_get_length(save_filesystem_list_ctx_t
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_fs_list_set_capacity(save_filesystem_list_ctx_t *ctx, uint32_t capacity) {
|
static inline __attribute__((always_inline)) bool save_fs_list_set_capacity(save_filesystem_list_ctx_t *ctx, uint32_t capacity) {
|
||||||
return save_allocation_table_storage_write(&ctx->storage, &capacity, 4, 4) == 4;
|
return save_allocation_table_storage_write(&ctx->storage, &capacity, 4, 4) == 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool save_fs_list_set_length(save_filesystem_list_ctx_t *ctx, uint32_t length) {
|
static inline __attribute__((always_inline)) bool save_fs_list_set_length(save_filesystem_list_ctx_t *ctx, uint32_t length) {
|
||||||
return save_allocation_table_storage_write(&ctx->storage, &length, 0, 4) == 4;
|
return save_allocation_table_storage_write(&ctx->storage, &length, 0, 4) == 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,11 +76,11 @@ typedef struct {
|
|||||||
|
|
||||||
static_assert(sizeof(save_fs_list_entry_t) == 0x60, "Save filesystem list entry size is wrong!");
|
static_assert(sizeof(save_fs_list_entry_t) == 0x60, "Save filesystem list entry size is wrong!");
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t save_fs_list_read_entry(save_filesystem_list_ctx_t *ctx, uint32_t index, void *entry) {
|
static inline __attribute__((always_inline)) uint32_t save_fs_list_read_entry(save_filesystem_list_ctx_t *ctx, uint32_t index, void *entry) {
|
||||||
return save_allocation_table_storage_read(&ctx->storage, entry, index * SAVE_FS_LIST_ENTRY_SIZE, SAVE_FS_LIST_ENTRY_SIZE);
|
return save_allocation_table_storage_read(&ctx->storage, entry, index * SAVE_FS_LIST_ENTRY_SIZE, SAVE_FS_LIST_ENTRY_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t save_fs_list_write_entry(save_filesystem_list_ctx_t *ctx, uint32_t index, const void *entry) {
|
static inline __attribute__((always_inline)) uint32_t save_fs_list_write_entry(save_filesystem_list_ctx_t *ctx, uint32_t index, const void *entry) {
|
||||||
return save_allocation_table_storage_write(&ctx->storage, entry, index * SAVE_FS_LIST_ENTRY_SIZE, SAVE_FS_LIST_ENTRY_SIZE);
|
return save_allocation_table_storage_write(&ctx->storage, entry, index * SAVE_FS_LIST_ENTRY_SIZE, SAVE_FS_LIST_ENTRY_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||||||
|
|
||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
|
|
||||||
|
#define DIV_ROUND_UP(a, b) ((a + b - 1) / b)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t (*read)(void *ctx, void *buffer, uint64_t offset, uint64_t count);
|
uint32_t (*read)(void *ctx, void *buffer, uint64_t offset, uint64_t count);
|
||||||
uint32_t (*write)(void *ctx, const void *buffer, uint64_t offset, uint64_t count);
|
uint32_t (*write)(void *ctx, const void *buffer, uint64_t offset, uint64_t count);
|
||||||
@@ -51,7 +53,7 @@ typedef struct {
|
|||||||
void *ctx;
|
void *ctx;
|
||||||
} storage;
|
} storage;
|
||||||
|
|
||||||
static void ALWAYS_INLINE storage_init(storage *this, const storage_vt *vt, void *ctx) {
|
static void inline __attribute__((always_inline)) storage_init(storage *this, const storage_vt *vt, void *ctx) {
|
||||||
this->vt = vt;
|
this->vt = vt;
|
||||||
this->ctx = ctx;
|
this->ctx = ctx;
|
||||||
}
|
}
|
||||||
@@ -65,15 +67,15 @@ typedef struct {
|
|||||||
void substorage_init(substorage *this, const storage_vt *vt, void *ctx, uint64_t offset, uint64_t length);
|
void substorage_init(substorage *this, const storage_vt *vt, void *ctx, uint64_t offset, uint64_t length);
|
||||||
bool substorage_init_from_other(substorage *this, const substorage *other, uint64_t offset, uint64_t length);
|
bool substorage_init_from_other(substorage *this, const substorage *other, uint64_t offset, uint64_t length);
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t substorage_read(substorage *ctx, void *buffer, uint64_t offset, uint64_t count) {
|
static inline __attribute__((always_inline)) uint32_t substorage_read(substorage *ctx, void *buffer, uint64_t offset, uint64_t count) {
|
||||||
return ctx->base_storage.vt->read(ctx->base_storage.ctx, buffer, ctx->offset + offset, count);
|
return ctx->base_storage.vt->read(ctx->base_storage.ctx, buffer, ctx->offset + offset, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE uint32_t substorage_write(substorage *ctx, const void *buffer, uint64_t offset, uint64_t count) {
|
static inline __attribute__((always_inline)) uint32_t substorage_write(substorage *ctx, const void *buffer, uint64_t offset, uint64_t count) {
|
||||||
return ctx->base_storage.vt->write(ctx->base_storage.ctx, buffer, ctx->offset + offset, count);
|
return ctx->base_storage.vt->write(ctx->base_storage.ctx, buffer, ctx->offset + offset, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void substorage_get_size(substorage *ctx, uint64_t *out_size) {
|
static inline __attribute__((always_inline)) void substorage_get_size(substorage *ctx, uint64_t *out_size) {
|
||||||
ctx->base_storage.vt->get_size(ctx->base_storage.ctx, out_size);
|
ctx->base_storage.vt->get_size(ctx->base_storage.ctx, out_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +164,7 @@ static const storage_vt hierarchical_duplex_storage_vt = {
|
|||||||
save_hierarchical_duplex_storage_get_size_wrapper
|
save_hierarchical_duplex_storage_get_size_wrapper
|
||||||
};
|
};
|
||||||
|
|
||||||
static ALWAYS_INLINE bool is_range_valid(uint64_t offset, uint64_t size, uint64_t total_size) {
|
static inline __attribute__((always_inline)) bool is_range_valid(uint64_t offset, uint64_t size, uint64_t total_size) {
|
||||||
return offset >= 0 &&
|
return offset >= 0 &&
|
||||||
size >= 0 &&
|
size >= 0 &&
|
||||||
size <= total_size &&
|
size <= total_size &&
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* arch/arm/mach-tegra/tegra21_emc.h
|
* arch/arm/mach-tegra/tegra21_emc.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||||
* Copyright (c) 2019-2020, CTCaer.
|
* Copyright (c) 2019-2024, CTCaer.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#ifndef _EMC_H_
|
#ifndef _EMC_H_
|
||||||
#define _EMC_H_
|
#define _EMC_H_
|
||||||
|
|
||||||
|
#define EMC_INTSTATUS 0x0
|
||||||
#define EMC_DBG 0x8
|
#define EMC_DBG 0x8
|
||||||
#define EMC_CFG 0xC
|
#define EMC_CFG 0xC
|
||||||
#define EMC_CONFIG_SAMPLE_DELAY 0x5f0
|
#define EMC_CONFIG_SAMPLE_DELAY 0x5f0
|
||||||
@@ -698,6 +699,8 @@
|
|||||||
|
|
||||||
typedef enum _emc_mr_t
|
typedef enum _emc_mr_t
|
||||||
{
|
{
|
||||||
|
MR0_FEAT = 0,
|
||||||
|
MR4_TEMP = 4,
|
||||||
MR5_MAN_ID = 5,
|
MR5_MAN_ID = 5,
|
||||||
MR6_REV_ID1 = 6,
|
MR6_REV_ID1 = 6,
|
||||||
MR7_REV_ID2 = 7,
|
MR7_REV_ID2 = 7,
|
||||||
@@ -710,7 +713,7 @@ enum
|
|||||||
EMC_CHAN1 = 1
|
EMC_CHAN1 = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _emc_mr_data_t
|
typedef struct _emc_mr_chip_data_t
|
||||||
{
|
{
|
||||||
// Device 0.
|
// Device 0.
|
||||||
u8 rank0_ch0;
|
u8 rank0_ch0;
|
||||||
@@ -719,6 +722,12 @@ typedef struct _emc_mr_data_t
|
|||||||
// Device 1.
|
// Device 1.
|
||||||
u8 rank1_ch0;
|
u8 rank1_ch0;
|
||||||
u8 rank1_ch1;
|
u8 rank1_ch1;
|
||||||
|
} emc_mr_chip_data_t;
|
||||||
|
|
||||||
|
typedef struct _emc_mr_data_t
|
||||||
|
{
|
||||||
|
emc_mr_chip_data_t chip0;
|
||||||
|
emc_mr_chip_data_t chip1;
|
||||||
} emc_mr_data_t;
|
} emc_mr_data_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
1528
bdk/mem/emc_t210.h
Normal file
1528
bdk/mem/emc_t210.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2020 CTCaer
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -159,6 +159,13 @@ void *calloc(u32 num, u32 size)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *zalloc(u32 size)
|
||||||
|
{
|
||||||
|
void *res = (void *)_heap_alloc(size);
|
||||||
|
memset(res, 0, ALIGN(size, sizeof(hnode_t))); // Clear the aligned size.
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
void free(void *buf)
|
void free(void *buf)
|
||||||
{
|
{
|
||||||
if (buf >= _heap.start)
|
if (buf >= _heap.start)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2020 CTCaer
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -48,6 +48,7 @@ void heap_init(void *base);
|
|||||||
void heap_set(heap_t *heap);
|
void heap_set(heap_t *heap);
|
||||||
void *malloc(u32 size);
|
void *malloc(u32 size);
|
||||||
void *calloc(u32 num, u32 size);
|
void *calloc(u32 num, u32 size);
|
||||||
|
void *zalloc(u32 size);
|
||||||
void free(void *buf);
|
void free(void *buf);
|
||||||
void heap_monitor(heap_monitor_t *mon, bool print_node_stats);
|
void heap_monitor(heap_monitor_t *mon, bool print_node_stats);
|
||||||
|
|
||||||
|
|||||||
171
bdk/mem/mc.c
171
bdk/mem/mc.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2022 CTCaer
|
* Copyright (c) 2018-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -17,115 +17,99 @@
|
|||||||
|
|
||||||
#include <memory_map.h>
|
#include <memory_map.h>
|
||||||
#include <mem/mc.h>
|
#include <mem/mc.h>
|
||||||
|
#include <soc/bpmp.h>
|
||||||
#include <soc/timer.h>
|
#include <soc/timer.h>
|
||||||
#include <soc/t210.h>
|
#include <soc/t210.h>
|
||||||
#include <soc/clock.h>
|
#include <soc/clock.h>
|
||||||
|
|
||||||
void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock)
|
#define HOS_WPR1_BASE 0x80020000
|
||||||
{
|
|
||||||
MC(MC_SEC_CARVEOUT_BOM) = bom;
|
|
||||||
MC(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;
|
|
||||||
if (lock)
|
|
||||||
MC(MC_SEC_CARVEOUT_REG_CTRL) = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mc_config_carveout()
|
void mc_config_carveout_hos()
|
||||||
{
|
{
|
||||||
*(vu32 *)0x8005FFFC = 0xC0EDBBCC;
|
// Enable ACR GSR3 and flush data to ram.
|
||||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
|
*(u32 *)(HOS_WPR1_BASE + SZ_256K - sizeof(u32)) = ACR_GSC3_ENABLE_MAGIC;
|
||||||
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
|
||||||
|
|
||||||
|
// Set VPR CYA TRUSTED DEFAULT.
|
||||||
|
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = VPR_OVR0_CYA_TRUST_DEFAULT;
|
||||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
|
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
|
||||||
MC(MC_VIDEO_PROTECT_BOM) = 0;
|
|
||||||
MC(MC_VIDEO_PROTECT_SIZE_MB) = 0;
|
|
||||||
MC(MC_VIDEO_PROTECT_REG_CTRL) = 1;
|
|
||||||
|
|
||||||
// Configure TSEC carveout @ 0x90000000, 1MB.
|
// Disable VPR carveout.
|
||||||
//mc_config_tsec_carveout(0x90000000, 1, false);
|
MC(MC_VIDEO_PROTECT_BOM) = 0;
|
||||||
mc_config_tsec_carveout(0, 0, true);
|
MC(MC_VIDEO_PROTECT_SIZE_MB) = 0;
|
||||||
|
MC(MC_VIDEO_PROTECT_REG_CTRL) = VPR_CTRL_LOCKED;
|
||||||
|
|
||||||
MC(MC_MTS_CARVEOUT_BOM) = 0;
|
// Disable TZDRAM carveout.
|
||||||
MC(MC_MTS_CARVEOUT_SIZE_MB) = 0;
|
MC(MC_SEC_CARVEOUT_BOM) = 0;
|
||||||
MC(MC_MTS_CARVEOUT_ADR_HI) = 0;
|
MC(MC_SEC_CARVEOUT_SIZE_MB) = 0;
|
||||||
MC(MC_MTS_CARVEOUT_REG_CTRL) = 1;
|
MC(MC_SEC_CARVEOUT_REG_CTRL) = BIT(0);
|
||||||
|
|
||||||
MC(MC_SECURITY_CARVEOUT1_BOM) = 0;
|
// Disable CPU FW carveout.
|
||||||
MC(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;
|
MC(MC_MTS_CARVEOUT_BOM) = 0;
|
||||||
|
MC(MC_MTS_CARVEOUT_SIZE_MB) = 0;
|
||||||
|
MC(MC_MTS_CARVEOUT_REG_CTRL) = BIT(0);
|
||||||
|
|
||||||
|
// Disable GEN1 carveout.
|
||||||
MC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
|
MC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
|
||||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;
|
MC(MC_SECURITY_CARVEOUT1_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
|
||||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;
|
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
|
SEC_CARVEOUT_CFG_APERTURE_ID(0) |
|
||||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
|
SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH;
|
||||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;
|
|
||||||
|
|
||||||
MC(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;
|
// Enable GEN2 carveout as WPR1.
|
||||||
MC(MC_SECURITY_CARVEOUT2_BOM_HI) = 0;
|
MC(MC_SECURITY_CARVEOUT2_BOM) = HOS_WPR1_BASE;
|
||||||
MC(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;
|
MC(MC_SECURITY_CARVEOUT2_SIZE_128KB) = SZ_256K / SZ_128K;
|
||||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;
|
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU | SEC_CARVEOUT_CA2_R_TSEC;
|
||||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;
|
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = SEC_CARVEOUT_CA4_R_GPU2 | SEC_CARVEOUT_CA4_W_GPU2;
|
||||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = 0x3100000;
|
MC(MC_SECURITY_CARVEOUT2_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
|
||||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;
|
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = 0x300;
|
SEC_CARVEOUT_CFG_RD_NS |
|
||||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
SEC_CARVEOUT_CFG_RD_SEC |
|
||||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
SEC_CARVEOUT_CFG_RD_FALCON_LS |
|
||||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
SEC_CARVEOUT_CFG_RD_FALCON_HS |
|
||||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
SEC_CARVEOUT_CFG_WR_FALCON_LS |
|
||||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
SEC_CARVEOUT_CFG_WR_FALCON_HS |
|
||||||
MC(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;
|
SEC_CARVEOUT_CFG_APERTURE_ID(2) |
|
||||||
|
SEC_CARVEOUT_CFG_SEND_CFG_TO_GPU |
|
||||||
|
SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH;
|
||||||
|
|
||||||
MC(MC_SECURITY_CARVEOUT3_BOM) = 0;
|
// Prepare GEN3 carveout as WPR2.
|
||||||
MC(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
|
MC(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
|
||||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;
|
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU;
|
||||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;
|
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = SEC_CARVEOUT_CA4_R_GPU2 | SEC_CARVEOUT_CA4_W_GPU2;
|
||||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = 0x3000000;
|
MC(MC_SECURITY_CARVEOUT3_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
|
||||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;
|
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = 0x300;
|
SEC_CARVEOUT_CFG_RD_NS |
|
||||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
SEC_CARVEOUT_CFG_RD_SEC |
|
||||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
SEC_CARVEOUT_CFG_RD_FALCON_LS |
|
||||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
SEC_CARVEOUT_CFG_RD_FALCON_HS |
|
||||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
SEC_CARVEOUT_CFG_WR_FALCON_LS |
|
||||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
SEC_CARVEOUT_CFG_WR_FALCON_HS |
|
||||||
MC(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;
|
SEC_CARVEOUT_CFG_APERTURE_ID(3) |
|
||||||
|
SEC_CARVEOUT_CFG_SEND_CFG_TO_GPU |
|
||||||
|
SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH;
|
||||||
|
|
||||||
MC(MC_SECURITY_CARVEOUT4_BOM) = 0;
|
// Disable GEN4 carveout.
|
||||||
MC(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
|
MC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
|
||||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;
|
MC(MC_SECURITY_CARVEOUT4_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
|
||||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;
|
SEC_CARVEOUT_CFG_LOCKED |
|
||||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
|
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;
|
SEC_CARVEOUT_CFG_RD_NS |
|
||||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
|
SEC_CARVEOUT_CFG_WR_NS;
|
||||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;
|
|
||||||
|
|
||||||
MC(MC_SECURITY_CARVEOUT5_BOM) = 0;
|
// Disable GEN5 carveout.
|
||||||
MC(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
|
MC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
|
||||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;
|
MC(MC_SECURITY_CARVEOUT5_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
|
||||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;
|
SEC_CARVEOUT_CFG_LOCKED |
|
||||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
|
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;
|
SEC_CARVEOUT_CFG_RD_NS |
|
||||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;
|
SEC_CARVEOUT_CFG_WR_NS;
|
||||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
|
||||||
MC(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SDMMC, TSEC, XUSB and probably more need it to access < DRAM_START.
|
||||||
void mc_enable_ahb_redirect()
|
void mc_enable_ahb_redirect()
|
||||||
{
|
{
|
||||||
// Enable ARC_CLK_OVR_ON.
|
// Bypass ARC clock gating.
|
||||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) |= BIT(19);
|
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) |= BIT(19);
|
||||||
//MC(MC_IRAM_REG_CTRL) &= ~BIT(0);
|
//MC(MC_IRAM_REG_CTRL) &= ~BIT(0);
|
||||||
MC(MC_IRAM_BOM) = IRAM_BASE;
|
MC(MC_IRAM_BOM) = IRAM_BASE;
|
||||||
@@ -138,7 +122,7 @@ void mc_disable_ahb_redirect()
|
|||||||
MC(MC_IRAM_TOM) = 0;
|
MC(MC_IRAM_TOM) = 0;
|
||||||
// Disable IRAM_CFG_WRITE_ACCESS (sticky).
|
// Disable IRAM_CFG_WRITE_ACCESS (sticky).
|
||||||
//MC(MC_IRAM_REG_CTRL) |= BIT(0);
|
//MC(MC_IRAM_REG_CTRL) |= BIT(0);
|
||||||
// Disable ARC_CLK_OVR_ON.
|
// Set ARC clock gating to automatic.
|
||||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= ~BIT(19);
|
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= ~BIT(19);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,12 +141,11 @@ bool mc_client_has_access(void *address)
|
|||||||
void mc_enable()
|
void mc_enable()
|
||||||
{
|
{
|
||||||
// Reset EMC source to PLLP.
|
// Reset EMC source to PLLP.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | (2 << 29);
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | (2 << 29u);
|
||||||
// Enable memory clocks.
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC);
|
// Enable and clear reset for memory clocks.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MEM);
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_EMC_DLL);
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_EMC_DLL);
|
||||||
// Clear clock resets for memory.
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
||||||
usleep(5);
|
usleep(5);
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,7 @@
|
|||||||
#include <mem/mc_t210.h>
|
#include <mem/mc_t210.h>
|
||||||
|
|
||||||
void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock);
|
void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock);
|
||||||
void mc_config_carveout();
|
void mc_config_carveout_hos();
|
||||||
void mc_config_carveout_finalize();
|
|
||||||
void mc_enable_ahb_redirect();
|
void mc_enable_ahb_redirect();
|
||||||
void mc_disable_ahb_redirect();
|
void mc_disable_ahb_redirect();
|
||||||
bool mc_client_has_access(void *address);
|
bool mc_client_has_access(void *address);
|
||||||
|
|||||||
1655
bdk/mem/mc_t210.h
1655
bdk/mem/mc_t210.h
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2022 CTCaer
|
* Copyright (c) 2019-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -20,20 +20,25 @@
|
|||||||
#include "minerva.h"
|
#include "minerva.h"
|
||||||
|
|
||||||
#include <ianos/ianos.h>
|
#include <ianos/ianos.h>
|
||||||
#include <mem/emc.h>
|
#include <mem/emc_t210.h>
|
||||||
#include <soc/clock.h>
|
#include <soc/clock.h>
|
||||||
#include <soc/fuse.h>
|
#include <soc/fuse.h>
|
||||||
#include <soc/hw_init.h>
|
#include <soc/hw_init.h>
|
||||||
#include <soc/t210.h>
|
#include <soc/t210.h>
|
||||||
#include <utils/util.h>
|
#include <utils/util.h>
|
||||||
|
|
||||||
|
#define TABLE_FREQ_KHZ_OFFSET 0x40
|
||||||
|
#define TABLE_LA_REGS_T210_OFFSET 0x1284
|
||||||
|
#define TABLE_LA_REGS_T210B01_OFFSET 0xFA4
|
||||||
|
#define LA_SDMMC1_INDEX 6
|
||||||
|
|
||||||
extern volatile nyx_storage_t *nyx_str;
|
extern volatile nyx_storage_t *nyx_str;
|
||||||
|
|
||||||
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||||
|
|
||||||
u32 minerva_init()
|
u32 minerva_init()
|
||||||
{
|
{
|
||||||
u32 curr_ram_idx = 0;
|
u32 tbl_idx = 0;
|
||||||
|
|
||||||
minerva_cfg = NULL;
|
minerva_cfg = NULL;
|
||||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||||
@@ -98,13 +103,13 @@ u32 minerva_init()
|
|||||||
|
|
||||||
// Get current frequency
|
// Get current frequency
|
||||||
u32 current_emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
|
u32 current_emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
|
||||||
for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++)
|
for (tbl_idx = 0; tbl_idx < mtc_cfg->table_entries; tbl_idx++)
|
||||||
{
|
{
|
||||||
if (current_emc_clk_src == mtc_cfg->mtc_table[curr_ram_idx].clk_src_emc)
|
if (current_emc_clk_src == mtc_cfg->mtc_table[tbl_idx].clk_src_emc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtc_cfg->rate_from = mtc_cfg->mtc_table[curr_ram_idx].rate_khz;
|
mtc_cfg->rate_from = mtc_cfg->mtc_table[tbl_idx].rate_khz;
|
||||||
mtc_cfg->rate_to = FREQ_204;
|
mtc_cfg->rate_to = FREQ_204;
|
||||||
mtc_cfg->train_mode = OP_TRAIN;
|
mtc_cfg->train_mode = OP_TRAIN;
|
||||||
minerva_cfg(mtc_cfg, NULL);
|
minerva_cfg(mtc_cfg, NULL);
|
||||||
@@ -140,6 +145,26 @@ void minerva_change_freq(minerva_freq_t freq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void minerva_sdmmc_la_program(void *table, bool t210b01)
|
||||||
|
{
|
||||||
|
u32 freq = *(u32 *)(table + TABLE_FREQ_KHZ_OFFSET);
|
||||||
|
u32 *la_scale_regs = (u32 *)(table + (t210b01 ? TABLE_LA_REGS_T210B01_OFFSET : TABLE_LA_REGS_T210_OFFSET));
|
||||||
|
|
||||||
|
// Adjust SDMMC1 latency allowance.
|
||||||
|
switch (freq)
|
||||||
|
{
|
||||||
|
case 204000:
|
||||||
|
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 50;
|
||||||
|
break;
|
||||||
|
case 408000:
|
||||||
|
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 25;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 20;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void minerva_prep_boot_freq()
|
void minerva_prep_boot_freq()
|
||||||
{
|
{
|
||||||
if (!minerva_cfg)
|
if (!minerva_cfg)
|
||||||
@@ -157,23 +182,47 @@ void minerva_prep_boot_freq()
|
|||||||
minerva_change_freq(FREQ_800);
|
minerva_change_freq(FREQ_800);
|
||||||
}
|
}
|
||||||
|
|
||||||
void minerva_prep_boot_l4t(int oc_freq)
|
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom, bool prg_sdmmc_la)
|
||||||
{
|
{
|
||||||
if (!minerva_cfg)
|
if (!minerva_cfg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||||
|
|
||||||
|
// Program SDMMC LA regs.
|
||||||
|
if (prg_sdmmc_la)
|
||||||
|
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||||
|
minerva_sdmmc_la_program(&mtc_cfg->mtc_table[i], false);
|
||||||
|
|
||||||
// Add OC frequency.
|
// Add OC frequency.
|
||||||
if (oc_freq && mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600)
|
if (oc_freq && mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600)
|
||||||
{
|
{
|
||||||
memcpy(&mtc_cfg->mtc_table[mtc_cfg->table_entries],
|
memcpy(&mtc_cfg->mtc_table[mtc_cfg->table_entries],
|
||||||
&mtc_cfg->mtc_table[mtc_cfg->table_entries - 1],
|
&mtc_cfg->mtc_table[mtc_cfg->table_entries - 1],
|
||||||
sizeof(emc_table_t));
|
sizeof(emc_table_t));
|
||||||
mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
|
|
||||||
|
mtc_cfg->mtc_table[mtc_cfg->table_entries].opt_custom = opt_custom;
|
||||||
|
mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
|
||||||
mtc_cfg->table_entries++;
|
mtc_cfg->table_entries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Trim table.
|
||||||
|
int entries = 0;
|
||||||
|
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||||
|
{
|
||||||
|
// Copy frequencies from 204/408/800 MHz and 1333+ MHz.
|
||||||
|
int rate = mtc_cfg->mtc_table[i].rate_khz;
|
||||||
|
if (rate == FREQ_204 ||
|
||||||
|
rate == FREQ_408 ||
|
||||||
|
rate == FREQ_800 ||
|
||||||
|
rate >= FREQ_1333)
|
||||||
|
{
|
||||||
|
memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t));
|
||||||
|
entries++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mtc_cfg->table_entries = entries;
|
||||||
|
|
||||||
// Set init frequency.
|
// Set init frequency.
|
||||||
minerva_change_freq(FREQ_204);
|
minerva_change_freq(FREQ_204);
|
||||||
|
|
||||||
@@ -181,35 +230,21 @@ void minerva_prep_boot_l4t(int oc_freq)
|
|||||||
mtc_cfg->train_mode = OP_TRAIN;
|
mtc_cfg->train_mode = OP_TRAIN;
|
||||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||||
{
|
{
|
||||||
mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz;
|
// Skip already trained frequencies and OC freq (Arachne handles it).
|
||||||
// Skip already trained frequencies.
|
if (mtc_cfg->mtc_table[i].trained || mtc_cfg->rate_to == oc_freq)
|
||||||
if (mtc_cfg->rate_to == FREQ_204 || mtc_cfg->rate_to == FREQ_800 || mtc_cfg->rate_to == FREQ_1600)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Train frequency.
|
// Train frequency.
|
||||||
|
mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz;
|
||||||
minerva_cfg(mtc_cfg, NULL);
|
minerva_cfg(mtc_cfg, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do FSP WAR and scale to 800 MHz as boot freq.
|
// Do FSP WAR and scale to 800 MHz as boot freq.
|
||||||
bool fsp_opwr_disabled = !(EMC(EMC_MRW3) & 0xC0);
|
bool fsp_opwr_disabled = !(EMC(EMC_MRW3) & 0xC0);
|
||||||
if (fsp_opwr_disabled)
|
if (fsp_opwr_disabled)
|
||||||
minerva_change_freq(FREQ_666);
|
minerva_change_freq(FREQ_1333);
|
||||||
minerva_change_freq(FREQ_800);
|
minerva_change_freq(FREQ_800);
|
||||||
|
|
||||||
// Trim table.
|
|
||||||
int entries = 0;
|
|
||||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
|
||||||
{
|
|
||||||
// Copy freqs from 204 MHz to 800 MHz and 1600 MHz and above.
|
|
||||||
int rate = mtc_cfg->mtc_table[i].rate_khz;
|
|
||||||
if ((rate >= FREQ_204 && rate <= FREQ_800) || rate >= FREQ_1600)
|
|
||||||
{
|
|
||||||
memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t));
|
|
||||||
entries++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mtc_cfg->table_entries = entries;
|
|
||||||
|
|
||||||
// Do not let other mtc ops.
|
// Do not let other mtc ops.
|
||||||
mtc_cfg->init_done = 0;
|
mtc_cfg->init_done = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ typedef struct
|
|||||||
bool emc_2X_clk_src_is_pllmb;
|
bool emc_2X_clk_src_is_pllmb;
|
||||||
bool fsp_for_src_freq;
|
bool fsp_for_src_freq;
|
||||||
bool train_ram_patterns;
|
bool train_ram_patterns;
|
||||||
bool init_done;
|
u32 init_done;
|
||||||
} mtc_config_t;
|
} mtc_config_t;
|
||||||
|
|
||||||
enum train_mode_t
|
enum train_mode_t
|
||||||
@@ -53,16 +53,18 @@ enum train_mode_t
|
|||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
FREQ_204 = 204000,
|
FREQ_204 = 204000,
|
||||||
FREQ_666 = 665600,
|
FREQ_408 = 408000,
|
||||||
FREQ_800 = 800000,
|
FREQ_800 = 800000,
|
||||||
|
FREQ_1333 = 1331200,
|
||||||
FREQ_1600 = 1600000
|
FREQ_1600 = 1600000
|
||||||
} minerva_freq_t;
|
} minerva_freq_t;
|
||||||
|
|
||||||
extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||||
u32 minerva_init();
|
u32 minerva_init();
|
||||||
void minerva_change_freq(minerva_freq_t freq);
|
void minerva_change_freq(minerva_freq_t freq);
|
||||||
|
void minerva_sdmmc_la_program(void *table, bool t210b01);
|
||||||
void minerva_prep_boot_freq();
|
void minerva_prep_boot_freq();
|
||||||
void minerva_prep_boot_l4t(int oc_freq);
|
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom, bool prg_sdmmc_la);
|
||||||
void minerva_periodic_training();
|
void minerva_periodic_training();
|
||||||
emc_table_t *minerva_get_mtc_table();
|
emc_table_t *minerva_get_mtc_table();
|
||||||
int minerva_get_mtc_table_entries();
|
int minerva_get_mtc_table_entries();
|
||||||
|
|||||||
@@ -481,7 +481,8 @@ typedef struct
|
|||||||
u32 rate_khz;
|
u32 rate_khz;
|
||||||
u32 min_volt;
|
u32 min_volt;
|
||||||
u32 gpu_min_volt;
|
u32 gpu_min_volt;
|
||||||
char clock_src[32];
|
char clock_src[28];
|
||||||
|
u32 opt_custom;
|
||||||
u32 clk_src_emc;
|
u32 clk_src_emc;
|
||||||
u32 needs_training;
|
u32 needs_training;
|
||||||
u32 training_pattern;
|
u32 training_pattern;
|
||||||
|
|||||||
411
bdk/mem/sdram.c
411
bdk/mem/sdram.c
@@ -19,7 +19,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <mem/mc.h>
|
#include <mem/mc.h>
|
||||||
#include <mem/emc.h>
|
#include <mem/emc_t210.h>
|
||||||
#include <mem/sdram.h>
|
#include <mem/sdram.h>
|
||||||
#include <mem/sdram_param_t210.h>
|
#include <mem/sdram_param_t210.h>
|
||||||
#include <mem/sdram_param_t210b01.h>
|
#include <mem/sdram_param_t210b01.h>
|
||||||
@@ -34,16 +34,14 @@
|
|||||||
#include <soc/timer.h>
|
#include <soc/timer.h>
|
||||||
#include <soc/t210.h>
|
#include <soc/t210.h>
|
||||||
|
|
||||||
#define CONFIG_SDRAM_KEEP_ALIVE
|
|
||||||
|
|
||||||
#define DRAM_ID(x) BIT(x)
|
#define DRAM_ID(x) BIT(x)
|
||||||
#define DRAM_CC(x) BIT(x)
|
#define DRAM_CC(x) BIT(x)
|
||||||
|
|
||||||
typedef struct _sdram_vendor_patch_t
|
typedef struct _sdram_vendor_patch_t
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
u32 offset:16;
|
|
||||||
u32 dramcf:16;
|
u32 dramcf:16;
|
||||||
|
u32 offset:16;
|
||||||
} sdram_vendor_patch_t;
|
} sdram_vendor_patch_t;
|
||||||
|
|
||||||
static const u8 dram_encoding_t210b01[] = {
|
static const u8 dram_encoding_t210b01[] = {
|
||||||
@@ -67,21 +65,21 @@ static const u8 dram_encoding_t210b01[] = {
|
|||||||
/* 17 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
|
/* 17 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
|
||||||
/* 18 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
|
/* 18 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
|
||||||
/* 19 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
|
/* 19 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
|
||||||
/* 20 */ LPDDR4X_4GB_SAMSUNG_1Z,
|
/* 20 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL,
|
||||||
/* 21 */ LPDDR4X_4GB_SAMSUNG_1Z,
|
/* 21 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL,
|
||||||
/* 22 */ LPDDR4X_4GB_SAMSUNG_1Z,
|
/* 22 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL,
|
||||||
/* 23 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
|
/* 23 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
|
||||||
/* 24 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
|
/* 24 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
|
||||||
/* 25 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
|
/* 25 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
|
||||||
/* 26 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
|
/* 26 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
|
||||||
/* 27 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
|
/* 27 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
|
||||||
/* 28 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
|
/* 28 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
|
||||||
/* 29 */ LPDDR4X_4GB_HYNIX_1A,
|
/* 29 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
|
||||||
/* 30 */ LPDDR4X_4GB_HYNIX_1A,
|
/* 30 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
|
||||||
/* 31 */ LPDDR4X_4GB_HYNIX_1A,
|
/* 31 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
|
||||||
/* 32 */ LPDDR4X_4GB_MICRON_1A,
|
/* 32 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
|
||||||
/* 33 */ LPDDR4X_4GB_MICRON_1A,
|
/* 33 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
|
||||||
/* 34 */ LPDDR4X_4GB_MICRON_1A,
|
/* 34 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "sdram_config.inl"
|
#include "sdram_config.inl"
|
||||||
@@ -127,15 +125,19 @@ static void _sdram_req_mrr_data(u32 data, bool dual_channel)
|
|||||||
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
|
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
|
||||||
{
|
{
|
||||||
emc_mr_data_t data;
|
emc_mr_data_t data;
|
||||||
u32 dual_channel = (EMC(EMC_FBIO_CFG7) >> 2) & 1;
|
u32 mrr;
|
||||||
|
bool dual_rank = EMC(EMC_ADR_CFG) & 1;
|
||||||
|
bool dual_channel = (EMC(EMC_FBIO_CFG7) >> 2) & 1; // Each EMC channel is a RAM chip module.
|
||||||
|
|
||||||
// Clear left overs.
|
// Clear left overs.
|
||||||
for (u32 i = 0; i < 32; i++)
|
for (u32 i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
(void)EMC(EMC_MRR);
|
(void)EMC(EMC_MRR);
|
||||||
usleep(1);
|
usleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(&data, 0xFF, sizeof(emc_mr_data_t));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When a dram chip has only one rank, then the info from the 2 ranks differs.
|
* When a dram chip has only one rank, then the info from the 2 ranks differs.
|
||||||
* Info not matching is only allowed on different channels.
|
* Info not matching is only allowed on different channels.
|
||||||
@@ -143,36 +145,105 @@ emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
|
|||||||
|
|
||||||
// Get Device 0 (Rank 0) info from both dram chips (channels).
|
// Get Device 0 (Rank 0) info from both dram chips (channels).
|
||||||
_sdram_req_mrr_data((2u << 30) | (mrx << 16), dual_channel);
|
_sdram_req_mrr_data((2u << 30) | (mrx << 16), dual_channel);
|
||||||
data.rank0_ch0 = EMC(EMC_MRR) & 0xFF;
|
|
||||||
data.rank0_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8);
|
// Ram module 0 info.
|
||||||
|
mrr = EMC_CH0(EMC_MRR);
|
||||||
|
data.chip0.rank0_ch0 = mrr & 0xFF;
|
||||||
|
data.chip0.rank0_ch1 = (mrr & 0xFF00 >> 8);
|
||||||
|
|
||||||
|
// Ram module 1 info.
|
||||||
|
if (dual_channel)
|
||||||
|
{
|
||||||
|
mrr = EMC_CH1(EMC_MRR);
|
||||||
|
data.chip1.rank0_ch0 = mrr & 0xFF;
|
||||||
|
data.chip1.rank0_ch1 = (mrr & 0xFF00 >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
// If Rank 1 exists, get info.
|
// If Rank 1 exists, get info.
|
||||||
if (EMC(EMC_ADR_CFG) & 1)
|
if (dual_rank)
|
||||||
{
|
{
|
||||||
// Get Device 1 (Rank 1) info from both dram chips (channels).
|
// Get Device 1 (Rank 1) info from both dram chips (channels).
|
||||||
_sdram_req_mrr_data((1u << 30) | (mrx << 16), dual_channel);
|
_sdram_req_mrr_data((1u << 30) | (mrx << 16), dual_channel);
|
||||||
data.rank1_ch0 = EMC(EMC_MRR) & 0xFF;
|
|
||||||
data.rank1_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8);
|
// Ram module 0 info.
|
||||||
}
|
mrr = EMC_CH0(EMC_MRR);
|
||||||
else
|
data.chip0.rank1_ch0 = mrr & 0xFF;
|
||||||
{
|
data.chip0.rank1_ch1 = (mrr & 0xFF00 >> 8);
|
||||||
data.rank1_ch0 = 0xFF;
|
|
||||||
data.rank1_ch1 = 0xFF;
|
// Ram module 1 info.
|
||||||
|
if (dual_channel)
|
||||||
|
{
|
||||||
|
mrr = EMC_CH1(EMC_MRR);
|
||||||
|
data.chip1.rank1_ch0 = mrr & 0xFF;
|
||||||
|
data.chip1.rank1_ch1 = (mrr & 0xFF00 >> 8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sdram_src_pllc(bool enable)
|
||||||
|
{
|
||||||
|
static bool enabled = false;
|
||||||
|
|
||||||
|
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210 || enable == enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
enabled = enable;
|
||||||
|
|
||||||
|
// Clear CC interrupt.
|
||||||
|
EMC(EMC_INTSTATUS) = BIT(4);
|
||||||
|
(void)EMC(EMC_INTSTATUS);
|
||||||
|
|
||||||
|
u32 clk_src_emc = _dram_cfg_08_10_12_14_samsung_hynix_4gb.emc_clock_source;
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
// Check if clock source is not the expected one.
|
||||||
|
if (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) != clk_src_emc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Set source as PLLC_OUT0.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = 0x20188004;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Restore MC/EMC clock.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = clk_src_emc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for CC interrupt.
|
||||||
|
while (!(EMC(EMC_INTSTATUS) & BIT(4)))
|
||||||
|
usleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
static void _sdram_config_t210(const sdram_params_t210_t *params)
|
static void _sdram_config_t210(const sdram_params_t210_t *params)
|
||||||
{
|
{
|
||||||
|
// VDDP Select.
|
||||||
|
PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
|
||||||
|
usleep(params->pmc_vddp_sel_wait);
|
||||||
|
|
||||||
|
// Set DDR pad voltage.
|
||||||
|
PMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR); // Normally params->pmc_ddr_pwr.
|
||||||
|
|
||||||
|
// Turn on MEM IO Power.
|
||||||
|
PMC(APBDEV_PMC_NO_IOPOWER) &= PMC_NO_IOPOWER_SDMMC1; // Only keep SDMMC1 state. (Was params->pmc_no_io_power).
|
||||||
|
PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
|
||||||
|
|
||||||
|
PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
|
||||||
|
|
||||||
|
// Patch 1 using BCT spare variables
|
||||||
|
if (params->emc_bct_spare0)
|
||||||
|
*(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
|
||||||
|
|
||||||
// Program DPD3/DPD4 regs (coldboot path).
|
// Program DPD3/DPD4 regs (coldboot path).
|
||||||
// Enable sel_dpd on unused pins.
|
// Enable sel_dpd on unused pins.
|
||||||
u32 dpd_req = (params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x80000000;
|
u32 dpd_req = (params->emc_pmc_scratch1 & 0x3FFFFFFF) | PMC_IO_DPD_REQ_DPD_ON;
|
||||||
PMC(APBDEV_PMC_IO_DPD3_REQ) = (dpd_req ^ 0xFFFF) & 0xC000FFFF;
|
PMC(APBDEV_PMC_IO_DPD3_REQ) = (dpd_req ^ 0xFFFF) & 0xC000FFFF;
|
||||||
usleep(params->pmc_io_dpd3_req_wait);
|
usleep(params->pmc_io_dpd3_req_wait);
|
||||||
|
|
||||||
// Disable e_dpd_vttgen.
|
// Disable e_dpd_vttgen.
|
||||||
dpd_req = (params->emc_pmc_scratch2 & 0x3FFFFFFF) | 0x80000000;
|
dpd_req = (params->emc_pmc_scratch2 & 0x3FFFFFFF) | PMC_IO_DPD_REQ_DPD_ON;
|
||||||
PMC(APBDEV_PMC_IO_DPD4_REQ) = (dpd_req & 0xFFFF0000) ^ 0x3FFF0000;
|
PMC(APBDEV_PMC_IO_DPD4_REQ) = (dpd_req & 0xFFFF0000) ^ 0x3FFF0000;
|
||||||
usleep(params->pmc_io_dpd4_req_wait);
|
usleep(params->pmc_io_dpd4_req_wait);
|
||||||
|
|
||||||
@@ -183,45 +254,42 @@ static void _sdram_config_t210(const sdram_params_t210_t *params)
|
|||||||
PMC(APBDEV_PMC_WEAK_BIAS) = 0;
|
PMC(APBDEV_PMC_WEAK_BIAS) = 0;
|
||||||
usleep(1);
|
usleep(1);
|
||||||
|
|
||||||
// Start clocks.
|
// Start PLLM.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC1) = params->pllm_setup_control;
|
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC1) = params->pllm_setup_control;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC2) = 0;
|
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC2) = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_SDRAM_KEEP_ALIVE
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) =
|
|
||||||
(params->pllm_feedback_divider << 8) | params->pllm_input_divider | ((params->pllm_post_divider & 0xFFFF) << 20) | PLLCX_BASE_ENABLE;
|
|
||||||
#else
|
|
||||||
u32 pllm_div = (params->pllm_feedback_divider << 8) | params->pllm_input_divider | ((params->pllm_post_divider & 0xFFFF) << 20);
|
u32 pllm_div = (params->pllm_feedback_divider << 8) | params->pllm_input_divider | ((params->pllm_post_divider & 0xFFFF) << 20);
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = pllm_div;
|
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = pllm_div;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = pllm_div | PLLCX_BASE_ENABLE;
|
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = pllm_div | PLL_BASE_ENABLE;
|
||||||
#endif
|
|
||||||
|
|
||||||
u32 wait_end = get_tmr_us() + 300;
|
u32 wait_end = get_tmr_us() + 300;
|
||||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) & 0x8000000))
|
while (!(CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) & BIT(27)))
|
||||||
{
|
{
|
||||||
if (get_tmr_us() >= wait_end)
|
if (get_tmr_us() >= wait_end)
|
||||||
goto break_nosleep;
|
goto lock_timeout;
|
||||||
}
|
}
|
||||||
usleep(10);
|
usleep(10);
|
||||||
|
|
||||||
break_nosleep:
|
lock_timeout:
|
||||||
|
// Set clock sources.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = ((params->mc_emem_arb_misc0 >> 11) & 0x10000) | (params->emc_clock_source & 0xFFFEFFFF);
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = ((params->mc_emem_arb_misc0 >> 11) & 0x10000) | (params->emc_clock_source & 0xFFFEFFFF);
|
||||||
if (params->emc_clock_source_dll)
|
if (params->emc_clock_source_dll)
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
|
||||||
if (params->clear_clock2_mc1)
|
if (params->clear_clock2_mc1)
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000; // Clear Reset to MC1.
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = BIT(CLK_W_MC1); // Clear Reset to MC1.
|
||||||
|
|
||||||
// Enable and clear reset for memory clocks.
|
// Enable and clear reset for memory clocks.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_EMC_DLL);
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_EMC_DLL);
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
||||||
|
|
||||||
// Set pad macros.
|
// Set pad vtt levels.
|
||||||
EMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;
|
EMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;
|
||||||
EMC(EMC_PMACRO_VTTGEN_CTRL_1) = params->emc_pmacro_vttgen_ctrl1;
|
EMC(EMC_PMACRO_VTTGEN_CTRL_1) = params->emc_pmacro_vttgen_ctrl1;
|
||||||
EMC(EMC_PMACRO_VTTGEN_CTRL_2) = params->emc_pmacro_vttgen_ctrl2;
|
EMC(EMC_PMACRO_VTTGEN_CTRL_2) = params->emc_pmacro_vttgen_ctrl2;
|
||||||
|
|
||||||
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
// Trigger timing update so above writes take place.
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1;
|
||||||
usleep(10); // Ensure the regulators settle.
|
usleep(10); // Ensure the regulators settle.
|
||||||
|
|
||||||
// Select EMC write mux.
|
// Select EMC write mux.
|
||||||
@@ -233,7 +301,7 @@ break_nosleep:
|
|||||||
|
|
||||||
// Program CMD mapping. Required before brick mapping, else
|
// Program CMD mapping. Required before brick mapping, else
|
||||||
// we can't guarantee CK will be differential at all times.
|
// we can't guarantee CK will be differential at all times.
|
||||||
EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
|
EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
|
||||||
EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;
|
EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;
|
||||||
EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;
|
EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;
|
||||||
EMC(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2;
|
EMC(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2;
|
||||||
@@ -246,7 +314,7 @@ break_nosleep:
|
|||||||
EMC(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0;
|
EMC(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0;
|
||||||
EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;
|
EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;
|
||||||
EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;
|
EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;
|
||||||
EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
|
EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
|
||||||
|
|
||||||
// Program brick mapping.
|
// Program brick mapping.
|
||||||
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
|
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
|
||||||
@@ -258,6 +326,7 @@ break_nosleep:
|
|||||||
// This is required to do any reads from the pad macros.
|
// This is required to do any reads from the pad macros.
|
||||||
EMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
|
EMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
|
||||||
|
|
||||||
|
// Set data pipes mode.
|
||||||
EMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
|
EMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
|
||||||
|
|
||||||
// Set swizzle for Rank 0.
|
// Set swizzle for Rank 0.
|
||||||
@@ -275,12 +344,12 @@ break_nosleep:
|
|||||||
if (params->emc_bct_spare6)
|
if (params->emc_bct_spare6)
|
||||||
*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;
|
*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;
|
||||||
|
|
||||||
// Set pad controls.
|
// Program calibration impedance.
|
||||||
EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
|
EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
|
||||||
EMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;
|
EMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;
|
||||||
EMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;
|
EMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;
|
||||||
|
|
||||||
// Program Autocal controls with shadowed register fields.
|
// Program Autocal controls.
|
||||||
EMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;
|
EMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;
|
EMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;
|
EMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;
|
||||||
@@ -289,18 +358,21 @@ break_nosleep:
|
|||||||
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
|
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
|
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
|
||||||
|
|
||||||
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
|
// Program termination and drive strength
|
||||||
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
|
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
|
||||||
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
|
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
|
||||||
EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
|
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
|
||||||
|
EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
|
||||||
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;
|
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;
|
||||||
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
|
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
|
||||||
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
|
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
|
||||||
|
|
||||||
|
// Program dll config.
|
||||||
EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
|
EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
|
||||||
EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
|
EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
|
||||||
EMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;
|
EMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;
|
||||||
|
|
||||||
|
// Program barrelshift.
|
||||||
EMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;
|
EMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;
|
||||||
EMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;
|
EMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;
|
||||||
EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
|
EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
|
||||||
@@ -314,6 +386,7 @@ break_nosleep:
|
|||||||
EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;
|
EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;
|
||||||
EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;
|
EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;
|
||||||
|
|
||||||
|
// Program pad macros controls and termination.
|
||||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF) | 0x1E401E40;
|
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF) | 0x1E401E40;
|
||||||
EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
|
EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
|
||||||
|
|
||||||
@@ -328,7 +401,8 @@ break_nosleep:
|
|||||||
EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
|
EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
|
||||||
EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
|
EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
|
||||||
|
|
||||||
EMC(EMC_CFG_3) = params->emc_cfg3;
|
// Program pad macro pins/bytes.
|
||||||
|
EMC(EMC_CFG_3) = params->emc_cfg3;
|
||||||
EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
|
EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
|
||||||
EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
|
EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
|
||||||
EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;
|
EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;
|
||||||
@@ -348,12 +422,15 @@ break_nosleep:
|
|||||||
EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0;
|
EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0;
|
||||||
EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1;
|
EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1;
|
||||||
EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2;
|
EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2;
|
||||||
|
|
||||||
|
// Program inbound vref setting.
|
||||||
EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0;
|
EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0;
|
||||||
EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1;
|
EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1;
|
||||||
EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;
|
EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;
|
||||||
EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;
|
EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;
|
||||||
EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
|
EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
|
||||||
|
|
||||||
|
// Program quse trimmers.
|
||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;
|
||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;
|
||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;
|
||||||
@@ -368,6 +445,7 @@ break_nosleep:
|
|||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;
|
||||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;
|
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;
|
||||||
|
|
||||||
|
// Program outbound trimmers.
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;
|
||||||
@@ -402,6 +480,7 @@ break_nosleep:
|
|||||||
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;
|
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;
|
||||||
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;
|
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;
|
||||||
|
|
||||||
|
// Program clock trimmers.
|
||||||
EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
|
EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
|
||||||
EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
|
EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
|
||||||
EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
|
EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
|
||||||
@@ -418,7 +497,8 @@ break_nosleep:
|
|||||||
if (params->emc_bct_spare4)
|
if (params->emc_bct_spare4)
|
||||||
*(vu32 *)params->emc_bct_spare4 = params->emc_bct_spare5;
|
*(vu32 *)params->emc_bct_spare4 = params->emc_bct_spare5;
|
||||||
|
|
||||||
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
// Trigger timing update so above writes take place.
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1;
|
||||||
|
|
||||||
// Initialize MC VPR settings.
|
// Initialize MC VPR settings.
|
||||||
MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
|
MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
|
||||||
@@ -483,7 +563,8 @@ break_nosleep:
|
|||||||
MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
|
MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
|
||||||
MC(MC_DA_CONFIG0) = params->mc_da_cfg0;
|
MC(MC_DA_CONFIG0) = params->mc_da_cfg0;
|
||||||
|
|
||||||
MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
|
// Trigger MC timing update.
|
||||||
|
MC(MC_TIMING_CONTROL) = 1;
|
||||||
|
|
||||||
// Program second-level clock enable overrides.
|
// Program second-level clock enable overrides.
|
||||||
MC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;
|
MC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;
|
||||||
@@ -505,6 +586,7 @@ break_nosleep:
|
|||||||
EMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;
|
EMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;
|
||||||
EMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;
|
EMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;
|
||||||
|
|
||||||
|
// Program/Start auto calibration.
|
||||||
EMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;
|
EMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
|
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
|
||||||
usleep(params->emc_auto_cal_wait);
|
usleep(params->emc_auto_cal_wait);
|
||||||
@@ -561,9 +643,13 @@ break_nosleep:
|
|||||||
|
|
||||||
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;
|
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;
|
||||||
EMC(EMC_DBG) = params->emc_dbg;
|
EMC(EMC_DBG) = params->emc_dbg;
|
||||||
|
|
||||||
|
// Clear read fifo.
|
||||||
EMC(EMC_QRST) = params->emc_qrst;
|
EMC(EMC_QRST) = params->emc_qrst;
|
||||||
EMC(EMC_ISSUE_QRST) = 1;
|
EMC(EMC_ISSUE_QRST) = 1;
|
||||||
EMC(EMC_ISSUE_QRST) = 0;
|
EMC(EMC_ISSUE_QRST) = 0;
|
||||||
|
|
||||||
|
// Program the rest of EMC timing configuration.
|
||||||
EMC(EMC_QSAFE) = params->emc_qsafe;
|
EMC(EMC_QSAFE) = params->emc_qsafe;
|
||||||
EMC(EMC_RDV) = params->emc_rdv;
|
EMC(EMC_RDV) = params->emc_rdv;
|
||||||
EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
|
EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
|
||||||
@@ -612,14 +698,16 @@ break_nosleep:
|
|||||||
if (params->boot_rom_patch_control & BIT(31))
|
if (params->boot_rom_patch_control & BIT(31))
|
||||||
{
|
{
|
||||||
*(vu32 *)(APB_MISC_BASE + params->boot_rom_patch_control * 4) = params->boot_rom_patch_data;
|
*(vu32 *)(APB_MISC_BASE + params->boot_rom_patch_control * 4) = params->boot_rom_patch_data;
|
||||||
MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
|
|
||||||
|
// Trigger MC timing update.
|
||||||
|
MC(MC_TIMING_CONTROL) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release SEL_DPD_CMD.
|
// Release SEL_DPD_CMD.
|
||||||
PMC(APBDEV_PMC_IO_DPD3_REQ) = ((params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x40000000) & 0xCFFF0000;
|
PMC(APBDEV_PMC_IO_DPD3_REQ) = (params->emc_pmc_scratch1 & 0xFFF0000) | PMC_IO_DPD_REQ_DPD_OFF;
|
||||||
usleep(params->pmc_io_dpd3_req_wait);
|
usleep(params->pmc_io_dpd3_req_wait);
|
||||||
|
|
||||||
// Set autocal interval if not configured.
|
// Stall auto call measurements if periodic calibration is disabled.
|
||||||
if (!params->emc_auto_cal_interval)
|
if (!params->emc_auto_cal_interval)
|
||||||
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config | 0x200;
|
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config | 0x200;
|
||||||
|
|
||||||
@@ -632,7 +720,8 @@ break_nosleep:
|
|||||||
EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
|
EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
// Trigger timing update so above writes take place.
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1;
|
||||||
usleep(params->emc_timing_control_wait);
|
usleep(params->emc_timing_control_wait);
|
||||||
|
|
||||||
// Deassert HOLD_CKE_LOW.
|
// Deassert HOLD_CKE_LOW.
|
||||||
@@ -701,13 +790,14 @@ break_nosleep:
|
|||||||
if (params->emc_bct_spare12)
|
if (params->emc_bct_spare12)
|
||||||
*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;
|
*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;
|
||||||
|
|
||||||
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
// Trigger timing update so above writes take place.
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1;
|
||||||
|
|
||||||
if (params->emc_extra_refresh_num)
|
if (params->emc_extra_refresh_num)
|
||||||
EMC(EMC_REF) = (((1 << params->emc_extra_refresh_num) - 1) << 8) | (params->emc_dev_select << 30) | 3;
|
EMC(EMC_REF) = (((1 << params->emc_extra_refresh_num) - 1) << 8) | (params->emc_dev_select << 30) | 3;
|
||||||
|
|
||||||
// Enable refresh.
|
// Enable refresh.
|
||||||
EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;
|
EMC(EMC_REFCTRL) = params->emc_dev_select | BIT(31);
|
||||||
|
|
||||||
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
|
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
|
||||||
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
|
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
|
||||||
@@ -717,9 +807,10 @@ break_nosleep:
|
|||||||
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
|
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
|
||||||
|
|
||||||
// Write addr swizzle lock bit.
|
// Write addr swizzle lock bit.
|
||||||
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;
|
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | BIT(1);
|
||||||
|
|
||||||
EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions.
|
// Re-trigger timing to latch power saving functions.
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1;
|
||||||
|
|
||||||
// Enable EMC pipe clock gating.
|
// Enable EMC pipe clock gating.
|
||||||
EMC(EMC_CFG_PIPE_CLK) = params->emc_cfg_pipe_clk;
|
EMC(EMC_CFG_PIPE_CLK) = params->emc_cfg_pipe_clk;
|
||||||
@@ -741,8 +832,19 @@ break_nosleep:
|
|||||||
|
|
||||||
static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
||||||
{
|
{
|
||||||
u32 pmc_scratch1 = ~params->emc_pmc_scratch1;
|
// VDDP Select.
|
||||||
u32 pmc_scratch2 = ~params->emc_pmc_scratch2;
|
PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
|
||||||
|
usleep(params->pmc_vddp_sel_wait);
|
||||||
|
|
||||||
|
// Turn on MEM IO Power.
|
||||||
|
PMC(APBDEV_PMC_NO_IOPOWER) &= PMC_NO_IOPOWER_SDMMC1; // Only keep SDMMC1 state. (Was params->pmc_no_io_power).
|
||||||
|
PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
|
||||||
|
|
||||||
|
PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
|
||||||
|
|
||||||
|
// Patch 1 using BCT spare variables
|
||||||
|
if (params->emc_bct_spare0)
|
||||||
|
*(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
|
||||||
|
|
||||||
// Override HW FSM if needed.
|
// Override HW FSM if needed.
|
||||||
if (params->clk_rst_pllm_misc20_override_enable)
|
if (params->clk_rst_pllm_misc20_override_enable)
|
||||||
@@ -750,16 +852,18 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
|
|
||||||
// Program DPD3/DPD4 regs (coldboot path).
|
// Program DPD3/DPD4 regs (coldboot path).
|
||||||
// Enable sel_dpd on unused pins.
|
// Enable sel_dpd on unused pins.
|
||||||
|
u32 pmc_scratch1 = ~params->emc_pmc_scratch1;
|
||||||
PMC(APBDEV_PMC_WEAK_BIAS) = (pmc_scratch1 & 0x1000) << 19 | (pmc_scratch1 & 0xFFF) << 18 | (pmc_scratch1 & 0x8000) << 15;
|
PMC(APBDEV_PMC_WEAK_BIAS) = (pmc_scratch1 & 0x1000) << 19 | (pmc_scratch1 & 0xFFF) << 18 | (pmc_scratch1 & 0x8000) << 15;
|
||||||
PMC(APBDEV_PMC_IO_DPD3_REQ) = (pmc_scratch1 & 0x9FFF) + 0x80000000;
|
PMC(APBDEV_PMC_IO_DPD3_REQ) = (pmc_scratch1 & 0x9FFF) | PMC_IO_DPD_REQ_DPD_ON;
|
||||||
usleep(params->pmc_io_dpd3_req_wait);
|
usleep(params->pmc_io_dpd3_req_wait);
|
||||||
|
|
||||||
// Disable e_dpd_vttgen.
|
// Disable e_dpd_vttgen.
|
||||||
PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x3FFF0000) | 0x80000000;
|
u32 pmc_scratch2 = ~params->emc_pmc_scratch2;
|
||||||
|
PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x3FFF0000) | PMC_IO_DPD_REQ_DPD_ON;
|
||||||
usleep(params->pmc_io_dpd4_req_wait);
|
usleep(params->pmc_io_dpd4_req_wait);
|
||||||
|
|
||||||
// Disable e_dpd_bg.
|
// Disable e_dpd_bg.
|
||||||
PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x1FFF) | 0x80000000;
|
PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x1FFF) | PMC_IO_DPD_REQ_DPD_ON;
|
||||||
usleep(1);
|
usleep(1);
|
||||||
|
|
||||||
// Program CMD mapping. Required before brick mapping, else
|
// Program CMD mapping. Required before brick mapping, else
|
||||||
@@ -800,7 +904,8 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
if (params->emc_bct_spare_secure4)
|
if (params->emc_bct_spare_secure4)
|
||||||
*(vu32 *)params->emc_bct_spare_secure4 = params->emc_bct_spare_secure5;
|
*(vu32 *)params->emc_bct_spare_secure4 = params->emc_bct_spare_secure5;
|
||||||
|
|
||||||
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
// Trigger timing update so above writes take place.
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1;
|
||||||
usleep(params->pmc_vddp_sel_wait + 2); // Ensure the regulators settle.
|
usleep(params->pmc_vddp_sel_wait + 2); // Ensure the regulators settle.
|
||||||
|
|
||||||
// Set clock sources.
|
// Set clock sources.
|
||||||
@@ -817,6 +922,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
// This is required to do any reads from the pad macros.
|
// This is required to do any reads from the pad macros.
|
||||||
EMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
|
EMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
|
||||||
|
|
||||||
|
// Set data pipes mode.
|
||||||
EMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
|
EMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
|
||||||
|
|
||||||
// Set swizzle for Rank 0.
|
// Set swizzle for Rank 0.
|
||||||
@@ -834,12 +940,12 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
if (params->emc_bct_spare6)
|
if (params->emc_bct_spare6)
|
||||||
*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;
|
*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;
|
||||||
|
|
||||||
// Set pad controls.
|
// Program calibration impedance.
|
||||||
EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
|
EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
|
||||||
EMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;
|
EMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;
|
||||||
EMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;
|
EMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;
|
||||||
|
|
||||||
// Program Autocal controls with shadowed register fields.
|
// Program Autocal controls.
|
||||||
EMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;
|
EMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;
|
EMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;
|
EMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;
|
||||||
@@ -848,6 +954,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
|
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
|
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
|
||||||
|
|
||||||
|
// Program termination and drive strength
|
||||||
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
|
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
|
||||||
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
|
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
|
||||||
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
|
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
|
||||||
@@ -856,10 +963,12 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
|
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
|
||||||
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
|
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
|
||||||
|
|
||||||
|
// Program dll config.
|
||||||
EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
|
EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
|
||||||
EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
|
EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
|
||||||
EMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;
|
EMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;
|
||||||
|
|
||||||
|
// Program barrelshift.
|
||||||
EMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;
|
EMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;
|
||||||
EMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;
|
EMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;
|
||||||
EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
|
EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
|
||||||
@@ -873,6 +982,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;
|
EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;
|
||||||
EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;
|
EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;
|
||||||
|
|
||||||
|
// Program pad macros controls and termination.
|
||||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;
|
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;
|
||||||
EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
|
EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
|
||||||
|
|
||||||
@@ -886,6 +996,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
|
EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
|
||||||
EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl & 0xEFFFFFFF;
|
EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl & 0xEFFFFFFF;
|
||||||
|
|
||||||
|
// Program pad macro pins/bytes.
|
||||||
EMC(EMC_CFG_3) = params->emc_cfg3;
|
EMC(EMC_CFG_3) = params->emc_cfg3;
|
||||||
EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
|
EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
|
||||||
EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
|
EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
|
||||||
@@ -901,26 +1012,26 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_5) = params->emc_pmacro_tx_sel_clk_src5;
|
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_5) = params->emc_pmacro_tx_sel_clk_src5;
|
||||||
|
|
||||||
// Program per bit pad macros.
|
// Program per bit pad macros.
|
||||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_0) = params->emc_pmacro_perbit_fgcg_ctrl0;
|
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_0_B01) = params->emc_pmacro_perbit_fgcg_ctrl0;
|
||||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_1) = params->emc_pmacro_perbit_fgcg_ctrl1;
|
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_1_B01) = params->emc_pmacro_perbit_fgcg_ctrl1;
|
||||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_2) = params->emc_pmacro_perbit_fgcg_ctrl2;
|
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_2_B01) = params->emc_pmacro_perbit_fgcg_ctrl2;
|
||||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_3) = params->emc_pmacro_perbit_fgcg_ctrl3;
|
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_3_B01) = params->emc_pmacro_perbit_fgcg_ctrl3;
|
||||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_4) = params->emc_pmacro_perbit_fgcg_ctrl4;
|
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_4_B01) = params->emc_pmacro_perbit_fgcg_ctrl4;
|
||||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_5) = params->emc_pmacro_perbit_fgcg_ctrl5;
|
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_5_B01) = params->emc_pmacro_perbit_fgcg_ctrl5;
|
||||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_0) = params->emc_pmacro_perbit_rfu_ctrl0;
|
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_0_B01) = params->emc_pmacro_perbit_rfu_ctrl0;
|
||||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_1) = params->emc_pmacro_perbit_rfu_ctrl1;
|
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_1_B01) = params->emc_pmacro_perbit_rfu_ctrl1;
|
||||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_2) = params->emc_pmacro_perbit_rfu_ctrl2;
|
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_2_B01) = params->emc_pmacro_perbit_rfu_ctrl2;
|
||||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_3) = params->emc_pmacro_perbit_rfu_ctrl3;
|
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_3_B01) = params->emc_pmacro_perbit_rfu_ctrl3;
|
||||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_4) = params->emc_pmacro_perbit_rfu_ctrl4;
|
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_4_B01) = params->emc_pmacro_perbit_rfu_ctrl4;
|
||||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_5) = params->emc_pmacro_perbit_rfu_ctrl5;
|
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_5_B01) = params->emc_pmacro_perbit_rfu_ctrl5;
|
||||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_0) = params->emc_pmacro_perbit_rfu1_ctrl0;
|
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_0_B01) = params->emc_pmacro_perbit_rfu1_ctrl0;
|
||||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_1) = params->emc_pmacro_perbit_rfu1_ctrl1;
|
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_1_B01) = params->emc_pmacro_perbit_rfu1_ctrl1;
|
||||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_2) = params->emc_pmacro_perbit_rfu1_ctrl2;
|
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_2_B01) = params->emc_pmacro_perbit_rfu1_ctrl2;
|
||||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_3) = params->emc_pmacro_perbit_rfu1_ctrl3;
|
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_3_B01) = params->emc_pmacro_perbit_rfu1_ctrl3;
|
||||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_4) = params->emc_pmacro_perbit_rfu1_ctrl4;
|
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_4_B01) = params->emc_pmacro_perbit_rfu1_ctrl4;
|
||||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_5) = params->emc_pmacro_perbit_rfu1_ctrl5;
|
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_5_B01) = params->emc_pmacro_perbit_rfu1_ctrl5;
|
||||||
EMC(EMC_PMACRO_DATA_PI_CTRL) = params->emc_pmacro_data_pi_ctrl;
|
EMC(EMC_PMACRO_DATA_PI_CTRL_B01) = params->emc_pmacro_data_pi_ctrl;
|
||||||
EMC(EMC_PMACRO_CMD_PI_CTRL) = params->emc_pmacro_cmd_pi_ctrl;
|
EMC(EMC_PMACRO_CMD_PI_CTRL_B01) = params->emc_pmacro_cmd_pi_ctrl;
|
||||||
|
|
||||||
EMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass;
|
EMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass;
|
||||||
EMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0;
|
EMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0;
|
||||||
@@ -929,12 +1040,15 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0;
|
EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0;
|
||||||
EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1;
|
EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1;
|
||||||
EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2;
|
EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2;
|
||||||
|
|
||||||
|
// Program inbound vref setting.
|
||||||
EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0;
|
EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0;
|
||||||
EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1;
|
EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1;
|
||||||
EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;
|
EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;
|
||||||
EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;
|
EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;
|
||||||
EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
|
EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
|
||||||
|
|
||||||
|
// Program quse trimmers.
|
||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;
|
||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;
|
||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;
|
||||||
@@ -948,6 +1062,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_4) = params->emc_pmacro_quse_ddll_rank1_4;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_4) = params->emc_pmacro_quse_ddll_rank1_4;
|
||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;
|
||||||
|
|
||||||
|
// Program outbound trimmers.
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;
|
||||||
@@ -982,6 +1097,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;
|
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;
|
||||||
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;
|
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;
|
||||||
|
|
||||||
|
// Program clock trimmers.
|
||||||
EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
|
EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
|
||||||
EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
|
EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
|
||||||
EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
|
EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
|
||||||
@@ -1006,7 +1122,8 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
if (params->emc_bct_spare_secure10)
|
if (params->emc_bct_spare_secure10)
|
||||||
*(vu32 *)params->emc_bct_spare_secure10 = params->emc_bct_spare_secure11;
|
*(vu32 *)params->emc_bct_spare_secure10 = params->emc_bct_spare_secure11;
|
||||||
|
|
||||||
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
// Trigger timing update so above writes take place.
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1;
|
||||||
|
|
||||||
// Initialize MC VPR settings.
|
// Initialize MC VPR settings.
|
||||||
MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
|
MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
|
||||||
@@ -1071,7 +1188,8 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
|
MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
|
||||||
MC(MC_DA_CONFIG0) = params->mc_da_cfg0;
|
MC(MC_DA_CONFIG0) = params->mc_da_cfg0;
|
||||||
|
|
||||||
MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
|
// Trigger MC timing update.
|
||||||
|
MC(MC_TIMING_CONTROL) = 1;
|
||||||
|
|
||||||
// Program second-level clock enable overrides.
|
// Program second-level clock enable overrides.
|
||||||
MC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;
|
MC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;
|
||||||
@@ -1093,6 +1211,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;
|
EMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;
|
||||||
EMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;
|
EMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;
|
||||||
|
|
||||||
|
// Program/Start auto calibration.
|
||||||
EMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;
|
EMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
|
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
|
||||||
usleep(params->emc_auto_cal_wait);
|
usleep(params->emc_auto_cal_wait);
|
||||||
@@ -1101,7 +1220,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
if (params->emc_bct_spare8)
|
if (params->emc_bct_spare8)
|
||||||
*(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9;
|
*(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9;
|
||||||
|
|
||||||
EMC(EMC_AUTO_CAL_CONFIG9) = params->emc_auto_cal_config9;
|
EMC(EMC_AUTO_CAL_CONFIG9_B01) = params->emc_auto_cal_config9;
|
||||||
|
|
||||||
// Program EMC timing configuration.
|
// Program EMC timing configuration.
|
||||||
EMC(EMC_CFG_2) = params->emc_cfg2;
|
EMC(EMC_CFG_2) = params->emc_cfg2;
|
||||||
@@ -1121,11 +1240,11 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_RAS) = params->emc_ras;
|
EMC(EMC_RAS) = params->emc_ras;
|
||||||
EMC(EMC_RP) = params->emc_rp;
|
EMC(EMC_RP) = params->emc_rp;
|
||||||
EMC(EMC_TPPD) = params->emc_tppd;
|
EMC(EMC_TPPD) = params->emc_tppd;
|
||||||
EMC(EMC_CTT) = params->emc_trtm;
|
EMC(EMC_TRTM_B01) = params->emc_trtm;
|
||||||
EMC(EMC_FBIO_TWTM) = params->emc_twtm;
|
EMC(EMC_TWTM_B01) = params->emc_twtm;
|
||||||
EMC(EMC_FBIO_TRATM) = params->emc_tratm;
|
EMC(EMC_TRATM_B01) = params->emc_tratm;
|
||||||
EMC(EMC_FBIO_TWATM) = params->emc_twatm;
|
EMC(EMC_TWATM_B01) = params->emc_twatm;
|
||||||
EMC(EMC_FBIO_TR2REF) = params->emc_tr2ref;
|
EMC(EMC_TR2REF_B01) = params->emc_tr2ref;
|
||||||
EMC(EMC_R2R) = params->emc_r2r;
|
EMC(EMC_R2R) = params->emc_r2r;
|
||||||
EMC(EMC_W2W) = params->emc_w2w;
|
EMC(EMC_W2W) = params->emc_w2w;
|
||||||
EMC(EMC_R2W) = params->emc_r2w;
|
EMC(EMC_R2W) = params->emc_r2w;
|
||||||
@@ -1155,9 +1274,13 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
|
EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
|
||||||
|
|
||||||
EMC(EMC_DBG) = params->emc_dbg;
|
EMC(EMC_DBG) = params->emc_dbg;
|
||||||
|
|
||||||
|
// Clear read fifo.
|
||||||
EMC(EMC_QRST) = params->emc_qrst;
|
EMC(EMC_QRST) = params->emc_qrst;
|
||||||
EMC(EMC_ISSUE_QRST) = 1;
|
EMC(EMC_ISSUE_QRST) = 1;
|
||||||
EMC(EMC_ISSUE_QRST) = 0;
|
EMC(EMC_ISSUE_QRST) = 0;
|
||||||
|
|
||||||
|
// Program the rest of EMC timing configuration.
|
||||||
EMC(EMC_QSAFE) = params->emc_qsafe;
|
EMC(EMC_QSAFE) = params->emc_qsafe;
|
||||||
EMC(EMC_RDV) = params->emc_rdv;
|
EMC(EMC_RDV) = params->emc_rdv;
|
||||||
EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
|
EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
|
||||||
@@ -1198,7 +1321,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;
|
EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;
|
||||||
EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;
|
EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;
|
||||||
EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
|
EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
|
||||||
EMC(EMC_PMACRO_DSR_VTTGEN_CTRL0) = params->emc_pmacro_dsr_vttgen_ctrl0;
|
EMC(EMC_PMACRO_DSR_VTTGEN_CTRL_0_B01) = params->emc_pmacro_dsr_vttgen_ctrl0;
|
||||||
|
|
||||||
// Set pipe bypass enable bits before sending any DRAM commands.
|
// Set pipe bypass enable bits before sending any DRAM commands.
|
||||||
EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
|
EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
|
||||||
@@ -1207,7 +1330,9 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
if (params->boot_rom_patch_control)
|
if (params->boot_rom_patch_control)
|
||||||
{
|
{
|
||||||
*(vu32 *)params->boot_rom_patch_control = params->boot_rom_patch_data;
|
*(vu32 *)params->boot_rom_patch_control = params->boot_rom_patch_data;
|
||||||
MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
|
|
||||||
|
// Trigger MC timing update.
|
||||||
|
MC(MC_TIMING_CONTROL) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch 7 to 9 using BCT spare secure variables.
|
// Patch 7 to 9 using BCT spare secure variables.
|
||||||
@@ -1219,7 +1344,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
*(vu32 *)params->emc_bct_spare_secure16 = params->emc_bct_spare_secure17;
|
*(vu32 *)params->emc_bct_spare_secure16 = params->emc_bct_spare_secure17;
|
||||||
|
|
||||||
// Release SEL_DPD_CMD.
|
// Release SEL_DPD_CMD.
|
||||||
PMC(APBDEV_PMC_IO_DPD3_REQ) = ((params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x40000000) & 0xCFFF0000;
|
PMC(APBDEV_PMC_IO_DPD3_REQ) = (params->emc_pmc_scratch1 & 0xFFF0000) | PMC_IO_DPD_REQ_DPD_OFF;
|
||||||
usleep(params->pmc_io_dpd3_req_wait);
|
usleep(params->pmc_io_dpd3_req_wait);
|
||||||
|
|
||||||
// Set transmission pad control parameters.
|
// Set transmission pad control parameters.
|
||||||
@@ -1232,7 +1357,8 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
|
EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
// Trigger timing update so above writes take place.
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1;
|
||||||
usleep(params->emc_timing_control_wait);
|
usleep(params->emc_timing_control_wait);
|
||||||
|
|
||||||
// Deassert HOLD_CKE_LOW.
|
// Deassert HOLD_CKE_LOW.
|
||||||
@@ -1309,13 +1435,14 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
if (params->emc_bct_spare12)
|
if (params->emc_bct_spare12)
|
||||||
*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;
|
*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;
|
||||||
|
|
||||||
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
// Trigger timing update so above writes take place.
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1;
|
||||||
|
|
||||||
if (params->emc_extra_refresh_num)
|
if (params->emc_extra_refresh_num)
|
||||||
EMC(EMC_REF) = ((1 << params->emc_extra_refresh_num << 8) - 253) | (params->emc_dev_select << 30);
|
EMC(EMC_REF) = ((1 << params->emc_extra_refresh_num << 8) - 253) | (params->emc_dev_select << 30);
|
||||||
|
|
||||||
// Enable refresh.
|
// Enable refresh.
|
||||||
EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;
|
EMC(EMC_REFCTRL) = params->emc_dev_select | BIT(31);
|
||||||
|
|
||||||
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
|
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
|
||||||
EMC(EMC_CFG) = params->emc_cfg;
|
EMC(EMC_CFG) = params->emc_cfg;
|
||||||
@@ -1324,9 +1451,10 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
|
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
|
||||||
|
|
||||||
// Write addr swizzle lock bit.
|
// Write addr swizzle lock bit.
|
||||||
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;
|
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | BIT(1);
|
||||||
|
|
||||||
EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions.
|
// Re-trigger timing to latch power saving functions.
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1;
|
||||||
|
|
||||||
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
|
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
|
||||||
|
|
||||||
@@ -1337,7 +1465,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
|||||||
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;
|
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;
|
||||||
|
|
||||||
// Set untranslated region requirements.
|
// Set untranslated region requirements.
|
||||||
MC(MC_UNTRANSLATED_REGION_CHECK) = params->mc_untranslated_region_check;
|
MC(MC_UNTRANSLATED_REGION_CHECK_B01) = params->mc_untranslated_region_check;
|
||||||
|
|
||||||
// Lock carveouts per BCT cfg.
|
// Lock carveouts per BCT cfg.
|
||||||
MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;
|
MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;
|
||||||
@@ -1427,65 +1555,28 @@ void *sdram_get_params_patched()
|
|||||||
return (void *)sdram_params;
|
return (void *)sdram_params;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _sdram_init_t210()
|
|
||||||
{
|
|
||||||
const sdram_params_t210_t *params = (const sdram_params_t210_t *)_sdram_get_params_t210();
|
|
||||||
if (params->memory_type != MEMORY_TYPE_LPDDR4)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Set DRAM voltage.
|
|
||||||
max7762x_regulator_set_voltage(REGULATOR_SD1, 1125000); // HOS: 1.125V. Bootloader: 1.1V.
|
|
||||||
|
|
||||||
// VDDP Select.
|
|
||||||
PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
|
|
||||||
usleep(params->pmc_vddp_sel_wait);
|
|
||||||
|
|
||||||
// Set DDR pad voltage.
|
|
||||||
PMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR); // Normally params->pmc_ddr_pwr.
|
|
||||||
|
|
||||||
// Turn on MEM IO Power.
|
|
||||||
PMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power;
|
|
||||||
PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
|
|
||||||
|
|
||||||
PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
|
|
||||||
|
|
||||||
// Patch 1 using BCT spare variables
|
|
||||||
if (params->emc_bct_spare0)
|
|
||||||
*(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
|
|
||||||
|
|
||||||
_sdram_config_t210(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _sdram_init_t210b01()
|
|
||||||
{
|
|
||||||
const sdram_params_t210b01_t *params = (const sdram_params_t210b01_t *)sdram_get_params_t210b01();
|
|
||||||
if (params->memory_type != MEMORY_TYPE_LPDDR4)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// VDDP Select.
|
|
||||||
PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
|
|
||||||
usleep(params->pmc_vddp_sel_wait);
|
|
||||||
|
|
||||||
// Turn on MEM IO Power.
|
|
||||||
PMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power;
|
|
||||||
PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
|
|
||||||
|
|
||||||
PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
|
|
||||||
|
|
||||||
// Patch 1 using BCT spare variables
|
|
||||||
if (params->emc_bct_spare0)
|
|
||||||
*(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
|
|
||||||
|
|
||||||
_sdram_config_t210b01(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sdram_init()
|
void sdram_init()
|
||||||
{
|
{
|
||||||
// Disable remote sense for SD1.
|
// Disable remote sense for SD1.
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, MAX77620_SD_CNF2_ROVS_EN_SD0 | MAX77620_SD_CNF2_RSVD);
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, MAX77620_SD_CNF2_ROVS_EN_SD0 | MAX77620_SD_CNF2_RSVD);
|
||||||
|
|
||||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
||||||
_sdram_init_t210();
|
{
|
||||||
|
const sdram_params_t210_t *params = (const sdram_params_t210_t *)_sdram_get_params_t210();
|
||||||
|
if (params->memory_type != MEMORY_TYPE_LPDDR4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Set DRAM voltage.
|
||||||
|
max7762x_regulator_set_voltage(REGULATOR_SD1, 1125000); // HOS: 1.125V. Bootloader: 1.1V.
|
||||||
|
|
||||||
|
_sdram_config_t210(params);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
_sdram_init_t210b01();
|
{
|
||||||
|
const sdram_params_t210b01_t *params = (const sdram_params_t210b01_t *)sdram_get_params_t210b01();
|
||||||
|
if (params->memory_type != MEMORY_TYPE_LPDDR4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_sdram_config_t210b01(params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
124
bdk/mem/sdram.h
124
bdk/mem/sdram.h
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2020-2023 CTCaer
|
* Copyright (c) 2020-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -18,86 +18,98 @@
|
|||||||
#ifndef _SDRAM_H_
|
#ifndef _SDRAM_H_
|
||||||
#define _SDRAM_H_
|
#define _SDRAM_H_
|
||||||
|
|
||||||
#include <mem/emc.h>
|
#include <mem/emc_t210.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tegra X1/X1+ EMC/DRAM Bandwidth Chart:
|
* Tegra X1/X1+ EMC/DRAM Bandwidth Chart:
|
||||||
*
|
*
|
||||||
* Note: BWbits T210 = Hz x ddr x bus width x channels = Hz x 2 x 32 x 2.
|
* Note: Max BWbits = Hz x ddr x bus width x channels = Hz x 2 x 32 x 2.
|
||||||
* BWbits T210B01 = Hz x ddr x bus width x channels = Hz x 2 x 64 x 2.
|
* Max BWbits = Hz x ddr x bus width x channels = Hz x 2 x 64 x 1.
|
||||||
* Both assume that both sub-partitions are used and thus reaching max
|
* Configurations supported: 1x32, 2x32, 1x64.
|
||||||
* bandwidth per channel. (T210: 2x16-bit, T210B01: 2x32-bit).
|
* x64 ram modules can be used by combining the 2 32-bit channels into one.
|
||||||
* Retail Mariko use one sub-partition, in order to meet Erista perf.
|
|
||||||
*
|
|
||||||
* T210 T210B01
|
|
||||||
* 40.8 MHz: 0.61 1.22 GiB/s
|
|
||||||
* 68.0 MHz: 1.01 2.02 GiB/s
|
|
||||||
* 102.0 MHz: 1.52 3.04 GiB/s
|
|
||||||
* 204.0 MHz: 3.04 6.08 GiB/s <-- Tegra X1/X1+ Init/SC7 Frequency
|
|
||||||
* 408.0 MHz: 6.08 12.16 GiB/s
|
|
||||||
* 665.6 MHz: 9.92 19.84 GiB/s
|
|
||||||
* 800.0 MHz: 11.92 23.84 GiB/s <-- Tegra X1/X1+ Nvidia OS Boot Frequency
|
|
||||||
* 1065.6 MHz: 15.89 31.78 GiB/s
|
|
||||||
* 1331.2 MHz: 19.84 39.68 GiB/s
|
|
||||||
* 1600.0 MHz: 23.84 47.68 GiB/s <-- Tegra X1/X1+ HOS Max Frequency
|
|
||||||
* 1862.4 MHz: 27.75 55.50 GiB/s <-- Tegra X1 Official Max Frequency
|
|
||||||
* 2131.2 MHz: 31.76 63.52 GiB/s <-- Tegra X1+ Official Max Frequency
|
|
||||||
*
|
*
|
||||||
|
* 204.0 MHz: 3.04 <-- Tegra X1/X1+ Init/SC7 Frequency
|
||||||
|
* 408.0 MHz: 6.08
|
||||||
|
* 665.6 MHz: 9.92
|
||||||
|
* 800.0 MHz: 11.92 <-- Tegra X1/X1+ Nvidia OS Boot Frequency
|
||||||
|
* 1065.6 MHz: 15.89
|
||||||
|
* 1331.2 MHz: 19.84
|
||||||
|
* 1600.0 MHz: 23.84
|
||||||
|
* 1862.4 MHz: 27.75 <-- Tegra X1 Official Max Frequency
|
||||||
|
* 2131.2 MHz: 31.76 <-- Tegra X1+ Official Max Frequency. Not all regs have support for > 2046 MHz.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum sdram_ids_erista
|
enum sdram_ids_erista
|
||||||
{
|
{
|
||||||
// LPDDR4 3200Mbps.
|
// LPDDR4 3200Mbps.
|
||||||
LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0,
|
LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0, // Die-B. (2y-01).
|
||||||
LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1,
|
LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1, // Die-M. (2y-01).
|
||||||
LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT = 2, // WT:C.
|
LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC = 2, // Die-C. (2y-01).
|
||||||
|
|
||||||
LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4,
|
LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4, // Die-C. (2y-01).
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Custom hekate/L4T supported 8GB. 7 dram id can be easily applied in fuses.
|
||||||
|
*
|
||||||
|
* 4GB modules:
|
||||||
|
* Samsung K4FBE3D4HM-MGCH/CJ/CL. MG/TF/GF/TH/GH: Package + Temperature.
|
||||||
|
* Hynix H9HCNNNCPUMLXR-NME/NEE/NEI. E/I: Temperature.
|
||||||
|
* Hynix H54G56BYYVX046/QX046/PX046. V/Q/P: Package + Temperature.
|
||||||
|
*/
|
||||||
|
LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX = 7, // XX: CH/CJ/CL.
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sdram_ids_mariko
|
enum sdram_ids_mariko
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Nintendo Switch LPDRR4X generations:
|
||||||
|
* - 1x nm are 1st-gen
|
||||||
|
* - 1y nm are 2nd-gen
|
||||||
|
* - 1z/a nm are 3rd-gen
|
||||||
|
*/
|
||||||
|
|
||||||
// LPDDR4X 4266Mbps.
|
// LPDDR4X 4266Mbps.
|
||||||
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3, // Replaced from Copper. Die-M. (1y-01).
|
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3, // Die-M. (1y-01).
|
||||||
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5, // Replaced from Copper. Die-M. (1y-01).
|
LPDDR4X_AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5, // Die-M. (1y-01).
|
||||||
LPDDR4X_AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6, // Replaced from Copper. Die-M. (1y-01).
|
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6, // Die-M. (1y-01).
|
||||||
|
|
||||||
// LPDDR4X 3733Mbps.
|
// LPDDR4X 3733Mbps.
|
||||||
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. 1st gen. 8 banks. 3733Mbps.
|
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. (1x-03).
|
||||||
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M.
|
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M. (1x-03).
|
||||||
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M.
|
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M. (1x-03).
|
||||||
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11, // 4266Mbps. Die-E.
|
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11, // Die-E. (1x-03). D9WGB. 4266Mbps.
|
||||||
|
|
||||||
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. 1st gen. 8 banks. 3733Mbps.
|
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. (1x-03).
|
||||||
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M.
|
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M. (1x-03).
|
||||||
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M.
|
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M. (1x-03).
|
||||||
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15, // 4266Mbps. Die-E.
|
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15, // Die-E. (1x-03). D9WGB. 4266Mbps.
|
||||||
|
|
||||||
// LPDDR4X 4266Mbps.
|
// LPDDR4X 4266Mbps.
|
||||||
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A. (1y-X03). 2nd gen. 8 banks. 4266Mbps.
|
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A. (1y-X03).
|
||||||
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18, // Die-A. (1y-X03).
|
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18, // Die-A. (1y-X03).
|
||||||
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A. (1y-X03). 2nd gen. 8 banks. 4266Mbps.
|
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A. (1y-X03).
|
||||||
|
|
||||||
LPDDR4X_IOWA_4GB_SAMSUNG_1Z = 20, // 1z nm. 40% lower power usage. (1z-01).
|
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 20, // Die-B. (1z-01). 40% lp.
|
||||||
LPDDR4X_HOAG_4GB_SAMSUNG_1Z = 21, // 1z nm. 40% lower power usage. (1z-01).
|
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 21, // Die-B. (1z-01). 40% lp.
|
||||||
LPDDR4X_AULA_4GB_SAMSUNG_1Z = 22, // 1z nm. 40% lower power usage. (1z-01).
|
LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 22, // Die-B. (1z-01). 40% lp.
|
||||||
|
|
||||||
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A. (1y-X03).
|
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A. (1y-X03).
|
||||||
LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A. (1y-X03). 2nd gen. 8 banks. 4266Mbps.
|
LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A. (1y-X03).
|
||||||
|
|
||||||
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01).
|
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // Die-F. (1y-01). D9XRR.
|
||||||
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01).
|
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // Die-F. (1y-01). D9XRR.
|
||||||
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01).
|
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // Die-F. (1y-01). D9XRR.
|
||||||
|
|
||||||
LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A.
|
LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A. (1y-X03). 2nd gen.
|
||||||
|
|
||||||
LPDDR4X_UNK0_4GB_HYNIX_1A = 29, // 1a nm. 61% lower power usage. (1a-01).
|
// Old naming scheme: H9HCNNNBKMCLXR-NEE
|
||||||
LPDDR4X_UNK1_4GB_HYNIX_1A = 30, // 1a nm. 61% lower power usage. (1a-01).
|
LPDDR4X_IOWA_4GB_HYNIX_H54G46CYRBX267 = 29, // Die-C. (1a-01). 61% lp.
|
||||||
LPDDR4X_UNK2_4GB_HYNIX_1A = 31, // 1a nm. 61% lower power usage. (1a-01).
|
LPDDR4X_HOAG_4GB_HYNIX_H54G46CYRBX267 = 30, // Die-C. (1a-01). 61% lp.
|
||||||
|
LPDDR4X_AULA_4GB_HYNIX_H54G46CYRBX267 = 31, // Die-C. (1a-01). 61% lp.
|
||||||
|
|
||||||
LPDDR4X_UNK0_4GB_MICRON_1A = 32, // 1a nm. 61% lower power usage. (1a-01).
|
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 32, // Die-B. (1a-01). D8BQM. 61% lp.
|
||||||
LPDDR4X_UNK1_4GB_MICRON_1A = 33, // 1a nm. 61% lower power usage. (1a-01).
|
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D1NP_046_WTB = 33, // Die-B. (1a-01). D8BQM. 61% lp.
|
||||||
LPDDR4X_UNK2_4GB_MICRON_1A = 34, // 1a nm. 61% lower power usage. (1a-01).
|
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 34, // Die-B. (1a-01). D8BQM. 61% lp.
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sdram_codes_mariko
|
enum sdram_codes_mariko
|
||||||
@@ -112,18 +124,18 @@ enum sdram_codes_mariko
|
|||||||
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE = 2, // DRAM IDs: 11, 15.
|
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE = 2, // DRAM IDs: 11, 15.
|
||||||
LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 3, // DRAM IDs: 17, 19, 24.
|
LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 3, // DRAM IDs: 17, 19, 24.
|
||||||
LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 4, // DRAM IDs: 18, 23, 28.
|
LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 4, // DRAM IDs: 18, 23, 28.
|
||||||
LPDDR4X_4GB_SAMSUNG_1Z = 5, // DRAM IDs: 20, 21, 22.
|
LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 5, // DRAM IDs: 20, 21, 22.
|
||||||
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF = 6, // DRAM IDs: 25, 26, 27.
|
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF = 6, // DRAM IDs: 25, 26, 27.
|
||||||
LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 7, // DRAM IDs: 03, 05, 06.
|
LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 7, // DRAM IDs: 03, 05, 06.
|
||||||
|
LPDDR4X_4GB_HYNIX_H54G46CYRBX267 = 8, // DRAM IDs: 29, 30, 31.
|
||||||
LPDDR4X_4GB_HYNIX_1A = 8, // DRAM IDs: 29, 30, 31.
|
LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB = 9, // DRAM IDs: 32, 33, 34.
|
||||||
LPDDR4X_4GB_MICRON_1A = 9, // DRAM IDs: 32, 33, 34.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void sdram_init();
|
void sdram_init();
|
||||||
void *sdram_get_params_patched();
|
void *sdram_get_params_patched();
|
||||||
void *sdram_get_params_t210b01();
|
void *sdram_get_params_t210b01();
|
||||||
void sdram_lp0_save_params(const void *params);
|
void sdram_lp0_save_params(const void *params);
|
||||||
|
void sdram_src_pllc(bool enable);
|
||||||
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx);
|
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2020-2022 CTCaer
|
* Copyright (c) 2020-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -434,9 +434,9 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||||||
.emc_dll_cfg0 = 0x1F13412F,
|
.emc_dll_cfg0 = 0x1F13412F,
|
||||||
.emc_dll_cfg1 = 0x00010014,
|
.emc_dll_cfg1 = 0x00010014,
|
||||||
|
|
||||||
.emc_pmc_scratch1 = 0x4FAFFFFF,
|
.emc_pmc_scratch1 = 0x4FAFFFFF, // APBDEV_PMC_IO_DPD3_REQ.
|
||||||
.emc_pmc_scratch2 = 0x7FFFFFFF,
|
.emc_pmc_scratch2 = 0x7FFFFFFF,
|
||||||
.emc_pmc_scratch3 = 0x4006D70B,
|
.emc_pmc_scratch3 = 0x4006D70B, // APBDEV_PMC_DDR_CNTRL.
|
||||||
|
|
||||||
.emc_pmacro_pad_cfg_ctrl = 0x00020000,
|
.emc_pmacro_pad_cfg_ctrl = 0x00020000,
|
||||||
.emc_pmacro_vttgen_ctrl0 = 0x00030808,
|
.emc_pmacro_vttgen_ctrl0 = 0x00030808,
|
||||||
@@ -489,8 +489,8 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||||||
|
|
||||||
/* DRAM size information */
|
/* DRAM size information */
|
||||||
.mc_emem_adr_cfg = 0x00000001, // 2 Ranks.
|
.mc_emem_adr_cfg = 0x00000001, // 2 Ranks.
|
||||||
.mc_emem_adr_cfg_dev0 = 0x00070302, // Rank 0 Density 512MB.
|
.mc_emem_adr_cfg_dev0 = 0x00070302, // Chip 0 Density 512MB.
|
||||||
.mc_emem_adr_cfg_dev1 = 0x00070302, // Rank 1 Density 512MB.
|
.mc_emem_adr_cfg_dev1 = 0x00070302, // Chip 1 Density 512MB.
|
||||||
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
|
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
|
||||||
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
|
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
|
||||||
.mc_emem_adr_cfg_bank_mask1 = 0x39722800,
|
.mc_emem_adr_cfg_bank_mask1 = 0x39722800,
|
||||||
@@ -499,7 +499,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||||||
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
||||||
* size (in KBytes)
|
* size (in KBytes)
|
||||||
*/
|
*/
|
||||||
.mc_emem_cfg = 0x00001000, // 4GB total density.
|
.mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
|
||||||
|
|
||||||
/* MC arbitration configuration */
|
/* MC arbitration configuration */
|
||||||
.mc_emem_arb_cfg = 0x08000001,
|
.mc_emem_arb_cfg = 0x08000001,
|
||||||
@@ -538,20 +538,36 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||||||
.mc_clken_override = 0x00008000,
|
.mc_clken_override = 0x00008000,
|
||||||
|
|
||||||
.mc_stat_control = 0x00000000,
|
.mc_stat_control = 0x00000000,
|
||||||
|
|
||||||
|
/* VPR carveout configuration */
|
||||||
.mc_video_protect_bom = 0xFFF00000,
|
.mc_video_protect_bom = 0xFFF00000,
|
||||||
.mc_video_protect_bom_adr_hi = 0x00000000,
|
.mc_video_protect_bom_adr_hi = 0x00000000,
|
||||||
.mc_video_protect_size_mb = 0x00000000,
|
.mc_video_protect_size_mb = 0x00000000,
|
||||||
|
|
||||||
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A.
|
// Disable access:
|
||||||
.mc_video_protect_vpr_override = 0xE4BAC343,
|
// AFI (PCIE), BPMP, HC (HOST1x), ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1 (WinT), SDMMC1/2/3. Plus TSEC, NVENC.
|
||||||
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR.
|
// Enable access:
|
||||||
.mc_video_protect_vpr_override1 = 0x00001ED3,
|
// DC, DCB, HDA, VIC.
|
||||||
|
.mc_video_protect_vpr_override = 0xE4FACB43, // Stock/Reset: 0xE4BAC343. HOS new: 0xE4FACB43. + TSEC, NVENC.
|
||||||
|
// Disable access:
|
||||||
|
// SDMMC4, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus TSECB, TSEC1, TSECB1.
|
||||||
|
// Enable access:
|
||||||
|
// GPU, GPUB, NVDEC, NVJPG, NVDEC1.
|
||||||
|
.mc_video_protect_vpr_override1 = 0x0000FED3, // Stock/Reset: 0x00001ED3. HOS new: 0x0000FED3. + TSECB, TSEC1, TSECB1.
|
||||||
|
|
||||||
.mc_video_protect_gpu_override0 = 0x00000000,
|
// VPR CYA. L4T override (set PD, SCC, SKED, L1 as UNTRUSTED).
|
||||||
.mc_video_protect_gpu_override1 = 0x00000000,
|
.mc_video_protect_gpu_override0 = VPR_OVR0_CYA_TRUST_GCC(VPR_TRUST_GRAPHICS) |
|
||||||
|
VPR_OVR0_CYA_TRUST_RASTER(VPR_TRUST_GRAPHICS) |
|
||||||
|
VPR_OVR0_CYA_TRUST_PE(VPR_TRUST_GRAPHICS) |
|
||||||
|
VPR_OVR0_CYA_TRUST_TEX(VPR_TRUST_GRAPHICS) |
|
||||||
|
VPR_OVR0_CYA_TRUST_OVERRIDE, // Stock: 0. HOS: VPR_OVR0_CYA_TRUST_DEFAULT.
|
||||||
|
.mc_video_protect_gpu_override1 = VPR_OVR1_CYA_TRUST_PROP(VPR_TRUST_GRAPHICS), // Stock: 0. HOS: 0.
|
||||||
|
|
||||||
|
/* TZDRAM carveout configuration */
|
||||||
.mc_sec_carveout_bom = 0xFFF00000,
|
.mc_sec_carveout_bom = 0xFFF00000,
|
||||||
.mc_sec_carveout_adr_hi = 0x00000000,
|
.mc_sec_carveout_adr_hi = 0x00000000,
|
||||||
.mc_sec_carveout_size_mb = 0x00000000,
|
.mc_sec_carveout_size_mb = 0x00000000,
|
||||||
|
|
||||||
.mc_video_protect_write_access = 0x00000000,
|
.mc_video_protect_write_access = 0x00000000,
|
||||||
.mc_sec_carveout_protect_write_access = 0x00000000,
|
.mc_sec_carveout_protect_write_access = 0x00000000,
|
||||||
|
|
||||||
@@ -640,59 +656,34 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||||||
/* Specifies data for patched boot rom write */
|
/* Specifies data for patched boot rom write */
|
||||||
.boot_rom_patch_data = 0x00000000,
|
.boot_rom_patch_data = 0x00000000,
|
||||||
|
|
||||||
|
/* CPU FW carveout configuration */
|
||||||
.mc_mts_carveout_bom = 0xFFF00000,
|
.mc_mts_carveout_bom = 0xFFF00000,
|
||||||
.mc_mts_carveout_adr_hi = 0x00000000,
|
.mc_mts_carveout_adr_hi = 0x00000000,
|
||||||
.mc_mts_carveout_size_mb = 0x00000000,
|
.mc_mts_carveout_size_mb = 0x00000000,
|
||||||
.mc_mts_carveout_reg_ctrl = 0x00000000
|
.mc_mts_carveout_reg_ctrl = 0x00000000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DCFG_OFFSET_OF(m) (OFFSET_OF(sdram_params_t210_t, m) / 4)
|
||||||
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210[] = {
|
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210[] = {
|
||||||
// Hynix timing config.
|
// Hynix timing config.
|
||||||
{ 0x0000000D, 0x10C / 4, DRAM_ID(1) }, // emc_r2w.
|
{ 0x0000000D, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_r2w) },
|
||||||
{ 0x00000001, 0x16C / 4, DRAM_ID(1) }, // emc_puterm_extra.
|
{ 0x00000001, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_puterm_extra) },
|
||||||
{ 0x80000000, 0x170 / 4, DRAM_ID(1) }, // emc_puterm_width.
|
{ 0x80000000, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_puterm_width) },
|
||||||
{ 0x00000210, 0x4F4 / 4, DRAM_ID(1) }, // emc_pmacro_data_rx_term_mode.
|
{ 0x00000210, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_pmacro_data_rx_term_mode) },
|
||||||
{ 0x00000005, 0x5C0 / 4, DRAM_ID(1) }, // mc_emem_arb_timing_r2w.
|
{ 0x00000005, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(mc_emem_arb_timing_r2w) },
|
||||||
|
|
||||||
// Samsung 6GB density config.
|
// Samsung 6GB density config.
|
||||||
{ 0x000C0302, 0x56C / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB Rank 0 density.
|
{ 0x000C0302, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev0) }, // 768MB Chip 0 density.
|
||||||
{ 0x000C0302, 0x570 / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB Rank 1 density.
|
{ 0x000C0302, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev1) }, // 768MB Chip 1 density.
|
||||||
{ 0x00001800, 0x584 / 4, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density.
|
{ 0x00001800, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_cfg) }, // 6GB total density. Max 8GB.
|
||||||
|
|
||||||
#ifdef CONFIG_SDRAM_COPPER_SUPPORT
|
// Samsung 8GB density config.
|
||||||
// Copper prototype Samsung/Hynix/Micron timing configs.
|
{ 0x0000003A, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_rfc) },
|
||||||
{ 0x0000003A, 0xEC / 4, DRAM_ID(6) }, // emc_rfc. Auto refresh.
|
{ 0x0000001D, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_rfc_pb) },
|
||||||
{ 0x0000001D, 0xF0 / 4, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh.
|
{ 0x0000003B, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_txsr) },
|
||||||
{ 0x0000000D, 0x10C / 4, DRAM_ID(5) }, // emc_r2w.
|
{ 0x0000003B, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_txsr_dll) },
|
||||||
{ 0x00000001, 0x16C / 4, DRAM_ID(5) }, // emc_puterm_extra.
|
{ 0x00080302, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev0) }, // 1024MB Chip 0 density.
|
||||||
{ 0x80000000, 0x170 / 4, DRAM_ID(5) }, // emc_puterm_width.
|
{ 0x00080302, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev1) }, // 1024MB Chip 1 density.
|
||||||
{ 0x00000012, 0x1B0 / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_rw2pden.
|
{ 0x00002000, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_cfg) }, // 8GB total density. Max 8GB.
|
||||||
{ 0x0000003B, 0x1C0 / 4, DRAM_ID(6) }, // emc_txsr.
|
|
||||||
{ 0x0000003B, 0x1C4 / 4, DRAM_ID(6) }, // emc_txsr_dll.
|
|
||||||
{ 0x00000003, 0x1DC / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_tclkstable.
|
|
||||||
{ 0x00120015, 0x334 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
|
|
||||||
{ 0x00160012, 0x338 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_5.
|
|
||||||
{ 0x00120015, 0x34C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
|
|
||||||
{ 0x00160012, 0x350 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_5.
|
|
||||||
{ 0x002F0032, 0x354 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
|
|
||||||
{ 0x00310032, 0x358 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
|
|
||||||
{ 0x00360034, 0x35C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
|
|
||||||
{ 0x0033002F, 0x360 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3.
|
|
||||||
{ 0x00000006, 0x364 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
|
|
||||||
{ 0x002F0032, 0x36C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
|
|
||||||
{ 0x00310032, 0x370 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
|
|
||||||
{ 0x00360034, 0x374 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
|
|
||||||
{ 0x0033002F, 0x378 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3.
|
|
||||||
{ 0x00000006, 0x37C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
|
|
||||||
{ 0x00150015, 0x3A4 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_0.
|
|
||||||
{ 0x00120012, 0x3AC / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_2.
|
|
||||||
{ 0x00160016, 0x3B0 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_3.
|
|
||||||
{ 0x00000015, 0x3B4 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_4.
|
|
||||||
{ 0x00000012, 0x49C / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft2.
|
|
||||||
{ 0x00000012, 0x4A0 / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft3.
|
|
||||||
{ 0x00000210, 0x4F4 / 4, DRAM_ID(5) }, // emc_pmacro_data_rx_term_mode.
|
|
||||||
{ 0x00000005, 0x5C0 / 4, DRAM_ID(5) }, // mc_emem_arb_timing_r2w.
|
|
||||||
{ 0x00000007, 0x5C8 / 4, DRAM_ID(6) }, // mc_emem_arb_timing_rfcpb. Bank refresh.
|
|
||||||
{ 0x72A30504, 0x5D4 / 4, DRAM_ID(6) }, // mc_emem_arb_misc0.
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
#undef DCFG_OFFSET_OF
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020-2022 CTCaer
|
* Copyright (c) 2020-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -542,8 +542,8 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||||||
|
|
||||||
/* DRAM size information */
|
/* DRAM size information */
|
||||||
.mc_emem_adr_cfg = 0x00000000, // 1 Rank.
|
.mc_emem_adr_cfg = 0x00000000, // 1 Rank.
|
||||||
.mc_emem_adr_cfg_dev0 = 0x00080302, // Rank 0 Density 1024MB.
|
.mc_emem_adr_cfg_dev0 = 0x00080302, // Chip 0 Density 1024MB.
|
||||||
.mc_emem_adr_cfg_dev1 = 0x00080302, // Rank 1 Density 1024MB.
|
.mc_emem_adr_cfg_dev1 = 0x00080302, // Chip 1 Density 1024MB.
|
||||||
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
|
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
|
||||||
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
|
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
|
||||||
.mc_emem_adr_cfg_bank_mask1 = 0x39722800,
|
.mc_emem_adr_cfg_bank_mask1 = 0x39722800,
|
||||||
@@ -552,7 +552,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||||||
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
||||||
* size (in KBytes)
|
* size (in KBytes)
|
||||||
*/
|
*/
|
||||||
.mc_emem_cfg = 0x00001000, // 4GB total density.
|
.mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
|
||||||
|
|
||||||
/* MC arbitration configuration */
|
/* MC arbitration configuration */
|
||||||
.mc_emem_arb_cfg = 0x08000001,
|
.mc_emem_arb_cfg = 0x08000001,
|
||||||
@@ -595,17 +595,30 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||||||
.mc_video_protect_bom_adr_hi = 0x00000000,
|
.mc_video_protect_bom_adr_hi = 0x00000000,
|
||||||
.mc_video_protect_size_mb = 0x00000000,
|
.mc_video_protect_size_mb = 0x00000000,
|
||||||
|
|
||||||
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A.
|
// Disable access:
|
||||||
.mc_video_protect_vpr_override = 0xE4BAC343,
|
// AFI (PCIE), BPMP, HC (HOST1x), ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1 (WinT), SDMMC1/2/3. Plus TSEC, NVENC.
|
||||||
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus SE2, SE2B.
|
// Enable access:
|
||||||
.mc_video_protect_vpr_override1 = 0x06001ED3,
|
// DC, DCB, HDA, VIC.
|
||||||
|
.mc_video_protect_vpr_override = 0xE4FACB43, // Stock/Reset: 0xE4BAC343. HOS new: 0xE4FACB43. + TSEC, NVENC.
|
||||||
|
// Disable access:
|
||||||
|
// SDMMC4, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR, SE2, SE2B. Plus TSECB, TSEC1, TSECB1.
|
||||||
|
// Enable access:
|
||||||
|
// GPU, GPUB, NVDEC, NVJPG, NVDEC1.
|
||||||
|
.mc_video_protect_vpr_override1 = 0x0600FED3, // Reset: 0x06001ED3. HOS new: 0x0600FED3. + TSECB, TSEC1, TSECB1.
|
||||||
|
|
||||||
.mc_video_protect_gpu_override0 = 0x00000000,
|
// VPR CYA. L4T override (set PD, SCC, SKED, L1 as UNTRUSTED).
|
||||||
.mc_video_protect_gpu_override1 = 0x00000000,
|
.mc_video_protect_gpu_override0 = VPR_OVR0_CYA_TRUST_GCC(VPR_TRUST_GRAPHICS) |
|
||||||
|
VPR_OVR0_CYA_TRUST_RASTER(VPR_TRUST_GRAPHICS) |
|
||||||
|
VPR_OVR0_CYA_TRUST_PE(VPR_TRUST_GRAPHICS) |
|
||||||
|
VPR_OVR0_CYA_TRUST_TEX(VPR_TRUST_GRAPHICS) |
|
||||||
|
VPR_OVR0_CYA_TRUST_OVERRIDE, // Stock: 0. HOS: VPR_OVR0_CYA_TRUST_DEFAULT.
|
||||||
|
.mc_video_protect_gpu_override1 = VPR_OVR1_CYA_TRUST_PROP(VPR_TRUST_GRAPHICS), // Stock: 0. HOS: 0.
|
||||||
|
|
||||||
|
/* TZDRAM carveout configuration */
|
||||||
.mc_sec_carveout_bom = 0xFFF00000,
|
.mc_sec_carveout_bom = 0xFFF00000,
|
||||||
.mc_sec_carveout_adr_hi = 0x00000000,
|
.mc_sec_carveout_adr_hi = 0x00000000,
|
||||||
.mc_sec_carveout_size_mb = 0x00000000,
|
.mc_sec_carveout_size_mb = 0x00000000,
|
||||||
|
|
||||||
.mc_video_protect_write_access = 0x00000000,
|
.mc_video_protect_write_access = 0x00000000,
|
||||||
.mc_sec_carveout_protect_write_access = 0x00000000,
|
.mc_sec_carveout_protect_write_access = 0x00000000,
|
||||||
|
|
||||||
@@ -708,100 +721,104 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||||||
|
|
||||||
#define DRAM_CC_LPDDR4X_PMACRO_IB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ))
|
#define DRAM_CC_LPDDR4X_PMACRO_IB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ))
|
||||||
|
|
||||||
#define DRAM_CC_LPDDR4X_AUTOCAL_VPR (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
|
#define DRAM_CC_LPDDR4X_PUPD_VPR (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
|
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
|
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
|
||||||
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
|
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \
|
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \
|
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z))
|
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
|
||||||
|
|
||||||
#define DRAM_CC_LPDDR4X_DYN_SELF_CTRL (DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
|
#define DRAM_CC_LPDDR4X_DSR (DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
|
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \
|
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \
|
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z))
|
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
|
||||||
|
|
||||||
#define DRAM_CC_LPDDR4X_QUSE_EINPUT (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
|
#define DRAM_CC_LPDDR4X_QUSE (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
|
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
|
||||||
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
|
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \
|
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \
|
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z))
|
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
|
||||||
|
|
||||||
#define DRAM_CC_LPDDR4X_FAW (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
|
#define DRAM_CC_LPDDR4X_FAW (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_MICRON_1A))
|
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB))
|
||||||
|
|
||||||
#define DRAM_CC_LPDDR4X_VPR (DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
#define DRAM_CC_LPDDR4X_VPR (DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \
|
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \
|
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
|
||||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z))
|
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
|
||||||
|
|
||||||
#define DRAM_CC_LPDDR4X_SAMSUNG_8GB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
|
#define DRAM_CC_LPDDR4X_8GB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
|
||||||
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL))
|
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL))
|
||||||
|
|
||||||
|
#define DCFG_OFFSET_OF(m) (OFFSET_OF(sdram_params_t210b01_t, m) / 4)
|
||||||
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210b01[] = {
|
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210b01[] = {
|
||||||
|
|
||||||
// Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ Die-M for SDEV Iowa and Hoag.
|
// Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ Die-M for SDEV Iowa and Hoag.
|
||||||
{ 0x35353535, 0x350 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_vref_dq_0.
|
{ 0x35353535, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_vref_dq_0) },
|
||||||
{ 0x35353535, 0x354 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_vref_dq_1.
|
{ 0x35353535, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_vref_dq_1) },
|
||||||
{ 0x00100010, 0x3FC / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
|
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_0) },
|
||||||
{ 0x00100010, 0x400 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
|
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_1) },
|
||||||
{ 0x00100010, 0x404 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
|
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_2) },
|
||||||
{ 0x00100010, 0x408 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
|
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_3) },
|
||||||
{ 0x00100010, 0x40C / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
|
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_0) },
|
||||||
{ 0x00100010, 0x410 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
|
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_1) },
|
||||||
{ 0x00100010, 0x414 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
|
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_2) },
|
||||||
{ 0x00100010, 0x418 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
|
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_3) },
|
||||||
|
|
||||||
/*! Shared patched between DRAM Codes. */
|
/*! Shared patched between DRAM Codes. */
|
||||||
{ 0x05500000, 0x0D4 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // emc_auto_cal_config2.
|
{ 0x05500000, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(emc_auto_cal_config2) },
|
||||||
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // emc_auto_cal_vref_sel0.
|
{ 0xC9AFBCBC, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(emc_auto_cal_vref_sel0) },
|
||||||
{ 0x2A800000, 0x6DC / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // mc_video_protect_gpu_override0.
|
|
||||||
{ 0x00000002, 0x6E0 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // mc_video_protect_gpu_override1.
|
|
||||||
//!TODO Find out what mc_video_protect_gpu_override0 and mc_video_protect_gpu_override1 new bits are.
|
|
||||||
|
|
||||||
{ 0x88161414, 0x2E0 / 4, DRAM_CC_LPDDR4X_DYN_SELF_CTRL }, // emc_mrw14.
|
// Moved to default config.
|
||||||
{ 0x80000713, 0x32C / 4, DRAM_CC_LPDDR4X_DYN_SELF_CTRL }, // emc_dyn_self_ref_control.
|
// { 0x2A800000, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(mc_video_protect_gpu_override0) },
|
||||||
|
// { 0x00000002, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(mc_video_protect_gpu_override1) },
|
||||||
|
|
||||||
{ 0x00000006, 0x1CC / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_quse.
|
{ 0x88161414, DRAM_CC_LPDDR4X_DSR, DCFG_OFFSET_OF(emc_mrw14) },
|
||||||
{ 0x00000005, 0x1D0 / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_quse_width.
|
{ 0x80000713, DRAM_CC_LPDDR4X_DSR, DCFG_OFFSET_OF(emc_dyn_self_ref_control) },
|
||||||
{ 0x00000003, 0x1DC / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_einput.
|
|
||||||
{ 0x0000000C, 0x1E0 / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_einput_duration.
|
|
||||||
|
|
||||||
{ 0x00000008, 0x24C / 4, DRAM_CC_LPDDR4X_FAW }, // emc_tfaw.
|
{ 0x00000006, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_quse) },
|
||||||
{ 0x00000001, 0x670 / 4, DRAM_CC_LPDDR4X_FAW }, // mc_emem_arb_timing_faw.
|
{ 0x00000005, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_quse_width) },
|
||||||
|
{ 0x00000003, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_einput) },
|
||||||
|
{ 0x0000000C, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_einput_duration) },
|
||||||
|
|
||||||
{ 0xE4FACB43, 0x6D4 / 4, DRAM_CC_LPDDR4X_VPR }, // mc_video_protect_vpr_override. + TSEC, NVENC.
|
{ 0x00000008, DRAM_CC_LPDDR4X_FAW, DCFG_OFFSET_OF(emc_tfaw) },
|
||||||
{ 0x0600FED3, 0x6D8 / 4, DRAM_CC_LPDDR4X_VPR }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1.
|
{ 0x00000001, DRAM_CC_LPDDR4X_FAW, DCFG_OFFSET_OF(mc_emem_arb_timing_faw) },
|
||||||
|
|
||||||
{ 0x00000001, 0x134 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_adr_cfg. 2 Ranks.
|
// Moved to default config.
|
||||||
{ 0x08010004, 0x2B8 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw1.
|
// { 0xE4FACB43, DRAM_CC_LPDDR4X_VPR, DCFG_OFFSET_OF(mc_video_protect_vpr_override) }, // + TSEC, NVENC.
|
||||||
{ 0x08020000, 0x2BC / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw2.
|
// { 0x0600FED3, DRAM_CC_LPDDR4X_VPR, DCFG_OFFSET_OF(mc_video_protect_vpr_override1) }, // + TSECB, TSEC1, TSECB1.
|
||||||
{ 0x080D0000, 0x2C0 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw3.
|
|
||||||
{ 0x08033131, 0x2C8 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw6.
|
{ 0x00000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_adr_cfg) }, // 2 Ranks.
|
||||||
{ 0x080B0000, 0x2CC / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw8.
|
{ 0x08010004, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw1) },
|
||||||
{ 0x0C0E5D5D, 0x2D0 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw9.
|
{ 0x08020000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw2) },
|
||||||
{ 0x080C5D5D, 0x2D4 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw10.
|
{ 0x080D0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw3) },
|
||||||
{ 0x0C0D0808, 0x2D8 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw12.
|
{ 0x08033131, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw6) },
|
||||||
{ 0x0C0D0000, 0x2DC / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw13.
|
{ 0x080B0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw8) },
|
||||||
{ 0x08161414, 0x2E0 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw14.
|
{ 0x0C0E5D5D, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw9) },
|
||||||
{ 0x08010004, 0x2E4 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw_extra.
|
{ 0x080C5D5D, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw10) },
|
||||||
{ 0x00000000, 0x340 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_dev_select. Both devices.
|
{ 0x0C0D0808, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw12) },
|
||||||
{ 0x0051004F, 0x450 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_zcal_mrw_cmd.
|
{ 0x0C0D0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw13) },
|
||||||
{ 0x40000001, 0x45C / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_zcal_init_dev1.
|
{ 0x08161414, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw14) },
|
||||||
{ 0x00000000, 0x594 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_pmacro_tx_pwrd4.
|
{ 0x08010004, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw_extra) },
|
||||||
{ 0x00001000, 0x598 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_pmacro_tx_pwrd5.
|
{ 0x00000000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_dev_select) }, // Both devices.
|
||||||
{ 0x00000001, 0x630 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_adr_cfg. 2 Ranks.
|
{ 0x0051004F, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_zcal_mrw_cmd) },
|
||||||
{ 0x00002000, 0x64C / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_cfg. 8GB total density.
|
{ 0x40000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_zcal_init_dev1) },
|
||||||
{ 0x00000002, 0x680 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_arb_timing_r2r.
|
{ 0x00000000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_pmacro_tx_pwrd4) },
|
||||||
{ 0x02020001, 0x694 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_arb_da_turns.
|
{ 0x00001000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_pmacro_tx_pwrd5) },
|
||||||
|
{ 0x00000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_adr_cfg) }, // 2 Ranks.
|
||||||
|
{ 0x00002000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_cfg) }, // 8GB total density. Max 8GB.
|
||||||
|
{ 0x00000002, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_arb_timing_r2r) },
|
||||||
|
{ 0x02020001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_arb_da_turns) },
|
||||||
};
|
};
|
||||||
|
#undef DCFG_OFFSET_OF
|
||||||
|
|||||||
@@ -225,7 +225,6 @@ typedef struct _sdram_params_t210b01_t
|
|||||||
u32 emc_r2p;
|
u32 emc_r2p;
|
||||||
/* Specifies the value for EMC_W2P */
|
/* Specifies the value for EMC_W2P */
|
||||||
u32 emc_w2p;
|
u32 emc_w2p;
|
||||||
/* Specifies the value for EMC_RD_RCD */
|
|
||||||
|
|
||||||
u32 emc_tppd;
|
u32 emc_tppd;
|
||||||
u32 emc_trtm;
|
u32 emc_trtm;
|
||||||
@@ -235,6 +234,7 @@ typedef struct _sdram_params_t210b01_t
|
|||||||
u32 emc_tr2ref;
|
u32 emc_tr2ref;
|
||||||
u32 emc_ccdmw;
|
u32 emc_ccdmw;
|
||||||
|
|
||||||
|
/* Specifies the value for EMC_RD_RCD */
|
||||||
u32 emc_rd_rcd;
|
u32 emc_rd_rcd;
|
||||||
/* Specifies the value for EMC_WR_RCD */
|
/* Specifies the value for EMC_WR_RCD */
|
||||||
u32 emc_wr_rcd;
|
u32 emc_wr_rcd;
|
||||||
|
|||||||
248
bdk/mem/smmu.c
248
bdk/mem/smmu.c
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018 balika011
|
* Copyright (c) 2018 balika011
|
||||||
* Copyright (c) 2018-2022 CTCaer
|
* Copyright (c) 2018-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -18,156 +18,254 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <soc/bpmp.h>
|
||||||
#include <soc/ccplex.h>
|
#include <soc/ccplex.h>
|
||||||
#include <soc/timer.h>
|
#include <soc/timer.h>
|
||||||
#include <soc/t210.h>
|
#include <soc/t210.h>
|
||||||
#include <mem/mc_t210.h>
|
#include <mem/mc_t210.h>
|
||||||
#include <mem/smmu.h>
|
#include <mem/smmu.h>
|
||||||
#include <utils/aarch64_util.h>
|
#include <memory_map.h>
|
||||||
|
|
||||||
bool smmu_used = false;
|
/*! SMMU register defines */
|
||||||
u8 *_pageheap = (u8 *)SMMU_HEAP_ADDR;
|
#define SMMU_ASID(asid) (((asid) << 24u) | ((asid) << 16u) | ((asid) << 8u) | (asid))
|
||||||
|
#define SMMU_ENABLE BIT(31)
|
||||||
|
#define SMMU_TLB_ACTIVE_LINES(l) ((l) << 0u)
|
||||||
|
#define SMMU_TLB_RR_ARBITRATION BIT(28)
|
||||||
|
#define SMMU_TLB_HIT_UNDER_MISS BIT(29)
|
||||||
|
#define SMMU_TLB_STATS_ENABLE BIT(31)
|
||||||
|
#define SMUU_PTC_INDEX_MAP(m) ((m) << 0u)
|
||||||
|
#define SMUU_PTC_LINE_MASK(m) ((m) << 8u)
|
||||||
|
#define SMUU_PTC_REQ_LIMIT(l) ((l) << 24u)
|
||||||
|
#define SMUU_PTC_CACHE_ENABLE BIT(29)
|
||||||
|
#define SMUU_PTC_STATS_ENABLE BIT(31)
|
||||||
|
|
||||||
//Enabling SMMU requires a TZ secure write: MC(MC_SMMU_CONFIG) = 1;
|
/*! Page table defines */
|
||||||
u8 smmu_payload[] __attribute__((aligned(16))) = {
|
#define SMMU_4MB_REGION 0
|
||||||
0x41, 0x01, 0x00, 0x58, // 0x00: LDR X1, =0x70019010
|
#define SMMU_PAGE_TABLE 1
|
||||||
|
#define SMMU_PDIR_COUNT 1024
|
||||||
|
#define SMMU_PTBL_COUNT 1024
|
||||||
|
#define SMMU_PAGE_SHIFT 12u
|
||||||
|
#define SMMU_PTN_SHIFT SMMU_PAGE_SHIFT
|
||||||
|
#define SMMU_PDN_SHIFT 22u
|
||||||
|
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> SMMU_PAGE_SHIFT)
|
||||||
|
#define SMMU_ADDR_TO_PTN(addr) ((addr) >> SMMU_PTN_SHIFT)
|
||||||
|
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> SMMU_PDN_SHIFT)
|
||||||
|
#define SMMU_PTN_TO_ADDR(ptn) ((ptn) << SMMU_PTN_SHIFT)
|
||||||
|
#define SMMU_PDN_TO_ADDR(pdn) ((pdn) << SMMU_PDN_SHIFT)
|
||||||
|
#define SMMU_PTB(page, attr) (((attr) << 29u) | ((page) >> SMMU_PAGE_SHIFT))
|
||||||
|
|
||||||
|
#define SMMU_PAYLOAD_EN_SHIFT 4
|
||||||
|
#define SMMU_PAYLOAD_EN_SET 0x20
|
||||||
|
#define SMMU_PAYLOAD_EN_UNSET 0x00
|
||||||
|
|
||||||
|
// Enabling SMMU requires a TZ (EL3) secure write. MC(MC_SMMU_CONFIG) = 1;
|
||||||
|
static u8 smmu_enable_payload[] = {
|
||||||
|
0xC1, 0x00, 0x00, 0x18, // 0x00: LDR W1, =0x70019010
|
||||||
0x20, 0x00, 0x80, 0xD2, // 0x04: MOV X0, #0x1
|
0x20, 0x00, 0x80, 0xD2, // 0x04: MOV X0, #0x1
|
||||||
0x20, 0x00, 0x00, 0xB9, // 0x08: STR W0, [X1]
|
0x20, 0x00, 0x00, 0xB9, // 0x08: STR W0, [X1]
|
||||||
0x1F, 0x71, 0x08, 0xD5, // 0x0C: IC IALLUIS
|
0x1F, 0x71, 0x08, 0xD5, // 0x0C: IC IALLUIS
|
||||||
0x9F, 0x3B, 0x03, 0xD5, // 0x10: DSB ISH
|
0x9F, 0x3B, 0x03, 0xD5, // 0x10: DSB ISH
|
||||||
0xFE, 0xFF, 0xFF, 0x17, // 0x14: B loop
|
0xFE, 0xFF, 0xFF, 0x17, // 0x14: B loop
|
||||||
0x00, 0x00, 0x80, 0xD2, // 0x18: MOV X0, #0x0
|
0x10, 0x90, 0x01, 0x70, // 0x18: MC_SMMU_CONFIG
|
||||||
0x20, 0x00, 0x00, 0xB9, // 0x1C: STR W0, [X1]
|
|
||||||
0x80, 0x00, 0x00, 0x58, // 0x20: LDR X0, =0x4002B000
|
|
||||||
0x00, 0x00, 0x1F, 0xD6, // 0x28: BR X0
|
|
||||||
0x10, 0x90, 0x01, 0x70, // 0x28: MC_SMMU_CONFIG
|
|
||||||
0x00, 0x00, 0x00, 0x00, // 0x2C:
|
|
||||||
0x00, 0x00, 0x00, 0x00, // 0x30: secmon address
|
|
||||||
0x00, 0x00, 0x00, 0x00 // 0x34:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void *page_alloc(u32 num)
|
static void *smmu_heap = (void *)SMMU_HEAP_ADDR;
|
||||||
|
static bool smmu_enabled = false;
|
||||||
|
|
||||||
|
void *smmu_page_zalloc(u32 num)
|
||||||
{
|
{
|
||||||
u8 *res = _pageheap;
|
void *page = smmu_heap;
|
||||||
_pageheap += SZ_PAGE * num;
|
memset(page, 0, SZ_PAGE * num);
|
||||||
memset(res, 0, SZ_PAGE * num);
|
|
||||||
return res;
|
smmu_heap += SZ_PAGE * num;
|
||||||
|
|
||||||
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *smmu_alloc_pdir()
|
static pde_t *_smmu_pdir_alloc()
|
||||||
{
|
{
|
||||||
u32 *pdir = (u32 *)page_alloc(1);
|
pde_t *pdir = (pde_t *)smmu_page_zalloc(1);
|
||||||
for (int pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
|
|
||||||
pdir[pdn] = _PDE_VACANT(pdn);
|
// Initialize pdes with no permissions.
|
||||||
|
for (u32 pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
|
||||||
|
pdir[pdn].huge.page = pdn;
|
||||||
|
|
||||||
return pdir;
|
return pdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smmu_flush_regs()
|
static void _smmu_flush_regs()
|
||||||
{
|
{
|
||||||
(void)MC(MC_SMMU_PTB_DATA);
|
(void)MC(MC_SMMU_PTB_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void smmu_flush_all()
|
void smmu_flush_all()
|
||||||
{
|
{
|
||||||
|
// Flush the entire page table cache.
|
||||||
MC(MC_SMMU_PTC_FLUSH) = 0;
|
MC(MC_SMMU_PTC_FLUSH) = 0;
|
||||||
smmu_flush_regs();
|
_smmu_flush_regs();
|
||||||
|
|
||||||
|
// Flush the entire table.
|
||||||
MC(MC_SMMU_TLB_FLUSH) = 0;
|
MC(MC_SMMU_TLB_FLUSH) = 0;
|
||||||
smmu_flush_regs();
|
_smmu_flush_regs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void smmu_init(u32 secmon_base)
|
void smmu_init()
|
||||||
{
|
{
|
||||||
MC(MC_SMMU_PTB_ASID) = 0;
|
MC(MC_SMMU_PTB_ASID) = 0;
|
||||||
MC(MC_SMMU_PTB_DATA) = 0;
|
MC(MC_SMMU_PTB_DATA) = 0;
|
||||||
MC(MC_SMMU_TLB_CONFIG) = 0x30000030;
|
MC(MC_SMMU_TLB_CONFIG) = SMMU_TLB_HIT_UNDER_MISS | SMMU_TLB_RR_ARBITRATION | SMMU_TLB_ACTIVE_LINES(48);
|
||||||
MC(MC_SMMU_PTC_CONFIG) = 0x28000F3F;
|
MC(MC_SMMU_PTC_CONFIG) = SMUU_PTC_CACHE_ENABLE | SMUU_PTC_REQ_LIMIT(8) | SMUU_PTC_LINE_MASK(0xF) | SMUU_PTC_INDEX_MAP(0x3F);
|
||||||
MC(MC_SMMU_PTC_FLUSH) = 0;
|
MC(MC_SMMU_PTC_FLUSH) = 0;
|
||||||
MC(MC_SMMU_TLB_FLUSH) = 0;
|
MC(MC_SMMU_TLB_FLUSH) = 0;
|
||||||
|
|
||||||
// Set the secmon address
|
|
||||||
*(u32 *)(smmu_payload + 0x30) = secmon_base;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void smmu_enable()
|
void smmu_enable()
|
||||||
{
|
{
|
||||||
if (smmu_used)
|
if (smmu_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ccplex_boot_cpu0((u32)smmu_payload);
|
// Launch payload on CCPLEX in order to set SMMU enable bit.
|
||||||
smmu_used = true;
|
ccplex_boot_cpu0((u32)smmu_enable_payload, false);
|
||||||
msleep(150);
|
msleep(100);
|
||||||
|
ccplex_powergate_cpu0();
|
||||||
|
|
||||||
smmu_flush_all();
|
smmu_flush_all();
|
||||||
|
|
||||||
|
smmu_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool smmu_is_used()
|
void smmu_disable()
|
||||||
{
|
{
|
||||||
return smmu_used;
|
if (!smmu_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Set payload to disable SMMU.
|
||||||
|
smmu_enable_payload[SMMU_PAYLOAD_EN_SHIFT] = SMMU_PAYLOAD_EN_UNSET;
|
||||||
|
|
||||||
|
smmu_flush_all();
|
||||||
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||||
|
|
||||||
|
// Launch payload on CCPLEX in order to set SMMU enable bit.
|
||||||
|
ccplex_boot_cpu0((u32)smmu_enable_payload, false);
|
||||||
|
msleep(100);
|
||||||
|
ccplex_powergate_cpu0();
|
||||||
|
|
||||||
|
smmu_flush_all();
|
||||||
|
|
||||||
|
// Restore payload to SMMU enable.
|
||||||
|
smmu_enable_payload[SMMU_PAYLOAD_EN_SHIFT] = SMMU_PAYLOAD_EN_SET;
|
||||||
|
|
||||||
|
smmu_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smmu_exit()
|
void smmu_reset_heap()
|
||||||
{
|
{
|
||||||
*(u32 *)(smmu_payload + 0x14) = _NOP();
|
smmu_heap = (void *)SMMU_HEAP_ADDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *smmu_init_domain4(u32 dev_base, u32 asid)
|
void *smmu_init_domain(u32 dev_base, u32 asid)
|
||||||
{
|
{
|
||||||
u32 *pdir = smmu_alloc_pdir();
|
void *ptb = _smmu_pdir_alloc();
|
||||||
|
|
||||||
MC(MC_SMMU_PTB_ASID) = asid;
|
MC(MC_SMMU_PTB_ASID) = asid;
|
||||||
MC(MC_SMMU_PTB_DATA) = SMMU_MK_PDIR((u32)pdir, _PDIR_ATTR);
|
MC(MC_SMMU_PTB_DATA) = SMMU_PTB((u32)ptb, SMMU_ATTR_ALL);
|
||||||
smmu_flush_regs();
|
_smmu_flush_regs();
|
||||||
|
|
||||||
MC(dev_base) = 0x80000000 | (asid << 24) | (asid << 16) | (asid << 8) | (asid);
|
// Use the same macro for both quad and single domains. Reserved bits are not set anyway.
|
||||||
smmu_flush_regs();
|
MC(dev_base) = SMMU_ENABLE | SMMU_ASID(asid);
|
||||||
|
_smmu_flush_regs();
|
||||||
|
|
||||||
return pdir;
|
return ptb;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *smmu_get_pte(u32 *pdir, u32 iova)
|
void smmu_deinit_domain(u32 dev_base, u32 asid)
|
||||||
{
|
{
|
||||||
u32 ptn = SMMU_ADDR_TO_PFN(iova);
|
MC(MC_SMMU_PTB_ASID) = asid;
|
||||||
u32 pdn = SMMU_ADDR_TO_PDN(iova);
|
MC(MC_SMMU_PTB_DATA) = 0;
|
||||||
u32 *ptbl;
|
MC(dev_base) = 0;
|
||||||
|
_smmu_flush_regs();
|
||||||
|
}
|
||||||
|
|
||||||
if (pdir[pdn] != _PDE_VACANT(pdn))
|
void smmu_domain_bypass(u32 dev_base, bool bypass)
|
||||||
ptbl = (u32 *)((pdir[pdn] & SMMU_PFN_MASK) << SMMU_PDIR_SHIFT);
|
{
|
||||||
|
if (bypass)
|
||||||
|
{
|
||||||
|
smmu_flush_all();
|
||||||
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||||
|
MC(dev_base) &= ~SMMU_ENABLE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ptbl = (u32 *)page_alloc(1);
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||||
|
MC(dev_base) |= SMMU_ENABLE;
|
||||||
|
smmu_flush_all();
|
||||||
|
}
|
||||||
|
_smmu_flush_regs();
|
||||||
|
}
|
||||||
|
|
||||||
|
static pte_t *_smmu_get_pte(pde_t *pdir, u32 iova)
|
||||||
|
{
|
||||||
|
u32 pdn = SMMU_ADDR_TO_PDN(iova);
|
||||||
|
pte_t *ptbl;
|
||||||
|
|
||||||
|
// Get 4MB page table or initialize one.
|
||||||
|
if (pdir[pdn].tbl.attr)
|
||||||
|
ptbl = (pte_t *)(SMMU_PTN_TO_ADDR(pdir[pdn].tbl.table));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Allocate page table.
|
||||||
|
ptbl = (pte_t *)smmu_page_zalloc(1);
|
||||||
|
|
||||||
|
// Get address.
|
||||||
u32 addr = SMMU_PDN_TO_ADDR(pdn);
|
u32 addr = SMMU_PDN_TO_ADDR(pdn);
|
||||||
for (int pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SMMU_PAGE_SIZE)
|
|
||||||
ptbl[pn] = _PTE_VACANT(addr);
|
// Initialize page table with no permissions.
|
||||||
pdir[pdn] = SMMU_MK_PDE((u32)ptbl, _PDE_ATTR | _PDE_NEXT);
|
for (u32 pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SZ_PAGE)
|
||||||
|
ptbl[pn].page = SMMU_ADDR_TO_PFN(addr);
|
||||||
|
|
||||||
|
// Set page table to the page directory.
|
||||||
|
pdir[pdn].tbl.table = SMMU_ADDR_TO_PTN((u32)ptbl);
|
||||||
|
pdir[pdn].tbl.next = SMMU_PAGE_TABLE;
|
||||||
|
pdir[pdn].tbl.attr = SMMU_ATTR_ALL;
|
||||||
|
|
||||||
smmu_flush_all();
|
smmu_flush_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ptbl[ptn % SMMU_PTBL_COUNT];
|
return &ptbl[SMMU_ADDR_TO_PTN(iova) % SMMU_PTBL_COUNT];
|
||||||
}
|
}
|
||||||
|
|
||||||
void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr)
|
void smmu_map(void *ptb, u32 iova, u64 iopa, u32 pages, u32 attr)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < cnt; i++)
|
// Map pages to page table entries. VA/PA should be aligned to 4KB.
|
||||||
|
for (u32 i = 0; i < pages; i++)
|
||||||
{
|
{
|
||||||
u32 *pte = smmu_get_pte(pdir, addr);
|
pte_t *pte = _smmu_get_pte((pde_t *)ptb, iova);
|
||||||
*pte = SMMU_ADDR_TO_PFN(page) | attr;
|
|
||||||
addr += SZ_PAGE;
|
pte->page = SMMU_ADDR_TO_PFN(iopa);
|
||||||
page += SZ_PAGE;
|
pte->attr = attr;
|
||||||
|
|
||||||
|
iova += SZ_PAGE;
|
||||||
|
iopa += SZ_PAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
smmu_flush_all();
|
smmu_flush_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *smmu_init_for_tsec()
|
void smmu_map_huge(void *ptb, u32 iova, u64 iopa, u32 regions, u32 attr)
|
||||||
{
|
{
|
||||||
return smmu_init_domain4(MC_SMMU_TSEC_ASID, 1);
|
pde_t *pdir = (pde_t *)ptb;
|
||||||
}
|
|
||||||
|
|
||||||
void smmu_deinit_for_tsec()
|
// Map 4MB regions to page directory entries. VA/PA should be aligned to 4MB.
|
||||||
{
|
for (u32 i = 0; i < regions; i++)
|
||||||
MC(MC_SMMU_PTB_ASID) = 1;
|
{
|
||||||
MC(MC_SMMU_PTB_DATA) = 0;
|
u32 pdn = SMMU_ADDR_TO_PDN(iova);
|
||||||
MC(MC_SMMU_TSEC_ASID) = 0;
|
pdir[pdn].huge.page = SMMU_ADDR_TO_PDN(iopa);
|
||||||
smmu_flush_regs();
|
pdir[pdn].huge.next = SMMU_4MB_REGION;
|
||||||
}
|
pdir[pdn].huge.attr = attr;
|
||||||
|
|
||||||
|
iova += SZ_4M;
|
||||||
|
iopa += SZ_4M;
|
||||||
|
}
|
||||||
|
|
||||||
|
smmu_flush_all();
|
||||||
|
}
|
||||||
|
|||||||
111
bdk/mem/smmu.h
111
bdk/mem/smmu.h
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -14,70 +15,58 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
|
|
||||||
#define SMMU_HEAP_ADDR 0xA0000000
|
|
||||||
|
|
||||||
#define MC_INTSTATUS 0x0
|
|
||||||
#define MC_INTMASK 0x4
|
|
||||||
#define MC_ERR_STATUS 0x8
|
|
||||||
#define MC_ERR_ADR 0xc
|
|
||||||
#define MC_SMMU_CONFIG 0x10
|
|
||||||
#define MC_SMMU_TLB_CONFIG 0x14
|
|
||||||
#define MC_SMMU_PTC_CONFIG 0x18
|
|
||||||
#define MC_SMMU_PTB_ASID 0x1c
|
|
||||||
#define MC_SMMU_PTB_DATA 0x20
|
|
||||||
#define MC_SMMU_TLB_FLUSH 0x30
|
|
||||||
#define MC_SMMU_PTC_FLUSH 0x34
|
|
||||||
#define MC_SMMU_ASID_SECURITY 0x38
|
|
||||||
#define MC_SMMU_AVPC_ASID 0x23C
|
#define MC_SMMU_AVPC_ASID 0x23C
|
||||||
#define MC_SMMU_TSEC_ASID 0x294
|
#define MC_SMMU_TSEC_ASID 0x294
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
|
|
||||||
|
|
||||||
#define SMMU_PDE_NEXT_SHIFT 28
|
#define SMMU_NS BIT(0)
|
||||||
#define MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT 29
|
#define SMMU_WRITE BIT(1)
|
||||||
#define MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT 30
|
#define SMMU_READ BIT(2)
|
||||||
#define MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT 31
|
#define SMMU_ATTR_ALL (SMMU_READ | SMMU_WRITE | SMMU_NS)
|
||||||
#define SMMU_PAGE_SHIFT 12
|
|
||||||
#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT)
|
|
||||||
#define SMMU_PDIR_COUNT 1024
|
|
||||||
#define SMMU_PDIR_SIZE (sizeof(u32) * SMMU_PDIR_COUNT)
|
|
||||||
#define SMMU_PTBL_COUNT 1024
|
|
||||||
#define SMMU_PTBL_SIZE (sizeof(u32) * SMMU_PTBL_COUNT)
|
|
||||||
#define SMMU_PDIR_SHIFT 12
|
|
||||||
#define SMMU_PDE_SHIFT 12
|
|
||||||
#define SMMU_PTE_SHIFT 12
|
|
||||||
#define SMMU_PFN_MASK 0x000FFFFF
|
|
||||||
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)
|
|
||||||
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)
|
|
||||||
#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22)
|
|
||||||
#define _READABLE (1 << MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT)
|
|
||||||
#define _WRITABLE (1 << MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT)
|
|
||||||
#define _NONSECURE (1 << MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT)
|
|
||||||
#define _PDE_NEXT (1 << SMMU_PDE_NEXT_SHIFT)
|
|
||||||
#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE)
|
|
||||||
#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE)
|
|
||||||
#define _PDE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
|
|
||||||
#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR)
|
|
||||||
#define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
|
|
||||||
#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR)
|
|
||||||
#define SMMU_MK_PDIR(page, attr) (((page) >> SMMU_PDIR_SHIFT) | (attr))
|
|
||||||
#define SMMU_MK_PDE(page, attr) (((page) >> SMMU_PDE_SHIFT) | (attr))
|
|
||||||
|
|
||||||
void *page_alloc(u32 num);
|
typedef struct _pde_t {
|
||||||
u32 *smmu_alloc_pdir();
|
union {
|
||||||
void smmu_flush_regs();
|
union {
|
||||||
void smmu_flush_all();
|
struct {
|
||||||
void smmu_init(u32 secmon_base);
|
u32 table:22;
|
||||||
void smmu_enable();
|
u32 rsvd:6;
|
||||||
bool smmu_is_used();
|
u32 next:1;
|
||||||
void smmu_exit();
|
u32 attr:3;
|
||||||
u32 *smmu_init_domain4(u32 dev_base, u32 asid);
|
} tbl;
|
||||||
u32 *smmu_get_pte(u32 *pdir, u32 iova);
|
|
||||||
void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr);
|
struct {
|
||||||
u32 *smmu_init_for_tsec();
|
u32 rsvd_:10;
|
||||||
void smmu_deinit_for_tsec();
|
u32 page:12;
|
||||||
|
u32 rsvd:6;
|
||||||
|
u32 next:1;
|
||||||
|
u32 attr:3;
|
||||||
|
} huge;
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 pde;
|
||||||
|
};
|
||||||
|
} pde_t;
|
||||||
|
|
||||||
|
typedef struct _pte_t {
|
||||||
|
u32 page:22;
|
||||||
|
u32 rsvd:7;
|
||||||
|
u32 attr:3;
|
||||||
|
} pte_t;
|
||||||
|
|
||||||
|
static_assert(sizeof(pde_t) == sizeof(u32), "pde_t size is wrong!");
|
||||||
|
static_assert(sizeof(pte_t) == sizeof(u32), "pte_t size is wrong!");
|
||||||
|
|
||||||
|
void *smmu_page_zalloc(u32 num);
|
||||||
|
void smmu_flush_all();
|
||||||
|
void smmu_init();
|
||||||
|
void smmu_enable();
|
||||||
|
void smmu_disable();
|
||||||
|
void smmu_reset_heap();
|
||||||
|
void *smmu_init_domain(u32 dev_base, u32 asid);
|
||||||
|
void smmu_deinit_domain(u32 dev_base, u32 asid);
|
||||||
|
void smmu_domain_bypass(u32 dev_base, bool bypass);
|
||||||
|
void smmu_map(void *ptb, u32 iova, u64 iopa, u32 pages, u32 attr);
|
||||||
|
void smmu_map_huge(void *ptb, u32 iova, u64 iopa, u32 regions, u32 attr);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2021 CTCaer
|
* Copyright (c) 2019-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -29,7 +29,6 @@
|
|||||||
#define SECMON_MIN_START 0x4002B000 // Minimum reserved address for secmon.
|
#define SECMON_MIN_START 0x4002B000 // Minimum reserved address for secmon.
|
||||||
|
|
||||||
#define SDRAM_PARAMS_ADDR 0x40030000 // SDRAM extraction buffer during sdram init.
|
#define SDRAM_PARAMS_ADDR 0x40030000 // SDRAM extraction buffer during sdram init.
|
||||||
#define CBFS_DRAM_EN_ADDR 0x4003e000 // u32.
|
|
||||||
|
|
||||||
/* start.S / exception_handlers.S */
|
/* start.S / exception_handlers.S */
|
||||||
#define SYS_STACK_TOP_INIT 0x4003FF00
|
#define SYS_STACK_TOP_INIT 0x4003FF00
|
||||||
@@ -48,27 +47,27 @@
|
|||||||
#define NYX_SZ_MAX SZ_16M
|
#define NYX_SZ_MAX SZ_16M
|
||||||
/* --- Gap: 0x82000000 - 0x82FFFFFF --- */
|
/* --- Gap: 0x82000000 - 0x82FFFFFF --- */
|
||||||
|
|
||||||
/* Stack theoretical max: 33MB */
|
// Heap buffer.
|
||||||
#define IPL_STACK_TOP 0x83100000
|
#define IPL_HEAP_START 0x82000000
|
||||||
#define IPL_HEAP_START 0x84000000
|
#define IPL_HEAP_SZ (SZ_256M)
|
||||||
#define IPL_HEAP_SZ SZ_512M
|
|
||||||
/* --- Gap: 1040MB 0xA4000000 - 0xE4FFFFFF --- */
|
#define SMMU_HEAP_ADDR 0x92000000
|
||||||
|
/* --- Gap: 1280MB 0x96000000 - 0xE4FFFFFF --- */
|
||||||
|
|
||||||
// Virtual disk / Chainloader buffers.
|
// Virtual disk / Chainloader buffers.
|
||||||
#define RAM_DISK_ADDR 0xA4000000
|
#define RAM_DISK_ADDR 0x95000000
|
||||||
#define RAM_DISK_SZ 0x41000000 // 1040MB.
|
#define RAM_DISK_SZ 0x50000000 // 1280MB.
|
||||||
#define RAM_DISK2_SZ 0x21000000 // 528MB.
|
|
||||||
|
|
||||||
// NX BIS driver sector cache.
|
|
||||||
#define NX_BIS_CACHE_ADDR 0xC5000000
|
|
||||||
#define NX_BIS_CACHE_SZ 0x10020000 // 256MB.
|
|
||||||
#define NX_BIS_LOOKUP_ADDR 0xD6000000
|
|
||||||
#define NX_BIS_LOOKUP_SZ 0xF000000 // 240MB.
|
|
||||||
|
|
||||||
// L4T Kernel Panic Storage (PSTORE).
|
// L4T Kernel Panic Storage (PSTORE).
|
||||||
#define PSTORE_ADDR 0xB0000000
|
#define PSTORE_ADDR 0xB0000000
|
||||||
#define PSTORE_SZ SZ_2M
|
#define PSTORE_SZ SZ_2M
|
||||||
|
|
||||||
|
// NX BIS driver sector cache.
|
||||||
|
#define NX_BIS_CACHE_ADDR 0xC7000000
|
||||||
|
#define NX_BIS_CACHE_SZ 0x10020000 // 256MB.
|
||||||
|
#define NX_BIS_LOOKUP_ADDR 0xD8000000
|
||||||
|
#define NX_BIS_LOOKUP_SZ 0x8000000 // 128MB. 512GB eMMC partition max.
|
||||||
|
|
||||||
//#define DRAM_LIB_ADDR 0xE0000000
|
//#define DRAM_LIB_ADDR 0xE0000000
|
||||||
/* --- Chnldr: 252MB 0xC03C0000 - 0xCFFFFFFF --- */ //! Only used when chainloading.
|
/* --- Chnldr: 252MB 0xC03C0000 - 0xCFFFFFFF --- */ //! Only used when chainloading.
|
||||||
|
|
||||||
@@ -76,7 +75,7 @@
|
|||||||
#define SDMMC_UPPER_BUFFER 0xE5000000
|
#define SDMMC_UPPER_BUFFER 0xE5000000
|
||||||
#define SDMMC_UP_BUF_SZ SZ_128M
|
#define SDMMC_UP_BUF_SZ SZ_128M
|
||||||
|
|
||||||
// Nyx buffers.
|
// Nyx buffers. !Do not change!
|
||||||
#define NYX_STORAGE_ADDR 0xED000000
|
#define NYX_STORAGE_ADDR 0xED000000
|
||||||
#define NYX_RES_ADDR 0xEE000000
|
#define NYX_RES_ADDR 0xEE000000
|
||||||
#define NYX_RES_SZ SZ_16M
|
#define NYX_RES_SZ SZ_16M
|
||||||
@@ -84,7 +83,6 @@
|
|||||||
// SDMMC DMA buffers 2
|
// SDMMC DMA buffers 2
|
||||||
#define SDXC_BUF_ALIGNED 0xEF000000
|
#define SDXC_BUF_ALIGNED 0xEF000000
|
||||||
#define MIXD_BUF_ALIGNED 0xF0000000
|
#define MIXD_BUF_ALIGNED 0xF0000000
|
||||||
#define TITLEKEY_BUF_ADR MIXD_BUF_ALIGNED
|
|
||||||
#define EMMC_BUF_ALIGNED MIXD_BUF_ALIGNED
|
#define EMMC_BUF_ALIGNED MIXD_BUF_ALIGNED
|
||||||
#define SDMMC_DMA_BUF_SZ SZ_16M // 4MB currently used.
|
#define SDMMC_DMA_BUF_SZ SZ_16M // 4MB currently used.
|
||||||
|
|
||||||
@@ -94,7 +92,7 @@
|
|||||||
#define NYX_LV_MEM_ADR 0xF1400000
|
#define NYX_LV_MEM_ADR 0xF1400000
|
||||||
#define NYX_LV_MEM_SZ 0x6600000 // 70MB.
|
#define NYX_LV_MEM_SZ 0x6600000 // 70MB.
|
||||||
|
|
||||||
// Framebuffer addresses.
|
// Framebuffer addresses. !Do not change!
|
||||||
#define IPL_FB_ADDRESS 0xF5A00000
|
#define IPL_FB_ADDRESS 0xF5A00000
|
||||||
#define IPL_FB_SZ 0x384000 // 720 x 1280 x 4.
|
#define IPL_FB_SZ 0x384000 // 720 x 1280 x 4.
|
||||||
#define LOG_FB_ADDRESS 0xF5E00000
|
#define LOG_FB_ADDRESS 0xF5E00000
|
||||||
@@ -103,13 +101,6 @@
|
|||||||
#define NYX_FB2_ADDRESS 0xF6600000
|
#define NYX_FB2_ADDRESS 0xF6600000
|
||||||
#define NYX_FB_SZ 0x384000 // 1280 x 720 x 4.
|
#define NYX_FB_SZ 0x384000 // 1280 x 720 x 4.
|
||||||
|
|
||||||
/* OBSOLETE: Very old hwinit based payloads were setting a carveout here. */
|
|
||||||
#define DRAM_MEM_HOLE_ADR 0xF6A00000
|
|
||||||
#define NX_BIS_LOOKUP_ADR DRAM_MEM_HOLE_ADR
|
|
||||||
#define DRAM_MEM_HOLE_SZ 0x8140000
|
|
||||||
/* --- Hole: 129MB 0xF6A00000 - 0xFEB3FFFF --- */
|
|
||||||
#define DRAM_START2 0xFEB40000
|
|
||||||
|
|
||||||
// USB buffers.
|
// USB buffers.
|
||||||
#define USBD_ADDR 0xFEF00000
|
#define USBD_ADDR 0xFEF00000
|
||||||
#define USB_DESCRIPTOR_ADDR 0xFEF40000
|
#define USB_DESCRIPTOR_ADDR 0xFEF40000
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* USB-PD driver for Nintendo Switch's TI BM92T36
|
* USB-PD driver for Nintendo Switch's TI BM92T36
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020-2023 CTCaer
|
* Copyright (c) 2020-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -54,6 +54,10 @@
|
|||||||
|
|
||||||
#define STATUS1_INSERT BIT(7) // Cable inserted.
|
#define STATUS1_INSERT BIT(7) // Cable inserted.
|
||||||
|
|
||||||
|
#define VER_36 0x36
|
||||||
|
#define MAX_ROHM 0x4B5
|
||||||
|
#define DEV_BM92T 0x3B0
|
||||||
|
|
||||||
typedef struct _pd_object_t {
|
typedef struct _pd_object_t {
|
||||||
unsigned int amp:10;
|
unsigned int amp:10;
|
||||||
unsigned int volt:10;
|
unsigned int volt:10;
|
||||||
@@ -63,9 +67,29 @@ typedef struct _pd_object_t {
|
|||||||
|
|
||||||
static int _bm92t36_read_reg(u8 *buf, u32 size, u32 reg)
|
static int _bm92t36_read_reg(u8 *buf, u32 size, u32 reg)
|
||||||
{
|
{
|
||||||
|
memset(buf, 0, size);
|
||||||
return i2c_recv_buf_big(buf, size, I2C_1, BM92T36_I2C_ADDR, reg);
|
return i2c_recv_buf_big(buf, size, I2C_1, BM92T36_I2C_ADDR, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bm92t36_get_version(u32 *value)
|
||||||
|
{
|
||||||
|
u8 buf[2];
|
||||||
|
u16 version, man, dev;
|
||||||
|
_bm92t36_read_reg(buf, 2, FW_TYPE_REG);
|
||||||
|
version = (buf[0] << 4) | buf[1];
|
||||||
|
_bm92t36_read_reg(buf, 2, MAN_ID_REG);
|
||||||
|
man = (buf[1] << 8) | buf[0];
|
||||||
|
_bm92t36_read_reg(buf, 2, DEV_ID_REG);
|
||||||
|
dev = (buf[1] << 8) | buf[0];
|
||||||
|
if (value)
|
||||||
|
*value = (dev << 16) | version;
|
||||||
|
|
||||||
|
if (version == VER_36 && man == MAX_ROHM && dev == DEV_BM92T)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
|
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
|
||||||
{
|
{
|
||||||
u8 buf[32];
|
u8 buf[32];
|
||||||
@@ -73,14 +97,12 @@ void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
|
|||||||
|
|
||||||
if (inserted)
|
if (inserted)
|
||||||
{
|
{
|
||||||
memset(buf, 0, sizeof(buf));
|
|
||||||
_bm92t36_read_reg(buf, 2, STATUS1_REG);
|
_bm92t36_read_reg(buf, 2, STATUS1_REG);
|
||||||
*inserted = buf[0] & STATUS1_INSERT ? true : false;
|
*inserted = (buf[0] & STATUS1_INSERT) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usb_pd)
|
if (usb_pd)
|
||||||
{
|
{
|
||||||
memset(buf, 0, sizeof(buf));
|
|
||||||
_bm92t36_read_reg(buf, 29, READ_PDOS_SRC_REG);
|
_bm92t36_read_reg(buf, 29, READ_PDOS_SRC_REG);
|
||||||
memcpy(pdos, &buf[1], 28);
|
memcpy(pdos, &buf[1], 28);
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ typedef struct _usb_pd_objects_t
|
|||||||
usb_pd_object_t selected_pdo;
|
usb_pd_object_t selected_pdo;
|
||||||
} usb_pd_objects_t;
|
} usb_pd_objects_t;
|
||||||
|
|
||||||
|
int bm92t36_get_version(u32 *value);
|
||||||
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd);
|
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Battery charger driver for Nintendo Switch's TI BQ24193
|
* Battery charger driver for Nintendo Switch's TI BQ24193
|
||||||
*
|
*
|
||||||
* Copyright (c) 2018 CTCaer
|
* Copyright (c) 2018-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -25,131 +25,144 @@ static u8 bq24193_get_reg(u8 reg)
|
|||||||
return i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, reg);
|
return i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bq24193_get_version(u32 *value)
|
||||||
|
{
|
||||||
|
u16 data = bq24193_get_reg(BQ24193_VendorPart);
|
||||||
|
if (value)
|
||||||
|
*value = data;
|
||||||
|
|
||||||
|
if (data == 0x2F)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value)
|
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value)
|
||||||
{
|
{
|
||||||
u8 data;
|
u8 data;
|
||||||
|
|
||||||
switch (prop) {
|
switch (prop)
|
||||||
case BQ24193_InputVoltageLimit: // Input voltage limit (mV).
|
{
|
||||||
data = bq24193_get_reg(BQ24193_InputSource);
|
case BQ24193_InputVoltageLimit: // Input voltage limit (mV).
|
||||||
data = (data & BQ24193_INCONFIG_VINDPM_MASK) >> 3;
|
data = bq24193_get_reg(BQ24193_InputSource);
|
||||||
*value = 0;
|
data = (data & BQ24193_INCONFIG_VINDPM_MASK) >> 3;
|
||||||
*value += ((data >> 0) & 1) ? 80 : 0;
|
*value = 0;
|
||||||
*value += ((data >> 1) & 1) ? 160 : 0;
|
*value += ((data >> 0) & 1) ? 80 : 0;
|
||||||
*value += ((data >> 2) & 1) ? 320 : 0;
|
*value += ((data >> 1) & 1) ? 160 : 0;
|
||||||
*value += ((data >> 3) & 1) ? 640 : 0;
|
*value += ((data >> 2) & 1) ? 320 : 0;
|
||||||
*value += 3880;
|
*value += ((data >> 3) & 1) ? 640 : 0;
|
||||||
|
*value += 3880;
|
||||||
|
break;
|
||||||
|
case BQ24193_InputCurrentLimit: // Input current limit (mA).
|
||||||
|
data = bq24193_get_reg(BQ24193_InputSource);
|
||||||
|
data &= BQ24193_INCONFIG_INLIMIT_MASK;
|
||||||
|
switch (data)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
*value = 100;
|
||||||
break;
|
break;
|
||||||
case BQ24193_InputCurrentLimit: // Input current limit (mA).
|
case 1:
|
||||||
data = bq24193_get_reg(BQ24193_InputSource);
|
*value = 150;
|
||||||
data &= BQ24193_INCONFIG_INLIMIT_MASK;
|
|
||||||
switch (data)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
*value = 100;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
*value = 150;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
*value = 500;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
*value = 900;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
*value = 1200;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
*value = 1500;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
*value = 2000;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
*value = 3000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case BQ24193_SystemMinimumVoltage: // Minimum system voltage limit (mV).
|
case 2:
|
||||||
data = bq24193_get_reg(BQ24193_PORConfig);
|
*value = 500;
|
||||||
*value = (data & BQ24193_PORCONFIG_SYSMIN_MASK) >> 1;
|
|
||||||
*value *= 100;
|
|
||||||
*value += 3000;
|
|
||||||
break;
|
break;
|
||||||
case BQ24193_FastChargeCurrentLimit: // Fast charge current limit (mA).
|
case 3:
|
||||||
data = bq24193_get_reg(BQ24193_ChrgCurr);
|
*value = 900;
|
||||||
data = (data & BQ24193_CHRGCURR_ICHG_MASK) >> 2;
|
|
||||||
*value = 0;
|
|
||||||
*value += ((data >> 0) & 1) ? 64 : 0;
|
|
||||||
*value += ((data >> 1) & 1) ? 128 : 0;
|
|
||||||
*value += ((data >> 2) & 1) ? 256 : 0;
|
|
||||||
*value += ((data >> 3) & 1) ? 512 : 0;
|
|
||||||
*value += ((data >> 4) & 1) ? 1024 : 0;
|
|
||||||
*value += ((data >> 5) & 1) ? 2048 : 0;
|
|
||||||
*value += 512;
|
|
||||||
data = bq24193_get_reg(BQ24193_ChrgCurr);
|
|
||||||
data &= BQ24193_CHRGCURR_20PCT_MASK;
|
|
||||||
if (data)
|
|
||||||
*value = *value * 20 / 100; // Fast charge current limit is 20%.
|
|
||||||
break;
|
break;
|
||||||
case BQ24193_ChargeVoltageLimit: // Charge voltage limit (mV).
|
case 4:
|
||||||
data = bq24193_get_reg(BQ24193_ChrgVolt);
|
*value = 1200;
|
||||||
data = (data & BQ24193_CHRGVOLT_VREG) >> 2;
|
|
||||||
*value = 0;
|
|
||||||
*value += ((data >> 0) & 1) ? 16 : 0;
|
|
||||||
*value += ((data >> 1) & 1) ? 32 : 0;
|
|
||||||
*value += ((data >> 2) & 1) ? 64 : 0;
|
|
||||||
*value += ((data >> 3) & 1) ? 128 : 0;
|
|
||||||
*value += ((data >> 4) & 1) ? 256 : 0;
|
|
||||||
*value += ((data >> 5) & 1) ? 512 : 0;
|
|
||||||
*value += 3504;
|
|
||||||
break;
|
break;
|
||||||
case BQ24193_RechargeThreshold: // Recharge voltage threshold less than voltage limit (mV).
|
case 5:
|
||||||
data = bq24193_get_reg(BQ24193_ChrgVolt);
|
*value = 1500;
|
||||||
data &= BQ24193_IRTHERMAL_THERM_MASK;
|
|
||||||
if (data)
|
|
||||||
*value = 300;
|
|
||||||
else
|
|
||||||
*value = 100;
|
|
||||||
break;
|
break;
|
||||||
case BQ24193_ThermalRegulation: // Thermal regulation threshold (oC).
|
case 6:
|
||||||
data = bq24193_get_reg(BQ24193_IRCompThermal);
|
*value = 2000;
|
||||||
data &= BQ24193_IRTHERMAL_THERM_MASK;
|
|
||||||
switch (data)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
*value = 60;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
*value = 80;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
*value = 100;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
*value = 120;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case BQ24193_ChargeStatus: // 0: Not charging, 1: Pre-charge, 2: Fast charging, 3: Charge termination done
|
case 7:
|
||||||
data = bq24193_get_reg(BQ24193_Status);
|
*value = 3000;
|
||||||
*value = (data & BQ24193_STATUS_CHRG_MASK) >> 4;
|
|
||||||
break;
|
break;
|
||||||
case BQ24193_TempStatus: // 0: Normal, 2: Warm, 3: Cool, 5: Cold, 6: Hot.
|
}
|
||||||
data = bq24193_get_reg(BQ24193_FaultReg);
|
break;
|
||||||
*value = data & BQ24193_FAULT_THERM_MASK;
|
case BQ24193_SystemMinimumVoltage: // Minimum system voltage limit (mV).
|
||||||
|
data = bq24193_get_reg(BQ24193_PORConfig);
|
||||||
|
*value = (data & BQ24193_PORCONFIG_SYSMIN_MASK) >> 1;
|
||||||
|
*value *= 100;
|
||||||
|
*value += 3000;
|
||||||
|
break;
|
||||||
|
case BQ24193_FastChargeCurrentLimit: // Fast charge current limit (mA).
|
||||||
|
data = bq24193_get_reg(BQ24193_ChrgCurr);
|
||||||
|
data = (data & BQ24193_CHRGCURR_ICHG_MASK) >> 2;
|
||||||
|
*value = 0;
|
||||||
|
*value += ((data >> 0) & 1) ? 64 : 0;
|
||||||
|
*value += ((data >> 1) & 1) ? 128 : 0;
|
||||||
|
*value += ((data >> 2) & 1) ? 256 : 0;
|
||||||
|
*value += ((data >> 3) & 1) ? 512 : 0;
|
||||||
|
*value += ((data >> 4) & 1) ? 1024 : 0;
|
||||||
|
*value += ((data >> 5) & 1) ? 2048 : 0;
|
||||||
|
*value += 512;
|
||||||
|
data = bq24193_get_reg(BQ24193_ChrgCurr);
|
||||||
|
data &= BQ24193_CHRGCURR_20PCT_MASK;
|
||||||
|
if (data)
|
||||||
|
*value = *value * 20 / 100; // Fast charge current limit is 20%.
|
||||||
|
break;
|
||||||
|
case BQ24193_ChargeVoltageLimit: // Charge voltage limit (mV).
|
||||||
|
data = bq24193_get_reg(BQ24193_ChrgVolt);
|
||||||
|
data = (data & BQ24193_CHRGVOLT_VREG) >> 2;
|
||||||
|
*value = 0;
|
||||||
|
*value += ((data >> 0) & 1) ? 16 : 0;
|
||||||
|
*value += ((data >> 1) & 1) ? 32 : 0;
|
||||||
|
*value += ((data >> 2) & 1) ? 64 : 0;
|
||||||
|
*value += ((data >> 3) & 1) ? 128 : 0;
|
||||||
|
*value += ((data >> 4) & 1) ? 256 : 0;
|
||||||
|
*value += ((data >> 5) & 1) ? 512 : 0;
|
||||||
|
*value += 3504;
|
||||||
|
break;
|
||||||
|
case BQ24193_RechargeThreshold: // Recharge voltage threshold less than voltage limit (mV).
|
||||||
|
data = bq24193_get_reg(BQ24193_ChrgVolt);
|
||||||
|
data &= BQ24193_IRTHERMAL_THERM_MASK;
|
||||||
|
if (data)
|
||||||
|
*value = 300;
|
||||||
|
else
|
||||||
|
*value = 100;
|
||||||
|
break;
|
||||||
|
case BQ24193_ThermalRegulation: // Thermal regulation threshold (oC).
|
||||||
|
data = bq24193_get_reg(BQ24193_IRCompThermal);
|
||||||
|
data &= BQ24193_IRTHERMAL_THERM_MASK;
|
||||||
|
switch (data)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
*value = 60;
|
||||||
break;
|
break;
|
||||||
case BQ24193_DevID: // Dev ID.
|
case 1:
|
||||||
data = bq24193_get_reg(BQ24193_VendorPart);
|
*value = 80;
|
||||||
*value = data & BQ24193_VENDORPART_DEV_MASK;
|
|
||||||
break;
|
break;
|
||||||
case BQ24193_ProductNumber: // Product number.
|
case 2:
|
||||||
data = bq24193_get_reg(BQ24193_VendorPart);
|
*value = 100;
|
||||||
*value = (data & BQ24193_VENDORPART_PN_MASK) >> 3;
|
|
||||||
break;
|
break;
|
||||||
default:
|
case 3:
|
||||||
return -1;
|
*value = 120;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BQ24193_ChargeStatus: // 0: Not charging, 1: Pre-charge, 2: Fast charging, 3: Charge termination done
|
||||||
|
data = bq24193_get_reg(BQ24193_Status);
|
||||||
|
*value = (data & BQ24193_STATUS_CHRG_MASK) >> 4;
|
||||||
|
break;
|
||||||
|
case BQ24193_TempStatus: // 0: Normal, 2: Warm, 3: Cool, 5: Cold, 6: Hot.
|
||||||
|
data = bq24193_get_reg(BQ24193_FaultReg);
|
||||||
|
*value = data & BQ24193_FAULT_THERM_MASK;
|
||||||
|
break;
|
||||||
|
case BQ24193_DevID: // Dev ID.
|
||||||
|
data = bq24193_get_reg(BQ24193_VendorPart);
|
||||||
|
*value = data & BQ24193_VENDORPART_DEV_MASK;
|
||||||
|
break;
|
||||||
|
case BQ24193_ProductNumber: // Product number.
|
||||||
|
data = bq24193_get_reg(BQ24193_VendorPart);
|
||||||
|
*value = (data & BQ24193_VENDORPART_PN_MASK) >> 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
#ifndef __BQ24193_H_
|
#ifndef __BQ24193_H_
|
||||||
#define __BQ24193_H_
|
#define __BQ24193_H_
|
||||||
|
|
||||||
|
#include <utils/types.h>
|
||||||
|
|
||||||
#define BQ24193_I2C_ADDR 0x6B
|
#define BQ24193_I2C_ADDR 0x6B
|
||||||
|
|
||||||
// REG 0 masks.
|
// REG 0 masks.
|
||||||
@@ -114,7 +116,8 @@ enum BQ24193_reg_prop {
|
|||||||
BQ24193_ProductNumber, // REG A.
|
BQ24193_ProductNumber, // REG A.
|
||||||
};
|
};
|
||||||
|
|
||||||
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value);
|
int bq24193_get_version(u32 *value);
|
||||||
|
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value);
|
||||||
void bq24193_enable_charger();
|
void bq24193_enable_charger();
|
||||||
void bq24193_fake_battery_removal();
|
void bq24193_fake_battery_removal();
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2011 Samsung Electronics
|
* Copyright (c) 2011 Samsung Electronics
|
||||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||||
* Copyright (c) 2018 CTCaer
|
* Copyright (c) 2018-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -60,6 +60,18 @@ static u16 max17050_get_reg(u8 reg)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int max17050_get_version(u32 *value)
|
||||||
|
{
|
||||||
|
u16 data = max17050_get_reg(MAX17050_DevName);
|
||||||
|
if (value)
|
||||||
|
*value = data;
|
||||||
|
|
||||||
|
if (data == 0x00AC)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int max17050_get_property(enum MAX17050_reg reg, int *value)
|
int max17050_get_property(enum MAX17050_reg reg, int *value)
|
||||||
{
|
{
|
||||||
u16 data;
|
u16 data;
|
||||||
@@ -279,3 +291,26 @@ int max17050_fix_configuration()
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void max17050_dump_regs(void *buf)
|
||||||
|
{
|
||||||
|
u16 *buff = (u16 *)buf;
|
||||||
|
|
||||||
|
// Unlock model table.
|
||||||
|
u16 unlock = 0x59;
|
||||||
|
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable1, (u8 *)&unlock, 2);
|
||||||
|
unlock = 0xC4;
|
||||||
|
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable2, (u8 *)&unlock, 2);
|
||||||
|
|
||||||
|
// Dump all battery fuel gauge registers.
|
||||||
|
for (u32 i = 0; i < 0x100; i++)
|
||||||
|
{
|
||||||
|
buff[i] = max17050_get_reg(i);
|
||||||
|
msleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lock model table.
|
||||||
|
unlock = 0;
|
||||||
|
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable1, (u8 *)&unlock, 2);
|
||||||
|
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable2, (u8 *)&unlock, 2);
|
||||||
|
}
|
||||||
|
|||||||
@@ -130,8 +130,10 @@ enum MAX17050_reg {
|
|||||||
MAX17050_VFSOC = 0xFF,
|
MAX17050_VFSOC = 0xFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
int max17050_get_property(enum MAX17050_reg reg, int *value);
|
int max17050_get_version(u32 *value);
|
||||||
int max17050_fix_configuration();
|
int max17050_get_property(enum MAX17050_reg reg, int *value);
|
||||||
u32 max17050_get_cached_batt_volt();
|
int max17050_fix_configuration();
|
||||||
|
void max17050_dump_regs(void *buf);
|
||||||
|
u32 max17050_get_cached_batt_volt();
|
||||||
|
|
||||||
#endif /* __MAX17050_H_ */
|
#endif /* __MAX17050_H_ */
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ typedef struct _max77620_regulator_t
|
|||||||
|
|
||||||
static const max77620_regulator_t _pmic_regulators[] = {
|
static const max77620_regulator_t _pmic_regulators[] = {
|
||||||
{ "sd0", 12500, 600000, 625000, 1400000, REGULATOR_SD, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, {{ MAX77620_REG_FPS_SD0, 1, 7, 1 }} },
|
{ "sd0", 12500, 600000, 625000, 1400000, REGULATOR_SD, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, {{ MAX77620_REG_FPS_SD0, 1, 7, 1 }} },
|
||||||
{ "sd1", 12500, 600000, 1125000, 1250000, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
|
{ "sd1", 12500, 600000, 1125000, 1237500, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
|
||||||
{ "sd2", 12500, 600000, 1325000, 1350000, REGULATOR_SD, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD2, 1, 5, 2 }} },
|
{ "sd2", 12500, 600000, 1325000, 1350000, REGULATOR_SD, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD2, 1, 5, 2 }} },
|
||||||
{ "sd3", 12500, 600000, 1800000, 1800000, REGULATOR_SD, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD3, 0, 3, 3 }} },
|
{ "sd3", 12500, 600000, 1800000, 1800000, REGULATOR_SD, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD3, 0, 3, 3 }} },
|
||||||
{ "ldo0", 25000, 800000, 1200000, 1200000, REGULATOR_LDO, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO0, 3, 7, 0 }} },
|
{ "ldo0", 25000, 800000, 1200000, 1200000, REGULATOR_LDO, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO0, 3, 7, 0 }} },
|
||||||
@@ -103,7 +103,7 @@ static u8 _max77812_get_address()
|
|||||||
return max77812_i2c_addr;
|
return max77812_i2c_addr;
|
||||||
|
|
||||||
max77812_i2c_addr =
|
max77812_i2c_addr =
|
||||||
!(FUSE(FUSE_RESERVED_ODM28_T210B01) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR;
|
!(FUSE(FUSE_RESERVED_ODM28_B01) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR;
|
||||||
|
|
||||||
return max77812_i2c_addr;
|
return max77812_i2c_addr;
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ static u8 _max7762x_get_i2c_address(u32 id)
|
|||||||
case REGULATOR_BC1:
|
case REGULATOR_BC1:
|
||||||
{
|
{
|
||||||
u8 reg_addr = _max77812_get_address();
|
u8 reg_addr = _max77812_get_address();
|
||||||
if (id == REGULATOR_RAM1 && reg_addr == MAX77812_PHASE31_CPU_I2C_ADDR)
|
if (id == REGULATOR_RAM0 && reg_addr == MAX77812_PHASE31_CPU_I2C_ADDR)
|
||||||
reg_addr = 0;
|
reg_addr = 0;
|
||||||
return reg_addr;
|
return reg_addr;
|
||||||
}
|
}
|
||||||
@@ -327,7 +327,7 @@ void max77620_config_default()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Set default voltages and enable regulators.
|
// Set default voltages and enable regulators.
|
||||||
for (u32 i = 1; i <= REGULATOR_LDO8; i++)
|
for (u32 i = REGULATOR_SD1; i <= REGULATOR_LDO8; i++)
|
||||||
{
|
{
|
||||||
max77620_regulator_config_fps(i);
|
max77620_regulator_config_fps(i);
|
||||||
max7762x_regulator_set_voltage(i, _pmic_regulators[i].uv_default);
|
max7762x_regulator_set_voltage(i, _pmic_regulators[i].uv_default);
|
||||||
|
|||||||
@@ -47,6 +47,27 @@
|
|||||||
* ldo8 | XUSB, DP, MCU | 50000 | 800000 | 1050000 | 2800000 | 1.05V/2.8V (pcv)
|
* ldo8 | XUSB, DP, MCU | 50000 | 800000 | 1050000 | 2800000 | 1.05V/2.8V (pcv)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// GPIOs T210: 3: 3.3V, 5: CPU PMIC, 6: GPU PMIC, 7: DSI/VI 1.2V powered by ldo0.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OTP: T210 - T210B01:
|
||||||
|
* SD0: 1.0V 1.05V - SoC. EN Based on FPSSRC.
|
||||||
|
* SD1: 1.15V 1.1V - DRAM for T210. EN Based on FPSSRC.
|
||||||
|
* SD2: 1.35V 1.35V
|
||||||
|
* SD3: 1.8V 1.8V
|
||||||
|
* All powered off?
|
||||||
|
* LDO0: -- -- - Display
|
||||||
|
* LDO1: 1.05V 1.05V
|
||||||
|
* LDO2: -- -- - SD
|
||||||
|
* LDO3: 3.1V 3.1V - GC ASIC
|
||||||
|
* LDO4: 1.0V 0.8V - Needed for RTC domain on T210.
|
||||||
|
* LDO5: 3.1V 3.1V
|
||||||
|
* LDO6: 2.8V 2.9V - Touch.
|
||||||
|
* LDO7: 1.05V 1.0V
|
||||||
|
* LDO8: 1.05V 1.0V
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode
|
* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode
|
||||||
* MAX77620_REG_GPIOx: 0x9 sets output and enable
|
* MAX77620_REG_GPIOx: 0x9 sets output and enable
|
||||||
@@ -69,9 +90,9 @@
|
|||||||
#define REGULATOR_CPU0 13 // T210 CPU.
|
#define REGULATOR_CPU0 13 // T210 CPU.
|
||||||
#define REGULATOR_GPU0 14 // T210 CPU.
|
#define REGULATOR_GPU0 14 // T210 CPU.
|
||||||
#define REGULATOR_CPU1 15 // T210B01 CPU.
|
#define REGULATOR_CPU1 15 // T210B01 CPU.
|
||||||
#define REGULATOR_RAM1 16 // T210B01 RAM for PHASE211.
|
#define REGULATOR_RAM0 16 // T210B01 RAM for PHASE211.
|
||||||
//#define REGULATOR_GPU1 17 // T210B01 CPU.
|
//#define REGULATOR_GPU1 17 // T210B01 CPU.
|
||||||
#define REGULATOR_MAX REGULATOR_RAM1
|
#define REGULATOR_MAX REGULATOR_RAM0
|
||||||
|
|
||||||
#define MAX77621_CPU_I2C_ADDR 0x1B
|
#define MAX77621_CPU_I2C_ADDR 0x1B
|
||||||
#define MAX77621_GPU_I2C_ADDR 0x1C
|
#define MAX77621_GPU_I2C_ADDR 0x1C
|
||||||
|
|||||||
@@ -75,14 +75,14 @@
|
|||||||
#define MAX77812_REG_GLB_CFG3 0x35
|
#define MAX77812_REG_GLB_CFG3 0x35
|
||||||
|
|
||||||
/*! Protected area and settings only for MAX77812_ES2_VERSION */
|
/*! Protected area and settings only for MAX77812_ES2_VERSION */
|
||||||
#define MAX77812_REG_GLB_CFG4 0x36
|
#define MAX77812_REG_GLB_CFG4 0x36 // QS: 0xBB.
|
||||||
#define MAX77812_REG_GLB_CFG5 0x37 // HOS: 0x3E. Unmasked write.
|
#define MAX77812_REG_GLB_CFG5 0x37 // QS: 0x39. ES2: Set to 0x3E.
|
||||||
#define MAX77812_REG_GLB_CFG6 0x38 // HOS: 0x90. Unmasked write.
|
#define MAX77812_REG_GLB_CFG6 0x38 // QS: 0x88. ES2: Set to 0x90.
|
||||||
#define MAX77812_REG_GLB_CFG7 0x39
|
#define MAX77812_REG_GLB_CFG7 0x39 // QS: 0x04.
|
||||||
#define MAX77812_REG_GLB_CFG8 0x3A // HOS: 0x3A. Unmasked write.
|
#define MAX77812_REG_GLB_CFG8 0x3A // QS: 0x3A. ES2: Set to 0x3A.
|
||||||
|
|
||||||
#define MAX77812_REG_PROT_ACCESS 0xFD // 0x00: Lock, 0x5A: Unlock.
|
#define MAX77812_REG_PROT_ACCESS 0xFD // 0x00: Lock, 0x5A: Unlock.
|
||||||
#define MAX77812_REG_MAX 0xFD
|
#define MAX77812_REG_UNKNOWN 0xFE
|
||||||
|
|
||||||
#define MAX77812_REG_EN_CTRL_MASK(n) BIT(n)
|
#define MAX77812_REG_EN_CTRL_MASK(n) BIT(n)
|
||||||
#define MAX77812_START_SLEW_RATE_MASK 0x07
|
#define MAX77812_START_SLEW_RATE_MASK 0x07
|
||||||
|
|||||||
@@ -32,24 +32,24 @@ void regulator_5v_enable(u8 dev)
|
|||||||
// The power supply selection from battery or USB is automatic.
|
// The power supply selection from battery or USB is automatic.
|
||||||
if (!reg_5v_dev)
|
if (!reg_5v_dev)
|
||||||
{
|
{
|
||||||
// Fan and Rail power from battery 5V regulator.
|
// Fan and Rail power from battery 5V regulator EN.
|
||||||
PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = 1;
|
PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = 1;
|
||||||
gpio_direction_output(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
|
gpio_direction_output(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
|
||||||
|
|
||||||
// Only Icosa has USB 5V VBUS rails.
|
// Only Icosa has USB 5V VBUS rails.
|
||||||
if (tegra_t210)
|
if (tegra_t210)
|
||||||
{
|
{
|
||||||
// Fan and Rail power from USB 5V VBUS.
|
// Fan and Rail power from USB 5V VBUS EN.
|
||||||
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_LPDR | 1;
|
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_LPDR | 1;
|
||||||
gpio_direction_output(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
|
gpio_direction_output(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure GPIO IO power is enabled.
|
// Make sure GPIO IO power is enabled.
|
||||||
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO_IO_EN;
|
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO;
|
||||||
(void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
|
(void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
|
||||||
|
|
||||||
// Override power detect for GPIO AO IO rails.
|
// Inform GPIO IO pads that we switched to 1.8V.
|
||||||
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_GPIO_IO_EN;
|
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_33V_GPIO;
|
||||||
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
|
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
|
||||||
|
|
||||||
usb_src = false;
|
usb_src = false;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
|
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
|
||||||
*
|
*
|
||||||
* Copyright (c) 2018-2022 CTCaer
|
* Copyright (c) 2018-2025 CTCaer
|
||||||
* Copyright (c) 2019 shchmue
|
* Copyright (c) 2019 shchmue
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -23,6 +23,9 @@
|
|||||||
#include <soc/timer.h>
|
#include <soc/timer.h>
|
||||||
#include <soc/t210.h>
|
#include <soc/t210.h>
|
||||||
|
|
||||||
|
bool auto_dst = false;
|
||||||
|
int epoch_offset = 0;
|
||||||
|
|
||||||
void max77620_rtc_prep_read()
|
void max77620_rtc_prep_read()
|
||||||
{
|
{
|
||||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
|
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
|
||||||
@@ -37,20 +40,24 @@ void max77620_rtc_get_time(rtc_time_t *time)
|
|||||||
|
|
||||||
// Get control reg config.
|
// Get control reg config.
|
||||||
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_CONTROL_REG);
|
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_CONTROL_REG);
|
||||||
// TODO: Check for binary format also?
|
// TODO: Make also sure it's binary format?
|
||||||
|
|
||||||
// Get time.
|
// Get time.
|
||||||
time->sec = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_SEC_REG) & 0x7F;
|
time->sec = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_SEC_REG) & 0x7F;
|
||||||
time->min = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MIN_REG) & 0x7F;
|
time->min = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MIN_REG) & 0x7F;
|
||||||
u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG);
|
u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG) & 0x1F;
|
||||||
time->hour = hour & 0x1F;
|
time->hour = hour & 0x1F;
|
||||||
|
|
||||||
if (!(val & MAX77620_RTC_24H) && (hour & MAX77620_RTC_HOUR_PM_MASK))
|
if (!(val & MAX77620_RTC_24H))
|
||||||
time->hour = (time->hour & 0xF) + 12;
|
{
|
||||||
|
time->hour = hour & 0xF;
|
||||||
|
if (hour & MAX77620_RTC_HOUR_PM_MASK)
|
||||||
|
time->hour += 12;
|
||||||
|
}
|
||||||
|
|
||||||
// Get day of week. 1: Monday to 7: Sunday.
|
// Get day of week. 1: Monday to 7: Sunday.
|
||||||
time->weekday = 0;
|
time->weekday = 0;
|
||||||
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_WEEKDAY_REG);
|
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_WEEKDAY_REG) & 0x7F;
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
time->weekday++;
|
time->weekday++;
|
||||||
@@ -60,8 +67,9 @@ void max77620_rtc_get_time(rtc_time_t *time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get date.
|
// Get date.
|
||||||
time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f;
|
time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DAY_REG) & 0x1F;
|
||||||
time->month = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MONTH_REG) & 0xF) - 1;
|
time->month = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MONTH_REG) & 0xF) - 1;
|
||||||
|
time->month++; // Normally minus 1, but everything else expects 1 as January.
|
||||||
time->year = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_YEAR_REG) & 0x7F) + 2000;
|
time->year = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_YEAR_REG) & 0x7F) + 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +132,7 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
|
|||||||
time->day = day;
|
time->day = day;
|
||||||
|
|
||||||
// Set weekday.
|
// Set weekday.
|
||||||
time->weekday = 0; //! TODO.
|
time->weekday = (day + 4) % 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
|
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
|
||||||
@@ -154,6 +162,32 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
|
|||||||
return epoch;
|
return epoch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void max77620_rtc_get_time_adjusted(rtc_time_t *time)
|
||||||
|
{
|
||||||
|
max77620_rtc_get_time(time);
|
||||||
|
if (epoch_offset)
|
||||||
|
{
|
||||||
|
u32 epoch = (u32)((s64)max77620_rtc_date_to_epoch(time) + epoch_offset);
|
||||||
|
|
||||||
|
// Adjust for DST between 28 march and 28 october. Good enough to cover all years as week info is not valid.
|
||||||
|
u16 md = (time->month << 8) | time->day;
|
||||||
|
if (auto_dst && md >= 0x31C && md < 0xA1C)
|
||||||
|
epoch += 3600;
|
||||||
|
|
||||||
|
max77620_rtc_epoch_to_date(epoch, time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void max77620_rtc_set_auto_dst(bool enable)
|
||||||
|
{
|
||||||
|
auto_dst = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max77620_rtc_set_epoch_offset(int offset)
|
||||||
|
{
|
||||||
|
epoch_offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr)
|
void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr)
|
||||||
{
|
{
|
||||||
max77620_rtc_stop_alarm();
|
max77620_rtc_stop_alarm();
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
#define MAX77620_RTC_WEEKDAY_REG 0x0A
|
#define MAX77620_RTC_WEEKDAY_REG 0x0A
|
||||||
#define MAX77620_RTC_MONTH_REG 0x0B
|
#define MAX77620_RTC_MONTH_REG 0x0B
|
||||||
#define MAX77620_RTC_YEAR_REG 0x0C
|
#define MAX77620_RTC_YEAR_REG 0x0C
|
||||||
#define MAX77620_RTC_DATE_REG 0x0D
|
#define MAX77620_RTC_DAY_REG 0x0D
|
||||||
|
|
||||||
#define MAX77620_ALARM1_SEC_REG 0x0E
|
#define MAX77620_ALARM1_SEC_REG 0x0E
|
||||||
#define MAX77620_ALARM1_MIN_REG 0x0F
|
#define MAX77620_ALARM1_MIN_REG 0x0F
|
||||||
@@ -109,6 +109,9 @@ typedef struct _rtc_reboot_reason_t
|
|||||||
|
|
||||||
void max77620_rtc_prep_read();
|
void max77620_rtc_prep_read();
|
||||||
void max77620_rtc_get_time(rtc_time_t *time);
|
void max77620_rtc_get_time(rtc_time_t *time);
|
||||||
|
void max77620_rtc_get_time_adjusted(rtc_time_t *time);
|
||||||
|
void max77620_rtc_set_epoch_offset(int offset);
|
||||||
|
void max77620_rtc_set_auto_dst(bool enable);
|
||||||
void max77620_rtc_stop_alarm();
|
void max77620_rtc_stop_alarm();
|
||||||
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time);
|
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time);
|
||||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);
|
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);
|
||||||
|
|||||||
252
bdk/sec/se.c
252
bdk/sec/se.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2022 CTCaer
|
* Copyright (c) 2018-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "se.h"
|
#include "se.h"
|
||||||
#include <memory_map.h>
|
#include <memory_map.h>
|
||||||
#include <mem/heap.h>
|
|
||||||
#include <soc/bpmp.h>
|
#include <soc/bpmp.h>
|
||||||
#include <soc/hw_init.h>
|
#include <soc/hw_init.h>
|
||||||
#include <soc/pmc.h>
|
#include <soc/pmc.h>
|
||||||
@@ -182,7 +181,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
|
|||||||
if (!src || !dst)
|
if (!src || !dst)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
u8 *block = (u8 *)calloc(1, SE_AES_BLOCK_SIZE);
|
u32 block[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0};
|
||||||
|
|
||||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||||
|
|
||||||
@@ -190,11 +189,10 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
|
|||||||
int res = _se_execute_oneshot(op, block, SE_AES_BLOCK_SIZE, block, SE_AES_BLOCK_SIZE);
|
int res = _se_execute_oneshot(op, block, SE_AES_BLOCK_SIZE, block, SE_AES_BLOCK_SIZE);
|
||||||
memcpy(dst, block, dst_size);
|
memcpy(dst, block, dst_size);
|
||||||
|
|
||||||
free(block);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _se_aes_ctr_set(void *ctr)
|
static void _se_aes_ctr_set(const void *ctr)
|
||||||
{
|
{
|
||||||
u32 data[SE_AES_IV_SIZE / 4];
|
u32 data[SE_AES_IV_SIZE / 4];
|
||||||
memcpy(data, ctr, SE_AES_IV_SIZE);
|
memcpy(data, ctr, SE_AES_IV_SIZE);
|
||||||
@@ -226,7 +224,7 @@ u32 se_key_acc_ctrl_get(u32 ks)
|
|||||||
return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks);
|
return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_aes_key_set(u32 ks, void *key, u32 size)
|
void se_aes_key_set(u32 ks, const void *key, u32 size)
|
||||||
{
|
{
|
||||||
u32 data[SE_AES_MAX_KEY_SIZE / 4];
|
u32 data[SE_AES_MAX_KEY_SIZE / 4];
|
||||||
memcpy(data, key, size);
|
memcpy(data, key, size);
|
||||||
@@ -238,7 +236,7 @@ void se_aes_key_set(u32 ks, void *key, u32 size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_aes_iv_set(u32 ks, void *iv)
|
void se_aes_iv_set(u32 ks, const void *iv)
|
||||||
{
|
{
|
||||||
u32 data[SE_AES_IV_SIZE / 4];
|
u32 data[SE_AES_IV_SIZE / 4];
|
||||||
memcpy(data, iv, SE_AES_IV_SIZE);
|
memcpy(data, iv, SE_AES_IV_SIZE);
|
||||||
@@ -281,6 +279,14 @@ void se_aes_iv_clear(u32 ks)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void se_aes_iv_updated_clear(u32 ks)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
|
||||||
|
{
|
||||||
|
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(UPDATED_IV) | SE_KEYTABLE_PKT(i);
|
||||||
|
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
|
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
|
||||||
{
|
{
|
||||||
@@ -292,6 +298,26 @@ int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
|
|||||||
return _se_execute_oneshot(SE_OP_START, NULL, 0, input, SE_KEY_128_SIZE);
|
return _se_execute_oneshot(SE_OP_START, NULL, 0, input, SE_KEY_128_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||||
|
{
|
||||||
|
if (enc)
|
||||||
|
{
|
||||||
|
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||||
|
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
|
||||||
|
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP) |
|
||||||
|
SE_CRYPTO_HASH(HASH_ENABLE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
||||||
|
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
|
||||||
|
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM) |
|
||||||
|
SE_CRYPTO_HASH(HASH_ENABLE);
|
||||||
|
}
|
||||||
|
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||||
|
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
|
||||||
|
}
|
||||||
|
|
||||||
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
|
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||||
{
|
{
|
||||||
if (enc)
|
if (enc)
|
||||||
@@ -361,7 +387,8 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
|
|||||||
int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize)
|
int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
u8 *tweak = (u8 *)malloc(SE_AES_BLOCK_SIZE);
|
u32 tmp[SE_AES_BLOCK_SIZE / sizeof(u32)];
|
||||||
|
u8 *tweak = (u8 *)tmp;
|
||||||
u8 *pdst = (u8 *)dst;
|
u8 *pdst = (u8 *)dst;
|
||||||
u8 *psrc = (u8 *)src;
|
u8 *psrc = (u8 *)src;
|
||||||
|
|
||||||
@@ -371,7 +398,7 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst
|
|||||||
tweak[i] = sec & 0xFF;
|
tweak[i] = sec & 0xFF;
|
||||||
sec >>= 8;
|
sec >>= 8;
|
||||||
}
|
}
|
||||||
if (!se_aes_crypt_block_ecb(tweak_ks, CORE_ENCRYPT, tweak, tweak))
|
if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
// We are assuming a 0x10-aligned sector size in this implementation.
|
// We are assuming a 0x10-aligned sector size in this implementation.
|
||||||
@@ -390,8 +417,7 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst
|
|||||||
|
|
||||||
res = 1;
|
res = 1;
|
||||||
|
|
||||||
out:;
|
out:
|
||||||
free(tweak);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,7 +434,7 @@ int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tw
|
|||||||
tweak[i] = sec & 0xFF;
|
tweak[i] = sec & 0xFF;
|
||||||
sec >>= 8;
|
sec >>= 8;
|
||||||
}
|
}
|
||||||
if (!se_aes_crypt_block_ecb(tweak_ks, CORE_ENCRYPT, tweak, tweak))
|
if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,59 +485,21 @@ int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, vo
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// se_aes_cmac() was derived from Atmosphère's se_compute_aes_cmac
|
static void se_calc_sha256_get_hash(void *hash, u32 *msg_left)
|
||||||
int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
|
|
||||||
{
|
{
|
||||||
int res = 0;
|
u32 hash32[SE_SHA_256_SIZE / 4];
|
||||||
u8 *key = (u8 *)calloc(0x10, 1);
|
|
||||||
u8 *last_block = (u8 *)calloc(0x10, 1);
|
|
||||||
|
|
||||||
// generate derived key
|
// Backup message left.
|
||||||
if (!se_aes_crypt_block_ecb(ks, 1, key, key))
|
if (msg_left)
|
||||||
goto out;
|
|
||||||
_gf256_mul_x(key);
|
|
||||||
if (src_size & 0xF)
|
|
||||||
_gf256_mul_x(key);
|
|
||||||
|
|
||||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG);
|
|
||||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) |
|
|
||||||
SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) |
|
|
||||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
|
|
||||||
se_aes_iv_clear(ks);
|
|
||||||
|
|
||||||
u32 num_blocks = (src_size + 0xf) >> 4;
|
|
||||||
if (num_blocks > 1)
|
|
||||||
{
|
{
|
||||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2;
|
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
|
||||||
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size))
|
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
|
||||||
goto out;
|
|
||||||
SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src_size & 0xf)
|
// Copy output hash.
|
||||||
{
|
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
|
||||||
memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf);
|
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
|
||||||
last_block[src_size & 0xf] = 0x80;
|
memcpy(hash, hash32, SE_SHA_256_SIZE);
|
||||||
}
|
|
||||||
else if (src_size >= 0x10)
|
|
||||||
{
|
|
||||||
memcpy(last_block, src + src_size - 0x10, 0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (u32 i = 0; i < 0x10; i++)
|
|
||||||
last_block[i] ^= key[i];
|
|
||||||
|
|
||||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0;
|
|
||||||
res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, 0x10);
|
|
||||||
|
|
||||||
u32 *dst32 = (u32 *)dst;
|
|
||||||
for (u32 i = 0; i < (dst_size >> 2); i++)
|
|
||||||
dst32[i] = SE(SE_HASH_RESULT_REG + (i << 2));
|
|
||||||
|
|
||||||
out:;
|
|
||||||
free(key);
|
|
||||||
free(last_block);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot)
|
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot)
|
||||||
@@ -523,6 +511,17 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
|
|||||||
if (src_size > 0xFFFFFF || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer.
|
if (src_size > 0xFFFFFF || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer.
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// Src size of 0 is not supported, so return null string sha256.
|
||||||
|
if (!src_size)
|
||||||
|
{
|
||||||
|
const u8 null_hash[SE_SHA_256_SIZE] = {
|
||||||
|
0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
|
||||||
|
0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
|
||||||
|
};
|
||||||
|
memcpy(hash, null_hash, SE_SHA_256_SIZE);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Setup config for SHA256.
|
// Setup config for SHA256.
|
||||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
|
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
|
||||||
SE(SE_SHA_CONFIG_REG) = sha_cfg;
|
SE(SE_SHA_CONFIG_REG) = sha_cfg;
|
||||||
@@ -561,19 +560,7 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
|
|||||||
res = _se_execute(SE_OP_START, NULL, 0, src, src_size, is_oneshot);
|
res = _se_execute(SE_OP_START, NULL, 0, src, src_size, is_oneshot);
|
||||||
|
|
||||||
if (is_oneshot)
|
if (is_oneshot)
|
||||||
{
|
se_calc_sha256_get_hash(hash, msg_left);
|
||||||
// Backup message left.
|
|
||||||
if (msg_left)
|
|
||||||
{
|
|
||||||
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
|
|
||||||
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy output hash.
|
|
||||||
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
|
|
||||||
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
|
|
||||||
memcpy(hash, hash32, SE_SHA_256_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -585,65 +572,10 @@ int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size)
|
|||||||
|
|
||||||
int se_calc_sha256_finalize(void *hash, u32 *msg_left)
|
int se_calc_sha256_finalize(void *hash, u32 *msg_left)
|
||||||
{
|
{
|
||||||
u32 hash32[SE_SHA_256_SIZE / 4];
|
|
||||||
int res = _se_execute_finalize();
|
int res = _se_execute_finalize();
|
||||||
|
|
||||||
// Backup message left.
|
se_calc_sha256_get_hash(hash, msg_left);
|
||||||
if (msg_left)
|
|
||||||
{
|
|
||||||
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
|
|
||||||
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy output hash.
|
|
||||||
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
|
|
||||||
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
|
|
||||||
memcpy(hash, hash32, SE_SHA_256_SIZE);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size)
|
|
||||||
{
|
|
||||||
int res = 0;
|
|
||||||
u8 *secret = (u8 *)malloc(0x40);
|
|
||||||
u8 *ipad = (u8 *)malloc(0x40 + src_size);
|
|
||||||
u8 *opad = (u8 *)malloc(0x60);
|
|
||||||
|
|
||||||
if (key_size > 0x40)
|
|
||||||
{
|
|
||||||
if (!se_calc_sha256_oneshot(secret, key, key_size))
|
|
||||||
goto out;
|
|
||||||
memset(secret + 0x20, 0, 0x20);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(secret, key, key_size);
|
|
||||||
memset(secret + key_size, 0, 0x40 - key_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 *secret32 = (u32 *)secret;
|
|
||||||
u32 *ipad32 = (u32 *)ipad;
|
|
||||||
u32 *opad32 = (u32 *)opad;
|
|
||||||
for (u32 i = 0; i < 0x10; i++)
|
|
||||||
{
|
|
||||||
ipad32[i] = secret32[i] ^ 0x36363636;
|
|
||||||
opad32[i] = secret32[i] ^ 0x5C5C5C5C;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(ipad + 0x40, src, src_size);
|
|
||||||
if (!se_calc_sha256_oneshot(dst, ipad, 0x40 + src_size))
|
|
||||||
goto out;
|
|
||||||
memcpy(opad + 0x40, dst, 0x20);
|
|
||||||
if (!se_calc_sha256_oneshot(dst, opad, 0x60))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
res = 1;
|
|
||||||
|
|
||||||
out:;
|
|
||||||
free(secret);
|
|
||||||
free(ipad);
|
|
||||||
free(opad);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -716,6 +648,66 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
|||||||
// Decrypt context.
|
// Decrypt context.
|
||||||
se_aes_key_clear(3);
|
se_aes_key_clear(3);
|
||||||
se_aes_key_set(3, srk, SE_KEY_128_SIZE);
|
se_aes_key_set(3, srk, SE_KEY_128_SIZE);
|
||||||
se_aes_crypt_cbc(3, CORE_DECRYPT, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize);
|
se_aes_crypt_cbc(3, DECRYPT, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize);
|
||||||
se_aes_key_clear(3);
|
se_aes_key_clear(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
u32 tmp1[SE_KEY_128_SIZE / sizeof(u32)] = {0};
|
||||||
|
u32 tmp2[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0};
|
||||||
|
u8 *key = (u8 *)tmp1;
|
||||||
|
u8 *last_block = (u8 *)tmp2;
|
||||||
|
|
||||||
|
se_aes_iv_clear(ks);
|
||||||
|
se_aes_iv_updated_clear(ks);
|
||||||
|
|
||||||
|
// Generate sub key
|
||||||
|
if (!se_aes_crypt_hash(ks, ENCRYPT, key, SE_KEY_128_SIZE, key, SE_KEY_128_SIZE))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
_gf256_mul_x(key);
|
||||||
|
if (src_size & 0xF)
|
||||||
|
_gf256_mul_x(key);
|
||||||
|
|
||||||
|
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG);
|
||||||
|
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) |
|
||||||
|
SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) |
|
||||||
|
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
|
||||||
|
se_aes_iv_clear(ks);
|
||||||
|
se_aes_iv_updated_clear(ks);
|
||||||
|
|
||||||
|
u32 num_blocks = (src_size + 0xf) >> 4;
|
||||||
|
if (num_blocks > 1)
|
||||||
|
{
|
||||||
|
SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2;
|
||||||
|
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size))
|
||||||
|
goto out;
|
||||||
|
SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src_size & 0xf)
|
||||||
|
{
|
||||||
|
memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf);
|
||||||
|
last_block[src_size & 0xf] = 0x80;
|
||||||
|
}
|
||||||
|
else if (src_size >= SE_AES_BLOCK_SIZE)
|
||||||
|
{
|
||||||
|
memcpy(last_block, src + src_size - SE_AES_BLOCK_SIZE, SE_AES_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < SE_KEY_128_SIZE; i++)
|
||||||
|
last_block[i] ^= key[i];
|
||||||
|
|
||||||
|
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0;
|
||||||
|
res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, SE_AES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
u32 *dst32 = (u32 *)dst;
|
||||||
|
for (u32 i = 0; i < (SE_KEY_128_SIZE / 4); i++)
|
||||||
|
dst32[i] = SE(SE_HASH_RESULT_REG + (i * 4));
|
||||||
|
|
||||||
|
out:
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,12 +25,14 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags);
|
|||||||
void se_key_acc_ctrl(u32 ks, u32 flags);
|
void se_key_acc_ctrl(u32 ks, u32 flags);
|
||||||
u32 se_key_acc_ctrl_get(u32 ks);
|
u32 se_key_acc_ctrl_get(u32 ks);
|
||||||
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize);
|
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize);
|
||||||
void se_aes_key_set(u32 ks, void *key, u32 size);
|
void se_aes_key_set(u32 ks, const void *key, u32 size);
|
||||||
void se_aes_iv_set(u32 ks, void *iv);
|
void se_aes_iv_set(u32 ks, const void *iv);
|
||||||
void se_aes_key_get(u32 ks, void *key, u32 size);
|
void se_aes_key_get(u32 ks, void *key, u32 size);
|
||||||
void se_aes_key_clear(u32 ks);
|
void se_aes_key_clear(u32 ks);
|
||||||
void se_aes_iv_clear(u32 ks);
|
void se_aes_iv_clear(u32 ks);
|
||||||
|
void se_aes_iv_updated_clear(u32 ks);
|
||||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
|
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
|
||||||
|
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||||
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||||
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||||
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
|
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
|
||||||
@@ -38,11 +40,10 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *ds
|
|||||||
int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size);
|
int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size);
|
||||||
int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs);
|
int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs);
|
||||||
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);
|
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);
|
||||||
int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size);
|
|
||||||
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot);
|
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot);
|
||||||
int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size);
|
int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size);
|
||||||
int se_calc_sha256_finalize(void *hash, u32 *msg_left);
|
int se_calc_sha256_finalize(void *hash, u32 *msg_left);
|
||||||
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size);
|
|
||||||
int se_gen_prng128(void *dst);
|
int se_gen_prng128(void *dst);
|
||||||
|
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -50,6 +50,9 @@
|
|||||||
#define SE_RSA1536_DIGEST_SIZE 192
|
#define SE_RSA1536_DIGEST_SIZE 192
|
||||||
#define SE_RSA2048_DIGEST_SIZE 256
|
#define SE_RSA2048_DIGEST_SIZE 256
|
||||||
|
|
||||||
|
#define DECRYPT 0
|
||||||
|
#define ENCRYPT 1
|
||||||
|
|
||||||
/* SE register definitions */
|
/* SE register definitions */
|
||||||
#define SE_SE_SECURITY_REG 0x000
|
#define SE_SE_SECURITY_REG 0x000
|
||||||
#define SE_HARD_SETTING BIT(0)
|
#define SE_HARD_SETTING BIT(0)
|
||||||
|
|||||||
101
bdk/sec/tsec.c
101
bdk/sec/tsec.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2021 CTCaer
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
* Copyright (c) 2018 balika011
|
* Copyright (c) 2018 balika011
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -70,11 +70,12 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||||||
int res = 0;
|
int res = 0;
|
||||||
u8 *fwbuf = NULL;
|
u8 *fwbuf = NULL;
|
||||||
u32 type = tsec_ctxt->type;
|
u32 type = tsec_ctxt->type;
|
||||||
u32 *pdir, *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec;
|
u32 *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec;
|
||||||
u32 *pkg11_magic_off;
|
u32 *pkg11_magic_off;
|
||||||
|
void *ptb;
|
||||||
|
|
||||||
bpmp_mmu_disable();
|
bpmp_mmu_disable();
|
||||||
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
bpmp_clk_rate_relaxed(true);
|
||||||
|
|
||||||
// Enable clocks.
|
// Enable clocks.
|
||||||
clock_enable_tsec();
|
clock_enable_tsec();
|
||||||
@@ -90,10 +91,10 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||||||
if (type == TSEC_FW_TYPE_NEW)
|
if (type == TSEC_FW_TYPE_NEW)
|
||||||
{
|
{
|
||||||
// Disable all CCPLEX core rails.
|
// Disable all CCPLEX core rails.
|
||||||
pmc_enable_partition(POWER_RAIL_CE0, DISABLE);
|
pmc_domain_pwrgate_set(POWER_RAIL_CE0, DISABLE);
|
||||||
pmc_enable_partition(POWER_RAIL_CE1, DISABLE);
|
pmc_domain_pwrgate_set(POWER_RAIL_CE1, DISABLE);
|
||||||
pmc_enable_partition(POWER_RAIL_CE2, DISABLE);
|
pmc_domain_pwrgate_set(POWER_RAIL_CE2, DISABLE);
|
||||||
pmc_enable_partition(POWER_RAIL_CE3, DISABLE);
|
pmc_domain_pwrgate_set(POWER_RAIL_CE3, DISABLE);
|
||||||
|
|
||||||
// Enable AHB aperture and set it to full mmio.
|
// Enable AHB aperture and set it to full mmio.
|
||||||
mc_enable_ahb_redirect();
|
mc_enable_ahb_redirect();
|
||||||
@@ -145,64 +146,64 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||||||
if (type == TSEC_FW_TYPE_EMU)
|
if (type == TSEC_FW_TYPE_EMU)
|
||||||
{
|
{
|
||||||
// Init SMMU translation for TSEC.
|
// Init SMMU translation for TSEC.
|
||||||
pdir = smmu_init_for_tsec();
|
ptb = smmu_init_domain(MC_SMMU_TSEC_ASID, 1);
|
||||||
smmu_init(tsec_ctxt->secmon_base);
|
smmu_init();
|
||||||
// Enable SMMU
|
|
||||||
if (!smmu_is_used())
|
// Enable SMMU.
|
||||||
smmu_enable();
|
smmu_enable();
|
||||||
|
|
||||||
// Clock reset controller.
|
// Clock reset controller.
|
||||||
car = page_alloc(1);
|
car = smmu_page_zalloc(1);
|
||||||
memcpy(car, (void *)CLOCK_BASE, SZ_PAGE);
|
memcpy(car, (void *)CLOCK_BASE, SZ_PAGE);
|
||||||
car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = 2;
|
car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = CLK_SRC_DIV(2);
|
||||||
smmu_map(pdir, CLOCK_BASE, (u32)car, 1, _WRITABLE | _READABLE | _NONSECURE);
|
smmu_map(ptb, CLOCK_BASE, (u32)car, 1, SMMU_WRITE | SMMU_READ | SMMU_NS);
|
||||||
|
|
||||||
// Fuse driver.
|
// Fuse driver.
|
||||||
fuse = page_alloc(1);
|
fuse = smmu_page_zalloc(1);
|
||||||
memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, SZ_1K);
|
memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, SZ_1K);
|
||||||
fuse[0x82C / 4] = 0;
|
fuse[0x82C / 4] = 0;
|
||||||
fuse[0x9E0 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
|
fuse[0x9E0 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
|
||||||
fuse[0x9E4 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
|
fuse[0x9E4 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
|
||||||
smmu_map(pdir, (FUSE_BASE - 0x800), (u32)fuse, 1, _READABLE | _NONSECURE);
|
smmu_map(ptb, (FUSE_BASE - 0x800), (u32)fuse, 1, SMMU_READ | SMMU_NS);
|
||||||
|
|
||||||
// Power management controller.
|
// Power management controller.
|
||||||
pmc = page_alloc(1);
|
pmc = smmu_page_zalloc(1);
|
||||||
smmu_map(pdir, RTC_BASE, (u32)pmc, 1, _READABLE | _NONSECURE);
|
smmu_map(ptb, RTC_BASE, (u32)pmc, 1, SMMU_READ | SMMU_NS);
|
||||||
|
|
||||||
// Flow control.
|
// Flow control.
|
||||||
flowctrl = page_alloc(1);
|
flowctrl = smmu_page_zalloc(1);
|
||||||
smmu_map(pdir, FLOW_CTLR_BASE, (u32)flowctrl, 1, _WRITABLE | _NONSECURE);
|
smmu_map(ptb, FLOW_CTLR_BASE, (u32)flowctrl, 1, SMMU_WRITE | SMMU_NS);
|
||||||
|
|
||||||
// Security engine.
|
// Security engine.
|
||||||
se = page_alloc(1);
|
se = smmu_page_zalloc(1);
|
||||||
memcpy(se, (void *)SE_BASE, SZ_PAGE);
|
memcpy(se, (void *)SE_BASE, SZ_PAGE);
|
||||||
smmu_map(pdir, SE_BASE, (u32)se, 1, _READABLE | _WRITABLE | _NONSECURE);
|
smmu_map(ptb, SE_BASE, (u32)se, 1, SMMU_READ | SMMU_WRITE | SMMU_NS);
|
||||||
|
|
||||||
// Memory controller.
|
// Memory controller.
|
||||||
mc = page_alloc(1);
|
mc = smmu_page_zalloc(1);
|
||||||
memcpy(mc, (void *)MC_BASE, SZ_PAGE);
|
memcpy(mc, (void *)MC_BASE, SZ_PAGE);
|
||||||
mc[MC_IRAM_BOM / 4] = 0;
|
mc[MC_IRAM_BOM / 4] = 0;
|
||||||
mc[MC_IRAM_TOM / 4] = DRAM_START;
|
mc[MC_IRAM_TOM / 4] = DRAM_START;
|
||||||
smmu_map(pdir, MC_BASE, (u32)mc, 1, _READABLE | _NONSECURE);
|
smmu_map(ptb, MC_BASE, (u32)mc, 1, SMMU_READ | SMMU_NS);
|
||||||
|
|
||||||
// IRAM
|
// IRAM
|
||||||
iram = page_alloc(0x30);
|
iram = smmu_page_zalloc(0x30);
|
||||||
memcpy(iram, tsec_ctxt->pkg1, 0x30000);
|
memcpy(iram, tsec_ctxt->pkg1, 0x30000);
|
||||||
// PKG1.1 magic offset.
|
// PKG1.1 magic offset.
|
||||||
pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / 4));
|
pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / sizeof(u32)));
|
||||||
smmu_map(pdir, 0x40010000, (u32)iram, 0x30, _READABLE | _WRITABLE | _NONSECURE);
|
smmu_map(ptb, 0x40010000, (u32)iram, 0x30, SMMU_READ | SMMU_WRITE | SMMU_NS);
|
||||||
|
|
||||||
// Exception vectors
|
// Exception vectors
|
||||||
evec = page_alloc(1);
|
evec = smmu_page_zalloc(1);
|
||||||
smmu_map(pdir, EXCP_VEC_BASE, (u32)evec, 1, _READABLE | _WRITABLE | _NONSECURE);
|
smmu_map(ptb, EXCP_VEC_BASE, (u32)evec, 1, SMMU_READ | SMMU_WRITE | SMMU_NS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute firmware.
|
// Execute firmware.
|
||||||
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0x34C2E1DA;
|
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0x34C2E1DA;
|
||||||
TSEC(TSEC_STATUS) = 0;
|
TSEC(TSEC_MAILBOX1) = 0;
|
||||||
TSEC(TSEC_BOOTKEYVER) = 1; // HOS uses key version 1.
|
TSEC(TSEC_MAILBOX0) = 1; // Set HOS key version.
|
||||||
TSEC(TSEC_BOOTVEC) = 0;
|
TSEC(TSEC_BOOTVEC) = 0;
|
||||||
TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
|
TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
|
||||||
|
|
||||||
if (type == TSEC_FW_TYPE_EMU)
|
if (type == TSEC_FW_TYPE_EMU)
|
||||||
{
|
{
|
||||||
@@ -229,7 +230,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||||||
if (kidx != 8)
|
if (kidx != 8)
|
||||||
{
|
{
|
||||||
res = -6;
|
res = -6;
|
||||||
smmu_deinit_for_tsec();
|
smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
|
||||||
|
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
@@ -240,12 +241,12 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||||||
memcpy(tsec_keys, &key, 0x20);
|
memcpy(tsec_keys, &key, 0x20);
|
||||||
memcpy(tsec_ctxt->pkg1, iram, 0x30000);
|
memcpy(tsec_ctxt->pkg1, iram, 0x30000);
|
||||||
|
|
||||||
smmu_deinit_for_tsec();
|
smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
|
||||||
|
|
||||||
// for (int i = 0; i < kidx; i++)
|
// for (int i = 0; i < kidx; i++)
|
||||||
// gfx_printf("key %08X\n", key[i]);
|
// gfx_printf("key %08X\n", key[i]);
|
||||||
|
|
||||||
// gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_STATUS));
|
// gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_MAILBOX1));
|
||||||
|
|
||||||
// u32 errst = MC(MC_ERR_STATUS);
|
// u32 errst = MC(MC_ERR_STATUS);
|
||||||
// gfx_printf(" MC %08X %08X %08X\n", MC(MC_INTSTATUS), errst, MC(MC_ERR_ADR));
|
// gfx_printf(" MC %08X %08X %08X\n", MC(MC_INTSTATUS), errst, MC(MC_ERR_ADR));
|
||||||
@@ -261,14 +262,18 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||||||
res = -3;
|
res = -3;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 timeout = get_tmr_ms() + 2000;
|
u32 timeout = get_tmr_ms() + 2000;
|
||||||
while (!TSEC(TSEC_STATUS))
|
while (!TSEC(TSEC_MAILBOX1))
|
||||||
|
{
|
||||||
if (get_tmr_ms() > timeout)
|
if (get_tmr_ms() > timeout)
|
||||||
{
|
{
|
||||||
res = -4;
|
res = -4;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
if (TSEC(TSEC_STATUS) != 0xB0B0B0B0)
|
}
|
||||||
|
|
||||||
|
if (TSEC(TSEC_MAILBOX1) != 0xB0B0B0B0)
|
||||||
{
|
{
|
||||||
res = -5;
|
res = -5;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
@@ -277,14 +282,14 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||||||
// Fetch result.
|
// Fetch result.
|
||||||
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0;
|
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0;
|
||||||
u32 buf[4];
|
u32 buf[4];
|
||||||
buf[0] = SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB);
|
buf[0] = SOR1(SOR_DP_HDCP_BKSV_LSB);
|
||||||
buf[1] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB);
|
buf[1] = SOR1(SOR_TMDS_HDCP_BKSV_LSB);
|
||||||
buf[2] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB);
|
buf[2] = SOR1(SOR_TMDS_HDCP_CN_MSB);
|
||||||
buf[3] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB);
|
buf[3] = SOR1(SOR_TMDS_HDCP_CN_LSB);
|
||||||
SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB) = 0;
|
SOR1(SOR_DP_HDCP_BKSV_LSB) = 0;
|
||||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB) = 0;
|
SOR1(SOR_TMDS_HDCP_BKSV_LSB) = 0;
|
||||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0;
|
SOR1(SOR_TMDS_HDCP_CN_MSB) = 0;
|
||||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0;
|
SOR1(SOR_TMDS_HDCP_CN_LSB) = 0;
|
||||||
|
|
||||||
memcpy(tsec_keys, &buf, SE_KEY_128_SIZE);
|
memcpy(tsec_keys, &buf, SE_KEY_128_SIZE);
|
||||||
}
|
}
|
||||||
@@ -300,7 +305,7 @@ out:
|
|||||||
clock_disable_sor_safe();
|
clock_disable_sor_safe();
|
||||||
clock_disable_tsec();
|
clock_disable_tsec();
|
||||||
bpmp_mmu_enable();
|
bpmp_mmu_enable();
|
||||||
bpmp_clk_rate_set(prev_fid);
|
bpmp_clk_rate_relaxed(false);
|
||||||
|
|
||||||
#ifdef BDK_MC_ENABLE_AHB_REDIRECT
|
#ifdef BDK_MC_ENABLE_AHB_REDIRECT
|
||||||
// Re-enable AHB aperture.
|
// Re-enable AHB aperture.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2021 CTCaer
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -20,13 +20,11 @@
|
|||||||
|
|
||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
|
|
||||||
#define TSEC_KEY_DATA_OFFSET 0x300
|
|
||||||
|
|
||||||
enum tsec_fw_type
|
enum tsec_fw_type
|
||||||
{
|
{
|
||||||
// Retail Hovi Keygen.
|
// Retail Hovi Keygen.
|
||||||
TSEC_FW_TYPE_OLD = 0, // 1.0.0 - 6.1.0.
|
TSEC_FW_TYPE_OLD = 0, // 1.0.0 - 6.1.0.
|
||||||
TSEC_FW_TYPE_EMU = 1, // 6.2.0 emulated enviroment.
|
TSEC_FW_TYPE_EMU = 1, // 6.2.0 emulated environment.
|
||||||
TSEC_FW_TYPE_NEW = 2, // 7.0.0+.
|
TSEC_FW_TYPE_NEW = 2, // 7.0.0+.
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,26 +35,8 @@ typedef struct _tsec_ctxt_t
|
|||||||
u32 type;
|
u32 type;
|
||||||
void *pkg1;
|
void *pkg1;
|
||||||
u32 pkg11_off;
|
u32 pkg11_off;
|
||||||
u32 secmon_base;
|
|
||||||
} tsec_ctxt_t;
|
} tsec_ctxt_t;
|
||||||
|
|
||||||
typedef struct _tsec_key_data_t
|
|
||||||
{
|
|
||||||
u8 debug_key[0x10];
|
|
||||||
u8 blob0_auth_hash[0x10];
|
|
||||||
u8 blob1_auth_hash[0x10];
|
|
||||||
u8 blob2_auth_hash[0x10];
|
|
||||||
u8 blob2_aes_iv[0x10];
|
|
||||||
u8 hovi_eks_seed[0x10];
|
|
||||||
u8 hovi_common_seed[0x10];
|
|
||||||
u32 blob0_size;
|
|
||||||
u32 blob1_size;
|
|
||||||
u32 blob2_size;
|
|
||||||
u32 blob3_size;
|
|
||||||
u32 blob4_size;
|
|
||||||
u8 reserved[0x7C];
|
|
||||||
} tsec_key_data_t;
|
|
||||||
|
|
||||||
int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt);
|
int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 CTCaer
|
* Copyright (c) 2018-2023 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
#ifndef _TSEC_T210_H_
|
#ifndef _TSEC_T210_H_
|
||||||
#define _TSEC_T210_H_
|
#define _TSEC_T210_H_
|
||||||
|
|
||||||
#define TSEC_BOOTKEYVER 0x1040
|
#define TSEC_MAILBOX0 0x1040
|
||||||
#define TSEC_STATUS 0x1044
|
#define TSEC_MAILBOX1 0x1044
|
||||||
#define TSEC_ITFEN 0x1048
|
#define TSEC_ITFEN 0x1048
|
||||||
#define TSEC_ITFEN_CTXEN BIT(0)
|
#define TSEC_ITFEN_CTXEN BIT(0)
|
||||||
#define TSEC_ITFEN_MTHDEN BIT(1)
|
#define TSEC_ITFEN_MTHDEN BIT(1)
|
||||||
|
|||||||
@@ -76,7 +76,9 @@
|
|||||||
#define ACTMON_HISTOGRAM_DATA_BASE 0x380
|
#define ACTMON_HISTOGRAM_DATA_BASE 0x380
|
||||||
#define ACTMON_HISTOGRAM_DATA_NUM 32
|
#define ACTMON_HISTOGRAM_DATA_NUM 32
|
||||||
|
|
||||||
#define ACTMON_FREQ 19200000
|
#define ACTMON_FREQ 19200000
|
||||||
|
#define ACTMON_PERIOD_MS 20
|
||||||
|
#define DEV_COUNT_WEIGHT 5
|
||||||
|
|
||||||
typedef struct _actmon_dev_reg_t
|
typedef struct _actmon_dev_reg_t
|
||||||
{
|
{
|
||||||
@@ -91,11 +93,9 @@ typedef struct _actmon_dev_reg_t
|
|||||||
vu32 avg_count;
|
vu32 avg_count;
|
||||||
vu32 intr_status;
|
vu32 intr_status;
|
||||||
vu32 ctrl2;
|
vu32 ctrl2;
|
||||||
vu32 unk[5];
|
vu32 rsvd[5];
|
||||||
} actmon_dev_reg_t;
|
} actmon_dev_reg_t;
|
||||||
|
|
||||||
u32 sample_period = 0;
|
|
||||||
|
|
||||||
void actmon_hist_enable(actmon_hist_src_t src)
|
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_CONFIG) = ACTMON_HIST_CFG_SOURCE(src) | ACTMON_HIST_CFG_ACTIVE;
|
||||||
@@ -120,10 +120,10 @@ void actmon_dev_enable(actmon_dev_t dev)
|
|||||||
{
|
{
|
||||||
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
|
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
|
||||||
|
|
||||||
regs->init_avg = 0;
|
regs->init_avg = ACTMON_FREQ * ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT / 100;
|
||||||
regs->count_weight = 5;
|
regs->count_weight = DEV_COUNT_WEIGHT;
|
||||||
|
|
||||||
regs->ctrl = ACTMON_DEV_CTRL_ENB | ACTMON_DEV_CTRL_ENB_PERIODIC;
|
regs->ctrl = ACTMON_DEV_CTRL_ENB | ACTMON_DEV_CTRL_ENB_PERIODIC | ACTMON_DEV_CTRL_K_VAL(7); // 128 samples average.
|
||||||
}
|
}
|
||||||
|
|
||||||
void actmon_dev_disable(actmon_dev_t dev)
|
void actmon_dev_disable(actmon_dev_t dev)
|
||||||
@@ -138,7 +138,7 @@ 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));
|
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
|
||||||
|
|
||||||
// Get load-based sampling. 1 decimal point precision.
|
// Get load-based sampling. 1 decimal point precision.
|
||||||
u32 load = regs->count / (ACTMON_FREQ / 1000);
|
u32 load = regs->count * 100 / (ACTMON_FREQ / (ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT));
|
||||||
|
|
||||||
return load;
|
return load;
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ 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));
|
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
|
||||||
|
|
||||||
// Get load-based sampling. 1 decimal point precision.
|
// Get load-based sampling. 1 decimal point precision.
|
||||||
u32 avg_load = regs->avg_count / (ACTMON_FREQ / 1000);
|
u32 avg_load = regs->avg_count * 100 / (ACTMON_FREQ / (ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT));
|
||||||
|
|
||||||
return avg_load;
|
return avg_load;
|
||||||
}
|
}
|
||||||
@@ -162,9 +162,8 @@ void actmon_init()
|
|||||||
{
|
{
|
||||||
clock_enable_actmon();
|
clock_enable_actmon();
|
||||||
|
|
||||||
// Set period to 200ms.
|
// Set period.
|
||||||
ACTMON(ACTMON_GLB_PERIOD_CTRL) &= ~ACTMON_GLB_PERIOD_USEC;
|
ACTMON(ACTMON_GLB_PERIOD_CTRL) = ACTMON_GLB_PERIOD_SAMPLE(ACTMON_PERIOD_MS);
|
||||||
ACTMON(ACTMON_GLB_PERIOD_CTRL) |= ACTMON_GLB_PERIOD_SAMPLE(200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void actmon_end()
|
void actmon_end()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019-2023 CTCaer
|
* Copyright (c) 2019-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
#define MMU_EN_READ BIT(2)
|
#define MMU_EN_READ BIT(2)
|
||||||
#define MMU_EN_WRITE BIT(3)
|
#define MMU_EN_WRITE BIT(3)
|
||||||
|
|
||||||
bpmp_mmu_entry_t mmu_entries[] =
|
static const bpmp_mmu_entry_t mmu_entries[] =
|
||||||
{
|
{
|
||||||
{ DRAM_START, 0xFFFFFFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true },
|
{ DRAM_START, 0xFFFFFFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true },
|
||||||
{ IRAM_BASE, 0x4003FFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true }
|
{ IRAM_BASE, 0x4003FFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true }
|
||||||
@@ -140,7 +140,7 @@ void bpmp_mmu_maintenance(u32 op, bool force)
|
|||||||
BPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT);
|
BPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply)
|
void bpmp_mmu_set_entry(int idx, const bpmp_mmu_entry_t *entry, bool apply)
|
||||||
{
|
{
|
||||||
if (idx > 31)
|
if (idx > 31)
|
||||||
return;
|
return;
|
||||||
@@ -200,10 +200,45 @@ void bpmp_mmu_disable()
|
|||||||
BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0;
|
BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CLK_RST_CONTROLLER_SCLK_BURST_POLICY:
|
||||||
|
* 0 = CLKM
|
||||||
|
* 1 = PLLC_OUT1
|
||||||
|
* 2 = PLLC4_OUT3
|
||||||
|
* 3 = PLLP_OUT0
|
||||||
|
* 4 = PLLP_OUT2
|
||||||
|
* 5 = PLLC4_OUT1
|
||||||
|
* 6 = CLK_S
|
||||||
|
* 7 = PLLC4_OUT2
|
||||||
|
*/
|
||||||
|
|
||||||
|
bpmp_freq_t bpmp_fid_current = BPMP_CLK_NORMAL;
|
||||||
|
|
||||||
|
void bpmp_clk_rate_relaxed(bool enable)
|
||||||
|
{
|
||||||
|
// This is a glitch-free way to reduce the SCLK timings.
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
// Restore to PLLP source during PLLC configuration.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003330; // PLLP_OUT.
|
||||||
|
usleep(100); // Wait a bit for clock source change.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // PCLK = HCLK / (2 + 1). HCLK == SCLK.
|
||||||
|
}
|
||||||
|
else if (bpmp_fid_current)
|
||||||
|
{
|
||||||
|
// Restore to PLLC_OUT1.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 3; // PCLK = HCLK / (3 + 1). HCLK == SCLK.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003310; // PLLC_OUT1 and CLKM for idle.
|
||||||
|
usleep(100); // Wait a bit for clock source change.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// APB clock affects RTC, PWM, MEMFETCH, APE, USB, SOR PWM,
|
// APB clock affects RTC, PWM, MEMFETCH, APE, USB, SOR PWM,
|
||||||
// I2C host, DC/DSI/DISP. UART gives extra stress.
|
// I2C host, DC/DSI/DISP. UART gives extra stress.
|
||||||
// 92: 100% success ratio. 93-94: 595-602MHz has 99% success ratio. 95: 608MHz less.
|
// 92: 100% success ratio. 93-94: 595-602MHz has 99% success ratio. 95: 608MHz less.
|
||||||
const u8 pll_divn[] = {
|
// APB clock max is supposed to be 204 MHz though.
|
||||||
|
static const u8 pll_divn[] = {
|
||||||
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
|
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
|
||||||
85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB.
|
85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB.
|
||||||
88, // BPMP_CLK_HIGH2_BOOST: 563MHz 38% - 141MHz APB.
|
88, // BPMP_CLK_HIGH2_BOOST: 563MHz 38% - 141MHz APB.
|
||||||
@@ -213,8 +248,6 @@ const u8 pll_divn[] = {
|
|||||||
//95 // BPMP_CLK_DEV_BOOST: 608MHz 49% - 152MHz APB.
|
//95 // BPMP_CLK_DEV_BOOST: 608MHz 49% - 152MHz APB.
|
||||||
};
|
};
|
||||||
|
|
||||||
bpmp_freq_t bpmp_fid_current = BPMP_CLK_NORMAL;
|
|
||||||
|
|
||||||
void bpmp_clk_rate_get()
|
void bpmp_clk_rate_get()
|
||||||
{
|
{
|
||||||
bool clk_src_is_pllp = ((CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) >> 4) & 7) == 3;
|
bool clk_src_is_pllp = ((CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) >> 4) & 7) == 3;
|
||||||
@@ -237,45 +270,42 @@ void bpmp_clk_rate_get()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bpmp_freq_t bpmp_clk_rate_set(bpmp_freq_t fid)
|
void bpmp_clk_rate_set(bpmp_freq_t fid)
|
||||||
{
|
{
|
||||||
bpmp_freq_t prev_fid = bpmp_fid_current;
|
|
||||||
|
|
||||||
if (fid > (BPMP_CLK_MAX - 1))
|
if (fid > (BPMP_CLK_MAX - 1))
|
||||||
fid = BPMP_CLK_MAX - 1;
|
fid = BPMP_CLK_MAX - 1;
|
||||||
|
|
||||||
if (prev_fid == fid)
|
if (bpmp_fid_current == fid)
|
||||||
return prev_fid;
|
return;
|
||||||
|
|
||||||
|
bpmp_fid_current = fid;
|
||||||
|
|
||||||
if (fid)
|
if (fid)
|
||||||
{
|
{
|
||||||
if (prev_fid)
|
// Use default SCLK / HCLK / PCLK clocks.
|
||||||
{
|
bpmp_clk_rate_relaxed(true);
|
||||||
// Restore to PLLP source during PLLC configuration.
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // PLLP_OUT.
|
|
||||||
msleep(1); // Wait a bit for clock source change.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure and enable PLLC.
|
// Configure and enable PLLC.
|
||||||
clock_enable_pllc(pll_divn[fid]);
|
clock_enable_pllc(pll_divn[fid]);
|
||||||
|
|
||||||
// Set SCLK / HCLK / PCLK.
|
// Set new source and SCLK / HCLK / PCLK dividers.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 3; // PCLK = HCLK / (3 + 1). HCLK == SCLK.
|
bpmp_clk_rate_relaxed(false);
|
||||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003310; // PLLC_OUT1 for active and CLKM for idle.
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003330; // PLLP_OUT for active and CLKM for idle.
|
// Use default SCLK / HCLK / PCLK clocks.
|
||||||
msleep(1); // Wait a bit for clock source change.
|
bpmp_clk_rate_relaxed(true);
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // PCLK = HCLK / (2 + 1). HCLK == SCLK.
|
|
||||||
|
|
||||||
// Disable PLLC to save power.
|
// Disable PLLC to save power.
|
||||||
clock_disable_pllc();
|
clock_disable_pllc();
|
||||||
}
|
}
|
||||||
bpmp_fid_current = fid;
|
}
|
||||||
|
|
||||||
// Return old fid in case of temporary swap.
|
// State is reset to RUN on any clock or source set via SW.
|
||||||
return prev_fid;
|
void bpmp_state_set(bpmp_state_t state)
|
||||||
|
{
|
||||||
|
u32 cfg = CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & ~0xF0000000u;
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = cfg | (state << 28u);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following functions halt BPMP to reduce power while sleeping.
|
// The following functions halt BPMP to reduce power while sleeping.
|
||||||
@@ -287,10 +317,10 @@ void bpmp_usleep(u32 us)
|
|||||||
// Each iteration takes 1us.
|
// Each iteration takes 1us.
|
||||||
while (us)
|
while (us)
|
||||||
{
|
{
|
||||||
delay = (us > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : us;
|
delay = (us > HALT_MAX_CNT) ? HALT_MAX_CNT : us;
|
||||||
us -= delay;
|
us -= delay;
|
||||||
|
|
||||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_USEC | delay;
|
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_USEC | delay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,14 +331,14 @@ void bpmp_msleep(u32 ms)
|
|||||||
// Iteration time is variable. ~200 - 1000us.
|
// Iteration time is variable. ~200 - 1000us.
|
||||||
while (ms)
|
while (ms)
|
||||||
{
|
{
|
||||||
delay = (ms > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : ms;
|
delay = (ms > HALT_MAX_CNT) ? HALT_MAX_CNT : ms;
|
||||||
ms -= delay;
|
ms -= delay;
|
||||||
|
|
||||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_MSEC | delay;
|
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_MSEC | delay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bpmp_halt()
|
void bpmp_halt()
|
||||||
{
|
{
|
||||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_JTAG;
|
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_JTAG;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019-2023 CTCaer
|
* Copyright (c) 2019-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -54,16 +54,32 @@ typedef enum
|
|||||||
BPMP_CLK_MAX
|
BPMP_CLK_MAX
|
||||||
} bpmp_freq_t;
|
} bpmp_freq_t;
|
||||||
|
|
||||||
#define BPMP_CLK_LOWEST_BOOST BPMP_CLK_HIGH2_BOOST
|
typedef enum
|
||||||
#define BPMP_CLK_LOWER_BOOST BPMP_CLK_SUPER_BOOST
|
{
|
||||||
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST
|
BPMP_STATE_STANDBY = 0, // 32KHz.
|
||||||
|
BPMP_STATE_IDLE = 1,
|
||||||
|
BPMP_STATE_RUN = 2,
|
||||||
|
|
||||||
|
BPMP_STATE_IRQ = BIT(2),
|
||||||
|
BPMP_STATE_FIQ = BIT(3),
|
||||||
|
} bpmp_state_t;
|
||||||
|
|
||||||
|
#define BPMP_CLK_BIN0_BOOST BPMP_CLK_HYPER_BOOST
|
||||||
|
#define BPMP_CLK_BIN1_BOOST BPMP_CLK_SUPER_BOOST
|
||||||
|
#define BPMP_CLK_BIN2_BOOST BPMP_CLK_HIGH2_BOOST
|
||||||
|
#define BPMP_CLK_BIN3_BOOST BPMP_CLK_HIGH_BOOST
|
||||||
|
|
||||||
|
#define BPMP_CLK_LOWER_BOOST BPMP_CLK_BIN1_BOOST
|
||||||
|
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_BIN0_BOOST
|
||||||
|
|
||||||
void bpmp_mmu_maintenance(u32 op, bool force);
|
void bpmp_mmu_maintenance(u32 op, bool force);
|
||||||
void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply);
|
void bpmp_mmu_set_entry(int idx, const bpmp_mmu_entry_t *entry, bool apply);
|
||||||
void bpmp_mmu_enable();
|
void bpmp_mmu_enable();
|
||||||
void bpmp_mmu_disable();
|
void bpmp_mmu_disable();
|
||||||
|
void bpmp_clk_rate_relaxed(bool enable);
|
||||||
void bpmp_clk_rate_get();
|
void bpmp_clk_rate_get();
|
||||||
bpmp_freq_t bpmp_clk_rate_set(bpmp_freq_t fid);
|
void bpmp_clk_rate_set(bpmp_freq_t fid);
|
||||||
|
void bpmp_state_set(bpmp_state_t state);
|
||||||
void bpmp_usleep(u32 us);
|
void bpmp_usleep(u32 us);
|
||||||
void bpmp_msleep(u32 ms);
|
void bpmp_msleep(u32 ms);
|
||||||
void bpmp_halt();
|
void bpmp_halt();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2022 CTCaer
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -27,7 +27,9 @@
|
|||||||
#include <power/max77812.h>
|
#include <power/max77812.h>
|
||||||
#include <utils/util.h>
|
#include <utils/util.h>
|
||||||
|
|
||||||
void _ccplex_enable_power_t210()
|
#define CCPLEX_FLOWCTRL_POWERGATING 0
|
||||||
|
|
||||||
|
static void _ccplex_enable_power_t210()
|
||||||
{
|
{
|
||||||
// Configure GPIO5 and enable output in order to power CPU pmic.
|
// Configure GPIO5 and enable output in order to power CPU pmic.
|
||||||
max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_ENABLE);
|
max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_ENABLE);
|
||||||
@@ -37,19 +39,31 @@ void _ccplex_enable_power_t210()
|
|||||||
// 1.0.0-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL.
|
// 1.0.0-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL.
|
||||||
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_HOS_CFG);
|
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_HOS_CFG);
|
||||||
|
|
||||||
// Set voltage and enable cores power.
|
// Set voltage and enable cluster power.
|
||||||
max7762x_regulator_set_voltage(REGULATOR_CPU0, 950000);
|
max7762x_regulator_set_voltage(REGULATOR_CPU0, 950000);
|
||||||
max7762x_regulator_enable(REGULATOR_CPU0, true);
|
max7762x_regulator_enable(REGULATOR_CPU0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _ccplex_enable_power_t210b01()
|
static void _ccplex_enable_power_t210b01()
|
||||||
{
|
{
|
||||||
// Set voltage and enable cores power.
|
// Set voltage and enable cluster power.
|
||||||
max7762x_regulator_set_voltage(REGULATOR_CPU1, 800000);
|
max7762x_regulator_set_voltage(REGULATOR_CPU1, 800000);
|
||||||
max7762x_regulator_enable(REGULATOR_CPU1, true);
|
max7762x_regulator_enable(REGULATOR_CPU1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ccplex_boot_cpu0(u32 entry)
|
static void _ccplex_disable_power()
|
||||||
|
{
|
||||||
|
// Disable cluster power.
|
||||||
|
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
||||||
|
{
|
||||||
|
max7762x_regulator_enable(REGULATOR_CPU0, false);
|
||||||
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
max7762x_regulator_enable(REGULATOR_CPU1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ccplex_boot_cpu0(u32 entry, bool lock)
|
||||||
{
|
{
|
||||||
// Set ACTIVE_CLUSER to FAST.
|
// Set ACTIVE_CLUSER to FAST.
|
||||||
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW;
|
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW;
|
||||||
@@ -62,12 +76,12 @@ void ccplex_boot_cpu0(u32 entry)
|
|||||||
clock_enable_pllx();
|
clock_enable_pllx();
|
||||||
|
|
||||||
// Configure MSELECT source and enable clock to 102MHz.
|
// 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_SOURCE_MSELECT) = (0 << 29) | CLK_SRC_DIV(4);
|
||||||
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.
|
// Configure initial CPU clock frequency and enable clock.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; // PLLX_OUT0_LJ.
|
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; // PLLX_OUT0_LJ.
|
||||||
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;
|
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = BIT(31); // SUPER_CDIV_ENB.
|
||||||
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();
|
clock_enable_coresight();
|
||||||
@@ -76,11 +90,11 @@ void ccplex_boot_cpu0(u32 entry)
|
|||||||
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;
|
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;
|
||||||
|
|
||||||
// Enable CPU main rail.
|
// Enable CPU main rail.
|
||||||
pmc_enable_partition(POWER_RAIL_CRAIL, ENABLE);
|
pmc_domain_pwrgate_set(POWER_RAIL_CRAIL, ENABLE);
|
||||||
// Enable cluster 0 non-CPU rail.
|
// Enable cluster 0 non-CPU rail.
|
||||||
pmc_enable_partition(POWER_RAIL_C0NC, ENABLE);
|
pmc_domain_pwrgate_set(POWER_RAIL_C0NC, ENABLE);
|
||||||
// Enable CPU0 rail.
|
// Enable CPU0 rail.
|
||||||
pmc_enable_partition(POWER_RAIL_CE0, ENABLE);
|
pmc_domain_pwrgate_set(POWER_RAIL_CE0, ENABLE);
|
||||||
|
|
||||||
// Request and wait for RAM repair. Needed for the Fast cluster.
|
// Request and wait for RAM repair. Needed for the Fast cluster.
|
||||||
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = RAM_REPAIR_REQ;
|
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = RAM_REPAIR_REQ;
|
||||||
@@ -90,21 +104,62 @@ void ccplex_boot_cpu0(u32 entry)
|
|||||||
EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0;
|
EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0;
|
||||||
|
|
||||||
// Set reset vector.
|
// Set reset vector.
|
||||||
SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN;
|
SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN;
|
||||||
SB(SB_AA64_RESET_HIGH) = 0;
|
SB(SB_AA64_RESET_HIGH) = 0;
|
||||||
|
|
||||||
// Non-secure reset vector write disable.
|
// Non-secure reset vector write disable.
|
||||||
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
|
if (lock)
|
||||||
(void)SB(SB_CSR);
|
{
|
||||||
|
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
|
||||||
|
(void)SB(SB_CSR);
|
||||||
|
}
|
||||||
|
|
||||||
// Tighten up the security aperture.
|
// Tighten up the security aperture.
|
||||||
// MC(MC_TZ_SECURITY_CTRL) = 1;
|
// MC(MC_TZ_SECURITY_CTRL) = TZ_SEC_CTRL_CPU_STRICT_TZ_APERTURE_CHECK;
|
||||||
|
|
||||||
// Clear MSELECT reset.
|
// 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.
|
// Clear NONCPU reset.
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;
|
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = BIT(29); // CLR_NONCPURESET.
|
||||||
// Clear CPU0 reset.
|
// Clear CPU0 reset.
|
||||||
// < 5.x: 0x411F000F, Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.
|
// < 5.x: 0x411F000F, Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x41010001;
|
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = BIT(30) | BIT(24) | BIT(16) | BIT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ccplex_powergate_cpu0()
|
||||||
|
{
|
||||||
|
#if CCPLEX_FLOWCTRL_POWERGATING
|
||||||
|
// Halt CPU0.
|
||||||
|
FLOW_CTLR(FLOW_CTLR_HALT_CPU0_EVENTS) = HALT_MODE_STOP_UNTIL_IRQ;
|
||||||
|
|
||||||
|
// Powergate cluster via flow control without waiting for WFI.
|
||||||
|
FLOW_CTLR(FLOW_CTLR_CPU0_CSR) = CSR_INTR_FLAG | CSR_EVENT_FLAG | CSR_ENABLE_EXT_CPU_RAIL | CSR_WAIT_WFI_NONE | CSR_ENABLE;
|
||||||
|
|
||||||
|
// Wait for the rail power off to finish.
|
||||||
|
while((FLOW_CTLR(FLOW_CTLR_CPU_PWR_CSR) & CPU_PWR_RAIL_STS_MASK) != CPU_PWR_RAIL_OFF);
|
||||||
|
|
||||||
|
// Set CPU0 to waitevent.
|
||||||
|
FLOW_CTLR(FLOW_CTLR_HALT_CPU0_EVENTS) = HALT_MODE_WAITEVENT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set CPU0 POR and CORE, CX0, L2, and DBG reset.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET) = BIT(30) | BIT(24) | BIT(16) | BIT(0);
|
||||||
|
// Set NONCPU reset.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET) = BIT(29);
|
||||||
|
// Set MSELECT reset.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_SET) = BIT(CLK_V_MSELECT);
|
||||||
|
|
||||||
|
// Disable CE0.
|
||||||
|
pmc_domain_pwrgate_set(POWER_RAIL_CE0, DISABLE);
|
||||||
|
// Disable cluster 0 non-CPU.
|
||||||
|
pmc_domain_pwrgate_set(POWER_RAIL_C0NC, DISABLE);
|
||||||
|
// Disable CPU rail.
|
||||||
|
pmc_domain_pwrgate_set(POWER_RAIL_CRAIL, DISABLE);
|
||||||
|
|
||||||
|
clock_disable_coresight();
|
||||||
|
|
||||||
|
// Clear out MSELECT and CPU clocks.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_CLR) = BIT(CLK_V_MSELECT) | BIT(CLK_V_CPUG);
|
||||||
|
|
||||||
|
_ccplex_disable_power();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
|
|
||||||
void ccplex_boot_cpu0(u32 entry);
|
void ccplex_boot_cpu0(u32 entry, bool lock);
|
||||||
|
void ccplex_powergate_cpu0();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
460
bdk/soc/clock.c
460
bdk/soc/clock.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2023 CTCaer
|
* Copyright (c) 2018-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <soc/bpmp.h>
|
||||||
#include <soc/clock.h>
|
#include <soc/clock.h>
|
||||||
#include <soc/hw_init.h>
|
#include <soc/hw_init.h>
|
||||||
#include <soc/pmc.h>
|
#include <soc/pmc.h>
|
||||||
@@ -22,6 +23,14 @@
|
|||||||
#include <soc/t210.h>
|
#include <soc/t210.h>
|
||||||
#include <storage/sdmmc.h>
|
#include <storage/sdmmc.h>
|
||||||
|
|
||||||
|
typedef struct _clk_rst_mgd_t
|
||||||
|
{
|
||||||
|
u16 reset;
|
||||||
|
u16 enable;
|
||||||
|
u16 source;
|
||||||
|
u8 index;
|
||||||
|
} clk_rst_mgd_t;
|
||||||
|
|
||||||
typedef struct _clock_osc_t
|
typedef struct _clock_osc_t
|
||||||
{
|
{
|
||||||
u32 freq;
|
u32 freq;
|
||||||
@@ -39,108 +48,117 @@ static const clock_osc_t _clock_osc_cnt[] = {
|
|||||||
{ 48000, 2836, 3023 }
|
{ 48000, 2836, 3023 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* clock_t: reset, enable, source, index, clk_src, clk_div */
|
/* clk_rst_mgd_t: reset, enable, source, index */
|
||||||
|
|
||||||
static const clock_t _clock_uart[] = {
|
static const clk_rst_mgd_t _clock_sdmmc[] = {
|
||||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, 2 },
|
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1, CLK_L_SDMMC1 },
|
||||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, 2 },
|
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2, CLK_L_SDMMC2 },
|
||||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, 2 },
|
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3, CLK_U_SDMMC3 },
|
||||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, 2 },
|
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4, CLK_L_SDMMC4 },
|
||||||
{ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, 2 }
|
};
|
||||||
|
|
||||||
|
/* clk_rst_t: reset, enable, source, index, clk_src, clk_div */
|
||||||
|
|
||||||
|
static const clk_rst_t _clock_uart[] = {
|
||||||
|
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, CLK_SRC_DIV(2) },
|
||||||
|
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, CLK_SRC_DIV(2) },
|
||||||
|
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, CLK_SRC_DIV(2) },
|
||||||
|
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, CLK_SRC_DIV(2) },
|
||||||
|
{ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, CLK_SRC_DIV(2) }
|
||||||
};
|
};
|
||||||
|
|
||||||
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
|
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
|
||||||
static const clock_t _clock_i2c[] = {
|
static const clk_rst_t _clock_i2c[] = {
|
||||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, 19 }, //20.4MHz -> 100KHz
|
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, CLK_SRC_DIV(10.5) }, // 20.4 MHz -> 100 KHz
|
||||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, 4 }, //81.6MHz -> 400KHz
|
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, CLK_SRC_DIV(3) }, // 81.6 MHz -> 400 KHz
|
||||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, 4 }, //81.6MHz -> 400KHz
|
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, CLK_SRC_DIV(3) }, // 81.6 MHz -> 400 KHz
|
||||||
{ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, 19 }, //20.4MHz -> 100KHz
|
{ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, CLK_SRC_DIV(10.5) }, // 20.4 MHz -> 100 KHz
|
||||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, 4 }, //81.6MHz -> 400KHz
|
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, CLK_SRC_DIV(3) }, // 81.6 MHz -> 400 KHz
|
||||||
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, 19 } //20.4MHz -> 100KHz
|
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, CLK_SRC_DIV(10.5) } // 20.4 MHz -> 100 KHz
|
||||||
};
|
};
|
||||||
|
|
||||||
static clock_t _clock_se = {
|
static clk_rst_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. Default: 408MHz. Max: 627.2 MHz.
|
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2 MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_tzram = {
|
static clk_rst_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, CLK_SRC_DIV(1)
|
||||||
};
|
};
|
||||||
static clock_t _clock_host1x = {
|
static clk_rst_t _clock_host1x = { // Has idle divisor.
|
||||||
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.
|
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, CLK_SRC_DIV(2.5) // 163.2MHz. Max: 408 MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_tsec = {
|
static clk_rst_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. Max: 408MHz.
|
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, CLK_SRC_DIV(2) // 204 MHz. Max: 408 MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_nvdec = {
|
static clk_rst_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.
|
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 716.8/979.2 MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_nvjpg = {
|
static clk_rst_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.
|
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8 MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_vic = {
|
static clk_rst_t _clock_vic = { // Has idle divisor.
|
||||||
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.
|
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8 MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_sor_safe = {
|
static clk_rst_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, CLK_SRC_DIV(1) // 24 MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_sor0 = {
|
static clk_rst_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, CLK_SRC_DIV(1)
|
||||||
};
|
};
|
||||||
static clock_t _clock_sor1 = {
|
static clk_rst_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, CLK_SRC_DIV(2) // 204 MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_kfuse = {
|
static clk_rst_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, CLK_SRC_DIV(1)
|
||||||
};
|
};
|
||||||
static clock_t _clock_cl_dvfs = {
|
static clk_rst_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, CLK_SRC_DIV(1)
|
||||||
};
|
};
|
||||||
static clock_t _clock_coresight = {
|
static clk_rst_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, CLK_SRC_DIV(3) // 136 MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_pwm = {
|
static clk_rst_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, CLK_SRC_DIV(3) // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_sdmmc_legacy_tm = {
|
static clk_rst_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
|
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, CLK_SRC_DIV(34) // 12MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_apbdma = {
|
static clk_rst_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.
|
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_APBDMA, 0, CLK_SRC_DIV(1) // Max: 204 MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_ahbdma = {
|
static clk_rst_t _clock_ahbdma = {
|
||||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, 0
|
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, CLK_SRC_DIV(1)
|
||||||
};
|
};
|
||||||
static clock_t _clock_actmon = {
|
static clk_rst_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.
|
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, CLK_SRC_DIV(1) // 19.2 MHz.
|
||||||
};
|
};
|
||||||
static clock_t _clock_extperiph1 = {
|
static clk_rst_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
|
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, CLK_SRC_DIV(1)
|
||||||
};
|
};
|
||||||
static clock_t _clock_extperiph2 = {
|
static clk_rst_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
|
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, CLK_SRC_DIV(102) // 4.0 MHz
|
||||||
};
|
};
|
||||||
|
|
||||||
void clock_enable(const clock_t *clk)
|
void clock_enable(const clk_rst_t *clk)
|
||||||
{
|
{
|
||||||
// Put clock into reset.
|
// Put clock into reset.
|
||||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
|
CLOCK(clk->reset) |= BIT(clk->index);
|
||||||
// Disable.
|
// Disable.
|
||||||
CLOCK(clk->enable) &= ~BIT(clk->index);
|
CLOCK(clk->enable) &= ~BIT(clk->index);
|
||||||
// Configure clock source if required.
|
// Configure clock source if required.
|
||||||
if (clk->source)
|
if (clk->source)
|
||||||
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
|
CLOCK(clk->source) = (clk->clk_src << 29u) | clk->clk_div;
|
||||||
// Enable.
|
// Enable.
|
||||||
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~BIT(clk->index)) | BIT(clk->index);
|
CLOCK(clk->enable) |= BIT(clk->index);
|
||||||
usleep(2);
|
usleep(2);
|
||||||
|
|
||||||
// Take clock off reset.
|
// Take clock off reset.
|
||||||
CLOCK(clk->reset) &= ~BIT(clk->index);
|
CLOCK(clk->reset) &= ~BIT(clk->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_disable(const clock_t *clk)
|
void clock_disable(const clk_rst_t *clk)
|
||||||
{
|
{
|
||||||
// Put clock into reset.
|
// Put clock into reset.
|
||||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
|
CLOCK(clk->reset) |= BIT(clk->index);
|
||||||
// Disable.
|
// Disable.
|
||||||
CLOCK(clk->enable) &= ~BIT(clk->index);
|
CLOCK(clk->enable) &= ~BIT(clk->index);
|
||||||
}
|
}
|
||||||
@@ -153,7 +171,13 @@ void clock_enable_fuse(bool enable)
|
|||||||
|
|
||||||
void clock_enable_uart(u32 idx)
|
void clock_enable_uart(u32 idx)
|
||||||
{
|
{
|
||||||
|
// Ease the stress to APB.
|
||||||
|
bpmp_clk_rate_relaxed(true);
|
||||||
|
|
||||||
clock_enable(&_clock_uart[idx]);
|
clock_enable(&_clock_uart[idx]);
|
||||||
|
|
||||||
|
// Restore OC.
|
||||||
|
bpmp_clk_rate_relaxed(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_disable_uart(u32 idx)
|
void clock_disable_uart(u32 idx)
|
||||||
@@ -168,12 +192,12 @@ int clock_uart_use_src_div(u32 idx, u32 baud)
|
|||||||
u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000;
|
u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000;
|
||||||
|
|
||||||
if (baud == 3000000)
|
if (baud == 3000000)
|
||||||
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 15;
|
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(8.5);
|
||||||
else if (baud == 1000000)
|
else if (baud == 1000000)
|
||||||
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 49;
|
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(25.5);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CLOCK(_clock_uart[idx].source) = clk_src_div | 2;
|
CLOCK(_clock_uart[idx].source) = clk_src_div | CLK_SRC_DIV(2);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -208,6 +232,9 @@ void clock_enable_tzram()
|
|||||||
void clock_enable_host1x()
|
void clock_enable_host1x()
|
||||||
{
|
{
|
||||||
clock_enable(&_clock_host1x);
|
clock_enable(&_clock_host1x);
|
||||||
|
|
||||||
|
// Set idle frequency to 81.6 MHz.
|
||||||
|
// CLOCK(_clock_host1x.clk_src) |= CLK_SRC_DIV(5) << 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_disable_host1x()
|
void clock_disable_host1x()
|
||||||
@@ -247,7 +274,16 @@ void clock_disable_nvjpg()
|
|||||||
|
|
||||||
void clock_enable_vic()
|
void clock_enable_vic()
|
||||||
{
|
{
|
||||||
|
// Ease the stress to APB.
|
||||||
|
bpmp_clk_rate_relaxed(true);
|
||||||
|
|
||||||
clock_enable(&_clock_vic);
|
clock_enable(&_clock_vic);
|
||||||
|
|
||||||
|
// Set idle frequency to 136 MHz.
|
||||||
|
// CLOCK(_clock_vic.clk_src) |= CLK_SRC_DIV(3) << 8;
|
||||||
|
|
||||||
|
// Restore sys clock.
|
||||||
|
bpmp_clk_rate_relaxed(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_disable_vic()
|
void clock_disable_vic()
|
||||||
@@ -323,7 +359,13 @@ void clock_disable_coresight()
|
|||||||
|
|
||||||
void clock_enable_pwm()
|
void clock_enable_pwm()
|
||||||
{
|
{
|
||||||
|
// Ease the stress to APB.
|
||||||
|
bpmp_clk_rate_relaxed(true);
|
||||||
|
|
||||||
clock_enable(&_clock_pwm);
|
clock_enable(&_clock_pwm);
|
||||||
|
|
||||||
|
// Restore OC.
|
||||||
|
bpmp_clk_rate_relaxed(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_disable_pwm()
|
void clock_disable_pwm()
|
||||||
@@ -398,23 +440,27 @@ void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210)
|
|||||||
if (lowpower && tegra_t210)
|
if (lowpower && tegra_t210)
|
||||||
misc = 0x2D0000 | 0x0AAA; // Clock enable and PLLD_SDM_DIN: 2730 -> DIVN + 0.833.
|
misc = 0x2D0000 | 0x0AAA; // Clock enable and PLLD_SDM_DIN: 2730 -> DIVN + 0.833.
|
||||||
|
|
||||||
|
// Set DISP1 clock source.
|
||||||
// Set DISP1 clock source and parent clock.
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 2 << 29u; // PLLD_OUT0.
|
||||||
if (lowpower)
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 0x40000000; // PLLD_OUT0.
|
|
||||||
|
|
||||||
// Set dividers and enable PLLD.
|
// Set dividers and enable PLLD.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLL_BASE_ENABLE | PLL_BASE_LOCK | plld_div;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = tegra_t210 ? 0x20 : 0; // Keep default PLLD_SETUP.
|
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = tegra_t210 ? 0x20 : 0; // Keep default PLLD_SETUP.
|
||||||
|
|
||||||
// Set PLLD_SDM_DIN and enable PLLD to DSI pads.
|
// Set PLLD_SDM_DIN and enable (T210) PLLD to DSI pads.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = misc;
|
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = misc;
|
||||||
|
|
||||||
|
// Wait for PLL to stabilize.
|
||||||
|
while (!(CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) & PLL_BASE_LOCK))
|
||||||
|
;
|
||||||
|
|
||||||
|
usleep(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_enable_pllx()
|
void clock_enable_pllx()
|
||||||
{
|
{
|
||||||
// Configure and enable PLLX if disabled.
|
// Configure and enable PLLX if disabled.
|
||||||
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLLX_BASE_ENABLE)) // PLLX_ENABLE.
|
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLL_BASE_ENABLE)) // PLLX_ENABLE.
|
||||||
{
|
{
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= ~PLLX_MISC3_IDDQ; // Disable IDDQ.
|
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= ~PLLX_MISC3_IDDQ; // Disable IDDQ.
|
||||||
usleep(2);
|
usleep(2);
|
||||||
@@ -423,18 +469,20 @@ void clock_enable_pllx()
|
|||||||
const u32 pllx_div_cfg = (2 << 20) | (156 << 8) | 2; // P div: 2 (3), N div: 156, M div: 2. 998.4 MHz.
|
const u32 pllx_div_cfg = (2 << 20) | (156 << 8) | 2; // P div: 2 (3), N div: 156, M div: 2. 998.4 MHz.
|
||||||
|
|
||||||
// Bypass dividers.
|
// Bypass dividers.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLLX_BASE_BYPASS | pllx_div_cfg;
|
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLL_BASE_BYPASS | pllx_div_cfg;
|
||||||
// Disable bypass
|
// Disable bypass
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = pllx_div_cfg;
|
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = pllx_div_cfg;
|
||||||
// Set PLLX_LOCK_ENABLE.
|
// Set PLLX_LOCK_ENABLE.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) |= PLLX_MISC_LOCK_EN;
|
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) |= PLLX_MISC_LOCK_EN;
|
||||||
// Enable PLLX.
|
// Enable PLLX.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLLX_BASE_ENABLE | pllx_div_cfg;
|
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLL_BASE_ENABLE | pllx_div_cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for PLL to stabilize.
|
// Wait for PLL to stabilize.
|
||||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLLX_BASE_LOCK))
|
while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLL_BASE_LOCK))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
usleep(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_enable_pllc(u32 divn)
|
void clock_enable_pllc(u32 divn)
|
||||||
@@ -442,7 +490,7 @@ void clock_enable_pllc(u32 divn)
|
|||||||
u8 pll_divn_curr = (CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) >> 10) & 0xFF;
|
u8 pll_divn_curr = (CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) >> 10) & 0xFF;
|
||||||
|
|
||||||
// Check if already enabled and configured.
|
// Check if already enabled and configured.
|
||||||
if ((CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) & PLLCX_BASE_ENABLE) && (pll_divn_curr == divn))
|
if ((CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) & PLL_BASE_ENABLE) && (pll_divn_curr == divn))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Take PLLC out of reset and set basic misc parameters.
|
// Take PLLC out of reset and set basic misc parameters.
|
||||||
@@ -451,7 +499,7 @@ void clock_enable_pllc(u32 divn)
|
|||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) |= 0xF0 << 8; // PLLC_FLL_LD_MEM.
|
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) |= 0xF0 << 8; // PLLC_FLL_LD_MEM.
|
||||||
|
|
||||||
// Disable PLL and IDDQ in case they are on.
|
// Disable PLL and IDDQ in case they are on.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLLCX_BASE_ENABLE;
|
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLL_BASE_ENABLE;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) &= ~PLLC_MISC1_IDDQ;
|
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) &= ~PLLC_MISC1_IDDQ;
|
||||||
usleep(10);
|
usleep(10);
|
||||||
|
|
||||||
@@ -459,15 +507,15 @@ void clock_enable_pllc(u32 divn)
|
|||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) = (divn << 10) | 4; // DIVM: 4, DIVP: 1.
|
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) = (divn << 10) | 4; // DIVM: 4, DIVP: 1.
|
||||||
|
|
||||||
// Enable PLLC and wait for Phase and Frequency lock.
|
// Enable PLLC and wait for Phase and Frequency lock.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) |= PLLCX_BASE_ENABLE;
|
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) |= PLL_BASE_ENABLE;
|
||||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) & PLLCX_BASE_LOCK))
|
while (!(CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) & PLL_BASE_LOCK))
|
||||||
;
|
;
|
||||||
|
|
||||||
// Disable PLLC_OUT1, enable reset and set div to 1.5.
|
// Disable PLLC_OUT1, enable reset and set div to 1.5.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) = BIT(8);
|
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) = 1 << 8;
|
||||||
|
|
||||||
// Enable PLLC_OUT1 and bring it out of reset.
|
// Enable PLLC_OUT1 and bring it out of reset.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) |= (PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR);
|
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) |= PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR;
|
||||||
msleep(1); // Wait a bit for PLL to stabilize.
|
msleep(1); // Wait a bit for PLL to stabilize.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,7 +524,7 @@ void clock_disable_pllc()
|
|||||||
// Disable PLLC and PLLC_OUT1.
|
// Disable PLLC and PLLC_OUT1.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~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_MISC) = PLLC_MISC_RESET;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLLCX_BASE_ENABLE;
|
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLL_BASE_ENABLE;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) |= PLLC_MISC1_IDDQ;
|
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) |= PLLC_MISC1_IDDQ;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) &= ~(0xFF << 8); // PLLC_FLL_LD_MEM.
|
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) &= ~(0xFF << 8); // PLLC_FLL_LD_MEM.
|
||||||
usleep(10);
|
usleep(10);
|
||||||
@@ -498,16 +546,16 @@ static void _clock_enable_pllc4(u32 mask)
|
|||||||
//CLOCK(CLK_RST_CONTROLLER_PLLC4_MISC) = PLLC4_MISC_EN_LCKDET;
|
//CLOCK(CLK_RST_CONTROLLER_PLLC4_MISC) = PLLC4_MISC_EN_LCKDET;
|
||||||
|
|
||||||
// Disable PLL and IDDQ in case they are on.
|
// Disable PLL and IDDQ in case they are on.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLCX_BASE_ENABLE;
|
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLL_BASE_ENABLE;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLC4_BASE_IDDQ;
|
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLC4_BASE_IDDQ;
|
||||||
usleep(10);
|
usleep(10);
|
||||||
|
|
||||||
// Set PLLC4 dividers.
|
// Set PLLC4 dividers.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (104 << 8) | 4; // DIVM: 4, DIVP: 1.
|
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (0 << 19) | (104 << 8) | 4; // DIVP: 1, DIVN: 104, DIVM: 4. 998MHz OUT0, 199MHz OUT2.
|
||||||
|
|
||||||
// Enable PLLC4 and wait for Phase and Frequency lock.
|
// Enable PLLC4 and wait for Phase and Frequency lock.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLCX_BASE_ENABLE;
|
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLL_BASE_ENABLE;
|
||||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) & PLLCX_BASE_LOCK))
|
while (!(CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) & PLL_BASE_LOCK))
|
||||||
;
|
;
|
||||||
|
|
||||||
msleep(1); // Wait a bit for PLL to stabilize.
|
msleep(1); // Wait a bit for PLL to stabilize.
|
||||||
@@ -525,7 +573,7 @@ static void _clock_disable_pllc4(u32 mask)
|
|||||||
|
|
||||||
// Disable PLLC4.
|
// Disable PLLC4.
|
||||||
msleep(1); // Wait at least 1ms to prevent glitching.
|
msleep(1); // Wait at least 1ms to prevent glitching.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLCX_BASE_ENABLE;
|
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLL_BASE_ENABLE;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLC4_BASE_IDDQ;
|
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLC4_BASE_IDDQ;
|
||||||
usleep(10);
|
usleep(10);
|
||||||
|
|
||||||
@@ -538,11 +586,11 @@ void clock_enable_pllu()
|
|||||||
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) |= BIT(29); // Disable reference clock.
|
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) |= BIT(29); // Disable reference clock.
|
||||||
u32 pllu_cfg = (CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & 0xFFE00000) | BIT(24) | (1 << 16) | (0x19 << 8) | 2;
|
u32 pllu_cfg = (CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & 0xFFE00000) | BIT(24) | (1 << 16) | (0x19 << 8) | 2;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg;
|
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | PLLCX_BASE_ENABLE; // Enable.
|
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | PLL_BASE_ENABLE; // Enable.
|
||||||
|
|
||||||
// Wait for PLL to stabilize.
|
// Wait for PLL to stabilize.
|
||||||
u32 timeout = get_tmr_us() + 1300;
|
u32 timeout = get_tmr_us() + 1300;
|
||||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & PLLCX_BASE_LOCK)) // PLL_LOCK.
|
while (!(CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & PLL_BASE_LOCK)) // PLL_LOCK.
|
||||||
if (get_tmr_us() > timeout)
|
if (get_tmr_us() > timeout)
|
||||||
break;
|
break;
|
||||||
usleep(10);
|
usleep(10);
|
||||||
@@ -576,115 +624,50 @@ void clock_enable_utmipll()
|
|||||||
|
|
||||||
static int _clock_sdmmc_is_reset(u32 id)
|
static int _clock_sdmmc_is_reset(u32 id)
|
||||||
{
|
{
|
||||||
switch (id)
|
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||||
{
|
|
||||||
case SDMMC_1:
|
return CLOCK(clk->reset) & BIT(clk->index);
|
||||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC1);
|
|
||||||
case SDMMC_2:
|
|
||||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC2);
|
|
||||||
case SDMMC_3:
|
|
||||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_U) & BIT(CLK_U_SDMMC3);
|
|
||||||
case SDMMC_4:
|
|
||||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC4);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _clock_sdmmc_set_reset(u32 id)
|
static void _clock_sdmmc_set_reset(u32 id)
|
||||||
{
|
{
|
||||||
switch (id)
|
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||||
{
|
|
||||||
case SDMMC_1:
|
CLOCK(clk->reset) |= BIT(clk->index);
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC1);
|
|
||||||
break;
|
|
||||||
case SDMMC_2:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC2);
|
|
||||||
break;
|
|
||||||
case SDMMC_3:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = BIT(CLK_U_SDMMC3);
|
|
||||||
break;
|
|
||||||
case SDMMC_4:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC4);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _clock_sdmmc_clear_reset(u32 id)
|
static void _clock_sdmmc_clear_reset(u32 id)
|
||||||
{
|
{
|
||||||
switch (id)
|
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||||
{
|
|
||||||
case SDMMC_1:
|
CLOCK(clk->reset) &= ~BIT(clk->index);
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC1);
|
|
||||||
break;
|
|
||||||
case SDMMC_2:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC2);
|
|
||||||
break;
|
|
||||||
case SDMMC_3:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = BIT(CLK_U_SDMMC3);
|
|
||||||
break;
|
|
||||||
case SDMMC_4:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC4);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _clock_sdmmc_is_enabled(u32 id)
|
static int _clock_sdmmc_is_enabled(u32 id)
|
||||||
{
|
{
|
||||||
switch (id)
|
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||||
{
|
|
||||||
case SDMMC_1:
|
return CLOCK(clk->enable) & BIT(clk->index);
|
||||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC1);
|
|
||||||
case SDMMC_2:
|
|
||||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC2);
|
|
||||||
case SDMMC_3:
|
|
||||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) & BIT(CLK_U_SDMMC3);
|
|
||||||
case SDMMC_4:
|
|
||||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC4);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _clock_sdmmc_set_enable(u32 id)
|
static void _clock_sdmmc_set_enable(u32 id)
|
||||||
{
|
{
|
||||||
switch (id)
|
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||||
{
|
|
||||||
case SDMMC_1:
|
CLOCK(clk->enable) |= BIT(clk->index);
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC1);
|
|
||||||
break;
|
|
||||||
case SDMMC_2:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC2);
|
|
||||||
break;
|
|
||||||
case SDMMC_3:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = BIT(CLK_U_SDMMC3);
|
|
||||||
break;
|
|
||||||
case SDMMC_4:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC4);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _clock_sdmmc_clear_enable(u32 id)
|
static void _clock_sdmmc_clear_enable(u32 id)
|
||||||
{
|
{
|
||||||
switch (id)
|
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||||
{
|
|
||||||
case SDMMC_1:
|
CLOCK(clk->enable) &= ~BIT(clk->index);
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC1);
|
|
||||||
break;
|
|
||||||
case SDMMC_2:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC2);
|
|
||||||
break;
|
|
||||||
case SDMMC_3:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = BIT(CLK_U_SDMMC3);
|
|
||||||
break;
|
|
||||||
case SDMMC_4:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC4);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _clock_sdmmc_config_legacy_tm()
|
static void _clock_sdmmc_config_legacy_tm()
|
||||||
{
|
{
|
||||||
clock_t *clk = &_clock_sdmmc_legacy_tm;
|
const clk_rst_t *clk = &_clock_sdmmc_legacy_tm;
|
||||||
|
|
||||||
if (!(CLOCK(clk->enable) & BIT(clk->index)))
|
if (!(CLOCK(clk->enable) & BIT(clk->index)))
|
||||||
clock_enable(clk);
|
clock_enable(clk);
|
||||||
}
|
}
|
||||||
@@ -692,123 +675,123 @@ static void _clock_sdmmc_config_legacy_tm()
|
|||||||
typedef struct _clock_sdmmc_t
|
typedef struct _clock_sdmmc_t
|
||||||
{
|
{
|
||||||
u32 clock;
|
u32 clock;
|
||||||
u32 real_clock;
|
u32 pclock;
|
||||||
} clock_sdmmc_t;
|
} clock_sdmmc_t;
|
||||||
|
|
||||||
static clock_sdmmc_t _clock_sdmmc_table[4] = { 0 };
|
static clock_sdmmc_t _clock_sdmmc_table[4] = { 0 };
|
||||||
|
|
||||||
#define SDMMC_CLOCK_SRC_PLLP_OUT0 0x0
|
#define SDMMC_CLOCK_SRC_PLLP_OUT0 0x0
|
||||||
#define SDMMC_CLOCK_SRC_PLLC4_OUT2 0x3
|
#define SDMMC_CLOCK_SRC_PLLC4_OUT2 0x3
|
||||||
|
#define SDMMC_CLOCK_SRC_PLLC4_OUT0 0x7
|
||||||
#define SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ 0x1
|
#define SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ 0x1
|
||||||
|
|
||||||
static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 clock)
|
||||||
{
|
{
|
||||||
u32 divisor = 0;
|
u32 divisor = 0;
|
||||||
u32 source = SDMMC_CLOCK_SRC_PLLP_OUT0;
|
u32 source = SDMMC_CLOCK_SRC_PLLP_OUT0;
|
||||||
|
|
||||||
if (id > SDMMC_4)
|
if (id > SDMMC_4)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Get IO clock divisor.
|
// Get IO clock divisor.
|
||||||
switch (val)
|
switch (clock)
|
||||||
{
|
{
|
||||||
case 25000:
|
case 25000:
|
||||||
*pclock = 24728;
|
*pclock = 24728;
|
||||||
divisor = 31; // 16.5 div.
|
divisor = CLK_SRC_DIV(16.5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 26000:
|
case 26000:
|
||||||
*pclock = 25500;
|
*pclock = 25500;
|
||||||
divisor = 30; // 16 div.
|
divisor = CLK_SRC_DIV(16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 50000:
|
case 50000:
|
||||||
*pclock = 48000;
|
*pclock = 48000;
|
||||||
divisor = 15; // 8.5 div.
|
divisor = CLK_SRC_DIV(8.5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 52000:
|
case 52000:
|
||||||
*pclock = 51000;
|
*pclock = 51000;
|
||||||
divisor = 14; // 8 div.
|
divisor = CLK_SRC_DIV(8);
|
||||||
break;
|
break;
|
||||||
case 81600: // Originally MMC_HS50 for GC FPGA at 40800 KHz, div 18 (real 10).
|
|
||||||
|
case 82000:
|
||||||
*pclock = 81600;
|
*pclock = 81600;
|
||||||
divisor = 8; // 5 div.
|
divisor = CLK_SRC_DIV(5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 100000:
|
case 100000:
|
||||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||||
*pclock = 99840;
|
*pclock = 99840;
|
||||||
divisor = 2; // 2 div.
|
divisor = CLK_SRC_DIV(2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 164000:
|
case 164000:
|
||||||
*pclock = 163200;
|
*pclock = 163200;
|
||||||
divisor = 3; // 2.5 div.
|
divisor = CLK_SRC_DIV(2.5);
|
||||||
break;
|
break;
|
||||||
case 200000: // 240MHz evo+.
|
|
||||||
|
case 200000:
|
||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
case SDMMC_1:
|
case SDMMC_1:
|
||||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
|
||||||
break;
|
|
||||||
case SDMMC_2:
|
|
||||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ;
|
|
||||||
break;
|
|
||||||
case SDMMC_3:
|
case SDMMC_3:
|
||||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||||
break;
|
break;
|
||||||
|
case SDMMC_2:
|
||||||
case SDMMC_4:
|
case SDMMC_4:
|
||||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ;
|
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ; // CLK RST divisor is ignored.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*pclock = 199680;
|
*pclock = 199680;
|
||||||
divisor = 0; // 1 div.
|
divisor = CLK_SRC_DIV(1);
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
*pclock = 24728;
|
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||||
divisor = 31; // 16.5 div.
|
case 400000:
|
||||||
|
source = SDMMC_CLOCK_SRC_PLLC4_OUT0;
|
||||||
|
*pclock = 399360;
|
||||||
|
divisor = CLK_SRC_DIV(2.5);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
_clock_sdmmc_table[id].clock = val;
|
_clock_sdmmc_table[id].clock = clock;
|
||||||
_clock_sdmmc_table[id].real_clock = *pclock;
|
_clock_sdmmc_table[id].pclock = *pclock;
|
||||||
|
|
||||||
// Enable PLLC4 if in use by any SDMMC.
|
// Enable PLLC4 if in use by any SDMMC.
|
||||||
if (source)
|
if (source != SDMMC_CLOCK_SRC_PLLP_OUT0)
|
||||||
_clock_enable_pllc4(BIT(id));
|
_clock_enable_pllc4(BIT(id));
|
||||||
|
|
||||||
// Set SDMMC legacy timeout clock.
|
// Set SDMMC legacy timeout clock.
|
||||||
_clock_sdmmc_config_legacy_tm();
|
_clock_sdmmc_config_legacy_tm();
|
||||||
|
|
||||||
// Set SDMMC clock.
|
// Set SDMMC clock.
|
||||||
switch (id)
|
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||||
{
|
CLOCK(clk->source) = (source << 29u) | divisor;
|
||||||
case SDMMC_1:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = (source << 29) | divisor;
|
|
||||||
break;
|
|
||||||
case SDMMC_2:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = (source << 29) | divisor;
|
|
||||||
break;
|
|
||||||
case SDMMC_3:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = (source << 29) | divisor;
|
|
||||||
break;
|
|
||||||
case SDMMC_4:
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = (source << 29) | divisor;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 val)
|
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 clock)
|
||||||
{
|
{
|
||||||
if (_clock_sdmmc_table[id].clock == val)
|
if (_clock_sdmmc_table[id].clock == clock)
|
||||||
{
|
{
|
||||||
*pclock = _clock_sdmmc_table[id].real_clock;
|
*pclock = _clock_sdmmc_table[id].pclock;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int is_enabled = _clock_sdmmc_is_enabled(id);
|
int is_enabled = _clock_sdmmc_is_enabled(id);
|
||||||
if (is_enabled)
|
if (is_enabled)
|
||||||
_clock_sdmmc_clear_enable(id);
|
_clock_sdmmc_clear_enable(id);
|
||||||
_clock_sdmmc_config_clock_host(pclock, id, val);
|
|
||||||
|
_clock_sdmmc_config_clock_host(pclock, id, clock);
|
||||||
|
|
||||||
if (is_enabled)
|
if (is_enabled)
|
||||||
_clock_sdmmc_set_enable(id);
|
_clock_sdmmc_set_enable(id);
|
||||||
|
|
||||||
|
// Commit changes.
|
||||||
_clock_sdmmc_is_reset(id);
|
_clock_sdmmc_is_reset(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -818,54 +801,71 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type)
|
|||||||
// Get Card clock divisor.
|
// Get Card clock divisor.
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case SDHCI_TIMING_MMC_ID: // Actual IO Freq: 380.59 KHz.
|
case SDHCI_TIMING_MMC_ID: // Actual card clock: 386.36 KHz.
|
||||||
*pclock = 26000;
|
*pclock = 26000;
|
||||||
*pdivisor = 66;
|
*pdivisor = 66;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDHCI_TIMING_MMC_LS26:
|
case SDHCI_TIMING_MMC_LS26:
|
||||||
*pclock = 26000;
|
*pclock = 26000;
|
||||||
*pdivisor = 1;
|
*pdivisor = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDHCI_TIMING_MMC_HS52:
|
case SDHCI_TIMING_MMC_HS52:
|
||||||
*pclock = 52000;
|
*pclock = 52000;
|
||||||
*pdivisor = 1;
|
*pdivisor = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDHCI_TIMING_MMC_HS200:
|
case SDHCI_TIMING_MMC_HS200:
|
||||||
case SDHCI_TIMING_MMC_HS400:
|
case SDHCI_TIMING_MMC_HS400:
|
||||||
case SDHCI_TIMING_UHS_SDR104:
|
case SDHCI_TIMING_UHS_SDR104:
|
||||||
*pclock = 200000;
|
*pclock = 200000;
|
||||||
*pdivisor = 1;
|
*pdivisor = 1;
|
||||||
break;
|
break;
|
||||||
case SDHCI_TIMING_SD_ID: // Actual IO Freq: 380.43 KHz.
|
|
||||||
|
case SDHCI_TIMING_SD_ID: // Actual card clock: 386.38 KHz.
|
||||||
*pclock = 25000;
|
*pclock = 25000;
|
||||||
*pdivisor = 64;
|
*pdivisor = 64;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDHCI_TIMING_SD_DS12:
|
case SDHCI_TIMING_SD_DS12:
|
||||||
case SDHCI_TIMING_UHS_SDR12:
|
case SDHCI_TIMING_UHS_SDR12:
|
||||||
*pclock = 25000;
|
*pclock = 25000;
|
||||||
*pdivisor = 1;
|
*pdivisor = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDHCI_TIMING_SD_HS25:
|
case SDHCI_TIMING_SD_HS25:
|
||||||
case SDHCI_TIMING_UHS_SDR25:
|
case SDHCI_TIMING_UHS_SDR25:
|
||||||
*pclock = 50000;
|
*pclock = 50000;
|
||||||
*pdivisor = 1;
|
*pdivisor = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDHCI_TIMING_UHS_SDR50:
|
case SDHCI_TIMING_UHS_SDR50:
|
||||||
*pclock = 100000;
|
*pclock = 100000;
|
||||||
*pdivisor = 1;
|
*pdivisor = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDHCI_TIMING_UHS_SDR82:
|
case SDHCI_TIMING_UHS_SDR82:
|
||||||
*pclock = 164000;
|
*pclock = 164000;
|
||||||
*pdivisor = 1;
|
*pdivisor = 1;
|
||||||
break;
|
break;
|
||||||
case SDHCI_TIMING_UHS_DDR50:
|
|
||||||
*pclock = 81600; // Originally MMC_HS50 for GC FPGA at 40800 KHz, div 1.
|
case SDHCI_TIMING_UHS_DDR50: // Actual card clock: 40.80 MHz.
|
||||||
|
*pclock = 82000;
|
||||||
*pdivisor = 2;
|
*pdivisor = 2;
|
||||||
break;
|
break;
|
||||||
case SDHCI_TIMING_MMC_DDR100: // Actual IO Freq: 99.84 MHz.
|
|
||||||
|
case SDHCI_TIMING_MMC_HS100: // Actual card clock: 99.84 MHz.
|
||||||
*pclock = 200000;
|
*pclock = 200000;
|
||||||
*pdivisor = 2;
|
*pdivisor = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||||
|
case SDHCI_TIMING_UHS_DDR200: // Actual card clock: 199.68 KHz.
|
||||||
|
*pclock = 400000;
|
||||||
|
*pdivisor = 2;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -874,17 +874,17 @@ int clock_sdmmc_is_not_reset_and_enabled(u32 id)
|
|||||||
return !_clock_sdmmc_is_reset(id) && _clock_sdmmc_is_enabled(id);
|
return !_clock_sdmmc_is_reset(id) && _clock_sdmmc_is_enabled(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_sdmmc_enable(u32 id, u32 val)
|
void clock_sdmmc_enable(u32 id, u32 clock)
|
||||||
{
|
{
|
||||||
u32 clock = 0;
|
_clock_sdmmc_clear_enable(id);
|
||||||
|
|
||||||
if (_clock_sdmmc_is_enabled(id))
|
|
||||||
_clock_sdmmc_clear_enable(id);
|
|
||||||
_clock_sdmmc_set_reset(id);
|
_clock_sdmmc_set_reset(id);
|
||||||
_clock_sdmmc_config_clock_host(&clock, id, val);
|
_clock_sdmmc_config_clock_host(&clock, id, clock);
|
||||||
_clock_sdmmc_set_enable(id);
|
_clock_sdmmc_set_enable(id);
|
||||||
|
|
||||||
|
// // Commit changes and wait 100 cycles for reset and for clocks to stabilize.
|
||||||
_clock_sdmmc_is_reset(id);
|
_clock_sdmmc_is_reset(id);
|
||||||
usleep((100000 + clock - 1) / clock);
|
usleep((100 * 1000 + clock - 1) / clock);
|
||||||
|
|
||||||
_clock_sdmmc_clear_reset(id);
|
_clock_sdmmc_clear_reset(id);
|
||||||
_clock_sdmmc_is_reset(id);
|
_clock_sdmmc_is_reset(id);
|
||||||
}
|
}
|
||||||
|
|||||||
607
bdk/soc/clock.h
607
bdk/soc/clock.h
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2022 CTCaer
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -47,6 +47,7 @@
|
|||||||
#define CLK_RST_CONTROLLER_PLLM_MISC1 0x98
|
#define CLK_RST_CONTROLLER_PLLM_MISC1 0x98
|
||||||
#define CLK_RST_CONTROLLER_PLLM_MISC2 0x9C
|
#define CLK_RST_CONTROLLER_PLLM_MISC2 0x9C
|
||||||
#define CLK_RST_CONTROLLER_PLLP_BASE 0xA0
|
#define CLK_RST_CONTROLLER_PLLP_BASE 0xA0
|
||||||
|
#define CLK_RST_CONTROLLER_PLLP_OUTB 0xA8
|
||||||
#define CLK_RST_CONTROLLER_PLLA_BASE 0xB0
|
#define CLK_RST_CONTROLLER_PLLA_BASE 0xB0
|
||||||
#define CLK_RST_CONTROLLER_PLLA_OUT 0xB4
|
#define CLK_RST_CONTROLLER_PLLA_OUT 0xB4
|
||||||
#define CLK_RST_CONTROLLER_PLLA_MISC1 0xB8
|
#define CLK_RST_CONTROLLER_PLLA_MISC1 0xB8
|
||||||
@@ -149,6 +150,7 @@
|
|||||||
#define CLK_RST_CONTROLLER_PLLC_MISC_2 0x5D0
|
#define CLK_RST_CONTROLLER_PLLC_MISC_2 0x5D0
|
||||||
#define CLK_RST_CONTROLLER_PLLC4_OUT 0x5E4
|
#define CLK_RST_CONTROLLER_PLLC4_OUT 0x5E4
|
||||||
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
|
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
|
||||||
|
#define CLK_RST_CONTROLLER_PLLMB_MISC1 0x5EC
|
||||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FS 0x608
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FS 0x608
|
||||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_CORE_DEV 0x60C
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_CORE_DEV 0x60C
|
||||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_SS 0x610
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_SS 0x610
|
||||||
@@ -170,18 +172,14 @@
|
|||||||
#define CLK_NOT_USED 0x0
|
#define CLK_NOT_USED 0x0
|
||||||
|
|
||||||
/*! PLL control and status bits */
|
/*! PLL control and status bits */
|
||||||
#define PLLX_BASE_LOCK BIT(27)
|
#define PLL_BASE_LOCK BIT(27)
|
||||||
#define PLLX_BASE_REF_DIS BIT(29)
|
#define PLL_BASE_REF_DIS BIT(29)
|
||||||
#define PLLX_BASE_ENABLE BIT(30)
|
#define PLL_BASE_ENABLE BIT(30)
|
||||||
#define PLLX_BASE_BYPASS BIT(31)
|
#define PLL_BASE_BYPASS BIT(31)
|
||||||
|
|
||||||
#define PLLX_MISC_LOCK_EN BIT(18)
|
#define PLLX_MISC_LOCK_EN BIT(18)
|
||||||
#define PLLX_MISC3_IDDQ BIT(3)
|
#define PLLX_MISC3_IDDQ BIT(3)
|
||||||
|
|
||||||
#define PLLCX_BASE_LOCK BIT(27)
|
|
||||||
#define PLLCX_BASE_REF_DIS BIT(29)
|
|
||||||
#define PLLCX_BASE_ENABLE BIT(30)
|
|
||||||
#define PLLCX_BASE_BYPASS BIT(31)
|
|
||||||
|
|
||||||
#define PLLA_OUT0_RSTN_CLR BIT(0)
|
#define PLLA_OUT0_RSTN_CLR BIT(0)
|
||||||
#define PLLA_OUT0_CLKEN BIT(1)
|
#define PLLA_OUT0_CLKEN BIT(1)
|
||||||
#define PLLA_BASE_IDDQ BIT(25)
|
#define PLLA_BASE_IDDQ BIT(25)
|
||||||
@@ -198,6 +196,9 @@
|
|||||||
|
|
||||||
#define UTMIPLL_LOCK BIT(31)
|
#define UTMIPLL_LOCK BIT(31)
|
||||||
|
|
||||||
|
/*! Clock source */
|
||||||
|
#define CLK_SRC_DIV(d) ((d) ? ((u32)(((d) - 1) * 2)) : 0)
|
||||||
|
|
||||||
/*! PTO_CLK_CNT */
|
/*! PTO_CLK_CNT */
|
||||||
#define PTO_REF_CLK_WIN_CFG_MASK 0xF
|
#define PTO_REF_CLK_WIN_CFG_MASK 0xF
|
||||||
#define PTO_REF_CLK_WIN_CFG_16P 0xF
|
#define PTO_REF_CLK_WIN_CFG_16P 0xF
|
||||||
@@ -227,138 +228,232 @@
|
|||||||
/*! PTO IDs. */
|
/*! PTO IDs. */
|
||||||
typedef enum _clock_pto_id_t
|
typedef enum _clock_pto_id_t
|
||||||
{
|
{
|
||||||
CLK_PTO_PCLK_SYS = 0x06,
|
CLK_PTO_PCLK_SYS = 0x06,
|
||||||
CLK_PTO_HCLK_SYS = 0x07,
|
CLK_PTO_HCLK_SYS = 0x07,
|
||||||
|
CLK_PTO_DMIC1 = 0x08,
|
||||||
|
CLK_PTO_DMIC2 = 0x09,
|
||||||
|
CLK_PTO_HDMI_SLOWCLK_DIV2 = 0x0A,
|
||||||
|
CLK_PTO_JTAG_REG = 0x0B,
|
||||||
|
CLK_PTO_UTMIP_240_A = 0x0C,
|
||||||
|
CLK_PTO_UTMIP_240_B = 0x0D,
|
||||||
|
|
||||||
CLK_PTO_UTMIP_240 = 0x0C,
|
CLK_PTO_CCLK_G = 0x12,
|
||||||
|
CLK_PTO_CCLK_G_DIV2 = 0x13,
|
||||||
|
CLK_PTO_MIPIBIF = 0x14,
|
||||||
|
|
||||||
CLK_PTO_CCLK_G = 0x12,
|
CLK_PTO_SPI1 = 0x17,
|
||||||
CLK_PTO_CCLK_G_DIV2 = 0x13,
|
CLK_PTO_SPI2 = 0x18,
|
||||||
|
CLK_PTO_SPI3 = 0x19,
|
||||||
|
CLK_PTO_SPI4 = 0x1A,
|
||||||
|
CLK_PTO_MAUD = 0x1B,
|
||||||
|
CLK_PTO_SCLK = 0x1C,
|
||||||
|
|
||||||
CLK_PTO_SPI1 = 0x17,
|
CLK_PTO_SDMMC1 = 0x20,
|
||||||
CLK_PTO_SPI2 = 0x18,
|
CLK_PTO_SDMMC2 = 0x21,
|
||||||
CLK_PTO_SPI3 = 0x19,
|
CLK_PTO_SDMMC3 = 0x22,
|
||||||
CLK_PTO_SPI4 = 0x1A,
|
CLK_PTO_SDMMC4 = 0x23,
|
||||||
CLK_PTO_MAUD = 0x1B,
|
CLK_PTO_EMC = 0x24,
|
||||||
CLK_PTO_SCLK = 0x1C,
|
|
||||||
|
|
||||||
CLK_PTO_SDMMC1 = 0x20,
|
CLK_PTO_DMIC3 = 0x2A,
|
||||||
CLK_PTO_SDMMC2 = 0x21,
|
CLK_PTO_CCLK_LP = 0x2B,
|
||||||
CLK_PTO_SDMMC3 = 0x22,
|
CLK_PTO_CCLK_LP_DIV2 = 0x2C,
|
||||||
CLK_PTO_SDMMC4 = 0x23,
|
|
||||||
CLK_PTO_EMC = 0x24,
|
|
||||||
|
|
||||||
CLK_PTO_CCLK_LP = 0x2B,
|
CLK_PTO_MSELECT = 0x2F,
|
||||||
CLK_PTO_CCLK_LP_DIV2 = 0x2C,
|
|
||||||
|
|
||||||
CLK_PTO_MSELECT = 0x2F,
|
CLK_PTO_VI_SENSOR2 = 0x33,
|
||||||
|
CLK_PTO_VI_SENSOR = 0x34,
|
||||||
|
CLK_PTO_VIC = 0x35,
|
||||||
|
CLK_PTO_VIC_SKIP = 0x36,
|
||||||
|
CLK_PTO_ISP_SKIP = 0x37,
|
||||||
|
CLK_PTO_ISPB_SE2_SKIP = 0x38,
|
||||||
|
CLK_PTO_NVDEC_SKIP = 0x39,
|
||||||
|
CLK_PTO_NVENC_SKIP = 0x3A,
|
||||||
|
CLK_PTO_NVJPG_SKIP = 0x3B,
|
||||||
|
CLK_PTO_TSEC_SKIP = 0x3C,
|
||||||
|
CLK_PTO_TSECB_SKIP = 0x3D,
|
||||||
|
CLK_PTO_SE_SKIP = 0x3E,
|
||||||
|
CLK_PTO_VI_SKIP = 0x3F,
|
||||||
|
|
||||||
CLK_PTO_VIC = 0x36,
|
CLK_PTO_PLLX_OBS = 0x40,
|
||||||
|
CLK_PTO_PLLC_OBS = 0x41,
|
||||||
|
CLK_PTO_PLLM_OBS = 0x42,
|
||||||
|
CLK_PTO_PLLP_OBS = 0x43,
|
||||||
|
CLK_PTO_PLLA_OBS = 0x44,
|
||||||
|
CLK_PTO_PLLMB_OBS = 0x45,
|
||||||
|
CLK_PTO_SATA_OOB = 0x46,
|
||||||
|
|
||||||
CLK_PTO_NVDEC = 0x39,
|
CLK_PTO_FCPU_DVFS_DIV12_CPU = 0x48,
|
||||||
|
|
||||||
CLK_PTO_NVENC = 0x3A,
|
CLK_PTO_EQOS_AXI = 0x4C,
|
||||||
CLK_PTO_NVJPG = 0x3B,
|
CLK_PTO_EQOS_PTP_REF = 0x4D,
|
||||||
CLK_PTO_TSEC = 0x3C,
|
CLK_PTO_EQOS_TX = 0x4E,
|
||||||
CLK_PTO_TSECB = 0x3D,
|
CLK_PTO_EQOS_RX = 0x4F,
|
||||||
CLK_PTO_SE = 0x3E,
|
|
||||||
|
|
||||||
CLK_PTO_DSIA_LP = 0x62,
|
CLK_PTO_CILAB = 0x52,
|
||||||
|
CLK_PTO_CILCD = 0x53,
|
||||||
|
|
||||||
CLK_PTO_ISP = 0x64,
|
CLK_PTO_CILEF = 0x55,
|
||||||
CLK_PTO_MC = 0x6A,
|
CLK_PTO_PLLA1_PTO_OBS = 0x56,
|
||||||
|
CLK_PTO_PLLC4_PTO_OBS = 0x57,
|
||||||
|
|
||||||
CLK_PTO_ACTMON = 0x6B,
|
CLK_PTO_PLLC2_PTO_OBS = 0x59,
|
||||||
CLK_PTO_CSITE = 0x6C,
|
CLK_PTO_PLLC3_PTO_OBS = 0x5B,
|
||||||
|
|
||||||
CLK_PTO_HOST1X = 0x6F,
|
CLK_PTO_DSIA_LP = 0x62,
|
||||||
|
CLK_PTO_DSIB_LP = 0x63,
|
||||||
|
CLK_PTO_ISP = 0x64,
|
||||||
|
CLK_PTO_PEX_PAD = 0x65,
|
||||||
|
|
||||||
CLK_PTO_SE_2 = 0x74, // Same as CLK_PTO_SE.
|
CLK_PTO_MC = 0x6A,
|
||||||
CLK_PTO_SOC_THERM = 0x75,
|
|
||||||
|
|
||||||
CLK_PTO_TSEC_2 = 0x77, // Same as CLK_PTO_TSEC.
|
CLK_PTO_ACTMON = 0x6B,
|
||||||
|
CLK_PTO_CSITE = 0x6C,
|
||||||
|
CLK_PTO_VI_I2C = 0x6D,
|
||||||
|
|
||||||
CLK_PTO_ACLK = 0x7C,
|
CLK_PTO_HOST1X = 0x6F,
|
||||||
CLK_PTO_QSPI = 0x7D,
|
|
||||||
|
|
||||||
CLK_PTO_I2S1 = 0x80,
|
CLK_PTO_QSPI_2X = 0x71,
|
||||||
CLK_PTO_I2S2 = 0x81,
|
CLK_PTO_NVDEC = 0x72,
|
||||||
CLK_PTO_I2S3 = 0x82,
|
CLK_PTO_NVJPG = 0x73,
|
||||||
CLK_PTO_I2S4 = 0x83,
|
CLK_PTO_SE = 0x74,
|
||||||
CLK_PTO_I2S5 = 0x84,
|
CLK_PTO_SOC_THERM = 0x75,
|
||||||
CLK_PTO_AHUB = 0x85,
|
|
||||||
CLK_PTO_APE = 0x86,
|
|
||||||
|
|
||||||
CLK_PTO_DVFS_SOC = 0x88,
|
CLK_PTO_TSEC = 0x77,
|
||||||
CLK_PTO_DVFS_REF = 0x89,
|
CLK_PTO_TSECB = 0x78,
|
||||||
|
CLK_PTO_VI = 0x79,
|
||||||
|
CLK_PTO_LA = 0x7A,
|
||||||
|
CLK_PTO_SCLK_SKIP = 0x7B,
|
||||||
|
|
||||||
CLK_PTO_SPDIF = 0x8F,
|
CLK_PTO_ADSP_SKIP = 0x7C,
|
||||||
CLK_PTO_SPDIF_IN = 0x90,
|
CLK_PTO_QSPI = 0x7D,
|
||||||
|
|
||||||
|
CLK_PTO_SDMMC2_SHAPER = 0x7E,
|
||||||
|
CLK_PTO_SDMMC4_SHAPER = 0x7F,
|
||||||
|
CLK_PTO_I2S1 = 0x80,
|
||||||
|
CLK_PTO_I2S2 = 0x81,
|
||||||
|
CLK_PTO_I2S3 = 0x82,
|
||||||
|
CLK_PTO_I2S4 = 0x83,
|
||||||
|
CLK_PTO_I2S5 = 0x84,
|
||||||
|
CLK_PTO_AHUB = 0x85,
|
||||||
|
CLK_PTO_APE = 0x86,
|
||||||
|
|
||||||
|
CLK_PTO_DVFS_SOC = 0x88,
|
||||||
|
CLK_PTO_DVFS_REF = 0x89,
|
||||||
|
CLK_PTO_ADSP_CLK = 0x8A,
|
||||||
|
CLK_PTO_ADSP_DIV2_CLK = 0x8B,
|
||||||
|
|
||||||
|
CLK_PTO_SPDIF_OUT = 0x8F,
|
||||||
|
CLK_PTO_SPDIF_IN = 0x90,
|
||||||
CLK_PTO_UART_FST_MIPI_CAL = 0x91,
|
CLK_PTO_UART_FST_MIPI_CAL = 0x91,
|
||||||
|
CLK_PTO_SYS2HSIO_SATA_CLK = 0x92,
|
||||||
|
CLK_PTO_PWM = 0x93,
|
||||||
|
CLK_PTO_I2C1 = 0x94,
|
||||||
|
CLK_PTO_I2C2 = 0x95,
|
||||||
|
CLK_PTO_I2C3 = 0x96,
|
||||||
|
CLK_PTO_I2C4 = 0x97,
|
||||||
|
CLK_PTO_I2C5 = 0x98,
|
||||||
|
CLK_PTO_I2C6 = 0x99,
|
||||||
|
CLK_PTO_I2C_SLOW = 0x9A,
|
||||||
|
CLK_PTO_UARTAPE = 0x9B,
|
||||||
|
|
||||||
CLK_PTO_PWM = 0x93,
|
CLK_PTO_EXTPERIPH1 = 0x9D,
|
||||||
CLK_PTO_I2C1 = 0x94,
|
CLK_PTO_EXTPERIPH2 = 0x9E,
|
||||||
CLK_PTO_I2C2 = 0x95,
|
CLK_PTO_EXTPERIPH3 = 0x9F,
|
||||||
CLK_PTO_I2C3 = 0x96,
|
CLK_PTO_ENTROPY = 0xA0,
|
||||||
CLK_PTO_I2C4 = 0x97,
|
CLK_PTO_UARTA = 0xA1,
|
||||||
CLK_PTO_I2C5 = 0x98,
|
CLK_PTO_UARTB = 0xA2,
|
||||||
CLK_PTO_I2C6 = 0x99,
|
CLK_PTO_UARTC = 0xA3,
|
||||||
CLK_PTO_I2C_SLOW = 0x9A,
|
CLK_PTO_UARTD = 0xA4,
|
||||||
CLK_PTO_UARTAPE = 0x9B,
|
CLK_PTO_OWR = 0xA5,
|
||||||
|
CLK_PTO_TSENSOR = 0xA6,
|
||||||
|
CLK_PTO_HDA2CODEC_2X = 0xA7,
|
||||||
|
CLK_PTO_HDA = 0xA8,
|
||||||
|
CLK_PTO_EMC_LATENCY = 0xA9,
|
||||||
|
CLK_PTO_EMC_DLL = 0xAA,
|
||||||
|
CLK_PTO_SDMMC_LEGACY_TM = 0xAB,
|
||||||
|
CLK_PTO_DBGAPB = 0xAC,
|
||||||
|
|
||||||
CLK_PTO_EXTPERIPH1 = 0x9D,
|
CLK_PTO_SOR0 = 0xC0,
|
||||||
CLK_PTO_EXTPERIPH2 = 0x9E,
|
CLK_PTO_SOR1 = 0xC1,
|
||||||
|
CLK_PTO_HDMI = 0xC2,
|
||||||
|
|
||||||
CLK_PTO_ENTROPY = 0xA0,
|
CLK_PTO_DISP2 = 0xC4,
|
||||||
CLK_PTO_UARTA = 0xA1,
|
CLK_PTO_DISP1 = 0xC5,
|
||||||
CLK_PTO_UARTB = 0xA2,
|
|
||||||
CLK_PTO_UARTC = 0xA3,
|
|
||||||
CLK_PTO_UARTD = 0xA4,
|
|
||||||
CLK_PTO_OWR = 0xA5,
|
|
||||||
|
|
||||||
CLK_PTO_HDA2CODEC_2X = 0xA7,
|
CLK_PTO_PLLD_OBS = 0xCA,
|
||||||
CLK_PTO_HDA = 0xA8,
|
CLK_PTO_PLLD2_PTO_OBS = 0xCC,
|
||||||
|
CLK_PTO_PLLDP_OBS = 0xCE,
|
||||||
|
CLK_PTO_PLLE_OBS = 0x10A,
|
||||||
|
CLK_PTO_PLLU_OBS = 0x10C,
|
||||||
|
CLK_PTO_PLLREFE_OBS = 0x10E,
|
||||||
|
|
||||||
CLK_PTO_SDMMC_LEGACY_TM = 0xAB,
|
CLK_PTO_XUSB_FALCON = 0x110,
|
||||||
|
CLK_PTO_XUSB_CLK480M_HSIC = 0x111,
|
||||||
|
CLK_PTO_USB_L0_RX = 0x112,
|
||||||
|
CLK_PTO_USB_L3_RX = 0x113,
|
||||||
|
CLK_PTO_USB_RX = 0x114,
|
||||||
|
CLK_PTO_USB3_L0_TXCLKREF = 0x115,
|
||||||
|
CLK_PTO_PEX_TXCLKREF_SWITCH_TMS = 0x116,
|
||||||
|
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP0 = 0x117,
|
||||||
|
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP1 = 0x118,
|
||||||
|
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP2 = 0x119,
|
||||||
|
CLK_PTO_PEX_L4_RX = 0x11A,
|
||||||
|
CLK_PTO_PEX_TXCLKREF = 0x11B,
|
||||||
|
CLK_PTO_PEX_TXCLKREF_DIV2 = 0x11C,
|
||||||
|
CLK_PTO_PEX_TXCLKREF2 = 0x11D,
|
||||||
|
CLK_PTO_PEX_L0_RX = 0x11E,
|
||||||
|
CLK_PTO_PEX_L1_RX = 0x11F,
|
||||||
|
CLK_PTO_PEX_L2_RX = 0x120,
|
||||||
|
CLK_PTO_PEX_L3_RX = 0x121,
|
||||||
|
CLK_PTO_SATA_TXCLKREF = 0x122,
|
||||||
|
CLK_PTO_SATA_TXCLKREF_DIV2 = 0x123,
|
||||||
|
CLK_PTO_USB_L5_RX = 0x124,
|
||||||
|
CLK_PTO_SATA_TX = 0x125,
|
||||||
|
CLK_PTO_SATA_L0_RX = 0x126,
|
||||||
|
|
||||||
CLK_PTO_SOR0 = 0xC0,
|
CLK_PTO_USB3_L1_TXCLKREF = 0x129,
|
||||||
CLK_PTO_SOR1 = 0xC1,
|
CLK_PTO_USB3_L7_TXCLKREF = 0x12A,
|
||||||
|
CLK_PTO_USB3_L7_RX = 0x12B,
|
||||||
|
CLK_PTO_USB3_TX = 0x12C,
|
||||||
|
CLK_PTO_UTMIP_PLL_PAD = 0x12D,
|
||||||
|
|
||||||
CLK_PTO_DISP2 = 0xC4,
|
CLK_PTO_XUSB_FS = 0x136,
|
||||||
CLK_PTO_DISP1 = 0xC5,
|
CLK_PTO_XUSB_SS_HOST_DEV = 0x137,
|
||||||
|
CLK_PTO_XUSB_CORE_HOST = 0x138,
|
||||||
|
CLK_PTO_XUSB_CORE_DEV = 0x139,
|
||||||
|
|
||||||
CLK_PTO_XUSB_FALCON = 0x110,
|
CLK_PTO_USB3_L2_TXCLKREF = 0x13C,
|
||||||
|
CLK_PTO_USB3_L3_TXCLKREF = 0x13D,
|
||||||
CLK_PTO_XUSB_FS = 0x136,
|
CLK_PTO_USB_L4_RX = 0x13E,
|
||||||
CLK_PTO_XUSB_SS_HOST_DEV = 0x137,
|
CLK_PTO_USB_L6_RX = 0x13F,
|
||||||
CLK_PTO_XUSB_CORE_HOST = 0x138,
|
|
||||||
CLK_PTO_XUSB_CORE_DEV = 0x139,
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PLL need PTO enabled in MISC registers.
|
* PLL need PTO enabled in MISC registers.
|
||||||
* Normal div is 2 so result is multiplied with it.
|
* Normal div is 2 so result is multiplied with it.
|
||||||
*/
|
*/
|
||||||
CLK_PTO_PLLC_DIV2 = 0x01,
|
CLK_PTO_PLLC_DIV2 = 0x01,
|
||||||
CLK_PTO_PLLM_DIV2 = 0x02,
|
CLK_PTO_PLLM_DIV2 = 0x02,
|
||||||
CLK_PTO_PLLP_DIV2 = 0x03,
|
CLK_PTO_PLLP_DIV2 = 0x03,
|
||||||
CLK_PTO_PLLA_DIV2 = 0x04,
|
CLK_PTO_PLLA_DIV2 = 0x04,
|
||||||
CLK_PTO_PLLX_DIV2 = 0x05,
|
CLK_PTO_PLLX_DIV2 = 0x05,
|
||||||
|
|
||||||
CLK_PTO_PLLMB_DIV2 = 0x25,
|
CLK_PTO_PLLMB_DIV2 = 0x25,
|
||||||
|
|
||||||
CLK_PTO_PLLC4_DIV2 = 0x51,
|
CLK_PTO_PLLC4_DIV2 = 0x51,
|
||||||
|
|
||||||
CLK_PTO_PLLA1_DIV2 = 0x55,
|
CLK_PTO_PLLA1_DIV2 = 0x55,
|
||||||
CLK_PTO_PLLC2_DIV2 = 0x58,
|
CLK_PTO_PLLC2_DIV2 = 0x58,
|
||||||
CLK_PTO_PLLC3_DIV2 = 0x5A,
|
CLK_PTO_PLLC3_DIV2 = 0x5A,
|
||||||
|
|
||||||
CLK_PTO_PLLD_DIV2 = 0xCB,
|
CLK_PTO_PLLD_DIV2 = 0xCB,
|
||||||
CLK_PTO_PLLD2_DIV2 = 0xCD,
|
CLK_PTO_PLLD2_DIV2 = 0xCD,
|
||||||
CLK_PTO_PLLDP_DIV2 = 0xCF,
|
CLK_PTO_PLLDP_DIV2 = 0xCF,
|
||||||
|
|
||||||
CLK_PTO_PLLU_DIV2 = 0x10D,
|
CLK_PTO_PLLE_DIV2 = 0x10B,
|
||||||
|
|
||||||
CLK_PTO_PLLREFE_DIV2 = 0x10F,
|
CLK_PTO_PLLU_DIV2 = 0x10D,
|
||||||
|
|
||||||
|
CLK_PTO_PLLREFE_DIV2 = 0x10F,
|
||||||
} clock_pto_id_t;
|
} clock_pto_id_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -374,109 +469,85 @@ typedef enum _clock_pto_id_t
|
|||||||
|
|
||||||
enum CLK_L_DEV
|
enum CLK_L_DEV
|
||||||
{
|
{
|
||||||
CLK_L_CPU = 0, // Only reset. Deprecated.
|
CLK_L_CPU = 0, // Deprecated.
|
||||||
CLK_L_BPMP = 1, // Only reset.
|
CLK_L_BPMP = 1, // Only reset.
|
||||||
CLK_L_SYS = 2, // Only reset.
|
CLK_L_SYS = 2, // Only reset.
|
||||||
CLK_L_ISPB = 3,
|
CLK_L_ISPB = 3,
|
||||||
CLK_L_RTC = 4,
|
CLK_L_RTC = 4, // Only enable.
|
||||||
CLK_L_TMR = 5,
|
CLK_L_TMR = 5,
|
||||||
CLK_L_UARTA = 6,
|
CLK_L_UARTA = 6,
|
||||||
CLK_L_UARTB = 7,
|
CLK_L_UARTB = 7,
|
||||||
CLK_L_GPIO = 8,
|
CLK_L_GPIO = 8,
|
||||||
CLK_L_SDMMC2 = 9,
|
CLK_L_SDMMC2 = 9,
|
||||||
CLK_L_SPDIF = 10,
|
CLK_L_SPDIF = 10, // Only enable.
|
||||||
CLK_L_I2S2 = 11, // I2S1
|
CLK_L_I2S2 = 11, // Only enable.
|
||||||
CLK_L_I2C1 = 12,
|
CLK_L_I2C1 = 12,
|
||||||
CLK_L_NDFLASH = 13, // HIDDEN.
|
CLK_L_SDMMC1 = 14,
|
||||||
CLK_L_SDMMC1 = 14,
|
CLK_L_SDMMC4 = 15,
|
||||||
CLK_L_SDMMC4 = 15,
|
CLK_L_TWC = 16, // 3-Wire Controller. Deprecated.
|
||||||
CLK_L_TWC = 16, // HIDDEN.
|
CLK_L_PWM = 17,
|
||||||
CLK_L_PWM = 17,
|
CLK_L_I2S3 = 18, // Only enable.
|
||||||
CLK_L_I2S3 = 18,
|
CLK_L_VI = 20,
|
||||||
CLK_L_EPP = 19, // HIDDEN.
|
CLK_L_USBD = 22,
|
||||||
CLK_L_VI = 20,
|
CLK_L_ISP = 23,
|
||||||
CLK_L_2D = 21, // HIDDEN.
|
CLK_L_DISP2 = 26,
|
||||||
CLK_L_USBD = 22,
|
CLK_L_DISP1 = 27,
|
||||||
CLK_L_ISP = 23,
|
CLK_L_HOST1X = 28,
|
||||||
CLK_L_3D = 24, // HIDDEN.
|
CLK_L_I2S1 = 30, // Only enable.
|
||||||
CLK_L_IDE = 25, // RESERVED.
|
CLK_L_BPMP_CACHE_CTRL = 31, // Controller.
|
||||||
CLK_L_DISP2 = 26,
|
|
||||||
CLK_L_DISP1 = 27,
|
|
||||||
CLK_L_HOST1X = 28,
|
|
||||||
CLK_L_VCP = 29, // HIDDEN.
|
|
||||||
CLK_L_I2S1 = 30, // I2S0
|
|
||||||
CLK_L_BPMP_CACHE_CTRL = 31, // CONTROLLER
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CLK_H_DEV
|
enum CLK_H_DEV
|
||||||
{
|
{
|
||||||
CLK_H_MEM = 0, // MC.
|
CLK_H_MEM = 0, // MC.
|
||||||
CLK_H_AHBDMA = 1,
|
CLK_H_AHBDMA = 1,
|
||||||
CLK_H_APBDMA = 2,
|
CLK_H_APBDMA = 2,
|
||||||
//CLK_H_ = 3,
|
CLK_H_STAT_MON = 5,
|
||||||
CLK_H_KBC = 4, // HIDDEN.
|
CLK_H_PMC = 6, // Only enable.
|
||||||
CLK_H_STAT_MON = 5,
|
CLK_H_FUSE = 7,
|
||||||
CLK_H_PMC = 6,
|
CLK_H_KFUSE = 8,
|
||||||
CLK_H_FUSE = 7,
|
CLK_H_SPI1 = 9,
|
||||||
CLK_H_KFUSE = 8,
|
|
||||||
CLK_H_SPI1 = 9,
|
|
||||||
CLK_H_SNOR = 10, // HIDDEN.
|
|
||||||
CLK_H_JTAG2TBC = 11,
|
|
||||||
CLK_H_SPI2 = 12,
|
CLK_H_SPI2 = 12,
|
||||||
CLK_H_XIO = 13, // HIDDEN.
|
CLK_H_XIO = 13, // Misc IO. Deprecated?
|
||||||
CLK_H_SPI3 = 14,
|
CLK_H_SPI3 = 14,
|
||||||
CLK_H_I2C5 = 15,
|
CLK_H_I2C5 = 15,
|
||||||
CLK_H_DSI = 16,
|
CLK_H_DSI = 16,
|
||||||
CLK_H_TVO = 17, // RESERVED.
|
|
||||||
CLK_H_HSI = 18, // HIDDEN.
|
|
||||||
CLK_H_HDMI = 19, // HIDDEN.
|
|
||||||
CLK_H_CSI = 20,
|
CLK_H_CSI = 20,
|
||||||
CLK_H_TVDAC = 21, // RESERVED.
|
|
||||||
CLK_H_I2C2 = 22,
|
CLK_H_I2C2 = 22,
|
||||||
CLK_H_UARTC = 23,
|
CLK_H_UARTC = 23,
|
||||||
CLK_H_MIPI_CAL = 24,
|
CLK_H_MIPI_CAL = 24,
|
||||||
CLK_H_EMC = 25,
|
CLK_H_EMC = 25,
|
||||||
CLK_H_USB2 = 26,
|
CLK_H_USB2 = 26,
|
||||||
CLK_H_USB3 = 27, // HIDDEN.
|
|
||||||
CLK_H_MPE = 28, // HIDDEN.
|
|
||||||
CLK_H_VDE = 29, // HIDDEN.
|
|
||||||
CLK_H_BSEA = 30, // HIDDEN.
|
|
||||||
CLK_H_BSEV = 31,
|
CLK_H_BSEV = 31,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CLK_U_DEV
|
enum CLK_U_DEV
|
||||||
{
|
{
|
||||||
CLK_U_SPEEDO = 0, // RESERVED.
|
//CLK_U_SPEEDO = 0, // RESERVED. Old speedo ring oscillator.
|
||||||
CLK_U_UARTD = 1,
|
CLK_U_UARTD = 1,
|
||||||
CLK_U_UARTE = 2, // HIDDEN.
|
CLK_U_I2C3 = 3,
|
||||||
CLK_U_I2C3 = 3,
|
CLK_U_SPI4 = 4,
|
||||||
CLK_U_SPI4 = 4,
|
CLK_U_SDMMC3 = 5,
|
||||||
CLK_U_SDMMC3 = 5,
|
CLK_U_PCIE = 6,
|
||||||
CLK_U_PCIE = 6,
|
CLK_U_OWR = 7, // 1-Wire Controller. Deprecated.
|
||||||
CLK_U_OWR = 7, // RESERVED.
|
CLK_U_AFI = 8,
|
||||||
CLK_U_AFI = 8,
|
CLK_U_CSITE = 9,
|
||||||
CLK_U_CSITE = 9,
|
|
||||||
CLK_U_PCIEXCLK = 10, // Only reset.
|
CLK_U_PCIEXCLK = 10, // Only reset.
|
||||||
CLK_U_BPMPUCQ = 11, // HIDDEN.
|
CLK_U_LA = 12, // DFD.
|
||||||
CLK_U_LA = 12,
|
|
||||||
CLK_U_TRACECLKIN = 13, // HIDDEN.
|
|
||||||
CLK_U_SOC_THERM = 14,
|
CLK_U_SOC_THERM = 14,
|
||||||
CLK_U_DTV = 15,
|
CLK_U_DTV = 15, // Deprecated.
|
||||||
CLK_U_NAND_SPEED = 16, // HIDDEN.
|
|
||||||
CLK_U_I2C_SLOW = 17,
|
CLK_U_I2C_SLOW = 17,
|
||||||
CLK_U_DSIB = 18,
|
CLK_U_DSIB = 18,
|
||||||
CLK_U_TSEC = 19,
|
CLK_U_TSEC = 19,
|
||||||
CLK_U_IRAMA = 20,
|
CLK_U_IRAMA = 20, // Only enable.
|
||||||
CLK_U_IRAMB = 21,
|
CLK_U_IRAMB = 21, // Only enable.
|
||||||
CLK_U_IRAMC = 22,
|
CLK_U_IRAMC = 22, // Only enable.
|
||||||
CLK_U_IRAMD = 23, // EMUCIF ON RESET
|
CLK_U_IRAMD = 23, // EMUCIF ON RESET
|
||||||
CLK_U_BPMP_CACHE_RAM = 24,
|
CLK_U_BPMP_CACHE_RAM = 24, // Only enable.
|
||||||
CLK_U_XUSB_HOST = 25,
|
CLK_U_XUSB_HOST = 25,
|
||||||
CLK_U_CLK_M_DOUBLER = 26,
|
CLK_U_SUS_OUT = 28, // Only enable. VI MCLK. Deprecated?
|
||||||
CLK_U_MSENC = 27, // HIDDEN.
|
CLK_U_DEV2_OUT = 29, // Only enable. DAP MCLK. Deprecated?
|
||||||
CLK_U_SUS_OUT = 28,
|
CLK_U_DEV1_OUT = 30, // Only enable. DAP MCLK. Deprecated?
|
||||||
CLK_U_DEV2_OUT = 29,
|
|
||||||
CLK_U_DEV1_OUT = 30,
|
|
||||||
CLK_U_XUSB_DEV = 31,
|
CLK_U_XUSB_DEV = 31,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -484,133 +555,109 @@ enum CLK_V_DEV
|
|||||||
{
|
{
|
||||||
CLK_V_CPUG = 0,
|
CLK_V_CPUG = 0,
|
||||||
CLK_V_CPULP = 1, // Reserved.
|
CLK_V_CPULP = 1, // Reserved.
|
||||||
CLK_V_3D2 = 2, // HIDDEN.
|
|
||||||
CLK_V_MSELECT = 3,
|
CLK_V_MSELECT = 3,
|
||||||
CLK_V_TSENSOR = 4,
|
CLK_V_TSENSOR = 4, // Only enable.
|
||||||
CLK_V_I2S4 = 5,
|
CLK_V_I2S4 = 5, // Only enable.
|
||||||
CLK_V_I2S5 = 6,
|
CLK_V_I2S5 = 6, // Only enable.
|
||||||
CLK_V_I2C4 = 7,
|
CLK_V_I2C4 = 7,
|
||||||
CLK_V_SPI5 = 8, // HIDDEN.
|
CLK_V_AHUB = 10, // AUDIO. Only enable.
|
||||||
CLK_V_SPI6 = 9, // HIDDEN.
|
CLK_V_APB2APE = 11, // APBIF. Only enable.
|
||||||
CLK_V_AHUB = 10, // AUDIO.
|
|
||||||
CLK_V_APB2APE = 11, // APBIF.
|
|
||||||
CLK_V_DAM0 = 12, // HIDDEN.
|
|
||||||
CLK_V_DAM1 = 13, // HIDDEN.
|
|
||||||
CLK_V_DAM2 = 14, // HIDDEN.
|
|
||||||
CLK_V_HDA2CODEC_2X = 15,
|
CLK_V_HDA2CODEC_2X = 15,
|
||||||
CLK_V_ATOMICS = 16,
|
CLK_V_ATOMICS = 16,
|
||||||
//CLK_V_ = 17,
|
CLK_V_SPDIF_DOUBLER = 22, // Only enable.
|
||||||
//CLK_V_ = 18,
|
|
||||||
//CLK_V_ = 19,
|
|
||||||
//CLK_V_ = 20,
|
|
||||||
//CLK_V_ = 21,
|
|
||||||
CLK_V_SPDIF_DOUBLER = 22,
|
|
||||||
CLK_V_ACTMON = 23,
|
CLK_V_ACTMON = 23,
|
||||||
CLK_V_EXTPERIPH1 = 24,
|
CLK_V_EXTPERIPH1 = 24,
|
||||||
CLK_V_EXTPERIPH2 = 25,
|
CLK_V_EXTPERIPH2 = 25,
|
||||||
CLK_V_EXTPERIPH3 = 26,
|
CLK_V_EXTPERIPH3 = 26,
|
||||||
CLK_V_SATA_OOB = 27,
|
CLK_V_SATA_OOB = 27, // Only on T210.
|
||||||
CLK_V_SATA = 28,
|
CLK_V_SATA = 28, // Only on T210.
|
||||||
CLK_V_HDA = 29,
|
CLK_V_HDA = 29,
|
||||||
CLK_V_TZRAM = 30, // HIDDEN.
|
CLK_V_TZRAM = 30,
|
||||||
CLK_V_SE = 31, // HIDDEN.
|
CLK_V_SE = 31,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CLK_W_DEV
|
enum CLK_W_DEV
|
||||||
{
|
{
|
||||||
CLK_W_HDA2HDMICODEC = 0,
|
CLK_W_HDA2HDMICODEC = 0,
|
||||||
CLK_W_RESERVED0 = 1, //satacoldrstn
|
CLK_W_SATACOLD = 1, // Enable reserved. Unused.
|
||||||
CLK_W_PCIERX0 = 2,
|
CLK_W_PCIERX0 = 2, // Reset reserved.
|
||||||
CLK_W_PCIERX1 = 3,
|
CLK_W_PCIERX1 = 3, // Reset reserved.
|
||||||
CLK_W_PCIERX2 = 4,
|
CLK_W_PCIERX2 = 4, // Reset reserved.
|
||||||
CLK_W_PCIERX3 = 5,
|
CLK_W_PCIERX3 = 5, // Reset reserved.
|
||||||
CLK_W_PCIERX4 = 6,
|
CLK_W_PCIERX4 = 6, // Reset reserved.
|
||||||
CLK_W_PCIERX5 = 7,
|
CLK_W_PCIERX5 = 7, // Reset reserved.
|
||||||
CLK_W_CEC = 8,
|
CLK_W_CEC = 8,
|
||||||
CLK_W_PCIE2_IOBIST = 9,
|
CLK_W_PCIE2_IOBIST = 9, // Reset reserved.
|
||||||
CLK_W_EMC_IOBIST = 10,
|
CLK_W_EMC_IOBIST = 10, // Reset reserved.
|
||||||
CLK_W_HDMI_IOBIST = 11, // HIDDEN.
|
CLK_W_SATA_IOBIST = 12, // Reset reserved.
|
||||||
CLK_W_SATA_IOBIST = 12,
|
CLK_W_MIPI_IOBIST = 13, // Reset reserved.
|
||||||
CLK_W_MIPI_IOBIST = 13,
|
|
||||||
CLK_W_XUSB_PADCTL = 14, // Only reset.
|
CLK_W_XUSB_PADCTL = 14, // Only reset.
|
||||||
CLK_W_XUSB = 15,
|
CLK_W_XUSB = 15, // Only enable.
|
||||||
CLK_W_CILAB = 16,
|
CLK_W_CILAB = 16, // Only enable.
|
||||||
CLK_W_CILCD = 17,
|
CLK_W_CILCD = 17, // Only enable.
|
||||||
CLK_W_CILEF = 18,
|
CLK_W_CILEF = 18, // Only enable.
|
||||||
CLK_W_DSIA_LP = 19,
|
CLK_W_DSIA_LP = 19, // Only enable.
|
||||||
CLK_W_DSIB_LP = 20,
|
CLK_W_DSIB_LP = 20, // Only enable.
|
||||||
CLK_W_ENTROPY = 21,
|
CLK_W_ENTROPY = 21,
|
||||||
CLK_W_DDS = 22, // HIDDEN.
|
|
||||||
//CLK_W_ = 23,
|
|
||||||
CLK_W_DP2 = 24, // HIDDEN.
|
CLK_W_DP2 = 24, // HIDDEN.
|
||||||
CLK_W_AMX0 = 25, // HIDDEN.
|
|
||||||
CLK_W_ADX0 = 26, // HIDDEN.
|
|
||||||
CLK_W_DVFS = 27,
|
CLK_W_DVFS = 27,
|
||||||
CLK_W_XUSB_SS = 28,
|
CLK_W_XUSB_SS = 28,
|
||||||
CLK_W_EMC_LATENCY = 29,
|
CLK_W_EMC_LATENCY = 29, // Only enable.
|
||||||
CLK_W_MC1 = 30,
|
CLK_W_MC1 = 30, // Only enable.
|
||||||
//CLK_W_ = 31,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CLK_X_DEV
|
enum CLK_X_DEV
|
||||||
{
|
{
|
||||||
CLK_X_SPARE = 0,
|
CLK_X_SPARE = 0,
|
||||||
CLK_X_DMIC1 = 1,
|
CLK_X_DMIC1 = 1, // Only enable.
|
||||||
CLK_X_DMIC2 = 2,
|
CLK_X_DMIC2 = 2, // Only enable.
|
||||||
CLK_X_ETR = 3,
|
CLK_X_ETR = 3, // DFD.
|
||||||
CLK_X_CAM_MCLK = 4,
|
CLK_X_CAM_MCLK = 4, // Only enable.
|
||||||
CLK_X_CAM_MCLK2 = 5,
|
CLK_X_CAM_MCLK2 = 5, // Only enable.
|
||||||
CLK_X_I2C6 = 6,
|
CLK_X_I2C6 = 6,
|
||||||
CLK_X_MC_CAPA = 7, // MC DAISY CHAIN1
|
CLK_X_MC_CAPA = 7, // MC Clients daisy chain 1. Only enable.
|
||||||
CLK_X_MC_CBPA = 8, // MC DAISY CHAIN2
|
CLK_X_MC_CBPA = 8, // MC Clients daisy chain 2. Only enable.
|
||||||
CLK_X_MC_CPU = 9,
|
CLK_X_MC_CPU = 9, // MC CPU. Only enable.
|
||||||
CLK_X_MC_BBC = 10,
|
CLK_X_MC_BBC = 10, // MC Backbone. Only enable.
|
||||||
CLK_X_VIM2_CLK = 11,
|
CLK_X_VIM2_CLK = 11, // Only enable.
|
||||||
//CLK_X_ = 12,
|
CLK_X_MIPIBIF = 13,
|
||||||
CLK_X_MIPIBIF = 13, //RESERVED
|
CLK_X_EMC_DLL = 14, // Only enable.
|
||||||
CLK_X_EMC_DLL = 14,
|
CLK_X_UART_FST_MIPI_CAL = 17, // Only enable.
|
||||||
//CLK_X_ = 15,
|
|
||||||
CLK_X_HDMI_AUDIO = 16, // HIDDEN.
|
|
||||||
CLK_X_UART_FST_MIPI_CAL = 17,
|
|
||||||
CLK_X_VIC = 18,
|
CLK_X_VIC = 18,
|
||||||
//CLK_X_ = 19,
|
|
||||||
CLK_X_ADX1 = 20, // HIDDEN.
|
|
||||||
CLK_X_DPAUX = 21,
|
CLK_X_DPAUX = 21,
|
||||||
CLK_X_SOR0 = 22,
|
CLK_X_SOR0 = 22,
|
||||||
CLK_X_SOR1 = 23,
|
CLK_X_SOR1 = 23,
|
||||||
CLK_X_GPU = 24,
|
CLK_X_GPU = 24,
|
||||||
CLK_X_DBGAPB = 25,
|
CLK_X_DBGAPB = 25, // Only enable.
|
||||||
CLK_X_HPLL_ADSP = 26,
|
CLK_X_HPLL_ADSP = 26, // Only enable.
|
||||||
CLK_X_PLLP_ADSP = 27,
|
CLK_X_PLLP_ADSP = 27, // Only enable.
|
||||||
CLK_X_PLLA_ADSP = 28,
|
CLK_X_PLLA_ADSP = 28, // Only enable.
|
||||||
CLK_X_PLLG_REF = 29,
|
CLK_X_PLLG_REF = 29, // Only enable.
|
||||||
//CLK_X_ = 30,
|
CLK_X_EQOS = 30, // T210B01 only.
|
||||||
//CLK_X_ = 31,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CLK_Y_DEV
|
enum CLK_Y_DEV
|
||||||
{
|
{
|
||||||
CLK_Y_SPARE1 = 0,
|
CLK_Y_SPARE1 = 0,
|
||||||
CLK_Y_SDMMC_LEGACY_TM = 1,
|
CLK_Y_SDMMC_LEGACY_TM = 1, // Only enable.
|
||||||
CLK_Y_NVDEC = 2,
|
CLK_Y_NVDEC = 2,
|
||||||
CLK_Y_NVJPG = 3,
|
CLK_Y_NVJPG = 3,
|
||||||
CLK_Y_AXIAP = 4,
|
CLK_Y_AXIAP = 4, // DFD.
|
||||||
CLK_Y_DMIC3 = 5,
|
CLK_Y_DMIC3 = 5, // Only enable.
|
||||||
CLK_Y_APE = 6,
|
CLK_Y_APE = 6,
|
||||||
CLK_Y_ADSP = 7,
|
CLK_Y_ADSP = 7,
|
||||||
CLK_Y_MC_CDPA = 8, // MC DAISY CHAIN4
|
CLK_Y_MC_CDPA = 8, // MC Clients daisy chain 4. Only enable.
|
||||||
CLK_Y_MC_CCPA = 9, // MC DAISY CHAIN3
|
CLK_Y_MC_CCPA = 9, // MC Clients daisy chain 3. Only enable.
|
||||||
CLK_Y_MAUD = 10,
|
CLK_Y_MAUD = 10, // Only enable.
|
||||||
//CLK_Y_ = 11,
|
|
||||||
CLK_Y_SATA_USB_UPHY = 12, // Only reset.
|
CLK_Y_SATA_USB_UPHY = 12, // Only reset.
|
||||||
CLK_Y_PEX_USB_UPHY = 13, // Only reset.
|
CLK_Y_PEX_USB_UPHY = 13, // Only reset.
|
||||||
CLK_Y_TSECB = 14,
|
CLK_Y_TSECB = 14,
|
||||||
CLK_Y_DPAUX1 = 15,
|
CLK_Y_DPAUX1 = 15,
|
||||||
CLK_Y_VI_I2C = 16,
|
CLK_Y_VI_I2C = 16,
|
||||||
CLK_Y_HSIC_TRK = 17,
|
CLK_Y_HSIC_TRK = 17, // Only enable.
|
||||||
CLK_Y_USB2_TRK = 18,
|
CLK_Y_USB2_TRK = 18, // Only enable.
|
||||||
CLK_Y_QSPI = 19,
|
CLK_Y_QSPI = 19,
|
||||||
CLK_Y_UARTAPE = 20,
|
CLK_Y_UARTAPE = 20, // Only enable.
|
||||||
CLK_Y_ADSPINTF = 21, // Only reset.
|
CLK_Y_ADSPINTF = 21, // Only reset.
|
||||||
CLK_Y_ADSPPERIPH = 22, // Only reset.
|
CLK_Y_ADSPPERIPH = 22, // Only reset.
|
||||||
CLK_Y_ADSPDBG = 23, // Only reset.
|
CLK_Y_ADSPDBG = 23, // Only reset.
|
||||||
@@ -618,14 +665,14 @@ enum CLK_Y_DEV
|
|||||||
CLK_Y_ADSPSCU = 25, // Only reset.
|
CLK_Y_ADSPSCU = 25, // Only reset.
|
||||||
CLK_Y_ADSPNEON = 26,
|
CLK_Y_ADSPNEON = 26,
|
||||||
CLK_Y_NVENC = 27,
|
CLK_Y_NVENC = 27,
|
||||||
CLK_Y_IQC2 = 28,
|
CLK_Y_IQC2 = 28, // Only enable. (Audio.)
|
||||||
CLK_Y_IQC1 = 29,
|
CLK_Y_IQC1 = 29, // Only enable. (Audio.)
|
||||||
CLK_Y_SOR_SAFE = 30,
|
CLK_Y_SOR_SAFE = 30, // Only enable.
|
||||||
CLK_Y_PLLP_OUT_CPU = 31,
|
CLK_Y_PLLP_OUT_CPU = 31, // Only enable.
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! Generic clock descriptor. */
|
/*! Generic clock descriptor. */
|
||||||
typedef struct _clock_t
|
typedef struct _clk_rst_t
|
||||||
{
|
{
|
||||||
u16 reset;
|
u16 reset;
|
||||||
u16 enable;
|
u16 enable;
|
||||||
@@ -633,11 +680,11 @@ typedef struct _clock_t
|
|||||||
u8 index;
|
u8 index;
|
||||||
u8 clk_src;
|
u8 clk_src;
|
||||||
u8 clk_div;
|
u8 clk_div;
|
||||||
} clock_t;
|
} clk_rst_t;
|
||||||
|
|
||||||
/*! Generic clock enable/disable. */
|
/*! Generic clock enable/disable. */
|
||||||
void clock_enable(const clock_t *clk);
|
void clock_enable(const clk_rst_t *clk);
|
||||||
void clock_disable(const clock_t *clk);
|
void clock_disable(const clk_rst_t *clk);
|
||||||
|
|
||||||
/*! Clock control for specific hardware portions. */
|
/*! Clock control for specific hardware portions. */
|
||||||
void clock_enable_fuse(bool enable);
|
void clock_enable_fuse(bool enable);
|
||||||
@@ -691,10 +738,10 @@ void clock_enable_pllu();
|
|||||||
void clock_disable_pllu();
|
void clock_disable_pllu();
|
||||||
void clock_enable_utmipll();
|
void clock_enable_utmipll();
|
||||||
|
|
||||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 val);
|
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 clock);
|
||||||
void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type);
|
void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type);
|
||||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
||||||
void clock_sdmmc_enable(u32 id, u32 val);
|
void clock_sdmmc_enable(u32 id, u32 clock);
|
||||||
void clock_sdmmc_disable(u32 id);
|
void clock_sdmmc_disable(u32 id);
|
||||||
|
|
||||||
u32 clock_get_osc_freq();
|
u32 clock_get_osc_freq();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018 shuffle2
|
* Copyright (c) 2018 shuffle2
|
||||||
* Copyright (c) 2018 balika011
|
* Copyright (c) 2018 balika011
|
||||||
* Copyright (c) 2019-2022 CTCaer
|
* Copyright (c) 2019-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -22,9 +22,12 @@
|
|||||||
#include <mem/heap.h>
|
#include <mem/heap.h>
|
||||||
#include <sec/se.h>
|
#include <sec/se.h>
|
||||||
#include <sec/se_t210.h>
|
#include <sec/se_t210.h>
|
||||||
|
#include <soc/clock.h>
|
||||||
#include <soc/fuse.h>
|
#include <soc/fuse.h>
|
||||||
#include <soc/hw_init.h>
|
#include <soc/hw_init.h>
|
||||||
|
#include <soc/pmc.h>
|
||||||
#include <soc/t210.h>
|
#include <soc/t210.h>
|
||||||
|
#include <soc/timer.h>
|
||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
|
|
||||||
static const u32 evp_thunk_template[] = {
|
static const u32 evp_thunk_template[] = {
|
||||||
@@ -102,7 +105,7 @@ u32 fuse_read_dramid(bool raw_id)
|
|||||||
|
|
||||||
if (tegra_t210)
|
if (tegra_t210)
|
||||||
{
|
{
|
||||||
if (dramid > 6)
|
if (dramid > 7)
|
||||||
dramid = 0;
|
dramid = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -167,17 +170,34 @@ int fuse_set_sbk()
|
|||||||
|
|
||||||
void fuse_wait_idle()
|
void fuse_wait_idle()
|
||||||
{
|
{
|
||||||
u32 ctrl;
|
while (((FUSE(FUSE_CTRL) >> 16) & 0x1F) != FUSE_STATUS_IDLE)
|
||||||
do
|
;
|
||||||
{
|
}
|
||||||
ctrl = FUSE(FUSE_CTRL);
|
|
||||||
} while (((ctrl >> 16) & 0x1f) != 4);
|
void fuse_sense()
|
||||||
|
{
|
||||||
|
clock_enable_fuse(false);
|
||||||
|
|
||||||
|
FUSE(FUSE_CTRL) = (FUSE(FUSE_CTRL) & (~FUSE_CMD_MASK)) | FUSE_SENSE;
|
||||||
|
usleep(1);
|
||||||
|
|
||||||
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
FUSE(FUSE_PRIV2INTFC) = FUSE_PRIV2INTFC_SKIP_RECORDS | FUSE_PRIV2INTFC_START_DATA;
|
||||||
|
usleep(1);
|
||||||
|
|
||||||
|
while (!(FUSE(FUSE_CTRL) & BIT(30)) || ((FUSE(FUSE_CTRL) >> 16) & 0x1F) != FUSE_STATUS_IDLE)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
clock_enable_fuse(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 fuse_read(u32 addr)
|
u32 fuse_read(u32 addr)
|
||||||
{
|
{
|
||||||
FUSE(FUSE_ADDR) = addr;
|
FUSE(FUSE_ADDR) = addr;
|
||||||
FUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;
|
FUSE(FUSE_CTRL) = (FUSE(FUSE_CTRL) & ~FUSE_CMD_MASK) | FUSE_READ;
|
||||||
|
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
return FUSE(FUSE_RDATA);
|
return FUSE(FUSE_RDATA);
|
||||||
@@ -186,13 +206,13 @@ u32 fuse_read(u32 addr)
|
|||||||
void fuse_read_array(u32 *words)
|
void fuse_read_array(u32 *words)
|
||||||
{
|
{
|
||||||
u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ?
|
u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ?
|
||||||
FUSE_ARRAY_WORDS_NUM_T210B01 : FUSE_ARRAY_WORDS_NUM;
|
FUSE_ARRAY_WORDS_NUM_B01 : FUSE_ARRAY_WORDS_NUM;
|
||||||
|
|
||||||
for (u32 i = 0; i < array_size; i++)
|
for (u32 i = 0; i < array_size; i++)
|
||||||
words[i] = fuse_read(i);
|
words[i] = fuse_read(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 _parity32_even(u32 *words, u32 count)
|
static u32 _parity32_even(const u32 *words, u32 count)
|
||||||
{
|
{
|
||||||
u32 acc = words[0];
|
u32 acc = words[0];
|
||||||
for (u32 i = 1; i < count; i++)
|
for (u32 i = 1; i < count; i++)
|
||||||
@@ -306,7 +326,7 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
|
|||||||
u32 words[80];
|
u32 words[80];
|
||||||
u32 word_count;
|
u32 word_count;
|
||||||
u32 word_addr;
|
u32 word_addr;
|
||||||
u32 word0 = 0;
|
u32 word0;
|
||||||
u32 total_read = 0;
|
u32 total_read = 0;
|
||||||
|
|
||||||
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
||||||
@@ -325,9 +345,9 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
|
|||||||
// Parse extra T210B01 fuses when the difference is reached.
|
// Parse extra T210B01 fuses when the difference is reached.
|
||||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
|
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
|
||||||
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
|
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
|
||||||
(FUSE_ARRAY_WORDS_NUM_T210B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
|
(FUSE_ARRAY_WORDS_NUM_B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
|
||||||
{
|
{
|
||||||
word_addr = FUSE_ARRAY_WORDS_NUM_T210B01 - 1;
|
word_addr = FUSE_ARRAY_WORDS_NUM_B01 - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,7 +386,7 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
|||||||
u32 words[80];
|
u32 words[80];
|
||||||
u32 word_count;
|
u32 word_count;
|
||||||
u32 word_addr;
|
u32 word_addr;
|
||||||
u32 word0 = 0;
|
u32 word0;
|
||||||
u32 total_read = 0;
|
u32 total_read = 0;
|
||||||
int evp_thunk_written = 0;
|
int evp_thunk_written = 0;
|
||||||
void *evp_thunk_dst_addr = 0;
|
void *evp_thunk_dst_addr = 0;
|
||||||
@@ -395,9 +415,9 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
|||||||
// Parse extra T210B01 fuses when the difference is reached.
|
// Parse extra T210B01 fuses when the difference is reached.
|
||||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
|
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
|
||||||
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
|
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
|
||||||
(FUSE_ARRAY_WORDS_NUM_T210B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
|
(FUSE_ARRAY_WORDS_NUM_B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
|
||||||
{
|
{
|
||||||
word_addr = FUSE_ARRAY_WORDS_NUM_T210B01 - 1;
|
word_addr = FUSE_ARRAY_WORDS_NUM_B01 - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
315
bdk/soc/fuse.h
315
bdk/soc/fuse.h
@@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018 shuffle2
|
* Copyright (c) 2018 shuffle2
|
||||||
* Copyright (c) 2018 balika011
|
* Copyright (c) 2018 balika011
|
||||||
* Copyright (c) 2019-2022 CTCaer
|
* Copyright (c) 2019-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -23,67 +23,276 @@
|
|||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
|
|
||||||
/*! Fuse registers. */
|
/*! Fuse registers. */
|
||||||
#define FUSE_CTRL 0x0
|
#define FUSE_CTRL 0x0
|
||||||
#define FUSE_ADDR 0x4
|
#define FUSE_ADDR 0x4
|
||||||
#define FUSE_RDATA 0x8
|
#define FUSE_RDATA 0x8
|
||||||
#define FUSE_WDATA 0xC
|
#define FUSE_WDATA 0xC
|
||||||
#define FUSE_TIME_RD1 0x10
|
#define FUSE_TIME_RD1 0x10
|
||||||
#define FUSE_TIME_RD2 0x14
|
#define FUSE_TIME_RD2 0x14
|
||||||
#define FUSE_TIME_PGM1 0x18
|
#define FUSE_TIME_PGM1 0x18
|
||||||
#define FUSE_TIME_PGM2 0x1C
|
#define FUSE_TIME_PGM2 0x1C
|
||||||
#define FUSE_PRIV2INTFC 0x20
|
#define FUSE_PRIV2INTFC 0x20
|
||||||
#define FUSE_FUSEBYPASS 0x24
|
#define FUSE_PRIV2INTFC_START_DATA BIT(0)
|
||||||
#define FUSE_PRIVATEKEYDISABLE 0x28
|
#define FUSE_PRIV2INTFC_SKIP_RECORDS BIT(1)
|
||||||
#define FUSE_DISABLEREGPROGRAM 0x2C
|
#define FUSE_FUSEBYPASS 0x24
|
||||||
#define FUSE_WRITE_ACCESS_SW 0x30
|
#define FUSE_PRIVATEKEYDISABLE 0x28
|
||||||
#define FUSE_PWR_GOOD_SW 0x34
|
#define FUSE_PRIVKEY_DISABLE BIT(0)
|
||||||
|
#define FUSE_PRIVKEY_TZ_STICKY_BIT BIT(4)
|
||||||
|
#define FUSE_DISABLEREGPROGRAM 0x2C
|
||||||
|
#define FUSE_WRITE_ACCESS_SW 0x30
|
||||||
|
#define FUSE_PWR_GOOD_SW 0x34
|
||||||
|
#define FUSE_PRIV2RESHIFT 0x3C
|
||||||
|
#define FUSE_FUSETIME_RD0 0x40
|
||||||
|
#define FUSE_FUSETIME_RD1 0x44
|
||||||
|
#define FUSE_FUSETIME_RD2 0x48
|
||||||
|
#define FUSE_FUSETIME_RD3 0x4C
|
||||||
|
#define FUSE_PRIVATE_KEY0_NONZERO 0x80
|
||||||
|
#define FUSE_PRIVATE_KEY1_NONZERO 0x84
|
||||||
|
#define FUSE_PRIVATE_KEY2_NONZERO 0x88
|
||||||
|
#define FUSE_PRIVATE_KEY3_NONZERO 0x8C
|
||||||
|
#define FUSE_PRIVATE_KEY4_NONZERO 0x90
|
||||||
|
|
||||||
/*! Fuse Cached registers */
|
/*! Fuse Cached registers */
|
||||||
#define FUSE_SKU_INFO 0x110
|
#define FUSE_RESERVED_ODM8_B01 0x98
|
||||||
#define FUSE_CPU_SPEEDO_0_CALIB 0x114
|
#define FUSE_RESERVED_ODM9_B01 0x9C
|
||||||
#define FUSE_CPU_IDDQ_CALIB 0x118
|
#define FUSE_RESERVED_ODM10_B01 0xA0
|
||||||
#define FUSE_OPT_FT_REV 0x128
|
#define FUSE_RESERVED_ODM11_B01 0xA4
|
||||||
#define FUSE_CPU_SPEEDO_1_CALIB 0x12C
|
#define FUSE_RESERVED_ODM12_B01 0xA8
|
||||||
#define FUSE_CPU_SPEEDO_2_CALIB 0x130
|
#define FUSE_RESERVED_ODM13_B01 0xAC
|
||||||
#define FUSE_SOC_SPEEDO_0_CALIB 0x134
|
#define FUSE_RESERVED_ODM14_B01 0xB0
|
||||||
#define FUSE_SOC_SPEEDO_1_CALIB 0x138
|
#define FUSE_RESERVED_ODM15_B01 0xB4
|
||||||
#define FUSE_SOC_SPEEDO_2_CALIB 0x13C
|
#define FUSE_RESERVED_ODM16_B01 0xB8
|
||||||
#define FUSE_SOC_IDDQ_CALIB 0x140
|
#define FUSE_RESERVED_ODM17_B01 0xBC
|
||||||
#define FUSE_OPT_CP_REV 0x190
|
#define FUSE_RESERVED_ODM18_B01 0xC0
|
||||||
#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19c
|
#define FUSE_RESERVED_ODM19_B01 0xC4
|
||||||
#define FUSE_PRIVATE_KEY0 0x1A4
|
#define FUSE_RESERVED_ODM20_B01 0xC8
|
||||||
#define FUSE_PRIVATE_KEY1 0x1A8
|
#define FUSE_RESERVED_ODM21_B01 0xCC
|
||||||
#define FUSE_PRIVATE_KEY2 0x1AC
|
#define FUSE_KEK00_B01 0xD0
|
||||||
#define FUSE_PRIVATE_KEY3 0x1B0
|
#define FUSE_KEK01_B01 0xD4
|
||||||
#define FUSE_PRIVATE_KEY4 0x1B4
|
#define FUSE_KEK02_B01 0xD8
|
||||||
#define FUSE_RESERVED_SW 0x1C0
|
#define FUSE_KEK03_B01 0xDC
|
||||||
#define FUSE_USB_CALIB 0x1F0
|
#define FUSE_BEK00_B01 0xE0
|
||||||
#define FUSE_SKU_DIRECT_CONFIG 0x1F4
|
#define FUSE_BEK01_B01 0xE4
|
||||||
#define FUSE_OPT_VENDOR_CODE 0x200
|
#define FUSE_BEK02_B01 0xE8
|
||||||
#define FUSE_OPT_FAB_CODE 0x204
|
#define FUSE_BEK03_B01 0xEC
|
||||||
#define FUSE_OPT_LOT_CODE_0 0x208
|
#define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4SVT_B01 0xF0
|
||||||
#define FUSE_OPT_LOT_CODE_1 0x20C
|
#define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4SVT_B01 0xF4
|
||||||
#define FUSE_OPT_WAFER_ID 0x210
|
#define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4SVT_B01 0xF8
|
||||||
#define FUSE_OPT_X_COORDINATE 0x214
|
#define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4SVT_B01 0xFC
|
||||||
#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
|
#define FUSE_PRODUCTION_MODE 0x100
|
||||||
|
#define FUSE_JTAG_SECUREID_VALID 0x104
|
||||||
|
#define FUSE_ODM_LOCK 0x108
|
||||||
|
#define FUSE_OPT_OPENGL_EN 0x10C
|
||||||
|
#define FUSE_SKU_INFO 0x110
|
||||||
|
#define FUSE_CPU_SPEEDO_0_CALIB 0x114
|
||||||
|
#define FUSE_CPU_IDDQ_CALIB 0x118
|
||||||
|
|
||||||
|
#define FUSE_RESERVED_ODM22_B01 0x11C
|
||||||
|
#define FUSE_RESERVED_ODM23_B01 0x120
|
||||||
|
#define FUSE_RESERVED_ODM24_B01 0x124
|
||||||
|
|
||||||
|
#define FUSE_OPT_FT_REV 0x128
|
||||||
|
#define FUSE_CPU_SPEEDO_1_CALIB 0x12C
|
||||||
|
#define FUSE_CPU_SPEEDO_2_CALIB 0x130
|
||||||
|
#define FUSE_SOC_SPEEDO_0_CALIB 0x134
|
||||||
|
#define FUSE_SOC_SPEEDO_1_CALIB 0x138
|
||||||
|
#define FUSE_SOC_SPEEDO_2_CALIB 0x13C
|
||||||
|
#define FUSE_SOC_IDDQ_CALIB 0x140
|
||||||
|
|
||||||
|
#define FUSE_RESERVED_ODM25_B01 0x144
|
||||||
|
|
||||||
|
#define FUSE_FA 0x148
|
||||||
|
#define FUSE_RESERVED_PRODUCTION 0x14C
|
||||||
|
#define FUSE_HDMI_LANE0_CALIB 0x150
|
||||||
|
#define FUSE_HDMI_LANE1_CALIB 0x154
|
||||||
|
#define FUSE_HDMI_LANE2_CALIB 0x158
|
||||||
|
#define FUSE_HDMI_LANE3_CALIB 0x15C
|
||||||
|
#define FUSE_ENCRYPTION_RATE 0x160
|
||||||
|
#define FUSE_PUBLIC_KEY0 0x164
|
||||||
|
#define FUSE_PUBLIC_KEY1 0x168
|
||||||
|
#define FUSE_PUBLIC_KEY2 0x16C
|
||||||
|
#define FUSE_PUBLIC_KEY3 0x170
|
||||||
|
#define FUSE_PUBLIC_KEY4 0x174
|
||||||
|
#define FUSE_PUBLIC_KEY5 0x178
|
||||||
|
#define FUSE_PUBLIC_KEY6 0x17C
|
||||||
|
#define FUSE_PUBLIC_KEY7 0x180
|
||||||
|
#define FUSE_TSENSOR1_CALIB 0x184 // CPU1.
|
||||||
|
#define FUSE_TSENSOR2_CALIB 0x188 // CPU2.
|
||||||
|
|
||||||
|
#define FUSE_OPT_SECURE_SCC_DIS_B01 0x18C
|
||||||
|
|
||||||
|
#define FUSE_OPT_CP_REV 0x190 // FUSE style revision - ATE. 0x101 0x100
|
||||||
|
#define FUSE_OPT_PFG 0x194
|
||||||
|
#define FUSE_TSENSOR0_CALIB 0x198 // CPU0.
|
||||||
|
#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19C
|
||||||
|
#define FUSE_SECURITY_MODE 0x1A0
|
||||||
|
#define FUSE_PRIVATE_KEY0 0x1A4
|
||||||
|
#define FUSE_PRIVATE_KEY1 0x1A8
|
||||||
|
#define FUSE_PRIVATE_KEY2 0x1AC
|
||||||
|
#define FUSE_PRIVATE_KEY3 0x1B0
|
||||||
|
#define FUSE_PRIVATE_KEY4 0x1B4
|
||||||
|
#define FUSE_ARM_JTAG_DIS 0x1B8
|
||||||
|
#define FUSE_BOOT_DEVICE_INFO 0x1BC
|
||||||
|
#define FUSE_RESERVED_SW 0x1C0
|
||||||
|
#define FUSE_OPT_VP9_DISABLE 0x1C4
|
||||||
|
|
||||||
|
#define FUSE_RESERVED_ODM0 0x1C8
|
||||||
|
#define FUSE_RESERVED_ODM1 0x1CC
|
||||||
|
#define FUSE_RESERVED_ODM2 0x1D0
|
||||||
|
#define FUSE_RESERVED_ODM3 0x1D4
|
||||||
|
#define FUSE_RESERVED_ODM4 0x1D8
|
||||||
|
#define FUSE_RESERVED_ODM5 0x1DC
|
||||||
|
#define FUSE_RESERVED_ODM6 0x1E0
|
||||||
|
#define FUSE_RESERVED_ODM7 0x1E4
|
||||||
|
|
||||||
|
#define FUSE_OBS_DIS 0x1E8
|
||||||
|
|
||||||
|
#define FUSE_OPT_NVJTAG_PROTECTION_ENABLE_B01 0x1EC
|
||||||
|
|
||||||
|
#define FUSE_USB_CALIB 0x1F0
|
||||||
|
#define FUSE_SKU_DIRECT_CONFIG 0x1F4
|
||||||
|
#define FUSE_KFUSE_PRIVKEY_CTRL 0x1F8
|
||||||
|
#define FUSE_PACKAGE_INFO 0x1FC
|
||||||
|
#define FUSE_OPT_VENDOR_CODE 0x200
|
||||||
|
#define FUSE_OPT_FAB_CODE 0x204
|
||||||
|
#define FUSE_OPT_LOT_CODE_0 0x208
|
||||||
|
#define FUSE_OPT_LOT_CODE_1 0x20C
|
||||||
|
#define FUSE_OPT_WAFER_ID 0x210
|
||||||
|
#define FUSE_OPT_X_COORDINATE 0x214
|
||||||
|
#define FUSE_OPT_Y_COORDINATE 0x218
|
||||||
|
#define FUSE_OPT_SEC_DEBUG_EN 0x21C
|
||||||
|
#define FUSE_OPT_OPS_RESERVED 0x220
|
||||||
|
#define FUSE_SATA_CALIB 0x224
|
||||||
|
|
||||||
|
#define FUSE_SPARE_REGISTER_ODM_B01 0x224
|
||||||
|
|
||||||
|
#define FUSE_GPU_IDDQ_CALIB 0x228
|
||||||
|
#define FUSE_TSENSOR3_CALIB 0x22C // CPU3.
|
||||||
|
#define FUSE_CLOCK_BONDOUT0 0x230
|
||||||
|
#define FUSE_CLOCK_BONDOUT1 0x234
|
||||||
|
|
||||||
|
#define FUSE_RESERVED_ODM26_B01 0x238
|
||||||
|
#define FUSE_RESERVED_ODM27_B01 0x23C
|
||||||
|
#define FUSE_RESERVED_ODM28_B01 0x240 // MAX77812 phase configuration.
|
||||||
|
|
||||||
|
#define FUSE_OPT_SAMPLE_TYPE 0x244
|
||||||
|
#define FUSE_OPT_SUBREVISION 0x248 // "", "p", "q", "r". e.g: A01p.
|
||||||
|
#define FUSE_OPT_SW_RESERVED_0 0x24C
|
||||||
|
#define FUSE_OPT_SW_RESERVED_1 0x250
|
||||||
|
#define FUSE_TSENSOR4_CALIB 0x254 // GPU.
|
||||||
|
#define FUSE_TSENSOR5_CALIB 0x258 // MEM0.
|
||||||
|
#define FUSE_TSENSOR6_CALIB 0x25C // MEM1.
|
||||||
|
#define FUSE_TSENSOR7_CALIB 0x260 // PLLX.
|
||||||
|
#define FUSE_OPT_PRIV_SEC_DIS 0x264
|
||||||
|
#define FUSE_PKC_DISABLE 0x268
|
||||||
|
|
||||||
|
#define FUSE_BOOT_SECURITY_INFO_B01 0x268
|
||||||
|
#define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4HVT_B01 0x26C
|
||||||
|
#define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4HVT_B01 0x270
|
||||||
|
#define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4HVT_B01 0x274
|
||||||
|
#define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4HVT_B01 0x278
|
||||||
|
|
||||||
|
#define FUSE_FUSE2TSEC_DEBUG_DISABLE 0x27C
|
||||||
|
#define FUSE_TSENSOR_COMMON 0x280
|
||||||
|
#define FUSE_OPT_CP_BIN 0x284
|
||||||
|
#define FUSE_OPT_GPU_DISABLE 0x288
|
||||||
|
#define FUSE_OPT_FT_BIN 0x28C
|
||||||
|
#define FUSE_OPT_DONE_MAP 0x290
|
||||||
|
|
||||||
|
#define FUSE_RESERVED_ODM29_B01 0x294
|
||||||
|
|
||||||
|
#define FUSE_APB2JTAG_DISABLE 0x298
|
||||||
|
#define FUSE_ODM_INFO 0x29C // Debug features disable.
|
||||||
|
#define FUSE_ARM_CRYPT_DE_FEATURE 0x2A8
|
||||||
|
|
||||||
|
#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4SVT_B01 0x2B0
|
||||||
|
#define FUSE_OPT_RAM_RCT_TSMCDP_PO4SVT_B01 0x2B4
|
||||||
|
#define FUSE_OPT_RAM_WCT_TSMCDP_PO4SVT_B01 0x2B8
|
||||||
|
#define FUSE_OPT_RAM_KP_TSMCDP_PO4SVT_B01 0x2BC
|
||||||
|
|
||||||
|
#define FUSE_WOA_SKU_FLAG 0x2C0
|
||||||
|
#define FUSE_ECO_RESERVE_1 0x2C4
|
||||||
|
#define FUSE_GCPLEX_CONFIG_FUSE 0x2C8
|
||||||
|
#define FUSE_GPU_VPR_AUTO_FETCH_DIS BIT(0)
|
||||||
|
#define FUSE_GPU_VPR_ENABLED BIT(1)
|
||||||
|
#define FUSE_GPU_WPR_ENABLED BIT(2)
|
||||||
|
#define FUSE_PRODUCTION_MONTH 0x2CC
|
||||||
|
#define FUSE_RAM_REPAIR_INDICATOR 0x2D0
|
||||||
|
#define FUSE_TSENSOR9_CALIB 0x2D4 // AOTAG.
|
||||||
|
#define FUSE_VMIN_CALIBRATION 0x2DC
|
||||||
|
#define FUSE_AGING_SENSOR_CALIBRATION 0x2E0
|
||||||
|
#define FUSE_DEBUG_AUTHENTICATION 0x2E4
|
||||||
|
#define FUSE_SECURE_PROVISION_INDEX 0x2E8
|
||||||
|
#define FUSE_SECURE_PROVISION_INFO 0x2EC
|
||||||
|
#define FUSE_OPT_GPU_DISABLE_CP1 0x2F0
|
||||||
|
#define FUSE_SPARE_ENDIS 0x2F4
|
||||||
|
#define FUSE_ECO_RESERVE_0 0x2F8 // AID.
|
||||||
|
#define FUSE_RESERVED_CALIB0 0x304 // GPCPLL ADC Calibration.
|
||||||
|
#define FUSE_RESERVED_CALIB1 0x308
|
||||||
|
#define FUSE_OPT_GPU_TPC0_DISABLE 0x30C
|
||||||
|
#define FUSE_OPT_GPU_TPC0_DISABLE_CP1 0x310
|
||||||
|
#define FUSE_OPT_CPU_DISABLE 0x314
|
||||||
|
#define FUSE_OPT_CPU_DISABLE_CP1 0x318
|
||||||
|
#define FUSE_TSENSOR10_CALIB 0x31C
|
||||||
|
#define FUSE_TSENSOR10_CALIB_AUX 0x320
|
||||||
|
#define FUSE_OPT_RAM_SVOP_DP 0x324
|
||||||
|
#define FUSE_OPT_RAM_SVOP_PDP 0x328
|
||||||
|
#define FUSE_OPT_RAM_SVOP_REG 0x32C
|
||||||
|
#define FUSE_OPT_RAM_SVOP_SP 0x330
|
||||||
|
#define FUSE_OPT_RAM_SVOP_SMPDP 0x334
|
||||||
|
|
||||||
|
#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4HVT_B01 0x324
|
||||||
|
#define FUSE_OPT_RAM_RCT_TSMCDP_PO4HVT_B01 0x328
|
||||||
|
#define FUSE_OPT_RAM_WCT_TSMCDP_PO4HVT_B01 0x32c
|
||||||
|
#define FUSE_OPT_RAM_KP_TSMCDP_PO4HVT_B01 0x330
|
||||||
|
#define FUSE_OPT_RAM_SVOP_SP_B01 0x334
|
||||||
|
|
||||||
|
#define FUSE_OPT_GPU_TPC0_DISABLE_CP2 0x338
|
||||||
|
#define FUSE_OPT_GPU_TPC1_DISABLE 0x33C
|
||||||
|
#define FUSE_OPT_GPU_TPC1_DISABLE_CP1 0x340
|
||||||
|
#define FUSE_OPT_GPU_TPC1_DISABLE_CP2 0x344
|
||||||
|
#define FUSE_OPT_CPU_DISABLE_CP2 0x348
|
||||||
|
#define FUSE_OPT_GPU_DISABLE_CP2 0x34C
|
||||||
|
#define FUSE_USB_CALIB_EXT 0x350
|
||||||
|
#define FUSE_RESERVED_FIELD 0x354 // RMA.
|
||||||
|
#define FUSE_SPARE_REALIGNMENT_REG 0x37C
|
||||||
|
#define FUSE_SPARE_BIT_0 0x380
|
||||||
|
//...
|
||||||
|
#define FUSE_SPARE_BIT_31 0x3FC
|
||||||
|
|
||||||
/*! Fuse commands. */
|
/*! Fuse commands. */
|
||||||
#define FUSE_READ 0x1
|
#define FUSE_IDLE 0x0
|
||||||
#define FUSE_WRITE 0x2
|
#define FUSE_READ 0x1
|
||||||
#define FUSE_SENSE 0x3
|
#define FUSE_WRITE 0x2
|
||||||
|
#define FUSE_SENSE 0x3
|
||||||
#define FUSE_CMD_MASK 0x3
|
#define FUSE_CMD_MASK 0x3
|
||||||
|
|
||||||
|
/*! Fuse status. */
|
||||||
|
#define FUSE_STATUS_RESET 0
|
||||||
|
#define FUSE_STATUS_POST_RESET 1
|
||||||
|
#define FUSE_STATUS_LOAD_ROW0 2
|
||||||
|
#define FUSE_STATUS_LOAD_ROW1 3
|
||||||
|
#define FUSE_STATUS_IDLE 4
|
||||||
|
#define FUSE_STATUS_READ_SETUP 5
|
||||||
|
#define FUSE_STATUS_READ_STROBE 6
|
||||||
|
#define FUSE_STATUS_SAMPLE_FUSES 7
|
||||||
|
#define FUSE_STATUS_READ_HOLD 8
|
||||||
|
#define FUSE_STATUS_FUSE_SRC_SETUP 9
|
||||||
|
#define FUSE_STATUS_WRITE_SETUP 10
|
||||||
|
#define FUSE_STATUS_WRITE_ADDR_SETUP 11
|
||||||
|
#define FUSE_STATUS_WRITE_PROGRAM 12
|
||||||
|
#define FUSE_STATUS_WRITE_ADDR_HOLD 13
|
||||||
|
#define FUSE_STATUS_FUSE_SRC_HOLD 14
|
||||||
|
#define FUSE_STATUS_LOAD_RIR 15
|
||||||
|
#define FUSE_STATUS_READ_BEFORE_WRITE_SETUP 16
|
||||||
|
#define FUSE_STATUS_READ_DEASSERT_PD 17
|
||||||
|
|
||||||
/*! Fuse cache registers. */
|
/*! Fuse cache registers. */
|
||||||
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
|
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
|
||||||
|
|
||||||
#define FUSE_ARRAY_WORDS_NUM 192
|
#define FUSE_ARRAY_WORDS_NUM 192
|
||||||
#define FUSE_ARRAY_WORDS_NUM_T210B01 256
|
#define FUSE_ARRAY_WORDS_NUM_B01 256
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -107,6 +316,8 @@ u32 fuse_read_hw_state();
|
|||||||
u32 fuse_read_hw_type();
|
u32 fuse_read_hw_type();
|
||||||
int fuse_set_sbk();
|
int fuse_set_sbk();
|
||||||
void fuse_wait_idle();
|
void fuse_wait_idle();
|
||||||
|
void fuse_sense();
|
||||||
|
u32 fuse_read(u32 addr);
|
||||||
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
|
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
|
||||||
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);
|
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);
|
||||||
void fuse_read_array(u32 *words);
|
void fuse_read_array(u32 *words);
|
||||||
|
|||||||
@@ -18,23 +18,27 @@
|
|||||||
#include <soc/gpio.h>
|
#include <soc/gpio.h>
|
||||||
#include <soc/t210.h>
|
#include <soc/t210.h>
|
||||||
|
|
||||||
#define GPIO_BANK_IDX(port) ((port) >> 2)
|
#define GPIO_BANK_IDX(port) ((port) >> 2)
|
||||||
|
#define GPIO_PORT_OFFSET(port) ((GPIO_BANK_IDX(port) << 8) + (((port) % 4) << 2))
|
||||||
|
|
||||||
#define GPIO_CNF_OFFSET(port) (0x00 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_CNF_OFFSET(port) (0x00 + GPIO_PORT_OFFSET(port))
|
||||||
#define GPIO_OE_OFFSET(port) (0x10 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_OE_OFFSET(port) (0x10 + GPIO_PORT_OFFSET(port))
|
||||||
#define GPIO_OUT_OFFSET(port) (0x20 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_OUT_OFFSET(port) (0x20 + GPIO_PORT_OFFSET(port))
|
||||||
#define GPIO_IN_OFFSET(port) (0x30 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_IN_OFFSET(port) (0x30 + GPIO_PORT_OFFSET(port))
|
||||||
#define GPIO_INT_STA_OFFSET(port) (0x40 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_INT_STA_OFFSET(port) (0x40 + GPIO_PORT_OFFSET(port))
|
||||||
#define GPIO_INT_ENB_OFFSET(port) (0x50 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_INT_ENB_OFFSET(port) (0x50 + GPIO_PORT_OFFSET(port))
|
||||||
#define GPIO_INT_LVL_OFFSET(port) (0x60 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_INT_LVL_OFFSET(port) (0x60 + GPIO_PORT_OFFSET(port))
|
||||||
#define GPIO_INT_CLR_OFFSET(port) (0x70 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_INT_CLR_OFFSET(port) (0x70 + GPIO_PORT_OFFSET(port))
|
||||||
|
|
||||||
#define GPIO_CNF_MASKED_OFFSET(port) (0x80 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_CNF_MASKED_OFFSET(port) (0x80 + GPIO_PORT_OFFSET(port))
|
||||||
#define GPIO_OE_MASKED_OFFSET(port) (0x90 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_OE_MASKED_OFFSET(port) (0x90 + GPIO_PORT_OFFSET(port))
|
||||||
#define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + GPIO_PORT_OFFSET(port))
|
||||||
#define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + GPIO_PORT_OFFSET(port))
|
||||||
#define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + GPIO_PORT_OFFSET(port))
|
||||||
#define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
#define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + GPIO_PORT_OFFSET(port))
|
||||||
|
|
||||||
|
#define GPIO_DB_CTRL_OFFSET(port) (0xB0 + GPIO_PORT_OFFSET(port))
|
||||||
|
#define GPIO_DB_CNT_OFFSET(port) (0xF0 + GPIO_PORT_OFFSET(port))
|
||||||
|
|
||||||
#define GPIO_IRQ_BANK1 32
|
#define GPIO_IRQ_BANK1 32
|
||||||
#define GPIO_IRQ_BANK2 33
|
#define GPIO_IRQ_BANK2 33
|
||||||
@@ -52,7 +56,7 @@ static u8 gpio_bank_irq_ids[8] = {
|
|||||||
|
|
||||||
void gpio_config(u32 port, u32 pins, int mode)
|
void gpio_config(u32 port, u32 pins, int mode)
|
||||||
{
|
{
|
||||||
u32 offset = GPIO_CNF_OFFSET(port);
|
const u32 offset = GPIO_CNF_OFFSET(port);
|
||||||
|
|
||||||
if (mode)
|
if (mode)
|
||||||
GPIO(offset) |= pins;
|
GPIO(offset) |= pins;
|
||||||
@@ -64,7 +68,7 @@ void gpio_config(u32 port, u32 pins, int mode)
|
|||||||
|
|
||||||
void gpio_output_enable(u32 port, u32 pins, int enable)
|
void gpio_output_enable(u32 port, u32 pins, int enable)
|
||||||
{
|
{
|
||||||
u32 port_offset = GPIO_OE_OFFSET(port);
|
const u32 port_offset = GPIO_OE_OFFSET(port);
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
GPIO(port_offset) |= pins;
|
GPIO(port_offset) |= pins;
|
||||||
@@ -76,7 +80,7 @@ void gpio_output_enable(u32 port, u32 pins, int enable)
|
|||||||
|
|
||||||
void gpio_write(u32 port, u32 pins, int high)
|
void gpio_write(u32 port, u32 pins, int high)
|
||||||
{
|
{
|
||||||
u32 port_offset = GPIO_OUT_OFFSET(port);
|
const u32 port_offset = GPIO_OUT_OFFSET(port);
|
||||||
|
|
||||||
if (high)
|
if (high)
|
||||||
GPIO(port_offset) |= pins;
|
GPIO(port_offset) |= pins;
|
||||||
@@ -88,27 +92,47 @@ void gpio_write(u32 port, u32 pins, int high)
|
|||||||
|
|
||||||
void gpio_direction_input(u32 port, u32 pins)
|
void gpio_direction_input(u32 port, u32 pins)
|
||||||
{
|
{
|
||||||
gpio_output_enable(port, pins, GPIO_OUTPUT_DISABLE);
|
|
||||||
gpio_config(port, pins, GPIO_MODE_GPIO);
|
gpio_config(port, pins, GPIO_MODE_GPIO);
|
||||||
|
gpio_output_enable(port, pins, GPIO_OUTPUT_DISABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_direction_output(u32 port, u32 pins, int high)
|
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_config(port, pins, GPIO_MODE_GPIO);
|
||||||
gpio_write(port, pins, high);
|
gpio_write(port, pins, high);
|
||||||
|
gpio_output_enable(port, pins, GPIO_OUTPUT_ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gpio_read(u32 port, u32 pins)
|
int gpio_read(u32 port, u32 pins)
|
||||||
{
|
{
|
||||||
u32 port_offset = GPIO_IN_OFFSET(port);
|
const u32 port_offset = GPIO_IN_OFFSET(port);
|
||||||
|
|
||||||
return (GPIO(port_offset) & pins) ? 1 : 0;
|
return (GPIO(port_offset) & pins) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gpio_set_debounce(u32 port, u32 pins, u32 ms)
|
||||||
|
{
|
||||||
|
const u32 db_ctrl_offset = GPIO_DB_CTRL_OFFSET(port);
|
||||||
|
const u32 db_cnt_offset = GPIO_DB_CNT_OFFSET(port);
|
||||||
|
|
||||||
|
if (ms)
|
||||||
|
{
|
||||||
|
if (ms > 255)
|
||||||
|
ms = 255;
|
||||||
|
|
||||||
|
// Debounce time affects all pins of the same port.
|
||||||
|
GPIO(db_cnt_offset) = ms;
|
||||||
|
GPIO(db_ctrl_offset) = (pins << 8) | pins;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
GPIO(db_ctrl_offset) = (pins << 8) | 0;
|
||||||
|
|
||||||
|
(void)GPIO(db_ctrl_offset); // Commit the write.
|
||||||
|
}
|
||||||
|
|
||||||
static void _gpio_interrupt_clear(u32 port, u32 pins)
|
static void _gpio_interrupt_clear(u32 port, u32 pins)
|
||||||
{
|
{
|
||||||
u32 port_offset = GPIO_INT_CLR_OFFSET(port);
|
const u32 port_offset = GPIO_INT_CLR_OFFSET(port);
|
||||||
|
|
||||||
GPIO(port_offset) |= pins;
|
GPIO(port_offset) |= pins;
|
||||||
|
|
||||||
@@ -117,10 +141,10 @@ static void _gpio_interrupt_clear(u32 port, u32 pins)
|
|||||||
|
|
||||||
int gpio_interrupt_status(u32 port, u32 pins)
|
int gpio_interrupt_status(u32 port, u32 pins)
|
||||||
{
|
{
|
||||||
u32 port_offset = GPIO_INT_STA_OFFSET(port);
|
const u32 port_offset = GPIO_INT_STA_OFFSET(port);
|
||||||
u32 enabled = GPIO(GPIO_INT_ENB_OFFSET(port)) & pins;
|
const u32 enabled_mask = GPIO(GPIO_INT_ENB_OFFSET(port)) & pins;
|
||||||
|
|
||||||
int status = ((GPIO(port_offset) & pins) && enabled) ? 1 : 0;
|
int status = ((GPIO(port_offset) & pins) && enabled_mask) ? 1 : 0;
|
||||||
|
|
||||||
// Clear the interrupt status.
|
// Clear the interrupt status.
|
||||||
if (status)
|
if (status)
|
||||||
@@ -131,7 +155,7 @@ int gpio_interrupt_status(u32 port, u32 pins)
|
|||||||
|
|
||||||
void gpio_interrupt_enable(u32 port, u32 pins, int enable)
|
void gpio_interrupt_enable(u32 port, u32 pins, int enable)
|
||||||
{
|
{
|
||||||
u32 port_offset = GPIO_INT_ENB_OFFSET(port);
|
const u32 port_offset = GPIO_INT_ENB_OFFSET(port);
|
||||||
|
|
||||||
// Clear any possible stray interrupt.
|
// Clear any possible stray interrupt.
|
||||||
_gpio_interrupt_clear(port, pins);
|
_gpio_interrupt_clear(port, pins);
|
||||||
@@ -146,7 +170,7 @@ void gpio_interrupt_enable(u32 port, u32 pins, int enable)
|
|||||||
|
|
||||||
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta)
|
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta)
|
||||||
{
|
{
|
||||||
u32 port_offset = GPIO_INT_LVL_OFFSET(port);
|
const u32 port_offset = GPIO_INT_LVL_OFFSET(port);
|
||||||
|
|
||||||
u32 val = GPIO(port_offset);
|
u32 val = GPIO(port_offset);
|
||||||
|
|
||||||
@@ -175,7 +199,7 @@ void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta)
|
|||||||
|
|
||||||
u32 gpio_get_bank_irq_id(u32 port)
|
u32 gpio_get_bank_irq_id(u32 port)
|
||||||
{
|
{
|
||||||
u32 bank_idx = GPIO_BANK_IDX(port);
|
const u32 bank_idx = GPIO_BANK_IDX(port);
|
||||||
|
|
||||||
return gpio_bank_irq_ids[bank_idx];
|
return gpio_bank_irq_ids[bank_idx];
|
||||||
}
|
}
|
||||||
@@ -89,6 +89,7 @@ void gpio_direction_input(u32 port, u32 pins);
|
|||||||
void gpio_direction_output(u32 port, u32 pins, int high);
|
void gpio_direction_output(u32 port, u32 pins, int high);
|
||||||
void gpio_write(u32 port, u32 pins, int high);
|
void gpio_write(u32 port, u32 pins, int high);
|
||||||
int gpio_read(u32 port, u32 pins);
|
int gpio_read(u32 port, u32 pins);
|
||||||
|
void gpio_set_debounce(u32 port, u32 pins, u32 ms);
|
||||||
int gpio_interrupt_status(u32 port, u32 pins);
|
int gpio_interrupt_status(u32 port, u32 pins);
|
||||||
void gpio_interrupt_enable(u32 port, u32 pins, int enable);
|
void gpio_interrupt_enable(u32 port, u32 pins, int enable);
|
||||||
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta);
|
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2023 CTCaer
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -77,15 +77,15 @@ static void _config_oscillators()
|
|||||||
TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
|
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.
|
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) & 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_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_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.
|
APB_MISC(APB_MISC_GP_ASDBGREG) = (APB_MISC(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_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_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
|
||||||
|
|
||||||
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
|
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_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_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
|
||||||
@@ -93,6 +93,24 @@ static void _config_oscillators()
|
|||||||
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.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hw_config_arbiter(bool reset)
|
||||||
|
{
|
||||||
|
if (reset)
|
||||||
|
{
|
||||||
|
ARB_PRI(ARB_PRIO_CPU_PRIORITY) = 0x0040090;
|
||||||
|
ARB_PRI(ARB_PRIO_COP_PRIORITY) = 0x12024C2;
|
||||||
|
ARB_PRI(ARB_PRIO_VCP_PRIORITY) = 0x2201209;
|
||||||
|
ARB_PRI(ARB_PRIO_DMA_PRIORITY) = 0x320365B;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ARB_PRI(ARB_PRIO_CPU_PRIORITY) = 0x12412D1;
|
||||||
|
ARB_PRI(ARB_PRIO_COP_PRIORITY) = 0x0000000;
|
||||||
|
ARB_PRI(ARB_PRIO_VCP_PRIORITY) = 0x220244A;
|
||||||
|
ARB_PRI(ARB_PRIO_DMA_PRIORITY) = 0x320369B;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The uart is skipped for Copper, Hoag and Calcio. Used in Icosa, Iowa and Aula.
|
// The uart is skipped for Copper, Hoag and Calcio. Used in Icosa, Iowa and Aula.
|
||||||
static void _config_gpios(bool nx_hoag)
|
static void _config_gpios(bool nx_hoag)
|
||||||
{
|
{
|
||||||
@@ -137,16 +155,34 @@ static void _config_pmc_scratch()
|
|||||||
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
|
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _mbist_workaround()
|
static void _mbist_workaround_bl()
|
||||||
{
|
{
|
||||||
// Make sure Audio clocks are enabled before accessing I2S.
|
/*
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
* DFT MBIST HW Errata for T210.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
* RAM Data corruption observed when MBIST_EN from DFT (Tegra X1 Si Errata)
|
||||||
|
*
|
||||||
|
* The MBIST_EN signals from the DFT logic can impact the functional logic of
|
||||||
|
* internal rams after power-on since they are driven by non-resetable flops.
|
||||||
|
* That can be worked around by enabling and then disabling the related clocks.
|
||||||
|
*
|
||||||
|
* The bootrom patches, already handle the LVL2 SLCG war by enabling all clocks
|
||||||
|
* and all LVL2 CLK overrides (power saving disable).
|
||||||
|
* The Bootloader then handles the IP block SLCG part and also restores the
|
||||||
|
* state for the clocks/lvl2 slcg.
|
||||||
|
* After these, per domain MBIST WAR is needed every time a domain gets
|
||||||
|
* unpowergated if it was previously powergated.
|
||||||
|
*
|
||||||
|
* Affected power domains: all except IRAM and CCPLEX.
|
||||||
|
*/
|
||||||
|
|
||||||
// Set mux output to SOR1 clock switch.
|
// Set mux output to SOR1 clock switch (for VI).
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) | 0x8000) & 0xFFFFBFFF;
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) & ~BIT(14)) | BIT(15);
|
||||||
// Enabled PLLD and set csi to PLLD for test pattern generation.
|
// Enable PLLD and set csi to PLLD for test pattern generation (for VI).
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= 0x40800000;
|
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= PLL_BASE_ENABLE | BIT(23);
|
||||||
|
|
||||||
|
// Make sure Audio clocks are enabled before accessing I2S.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_AHUB);
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_APE);
|
||||||
|
|
||||||
// Clear per-clock resets for APE/VIC/HOST1X/DISP1.
|
// Clear per-clock resets for APE/VIC/HOST1X/DISP1.
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = BIT(CLK_Y_APE);
|
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = BIT(CLK_Y_APE);
|
||||||
@@ -154,78 +190,73 @@ static void _mbist_workaround()
|
|||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||||
usleep(2);
|
usleep(2);
|
||||||
|
|
||||||
// I2S channels to master and disable SLCG.
|
// Set I2S to master to enable clocks and set SLCG overrides.
|
||||||
I2S(I2S1_CTRL) |= I2S_CTRL_MASTER_EN;
|
for (u32 i2s_idx = 0; i2s_idx < 5; i2s_idx++)
|
||||||
I2S(I2S1_CG) &= ~I2S_CG_SLCG_ENABLE;
|
{
|
||||||
I2S(I2S2_CTRL) |= I2S_CTRL_MASTER_EN;
|
I2S(I2S_CTRL + (i2s_idx << 8u)) |= I2S_CTRL_MASTER_EN;
|
||||||
I2S(I2S2_CG) &= ~I2S_CG_SLCG_ENABLE;
|
I2S(I2S_CG + (i2s_idx << 8u)) = I2S_CG_SLCG_DISABLE;
|
||||||
I2S(I2S3_CTRL) |= I2S_CTRL_MASTER_EN;
|
}
|
||||||
I2S(I2S3_CG) &= ~I2S_CG_SLCG_ENABLE;
|
// Set SLCG overrides for DISPA and VIC.
|
||||||
I2S(I2S4_CTRL) |= I2S_CTRL_MASTER_EN;
|
DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= BIT(2); // DSC_SLCG_OVERRIDE.
|
||||||
I2S(I2S4_CG) &= ~I2S_CG_SLCG_ENABLE;
|
|
||||||
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(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0xFFFFFFFF;
|
VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
// Wait a bit for MBIST_EN to get unstuck (1 cycle min).
|
||||||
usleep(2);
|
usleep(2);
|
||||||
|
|
||||||
|
// Reset SLCG to automatic mode.
|
||||||
|
// for (u32 i2s_idx = 0; i2s_idx < 5; i2s_idx++)
|
||||||
|
// I2S(I2S_CG + (i2s_idx << 8u)) = I2S_CG_SLCG_ENABLE;
|
||||||
|
// DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) &= ~BIT(2); // DSC_SLCG_OVERRIDE.
|
||||||
|
// VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0;
|
||||||
|
|
||||||
// Set per-clock reset for APE/VIC/HOST1X/DISP1.
|
// Set per-clock reset for APE/VIC/HOST1X/DISP1.
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = BIT(CLK_Y_APE);
|
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = BIT(CLK_Y_APE);
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = BIT(CLK_X_VIC);
|
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = BIT(CLK_X_VIC);
|
||||||
|
|
||||||
// Enable specific clocks and disable all others.
|
// Disable all unneeded clocks that were enabled in bootrom.
|
||||||
// CLK L Devices.
|
// CLK L Devices.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) =
|
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = BIT(CLK_H_PMC) |
|
||||||
BIT(CLK_H_PMC) |
|
BIT(CLK_H_FUSE);
|
||||||
BIT(CLK_H_FUSE);
|
|
||||||
// CLK H Devices.
|
// CLK H Devices.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) =
|
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = BIT(CLK_L_RTC) |
|
||||||
BIT(CLK_L_RTC) |
|
BIT(CLK_L_TMR) |
|
||||||
BIT(CLK_L_TMR) |
|
BIT(CLK_L_GPIO) |
|
||||||
BIT(CLK_L_GPIO) |
|
BIT(CLK_L_BPMP_CACHE_CTRL);
|
||||||
BIT(CLK_L_BPMP_CACHE_CTRL);
|
|
||||||
// CLK U Devices.
|
// CLK U Devices.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) =
|
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = BIT(CLK_U_CSITE) |
|
||||||
BIT(CLK_U_CSITE) |
|
BIT(CLK_U_IRAMA) |
|
||||||
BIT(CLK_U_IRAMA) |
|
BIT(CLK_U_IRAMB) |
|
||||||
BIT(CLK_U_IRAMB) |
|
BIT(CLK_U_IRAMC) |
|
||||||
BIT(CLK_U_IRAMC) |
|
BIT(CLK_U_IRAMD) |
|
||||||
BIT(CLK_U_IRAMD) |
|
BIT(CLK_U_BPMP_CACHE_RAM);
|
||||||
BIT(CLK_U_BPMP_CACHE_RAM);
|
|
||||||
// CLK V Devices.
|
// CLK V Devices.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) =
|
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = BIT(CLK_V_MSELECT) |
|
||||||
BIT(CLK_V_MSELECT) |
|
BIT(CLK_V_APB2APE) |
|
||||||
BIT(CLK_V_APB2APE) |
|
BIT(CLK_V_SPDIF_DOUBLER) |
|
||||||
BIT(CLK_V_SPDIF_DOUBLER) |
|
BIT(CLK_V_SE);
|
||||||
BIT(CLK_V_SE);
|
|
||||||
// CLK W Devices.
|
// CLK W Devices.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) =
|
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = BIT(CLK_W_PCIERX0) |
|
||||||
BIT(CLK_W_PCIERX0) |
|
BIT(CLK_W_PCIERX1) |
|
||||||
BIT(CLK_W_PCIERX1) |
|
BIT(CLK_W_PCIERX2) |
|
||||||
BIT(CLK_W_PCIERX2) |
|
BIT(CLK_W_PCIERX3) |
|
||||||
BIT(CLK_W_PCIERX3) |
|
BIT(CLK_W_PCIERX4) |
|
||||||
BIT(CLK_W_PCIERX4) |
|
BIT(CLK_W_PCIERX5) |
|
||||||
BIT(CLK_W_PCIERX5) |
|
BIT(CLK_W_ENTROPY) |
|
||||||
BIT(CLK_W_ENTROPY) |
|
BIT(CLK_W_MC1);
|
||||||
BIT(CLK_W_MC1);
|
|
||||||
// CLK X Devices.
|
// CLK X Devices.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) =
|
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) = BIT(CLK_X_MC_CAPA) |
|
||||||
BIT(CLK_X_MC_CAPA) |
|
BIT(CLK_X_MC_CBPA) |
|
||||||
BIT(CLK_X_MC_CBPA) |
|
BIT(CLK_X_MC_CPU) |
|
||||||
BIT(CLK_X_MC_CPU) |
|
BIT(CLK_X_MC_BBC) |
|
||||||
BIT(CLK_X_MC_BBC) |
|
BIT(CLK_X_GPU) |
|
||||||
BIT(CLK_X_GPU) |
|
BIT(CLK_X_DBGAPB) |
|
||||||
BIT(CLK_X_DBGAPB) |
|
BIT(CLK_X_PLLG_REF);
|
||||||
BIT(CLK_X_PLLG_REF);
|
|
||||||
// CLK Y Devices.
|
// CLK Y Devices.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) =
|
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) = BIT(CLK_Y_MC_CDPA) |
|
||||||
BIT(CLK_Y_MC_CDPA) |
|
BIT(CLK_Y_MC_CCPA);
|
||||||
BIT(CLK_Y_MC_CCPA);
|
|
||||||
|
|
||||||
// Disable clock gate overrides.
|
// Reset clock gate overrides to automatic mode.
|
||||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA) = 0;
|
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA) = 0;
|
||||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB) = 0;
|
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB) = 0;
|
||||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC) = 0;
|
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC) = 0;
|
||||||
@@ -234,10 +265,10 @@ static void _mbist_workaround()
|
|||||||
|
|
||||||
// Set child clock sources.
|
// Set child clock sources.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock.
|
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_SOR1) &= ~(BIT(15) | BIT(14)); // 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) | (4 << 29u); // 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_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | (4 << 29u); // 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) | (4 << 29u); // Set clock source to PLLP_OUT.
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _config_se_brom()
|
static void _config_se_brom()
|
||||||
@@ -248,25 +279,30 @@ static void _config_se_brom()
|
|||||||
// Try to set SBK from fuses. If patched, skip.
|
// Try to set SBK from fuses. If patched, skip.
|
||||||
fuse_set_sbk();
|
fuse_set_sbk();
|
||||||
|
|
||||||
|
// Make SBK unreadable.
|
||||||
|
//FUSE(FUSE_PRIVATEKEYDISABLE) = FUSE_PRIVKEY_TZ_STICKY_BIT | FUSE_PRIVKEY_DISABLE;
|
||||||
|
|
||||||
// Lock SSK (although it's not set and unused anyways).
|
// Lock SSK (although it's not set and unused anyways).
|
||||||
// se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
// se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
||||||
|
|
||||||
// This memset needs to happen here, else TZRAM will behave weirdly later on.
|
// This memset needs to happen here, else TZRAM will behave weirdly later on.
|
||||||
memset((void *)TZRAM_BASE, 0, TZRAM_SIZE);
|
memset((void *)TZRAM_BASE, 0, TZRAM_SIZE);
|
||||||
PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE;
|
PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE;
|
||||||
SE(SE_INT_STATUS_REG) = 0x1F; // Clear all SE interrupts.
|
|
||||||
|
// Clear SE interrupts.
|
||||||
|
SE(SE_INT_STATUS_REG) = SE_INT_OP_DONE | SE_INT_OUT_DONE | SE_INT_OUT_LL_BUF_WR | SE_INT_IN_DONE | SE_INT_IN_LL_BUF_RD;
|
||||||
|
|
||||||
// Save reset reason.
|
// Save reset reason.
|
||||||
hw_rst_status = PMC(APBDEV_PMC_SCRATCH200);
|
hw_rst_status = PMC(APBDEV_PMC_SCRATCH200);
|
||||||
hw_rst_reason = PMC(APBDEV_PMC_RST_STATUS) & PMC_RST_STATUS_MASK;
|
hw_rst_reason = PMC(APBDEV_PMC_RST_STATUS) & PMC_RST_STATUS_MASK;
|
||||||
|
|
||||||
// Clear the boot reason to avoid problems later.
|
// Clear the boot reason to avoid problems later.
|
||||||
PMC(APBDEV_PMC_SCRATCH200) = 0x0;
|
PMC(APBDEV_PMC_SCRATCH200) = 0;
|
||||||
PMC(APBDEV_PMC_RST_STATUS) = 0x0;
|
PMC(APBDEV_PMC_RST_STATUS) = PMC_RST_STATUS_POR;
|
||||||
APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10);
|
APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _config_regulators(bool tegra_t210)
|
static void _config_regulators(bool tegra_t210, bool nx_hoag)
|
||||||
{
|
{
|
||||||
// Set RTC/AO domain to POR voltage.
|
// Set RTC/AO domain to POR voltage.
|
||||||
if (tegra_t210)
|
if (tegra_t210)
|
||||||
@@ -275,22 +311,26 @@ static void _config_regulators(bool tegra_t210)
|
|||||||
// Disable low battery shutdown monitor.
|
// Disable low battery shutdown monitor.
|
||||||
max77620_low_battery_monitor_config(false);
|
max77620_low_battery_monitor_config(false);
|
||||||
|
|
||||||
// Disable SDMMC1 IO power.
|
// Power on all relevant rails in case we came out of warmboot. Only keep MEM/MEM_COMP and SDMMC1 states.
|
||||||
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
|
PMC(APBDEV_PMC_NO_IOPOWER) &= PMC_NO_IOPOWER_MEM_COMP | PMC_NO_IOPOWER_SDMMC1 | PMC_NO_IOPOWER_MEM;
|
||||||
|
|
||||||
|
// Make sure SDMMC1 IO/Core are powered off.
|
||||||
max7762x_regulator_enable(REGULATOR_LDO2, false);
|
max7762x_regulator_enable(REGULATOR_LDO2, false);
|
||||||
|
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
|
||||||
|
PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1;
|
||||||
|
(void)PMC(APBDEV_PMC_NO_IOPOWER);
|
||||||
sd_power_cycle_time_start = get_tmr_ms();
|
sd_power_cycle_time_start = get_tmr_ms();
|
||||||
|
|
||||||
// Disable LCD DVDD.
|
// Disable backup battery charger.
|
||||||
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_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.
|
// Set PWR delay for forced shutdown off to 6s.
|
||||||
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_RSVD | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT));
|
||||||
|
|
||||||
if (tegra_t210)
|
if (tegra_t210)
|
||||||
{
|
{
|
||||||
// Configure all Flexible Power Sequencers for MAX77620.
|
// Configure all Flexible Power Sequencers for MAX77620.
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (0 << MAX77620_FPS_EN_SRC_SHIFT));
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT));
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT));
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
|
||||||
max77620_regulator_config_fps(REGULATOR_LDO4);
|
max77620_regulator_config_fps(REGULATOR_LDO4);
|
||||||
@@ -299,13 +339,13 @@ static void _config_regulators(bool tegra_t210)
|
|||||||
max77620_regulator_config_fps(REGULATOR_SD1);
|
max77620_regulator_config_fps(REGULATOR_SD1);
|
||||||
max77620_regulator_config_fps(REGULATOR_SD3);
|
max77620_regulator_config_fps(REGULATOR_SD3);
|
||||||
|
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3,
|
// Set GPIO3 to FPS0 for SYS 3V3 EN. Enabled when FPS0 is enabled.
|
||||||
(4 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT)); // 3.x+
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3, (4 << MAX77620_FPS_PU_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT));
|
||||||
|
|
||||||
// Set vdd_core voltage to 1.125V.
|
// Set vdd_core voltage to 1.125V.
|
||||||
max7762x_regulator_set_voltage(REGULATOR_SD0, 1125000);
|
max7762x_regulator_set_voltage(REGULATOR_SD0, 1125000);
|
||||||
|
|
||||||
// Fix CPU/GPU after L4T warmboot.
|
// Power down CPU/GPU regulators after L4T warmboot.
|
||||||
max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_DISABLE);
|
max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_DISABLE);
|
||||||
max77620_config_gpio(6, MAX77620_GPIO_OUTPUT_DISABLE);
|
max77620_config_gpio(6, MAX77620_GPIO_OUTPUT_DISABLE);
|
||||||
|
|
||||||
@@ -313,8 +353,26 @@ static void _config_regulators(bool tegra_t210)
|
|||||||
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_POR_CFG);
|
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_POR_CFG);
|
||||||
max77621_config_default(REGULATOR_GPU0, MAX77621_CTRL_POR_CFG);
|
max77621_config_default(REGULATOR_GPU0, MAX77621_CTRL_POR_CFG);
|
||||||
}
|
}
|
||||||
else // Tegra X1+ set vdd_core voltage to 1.05V.
|
else
|
||||||
|
{
|
||||||
|
// Tegra X1+ set vdd_core voltage to 1.05V.
|
||||||
max7762x_regulator_set_voltage(REGULATOR_SD0, 1050000);
|
max7762x_regulator_set_voltage(REGULATOR_SD0, 1050000);
|
||||||
|
|
||||||
|
// Power on SD2 regulator for supplying LDO0/1/8.
|
||||||
|
max7762x_regulator_set_voltage(REGULATOR_SD2, 1325000);
|
||||||
|
|
||||||
|
// Set slew rate and enable SD2 regulator.
|
||||||
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD2_CFG, (1 << MAX77620_SD_SR_SHIFT) |
|
||||||
|
(MAX77620_POWER_MODE_NORMAL << MAX77620_SD_POWER_MODE_SHIFT) |
|
||||||
|
MAX77620_SD_CFG1_FSRADE_SD_ENABLE);
|
||||||
|
|
||||||
|
// Enable LDO8 on HOAG as it also powers I2C1 IO pads.
|
||||||
|
if (nx_hoag)
|
||||||
|
{
|
||||||
|
max7762x_regulator_set_voltage(REGULATOR_LDO8, 2800000);
|
||||||
|
max7762x_regulator_enable(REGULATOR_LDO8, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hw_init()
|
void hw_init()
|
||||||
@@ -323,15 +381,19 @@ void hw_init()
|
|||||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||||
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
|
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
|
||||||
|
|
||||||
// Bootrom stuff we skipped by going through rcm.
|
// Bootrom stuff we might skipped by going through rcm.
|
||||||
_config_se_brom();
|
_config_se_brom();
|
||||||
//FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11;
|
|
||||||
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F; // Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
|
|
||||||
PMC(APBDEV_PMC_SCRATCH49) = PMC(APBDEV_PMC_SCRATCH49) & 0xFFFFFFFC;
|
|
||||||
|
|
||||||
// Perform Memory Built-In Self Test WAR if T210.
|
// Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
|
||||||
|
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F;
|
||||||
|
PMC(APBDEV_PMC_SCRATCH49) &= 0xFFFFFFFC;
|
||||||
|
|
||||||
|
// Perform the bootloader part of the Memory Built-In Self Test WAR if T210.
|
||||||
if (tegra_t210)
|
if (tegra_t210)
|
||||||
_mbist_workaround();
|
_mbist_workaround_bl();
|
||||||
|
|
||||||
|
// Make sure PLLP_OUT3/4 is set to 408 MHz and enabled.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_PLLP_OUTB) = 0x30003;
|
||||||
|
|
||||||
// Enable Security Engine clock.
|
// Enable Security Engine clock.
|
||||||
clock_enable_se();
|
clock_enable_se();
|
||||||
@@ -351,19 +413,7 @@ void hw_init()
|
|||||||
// Initialize pin configuration.
|
// Initialize pin configuration.
|
||||||
_config_gpios(nx_hoag);
|
_config_gpios(nx_hoag);
|
||||||
|
|
||||||
#ifdef DEBUG_UART_PORT
|
// Enable CL-DVFS clock unconditionally to avoid issues with I2C5 sharing.
|
||||||
#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_AO_TX_AO_RX);
|
|
||||||
uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Enable Dynamic Voltage and Frequency Scaling device clock.
|
|
||||||
clock_enable_cl_dvfs();
|
clock_enable_cl_dvfs();
|
||||||
|
|
||||||
// Enable clocks to I2C1 and I2CPWR.
|
// Enable clocks to I2C1 and I2CPWR.
|
||||||
@@ -376,32 +426,29 @@ void hw_init()
|
|||||||
// Initialize I2C5, mandatory for PMIC.
|
// Initialize I2C5, mandatory for PMIC.
|
||||||
i2c_init(I2C_5);
|
i2c_init(I2C_5);
|
||||||
|
|
||||||
// Enable LDO8 on HOAG as it also powers I2C1 IO pads.
|
// Initialize various regulators based on Erista/Mariko platform.
|
||||||
if (nx_hoag)
|
_config_regulators(tegra_t210, nx_hoag);
|
||||||
{
|
|
||||||
max7762x_regulator_set_voltage(REGULATOR_LDO8, 2800000);
|
|
||||||
max7762x_regulator_enable(REGULATOR_LDO8, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize I2C1 for various power related devices.
|
// Initialize I2C1 for various power related devices.
|
||||||
i2c_init(I2C_1);
|
i2c_init(I2C_1);
|
||||||
|
|
||||||
// Initialize various regulators based on Erista/Mariko platform.
|
|
||||||
_config_regulators(tegra_t210);
|
|
||||||
|
|
||||||
_config_pmc_scratch(); // Missing from 4.x+
|
_config_pmc_scratch(); // Missing from 4.x+
|
||||||
|
|
||||||
// Set BPMP/SCLK to PLLP_OUT (408MHz).
|
// Set BPMP/SCLK to PLLP_OUT (408MHz).
|
||||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333;
|
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333;
|
||||||
|
|
||||||
// Power on T210B01 shadow TZRAM and lock the reg.
|
// Disable T210B01 TZRAM power-gating and lock the reg.
|
||||||
if (!tegra_t210)
|
if (!tegra_t210)
|
||||||
{
|
{
|
||||||
|
// This is not actually needed since it's done by bootrom. The read locks are extra.
|
||||||
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= ~PMC_TZRAM_PWR_CNTRL_SD;
|
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_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;
|
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set arbiter.
|
||||||
|
hw_config_arbiter(false);
|
||||||
|
|
||||||
// Initialize External memory controller and configure DRAM parameters.
|
// Initialize External memory controller and configure DRAM parameters.
|
||||||
sdram_init();
|
sdram_init();
|
||||||
|
|
||||||
@@ -409,9 +456,22 @@ void hw_init()
|
|||||||
|
|
||||||
// Enable HOST1X used by every display module (DC, VIC, NVDEC, NVENC, TSEC, etc).
|
// Enable HOST1X used by every display module (DC, VIC, NVDEC, NVENC, TSEC, etc).
|
||||||
clock_enable_host1x();
|
clock_enable_host1x();
|
||||||
|
|
||||||
|
#ifdef DEBUG_UART_PORT
|
||||||
|
// Setup 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_AO_TX_AO_RX);
|
||||||
|
uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
void hw_deinit(bool coreboot, u32 bl_magic)
|
||||||
{
|
{
|
||||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||||
|
|
||||||
@@ -422,7 +482,7 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
|||||||
// Disable temperature sensor, touchscreen, 5V regulators, Joy-Con and VIC.
|
// Disable temperature sensor, touchscreen, 5V regulators, Joy-Con and VIC.
|
||||||
vic_end();
|
vic_end();
|
||||||
tmp451_end();
|
tmp451_end();
|
||||||
set_fan_duty(0);
|
fan_set_duty(0);
|
||||||
touch_power_off();
|
touch_power_off();
|
||||||
jc_deinit();
|
jc_deinit();
|
||||||
regulator_5v_disable(REGULATOR_5V_ALL);
|
regulator_5v_disable(REGULATOR_5V_ALL);
|
||||||
@@ -435,11 +495,14 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
|||||||
// Flush/disable MMU cache.
|
// Flush/disable MMU cache.
|
||||||
bpmp_mmu_disable();
|
bpmp_mmu_disable();
|
||||||
|
|
||||||
// Re-enable clocks to Audio Processing Engine as a workaround to hanging.
|
// Reset arbiter.
|
||||||
|
hw_config_arbiter(true);
|
||||||
|
|
||||||
|
// Re-enable clocks to Audio Processing Engine as a workaround to rerunning mbist war.
|
||||||
if (tegra_t210)
|
if (tegra_t210)
|
||||||
{
|
{
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_AHUB);
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_APE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do coreboot mitigations.
|
// Do coreboot mitigations.
|
||||||
@@ -454,7 +517,7 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
|||||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||||
|
|
||||||
// Reinstate SD controller power.
|
// Reinstate SD controller power.
|
||||||
PMC(APBDEV_PMC_NO_IOPOWER) &= ~(PMC_NO_IOPOWER_SDMMC1_IO_EN);
|
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_SDMMC1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seamless display or display power off.
|
// Seamless display or display power off.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2021 CTCaer
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -27,7 +27,8 @@ extern u32 hw_rst_status;
|
|||||||
extern u32 hw_rst_reason;
|
extern u32 hw_rst_reason;
|
||||||
|
|
||||||
void hw_init();
|
void hw_init();
|
||||||
void hw_reinit_workaround(bool coreboot, u32 magic);
|
void hw_deinit(bool coreboot, u32 magic);
|
||||||
|
void hw_config_arbiter(bool reset);
|
||||||
u32 hw_get_chip_id();
|
u32 hw_get_chip_id();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <soc/i2c.h>
|
#include <soc/i2c.h>
|
||||||
|
#include <soc/t210.h>
|
||||||
#include <soc/timer.h>
|
#include <soc/timer.h>
|
||||||
|
|
||||||
#define I2C_PACKET_PROT_I2C BIT(4)
|
#define I2C_PACKET_PROT_I2C BIT(4)
|
||||||
@@ -81,14 +82,8 @@
|
|||||||
#define MSTR_CONFIG_LOAD BIT(0)
|
#define MSTR_CONFIG_LOAD BIT(0)
|
||||||
#define TIMEOUT_CONFIG_LOAD BIT(2)
|
#define TIMEOUT_CONFIG_LOAD BIT(2)
|
||||||
|
|
||||||
static const u32 i2c_addrs[] = {
|
/* I2C_1, 2, 3, 4, 5 and 6. */
|
||||||
0x7000C000, // I2C_1.
|
static const u16 _i2c_base_offsets[6] = { 0x0, 0x400, 0x500, 0x700, 0x1000, 0x1100 };
|
||||||
0x7000C400, // I2C_2.
|
|
||||||
0x7000C500, // I2C_3.
|
|
||||||
0x7000C700, // I2C_4.
|
|
||||||
0x7000D000, // I2C_5.
|
|
||||||
0x7000D100 // I2C_6.
|
|
||||||
};
|
|
||||||
|
|
||||||
static void _i2c_load_cfg_wait(vu32 *base)
|
static void _i2c_load_cfg_wait(vu32 *base)
|
||||||
{
|
{
|
||||||
@@ -101,14 +96,14 @@ static void _i2c_load_cfg_wait(vu32 *base)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
|
static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, const u8 *buf, u32 size)
|
||||||
{
|
{
|
||||||
if (size > 8)
|
if (size > 8)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
u32 tmp = 0;
|
u32 tmp = 0;
|
||||||
|
|
||||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||||
|
|
||||||
// Set device address and send mode.
|
// Set device address and send mode.
|
||||||
base[I2C_CMD_ADDR0] = dev_addr << 1 | ADDR0_WRITE;
|
base[I2C_CMD_ADDR0] = dev_addr << 1 | ADDR0_WRITE;
|
||||||
@@ -154,7 +149,7 @@ static int _i2c_recv_single(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
|||||||
if (size > 8)
|
if (size > 8)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||||
|
|
||||||
// Set device address and recv mode.
|
// Set device address and recv mode.
|
||||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
|
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
|
||||||
@@ -198,7 +193,7 @@ static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
|||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||||
|
|
||||||
// Enable interrupts.
|
// Enable interrupts.
|
||||||
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
|
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
|
||||||
@@ -270,7 +265,7 @@ static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
|
|||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||||
|
|
||||||
// Enable interrupts.
|
// Enable interrupts.
|
||||||
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
|
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
|
||||||
@@ -352,7 +347,7 @@ static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
|
|||||||
|
|
||||||
void i2c_init(u32 i2c_idx)
|
void i2c_init(u32 i2c_idx)
|
||||||
{
|
{
|
||||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||||
|
|
||||||
base[I2C_CLK_DIVISOR] = (5 << 16) | 1; // SF mode Div: 6, HS mode div: 2.
|
base[I2C_CLK_DIVISOR] = (5 << 16) | 1; // SF mode Div: 6, HS mode div: 2.
|
||||||
base[I2C_BUS_CLEAR_CONFIG] = (9 << 16) | BC_TERMINATE | BC_ENABLE;
|
base[I2C_BUS_CLEAR_CONFIG] = (9 << 16) | BC_TERMINATE | BC_ENABLE;
|
||||||
@@ -389,9 +384,9 @@ int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
|
|||||||
return _i2c_recv_pkt(i2c_idx, buf, size, dev_addr, reg);
|
return _i2c_recv_pkt(i2c_idx, buf, size, dev_addr, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size)
|
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, const u8 *buf, u32 size)
|
||||||
{
|
{
|
||||||
u8 tmp[4];
|
u8 tmp[8];
|
||||||
|
|
||||||
if (size > 7)
|
if (size > 7)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ void i2c_init(u32 i2c_idx);
|
|||||||
int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr);
|
int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr);
|
||||||
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size);
|
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size);
|
||||||
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size);
|
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, const u8 *buf, u32 size);
|
||||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||||
int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val);
|
int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val);
|
||||||
u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg);
|
u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user