[dm2.0] add new bsp for rk platform
This commit is contained in:
parent
f98f772a84
commit
1572a44055
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
||||||
|
mainmenu "RT-Thread Project Configuration"
|
||||||
|
|
||||||
|
config BSP_DIR
|
||||||
|
string
|
||||||
|
option env="BSP_ROOT"
|
||||||
|
default "."
|
||||||
|
|
||||||
|
config RTT_DIR
|
||||||
|
string
|
||||||
|
option env="RTT_ROOT"
|
||||||
|
default "../../.."
|
||||||
|
|
||||||
|
config PKGS_DIR
|
||||||
|
string
|
||||||
|
option env="PKGS_ROOT"
|
||||||
|
default "packages"
|
||||||
|
|
||||||
|
source "$RTT_DIR/Kconfig"
|
||||||
|
source "$PKGS_DIR/Kconfig"
|
||||||
|
source "$BSP_DIR/driver/Kconfig"
|
||||||
|
|
||||||
|
config SOC_RK3568
|
||||||
|
bool
|
||||||
|
select ARCH_ARMV8
|
||||||
|
select ARCH_CPU_64BIT
|
||||||
|
select RT_USING_CACHE
|
||||||
|
select RT_USING_COMPONENTS_INIT
|
||||||
|
select RT_USING_USER_MAIN
|
||||||
|
select ARCH_ARM_BOOTWITH_FLUSH_CACHE
|
||||||
|
default y
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# RK3568 BSP Introduction
|
||||||
|
|
||||||
|
[中文页]() | English
|
||||||
|
|
||||||
|
## 1. Introduction
|
||||||
|
|
||||||
|
RK3568 is a general-purpose SOC, quad-core 64-bit Cortex-A55 processor, with 22nm lithography process, has frequency up to 2.0GHz and Mali G52 GPU, support 4K decoding and 1080P encoding. Support mangy interfaces such as SATA/PCIE/USB3.0, an 0.8T NPU for lightweight AI applications. Support dual Gigabit Ethernet ports, LPDDR4 memory, etc.
|
||||||
|
|
||||||
|
This project ported RT-Thread on RK3568, you can use the RADXA ROCK 3A version of the RK3568 in low-priced, which can even replace the Raspberry Pi 4B.
|
||||||
|
|
||||||
|
## 2. Compiling
|
||||||
|
|
||||||
|
Usage ARM Developer GNU ToolChain, it support Linux and Windows:
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads/
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Download the `xxx-aarch64-none-elf` of x86_64 hosted platform, set the `RTT_EXEC_PATH` is system environment after decompress the binary.
|
||||||
|
|
||||||
|
Enter directory `rt-thread/bsp/qemu-virt64-aarch64` and input:
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
scons
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 3. Execution
|
||||||
|
|
||||||
|
RK3568 has different Kernel install methods according to different boardsit, recommend to install into the SD card: ([Official](https://wiki.t-firefly.com/en/ROC-RK3568-PC/hardware_doc.html)|[RADXA ROCK 3A](https://wiki.radxa.com/Rock3/install/microSD)).
|
||||||
|
|
||||||
|
After install Kernel, storage the `rtthread.bin` to EFI partition (the second partition), and add this line in the front of `boot.cmd` in this partition:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
fatload mmc 1:1 0x208000 /rtthread.bin;dcache flush;go 0x208000
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
After modifying the script, build a binary script `boot.scr ` in this partition:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Install the uboot-mkimage package on Linux, or use MSYS2 to install the u-boot-tools package on Windows
|
||||||
|
mkimage -C none -A arm -T script -d boot.cmd boot.scr
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
According to different boards, the serial port can support up to UART0~9, this project uses UART2 ([Official](https://wiki.t-firefly.com/en/ROC-RK3568-PC/debug.html)|[RADXA ROCK 3A](https://wiki.radxa.com/Rock3/dev/serial-console)) by default, the baud rate is 1500000, please make sure that the serial port used supports this baud rate.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
heap: [0x002663f0 - 0x042663f0]
|
||||||
|
|
||||||
|
\ | /
|
||||||
|
- RT - Thread Operating System
|
||||||
|
/ | \ 4.1.0 build Mar 19 2022 17:17:29
|
||||||
|
2006 - 2022 Copyright by RT-Thread team
|
||||||
|
Hi, this is RT-Thread!!
|
||||||
|
msh />
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 4. Condition
|
||||||
|
|
||||||
|
| Driver | Condition | Remark |
|
||||||
|
| ------ | --------- | ------- |
|
||||||
|
| UART | Support | UART0~9 |
|
|
@ -0,0 +1,14 @@
|
||||||
|
# for module compiling
|
||||||
|
import os
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
objs = []
|
||||||
|
list = os.listdir(cwd)
|
||||||
|
|
||||||
|
for d in list:
|
||||||
|
path = os.path.join(cwd, d)
|
||||||
|
if os.path.isfile(os.path.join(path, 'SConscript')):
|
||||||
|
objs = objs + SConscript(os.path.join(d, 'SConscript'))
|
||||||
|
|
||||||
|
Return('objs')
|
|
@ -0,0 +1,29 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import rtconfig
|
||||||
|
|
||||||
|
from rtconfig import RTT_ROOT
|
||||||
|
|
||||||
|
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
TARGET = 'rtthread.' + rtconfig.TARGET_EXT
|
||||||
|
|
||||||
|
DefaultEnvironment(tools=[])
|
||||||
|
env = Environment(tools = ['mingw'],
|
||||||
|
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
|
||||||
|
CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS,
|
||||||
|
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
|
||||||
|
AR = rtconfig.AR, ARFLAGS = '-rc',
|
||||||
|
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
|
||||||
|
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
|
||||||
|
env['ASCOM'] = env['ASPPCOM']
|
||||||
|
|
||||||
|
Export('RTT_ROOT')
|
||||||
|
Export('rtconfig')
|
||||||
|
|
||||||
|
# prepare building environment
|
||||||
|
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
|
||||||
|
|
||||||
|
# make a building
|
||||||
|
DoBuilding(TARGET, objs)
|
|
@ -0,0 +1,14 @@
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
src = Glob('*.c') + Glob('*.cpp')
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
list = os.listdir(cwd)
|
||||||
|
for item in list:
|
||||||
|
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
|
||||||
|
group += SConscript(os.path.join(item, 'SConscript'))
|
||||||
|
|
||||||
|
Return('group')
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2017-5-30 Bernard the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
rt_kprintf("Hi, this is RT-Thread!!\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
menu "RT-Thread rockchip RK3500 drivers"
|
||||||
|
|
||||||
|
source "$BSP_DIR/driver/clk/Kconfig"
|
||||||
|
source "$BSP_DIR/driver/uart8250/Kconfig"
|
||||||
|
source "$BSP_DIR/driver/reset/Kconfig"
|
||||||
|
source "$BSP_DIR/driver/hwtimer/Kconfig"
|
||||||
|
endmenu
|
|
@ -0,0 +1,19 @@
|
||||||
|
# RT-Thread building script for component
|
||||||
|
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
src = Glob('*.c')
|
||||||
|
list = os.listdir(cwd)
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
objs = []
|
||||||
|
|
||||||
|
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
for d in list:
|
||||||
|
path = os.path.join(cwd, d)
|
||||||
|
if os.path.isfile(os.path.join(path, 'SConscript')):
|
||||||
|
objs = objs + SConscript(os.path.join(d, 'SConscript'))
|
||||||
|
objs = objs + group
|
||||||
|
|
||||||
|
Return('objs')
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-3-08 GuEe-GUI the first version
|
||||||
|
*/
|
||||||
|
#include <setup.h>
|
||||||
|
#include <board.h>
|
||||||
|
#include <psci.h>
|
||||||
|
|
||||||
|
void rt_hw_board_init(void)
|
||||||
|
{
|
||||||
|
#if RT_VER_NUM < 0x50200
|
||||||
|
rt_fdt_commit_memregion_early(&(rt_region_t)
|
||||||
|
{
|
||||||
|
.name = "memheap",
|
||||||
|
.start = (rt_size_t)rt_kmem_v2p(HEAP_BEGIN),
|
||||||
|
.end = (rt_size_t)rt_kmem_v2p(HEAP_END),
|
||||||
|
}, RT_TRUE);
|
||||||
|
#endif
|
||||||
|
rt_hw_common_setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reboot(void)
|
||||||
|
{
|
||||||
|
psci_system_reboot();
|
||||||
|
}
|
||||||
|
MSH_CMD_EXPORT(reboot, reboot...);
|
||||||
|
|
||||||
|
void rt_hw_cpu_shutdown(void)
|
||||||
|
{
|
||||||
|
psci_system_off();
|
||||||
|
}
|
||||||
|
MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_shutdown, shutdown, shutdown...);
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2017-5-30 Bernard the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BOARD_H__
|
||||||
|
#define __BOARD_H__
|
||||||
|
|
||||||
|
#include <rtdef.h>
|
||||||
|
|
||||||
|
extern unsigned char __bss_start;
|
||||||
|
extern unsigned char __bss_end;
|
||||||
|
|
||||||
|
#define HEAP_BEGIN (void *)&__bss_end
|
||||||
|
#define HEAP_END ((void *)HEAP_BEGIN + 64 * 1024 * 1024)
|
||||||
|
|
||||||
|
|
||||||
|
void rt_hw_board_init(void);
|
||||||
|
|
||||||
|
#endif /* __BOARD_H__ */
|
|
@ -0,0 +1,15 @@
|
||||||
|
menuconfig RT_CLK_ROCKCHIP
|
||||||
|
bool "Rockchip clock controller common"
|
||||||
|
select RT_USING_OFW
|
||||||
|
select RT_USING_RESET
|
||||||
|
default n
|
||||||
|
|
||||||
|
config RT_CLK_ROCKCHIP_RK3568
|
||||||
|
bool "Rockchip RK3568 clock controller support"
|
||||||
|
depends on RT_CLK_ROCKCHIP
|
||||||
|
default n
|
||||||
|
|
||||||
|
config RT_CLK_ROCKCHIP_RK3588
|
||||||
|
bool "Rockchip RK3588 clock controller support"
|
||||||
|
depends on RT_CLK_ROCKCHIP
|
||||||
|
default n
|
|
@ -0,0 +1,16 @@
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
src = []
|
||||||
|
|
||||||
|
if GetDepend(['RT_CLK_ROCKCHIP_RK3568']):
|
||||||
|
src += ['clk-rk3568.c']
|
||||||
|
|
||||||
|
if GetDepend(['RT_CLK_ROCKCHIP_RK3588']):
|
||||||
|
src += ['clk-rk3588.c']
|
||||||
|
|
||||||
|
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
Return('group')
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-3-08 GuEe-GUI the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ROCKCHIP_MMC_DELAY_SEL RT_BIT(11)
|
||||||
|
#define ROCKCHIP_MMC_DEGREE_OFFSET 1
|
||||||
|
#define ROCKCHIP_MMC_DEGREE_MASK (0x3 << ROCKCHIP_MMC_DEGREE_OFFSET)
|
||||||
|
#define ROCKCHIP_MMC_DELAYNUM_OFFSET 3
|
||||||
|
#define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
|
||||||
|
/*
|
||||||
|
* Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
|
||||||
|
* simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
|
||||||
|
*/
|
||||||
|
#define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
|
||||||
|
|
||||||
|
#define PSECS_PER_SEC 1000000000000LL
|
||||||
|
|
||||||
|
#define RK3288_MMC_CLKGEN_DIV 2
|
||||||
|
|
||||||
|
rt_inline rt_ubase_t rk_clk_mmc_recalc(rt_ubase_t parent_rate)
|
||||||
|
{
|
||||||
|
return parent_rate / RK3288_MMC_CLKGEN_DIV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rk_clk_mmc_set_phase(rt_ubase_t rate, void *reg, int shift,
|
||||||
|
int degrees)
|
||||||
|
{
|
||||||
|
rt_uint32_t raw_value, delay;
|
||||||
|
rt_uint8_t nineties, remainder, delay_num;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The below calculation is based on the output clock from
|
||||||
|
* MMC host to the card, which expects the phase clock inherits
|
||||||
|
* the clock rate from its parent, namely the output clock
|
||||||
|
* provider of MMC host. However, things may go wrong if
|
||||||
|
* (1) It is orphan.
|
||||||
|
* (2) It is assigned to the wrong parent.
|
||||||
|
*
|
||||||
|
* This check help debug the case (1), which seems to be the
|
||||||
|
* most likely problem we often face and which makes it difficult
|
||||||
|
* for people to debug unstable mmc tuning results.
|
||||||
|
*/
|
||||||
|
if (!rate)
|
||||||
|
{
|
||||||
|
LOG_E("Invalid CLK rate in phase setting");
|
||||||
|
|
||||||
|
return -RT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nineties = degrees / 90;
|
||||||
|
remainder = (degrees % 90);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Due to the inexact nature of the "fine" delay, we might
|
||||||
|
* actually go non-monotonic. We don't go _too_ monotonic
|
||||||
|
* though, so we should be OK. Here are options of how we may
|
||||||
|
* work:
|
||||||
|
*
|
||||||
|
* Ideally we end up with:
|
||||||
|
* 1.0, 2.0, ..., 69.0, 70.0, ..., 89.0, 90.0
|
||||||
|
*
|
||||||
|
* On one extreme (if delay is actually 44ps):
|
||||||
|
* .73, 1.5, ..., 50.6, 51.3, ..., 65.3, 90.0
|
||||||
|
* The other (if delay is actually 77ps):
|
||||||
|
* 1.3, 2.6, ..., 88.6. 89.8, ..., 114.0, 90
|
||||||
|
*
|
||||||
|
* It's possible we might make a delay that is up to 25
|
||||||
|
* degrees off from what we think we're making. That's OK
|
||||||
|
* though because we should be REALLY far from any bad range.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert to delay; do a little extra work to make sure we
|
||||||
|
* don't overflow 32-bit / 64-bit numbers.
|
||||||
|
*/
|
||||||
|
delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
|
||||||
|
delay *= remainder;
|
||||||
|
delay = RT_DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
|
||||||
|
(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
|
||||||
|
|
||||||
|
delay_num = (rt_uint8_t)rt_min_t(rt_uint32_t, delay, 255);
|
||||||
|
|
||||||
|
raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
|
||||||
|
raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
|
||||||
|
raw_value |= nineties;
|
||||||
|
HWREG32(reg) = HIWORD_UPDATE(raw_value, 0x07ff, shift);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_base_t rk_clk_mmc_get_phase(rt_ubase_t rate, void *reg, int shift)
|
||||||
|
{
|
||||||
|
rt_uint16_t degrees;
|
||||||
|
rt_uint32_t raw_value, delay_num = 0;
|
||||||
|
|
||||||
|
/* Constant signal, no measurable phase shift */
|
||||||
|
if (!rate)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
raw_value = HWREG32(reg) >> shift;
|
||||||
|
degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
|
||||||
|
|
||||||
|
if (raw_value & ROCKCHIP_MMC_DELAY_SEL)
|
||||||
|
{
|
||||||
|
/* degrees/delaynum * 1000000 */
|
||||||
|
rt_ubase_t factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
|
||||||
|
36 * (rate / 10000);
|
||||||
|
|
||||||
|
delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
|
||||||
|
delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
|
||||||
|
degrees += RT_DIV_ROUND_CLOSEST(delay_num * factor, 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return degrees % 360;
|
||||||
|
}
|
|
@ -0,0 +1,403 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-3-08 GuEe-GUI the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define pll mode */
|
||||||
|
#define RKCLK_PLL_MODE_SLOW 0
|
||||||
|
#define RKCLK_PLL_MODE_NORMAL 1
|
||||||
|
#define RKCLK_PLL_MODE_DEEP 2
|
||||||
|
|
||||||
|
/* Only support RK3036 type CLK */
|
||||||
|
#define PLLCON0_FBDIV_MASK 0xfff
|
||||||
|
#define PLLCON0_FBDIV_SHIFT 0
|
||||||
|
#define PLLCON0_POSTDIV1_MASK (0x7 << 12)
|
||||||
|
#define PLLCON0_POSTDIV1_SHIFT 12
|
||||||
|
#define PLLCON1_LOCK_STATUS (1 << 10)
|
||||||
|
#define PLLCON1_REFDIV_MASK 0x3f
|
||||||
|
#define PLLCON1_REFDIV_SHIFT 0
|
||||||
|
#define PLLCON1_POSTDIV2_MASK (0x7 << 6)
|
||||||
|
#define PLLCON1_POSTDIV2_SHIFT 6
|
||||||
|
#define PLLCON1_DSMPD_MASK (0x1 << 12)
|
||||||
|
#define PLLCON1_DSMPD_SHIFT 12
|
||||||
|
#define PLLCON2_FRAC_MASK 0xffffff
|
||||||
|
#define PLLCON2_FRAC_SHIFT 0
|
||||||
|
#define PLLCON1_PWRDOWN_SHIT 13
|
||||||
|
#define PLLCON1_PWRDOWN (1 << PLLCON1_PWRDOWN_SHIT)
|
||||||
|
|
||||||
|
#define MIN_FOUTVCO_FREQ (800 * MHZ)
|
||||||
|
#define MAX_FOUTVCO_FREQ (2000 * MHZ)
|
||||||
|
|
||||||
|
static struct rk_pll_rate_table auto_table;
|
||||||
|
|
||||||
|
static int gcd(int m, int n)
|
||||||
|
{
|
||||||
|
while (m > 0)
|
||||||
|
{
|
||||||
|
if (n > m)
|
||||||
|
{
|
||||||
|
int t = m;
|
||||||
|
m = n;
|
||||||
|
n = t;
|
||||||
|
}
|
||||||
|
m -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rational_best_approximation(31415, 10000,
|
||||||
|
* (1 << 8) - 1, (1 << 5) - 1, &n, &d);
|
||||||
|
*
|
||||||
|
* you may look at given_numerator as a fixed point number,
|
||||||
|
* with the fractional part size described in given_denominator.
|
||||||
|
*
|
||||||
|
* for theoretical background, see:
|
||||||
|
* http://en.wikipedia.org/wiki/Continued_fraction
|
||||||
|
*/
|
||||||
|
static void rational_best_approximation(rt_ubase_t given_numerator,
|
||||||
|
rt_ubase_t given_denominator,
|
||||||
|
rt_ubase_t max_numerator,
|
||||||
|
rt_ubase_t max_denominator,
|
||||||
|
rt_ubase_t *best_numerator,
|
||||||
|
rt_ubase_t *best_denominator)
|
||||||
|
{
|
||||||
|
rt_ubase_t n, d, n0, d0, n1, d1;
|
||||||
|
|
||||||
|
n = given_numerator;
|
||||||
|
d = given_denominator;
|
||||||
|
n0 = 0;
|
||||||
|
d1 = 0;
|
||||||
|
n1 = 1;
|
||||||
|
d0 = 1;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
rt_ubase_t t, a;
|
||||||
|
|
||||||
|
if (n1 > max_numerator || d1 > max_denominator)
|
||||||
|
{
|
||||||
|
n1 = n0;
|
||||||
|
d1 = d0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (d == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
t = d;
|
||||||
|
a = n / d;
|
||||||
|
d = n % d;
|
||||||
|
n = t;
|
||||||
|
t = n0 + a * n1;
|
||||||
|
n0 = n1;
|
||||||
|
n1 = t;
|
||||||
|
t = d0 + a * d1;
|
||||||
|
d0 = d1;
|
||||||
|
d1 = t;
|
||||||
|
}
|
||||||
|
*best_numerator = n1;
|
||||||
|
*best_denominator = d1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
|
||||||
|
* Formulas also embedded within the Fractional PLL Verilog model:
|
||||||
|
* If DSMPD = 1 (DSM is disabled, "integer mode")
|
||||||
|
* FOUTVCO = FREF / REFDIV * FBDIV
|
||||||
|
* FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
|
||||||
|
* Where:
|
||||||
|
* FOUTVCO = Fractional PLL non-divided output frequency
|
||||||
|
* FOUTPOSTDIV = Fractional PLL divided output frequency
|
||||||
|
* (output of second post divider)
|
||||||
|
* FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
|
||||||
|
* REFDIV = Fractional PLL input reference clock divider
|
||||||
|
* FBDIV = Integer value programmed into feedback divide
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int rk_pll_clk_set_postdiv(rt_ubase_t fout_hz, rt_uint32_t *postdiv1,
|
||||||
|
rt_uint32_t *postdiv2, rt_uint32_t *foutvco)
|
||||||
|
{
|
||||||
|
rt_ubase_t freq;
|
||||||
|
|
||||||
|
if (fout_hz < MIN_FOUTVCO_FREQ)
|
||||||
|
{
|
||||||
|
for (*postdiv1 = 1; *postdiv1 <= 7; ++(*postdiv1))
|
||||||
|
{
|
||||||
|
for (*postdiv2 = 1; *postdiv2 <= 7; ++(*postdiv2))
|
||||||
|
{
|
||||||
|
freq = fout_hz * (*postdiv1) * (*postdiv2);
|
||||||
|
if (freq >= MIN_FOUTVCO_FREQ && freq <= MAX_FOUTVCO_FREQ)
|
||||||
|
{
|
||||||
|
*foutvco = freq;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*postdiv1 = 1;
|
||||||
|
*postdiv2 = 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rk_pll_rate_table *rk_pll_clk_set_by_auto(rt_ubase_t fin_hz, rt_ubase_t fout_hz)
|
||||||
|
{
|
||||||
|
struct rk_pll_rate_table *rate_table = &auto_table;
|
||||||
|
rt_uint32_t foutvco = fout_hz;
|
||||||
|
rt_ubase_t fin_64, frac_64;
|
||||||
|
rt_uint32_t f_frac, postdiv1, postdiv2;
|
||||||
|
rt_ubase_t clk_gcd = 0;
|
||||||
|
|
||||||
|
if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
|
||||||
|
{
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rk_pll_clk_set_postdiv(fout_hz, &postdiv1, &postdiv2, &foutvco);
|
||||||
|
rate_table->postdiv1 = postdiv1;
|
||||||
|
rate_table->postdiv2 = postdiv2;
|
||||||
|
rate_table->dsmpd = 1;
|
||||||
|
|
||||||
|
if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz)
|
||||||
|
{
|
||||||
|
fin_hz /= MHZ;
|
||||||
|
foutvco /= MHZ;
|
||||||
|
clk_gcd = gcd(fin_hz, foutvco);
|
||||||
|
rate_table->refdiv = fin_hz / clk_gcd;
|
||||||
|
rate_table->fbdiv = foutvco / clk_gcd;
|
||||||
|
|
||||||
|
rate_table->frac = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clk_gcd = gcd(fin_hz / MHZ, foutvco / MHZ);
|
||||||
|
rate_table->refdiv = fin_hz / MHZ / clk_gcd;
|
||||||
|
rate_table->fbdiv = foutvco / MHZ / clk_gcd;
|
||||||
|
|
||||||
|
rate_table->frac = 0;
|
||||||
|
|
||||||
|
f_frac = (foutvco % MHZ);
|
||||||
|
fin_64 = fin_hz;
|
||||||
|
fin_64 = fin_64 / rate_table->refdiv;
|
||||||
|
frac_64 = f_frac << 24;
|
||||||
|
frac_64 = frac_64 / fin_64;
|
||||||
|
rate_table->frac = frac_64;
|
||||||
|
|
||||||
|
if (rate_table->frac > 0)
|
||||||
|
{
|
||||||
|
rate_table->dsmpd = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rate_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct rk_pll_rate_table *rk_get_pll_settings(struct rk_pll_clock *pll, rt_ubase_t rate)
|
||||||
|
{
|
||||||
|
struct rk_pll_rate_table *rate_table = pll->rate_table;
|
||||||
|
|
||||||
|
while (rate_table->rate)
|
||||||
|
{
|
||||||
|
if (rate_table->rate == rate)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++rate_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rate_table->rate != rate)
|
||||||
|
{
|
||||||
|
return rk_pll_clk_set_by_auto(24 * MHZ, rate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return rate_table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_ubase_t rk_pll_get_rate(struct rk_pll_clock *pll, void *base);
|
||||||
|
|
||||||
|
static int rk_pll_set_rate(struct rk_pll_clock *pll, void *base, rt_ubase_t drate)
|
||||||
|
{
|
||||||
|
const struct rk_pll_rate_table *rate;
|
||||||
|
|
||||||
|
if (rk_pll_get_rate(pll, base) == drate)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pll->mode_mask = PLL_MODE_MASK;
|
||||||
|
rate = rk_get_pll_settings(pll, drate);
|
||||||
|
|
||||||
|
if (!rate)
|
||||||
|
{
|
||||||
|
return -RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When power on or changing PLL setting, we must force PLL into slow mode
|
||||||
|
* to ensure output stable clock.
|
||||||
|
*/
|
||||||
|
rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift, RKCLK_PLL_MODE_SLOW << pll->mode_shift);
|
||||||
|
|
||||||
|
/* Power down */
|
||||||
|
rk_setreg(base + pll->con_offset + 0x4, 1 << PLLCON1_PWRDOWN_SHIT);
|
||||||
|
|
||||||
|
rk_clrsetreg(base + pll->con_offset, (PLLCON0_POSTDIV1_MASK | PLLCON0_FBDIV_MASK),
|
||||||
|
(rate->postdiv1 << PLLCON0_POSTDIV1_SHIFT) |rate->fbdiv);
|
||||||
|
rk_clrsetreg(base + pll->con_offset + 0x4, (PLLCON1_POSTDIV2_MASK | PLLCON1_REFDIV_MASK),
|
||||||
|
(rate->postdiv2 << PLLCON1_POSTDIV2_SHIFT | rate->refdiv << PLLCON1_REFDIV_SHIFT));
|
||||||
|
|
||||||
|
if (!rate->dsmpd)
|
||||||
|
{
|
||||||
|
rt_uint32_t val;
|
||||||
|
|
||||||
|
rk_clrsetreg(base + pll->con_offset + 0x4, PLLCON1_DSMPD_MASK,
|
||||||
|
rate->dsmpd << PLLCON1_DSMPD_SHIFT);
|
||||||
|
|
||||||
|
val = HWREG32(base + pll->con_offset + 0x8) & (~PLLCON2_FRAC_MASK);
|
||||||
|
HWREG32(base + pll->con_offset + 0x8) = val | (rate->frac << PLLCON2_FRAC_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Power Up */
|
||||||
|
rk_clrreg(base + pll->con_offset + 0x4, 1 << PLLCON1_PWRDOWN_SHIT);
|
||||||
|
|
||||||
|
/* Waiting for pll lock */
|
||||||
|
while (!(HWREG32(base + pll->con_offset + 0x4) & (1 << pll->lock_shift)))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift, RKCLK_PLL_MODE_NORMAL << pll->mode_shift);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_ubase_t rk_pll_get_rate(struct rk_pll_clock *pll, void *base)
|
||||||
|
{
|
||||||
|
rt_uint32_t refdiv, fbdiv, postdiv1, postdiv2, dsmpd, frac;
|
||||||
|
rt_uint32_t con = 0, shift, mask;
|
||||||
|
rt_ubase_t rate;
|
||||||
|
|
||||||
|
pll->mode_mask = PLL_MODE_MASK;
|
||||||
|
|
||||||
|
con = HWREG32(base + pll->mode_offset);
|
||||||
|
shift = pll->mode_shift;
|
||||||
|
mask = pll->mode_mask << shift;
|
||||||
|
|
||||||
|
switch ((con & mask) >> shift)
|
||||||
|
{
|
||||||
|
case RKCLK_PLL_MODE_SLOW:
|
||||||
|
return OSC_HZ;
|
||||||
|
case RKCLK_PLL_MODE_NORMAL:
|
||||||
|
/* normal mode */
|
||||||
|
con = HWREG32(base + pll->con_offset);
|
||||||
|
postdiv1 = (con & PLLCON0_POSTDIV1_MASK) >> PLLCON0_POSTDIV1_SHIFT;
|
||||||
|
fbdiv = (con & PLLCON0_FBDIV_MASK) >> PLLCON0_FBDIV_SHIFT;
|
||||||
|
con = HWREG32(base + pll->con_offset + 0x4);
|
||||||
|
postdiv2 = (con & PLLCON1_POSTDIV2_MASK) >> PLLCON1_POSTDIV2_SHIFT;
|
||||||
|
refdiv = (con & PLLCON1_REFDIV_MASK) >> PLLCON1_REFDIV_SHIFT;
|
||||||
|
dsmpd = (con & PLLCON1_DSMPD_MASK) >> PLLCON1_DSMPD_SHIFT;
|
||||||
|
con = HWREG32(base + pll->con_offset + 0x8);
|
||||||
|
frac = (con & PLLCON2_FRAC_MASK) >> PLLCON2_FRAC_SHIFT;
|
||||||
|
rate = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
|
||||||
|
|
||||||
|
if (dsmpd == 0)
|
||||||
|
{
|
||||||
|
rt_uint64_t frac_rate = OSC_HZ * (rt_uint64_t)frac;
|
||||||
|
|
||||||
|
rt_do_div(frac_rate, refdiv);
|
||||||
|
frac_rate >>= 24;
|
||||||
|
rt_do_div(frac_rate, postdiv1);
|
||||||
|
rt_do_div(frac_rate, postdiv1);
|
||||||
|
rate += frac_rate;
|
||||||
|
}
|
||||||
|
return rate;
|
||||||
|
case RKCLK_PLL_MODE_DEEP:
|
||||||
|
default:
|
||||||
|
return 32768;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct rk_cpu_rate_table *rk_get_cpu_settings(struct rk_cpu_rate_table *cpu_table, rt_ubase_t rate)
|
||||||
|
{
|
||||||
|
struct rk_cpu_rate_table *ps = cpu_table;
|
||||||
|
|
||||||
|
while (ps->rate)
|
||||||
|
{
|
||||||
|
if (ps->rate == rate)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++ps;
|
||||||
|
}
|
||||||
|
if (ps->rate != rate)
|
||||||
|
{
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_base_t rk_clk_pll_round_rate(const struct rk_pll_rate_table *pll_rates,
|
||||||
|
rt_size_t rate_count, rt_ubase_t drate, rt_ubase_t *prate)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Assumming rate_table is in descending order */
|
||||||
|
for (i = 0; i < rate_count; i++)
|
||||||
|
{
|
||||||
|
if (drate >= pll_rates[i].rate)
|
||||||
|
{
|
||||||
|
return pll_rates[i].rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return minimum supported value */
|
||||||
|
return pll_rates[i - 1].rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rk_clk_set_default_rates(struct rt_clk *clk,
|
||||||
|
rt_err_t (*clk_set_rate)(struct rt_clk *, rt_ubase_t, rt_ubase_t), int id)
|
||||||
|
{
|
||||||
|
rt_uint32_t rate;
|
||||||
|
struct rt_ofw_cell_args clk_args;
|
||||||
|
struct rt_ofw_node *np = clk->fw_node;
|
||||||
|
const char *rate_propname = "assigned-clock-rates";
|
||||||
|
|
||||||
|
if (!rt_ofw_prop_read_bool(np, rate_propname))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; ; ++i)
|
||||||
|
{
|
||||||
|
if (rt_ofw_parse_phandle_cells(np, "assigned-clocks", "#clock-cells", i, &clk_args))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_ofw_node_put(clk_args.data);
|
||||||
|
|
||||||
|
if (clk_args.args[0] != id)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rt_ofw_prop_read_u32_index(np, rate_propname, i, &rate))
|
||||||
|
{
|
||||||
|
clk_set_rate(clk, rate, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,727 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2023-11-03 zmshahaha the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PLL_MODE_MASK 0x3
|
||||||
|
#define PLL_RK3328_MODE_MASK 0x1
|
||||||
|
|
||||||
|
/* Define pll mode */
|
||||||
|
#define RKCLK_PLL_MODE_SLOW 0
|
||||||
|
#define RKCLK_PLL_MODE_NORMAL 1
|
||||||
|
#define RKCLK_PLL_MODE_DEEP 2
|
||||||
|
|
||||||
|
/* Only support RK3036 type CLK */
|
||||||
|
#define RK3036_PLLCON0_FBDIV_MASK 0xfff
|
||||||
|
#define RK3036_PLLCON0_FBDIV_SHIFT 0
|
||||||
|
#define RK3036_PLLCON0_POSTDIV1_MASK (0x7 << 12)
|
||||||
|
#define RK3036_PLLCON0_POSTDIV1_SHIFT 12
|
||||||
|
#define RK3036_PLLCON1_LOCK_STATUS (1 << 10)
|
||||||
|
#define RK3036_PLLCON1_REFDIV_MASK 0x3f
|
||||||
|
#define RK3036_PLLCON1_REFDIV_SHIFT 0
|
||||||
|
#define RK3036_PLLCON1_POSTDIV2_MASK (0x7 << 6)
|
||||||
|
#define RK3036_PLLCON1_POSTDIV2_SHIFT 6
|
||||||
|
#define RK3036_PLLCON1_DSMPD_MASK (0x1 << 12)
|
||||||
|
#define RK3036_PLLCON1_DSMPD_SHIFT 12
|
||||||
|
#define RK3036_PLLCON2_FRAC_MASK 0xffffff
|
||||||
|
#define RK3036_PLLCON2_FRAC_SHIFT 0
|
||||||
|
#define RK3036_PLLCON1_PWRDOWN_SHIT 13
|
||||||
|
#define RK3036_PLLCON1_PWRDOWN (1 << RK3036_PLLCON1_PWRDOWN_SHIT)
|
||||||
|
|
||||||
|
#define VCO_MAX_HZ (3200UL * MHZ)
|
||||||
|
#define VCO_MIN_HZ (800UL * MHZ)
|
||||||
|
#define OUTPUT_MAX_HZ (3200UL * MHZ)
|
||||||
|
#define OUTPUT_MIN_HZ (24UL * MHZ)
|
||||||
|
#define MIN_FOUTVCO_FREQ (800UL * MHZ)
|
||||||
|
#define MAX_FOUTVCO_FREQ (2000UL * MHZ)
|
||||||
|
|
||||||
|
#define RK3588_VCO_MIN_HZ (2250UL * MHZ)
|
||||||
|
#define RK3588_VCO_MAX_HZ (4500UL * MHZ)
|
||||||
|
#define RK3588_FOUT_MIN_HZ (37UL * MHZ)
|
||||||
|
#define RK3588_FOUT_MAX_HZ (4500UL * MHZ)
|
||||||
|
|
||||||
|
#define RK3588_PLLCON(i) ((i) * 0x4)
|
||||||
|
#define RK3588_PLLCON0_M_MASK (0x3ff << 0)
|
||||||
|
#define RK3588_PLLCON0_M_SHIFT 0
|
||||||
|
#define RK3588_PLLCON1_P_MASK (0x3f << 0)
|
||||||
|
#define RK3588_PLLCON1_P_SHIFT 0
|
||||||
|
#define RK3588_PLLCON1_S_MASK (0x7 << 6)
|
||||||
|
#define RK3588_PLLCON1_S_SHIFT 6
|
||||||
|
#define RK3588_PLLCON2_K_MASK 0xffff
|
||||||
|
#define RK3588_PLLCON2_K_SHIFT 0
|
||||||
|
#define RK3588_PLLCON1_PWRDOWN (1 << 13)
|
||||||
|
#define RK3588_PLLCON6_LOCK_STATUS (1 << 15)
|
||||||
|
#define RK3588_B0PLL_CLKSEL_CON(i) ((i) * 0x4 + 0x50000 + 0x300)
|
||||||
|
#define RK3588_B1PLL_CLKSEL_CON(i) ((i) * 0x4 + 0x52000 + 0x300)
|
||||||
|
#define RK3588_LPLL_CLKSEL_CON(i) ((i) * 0x4 + 0x58000 + 0x300)
|
||||||
|
#define RK3588_CORE_DIV_MASK 0x1f
|
||||||
|
#define RK3588_CORE_L02_DIV_SHIFT 0
|
||||||
|
#define RK3588_CORE_L13_DIV_SHIFT 7
|
||||||
|
#define RK3588_CORE_B02_DIV_SHIFT 8
|
||||||
|
#define RK3588_CORE_B13_DIV_SHIFT 0
|
||||||
|
|
||||||
|
static struct rk_pll_rate_table auto_table;
|
||||||
|
|
||||||
|
static int gcd(int m, int n)
|
||||||
|
{
|
||||||
|
while (m > 0)
|
||||||
|
{
|
||||||
|
if (n > m)
|
||||||
|
{
|
||||||
|
int t = m;
|
||||||
|
m = n;
|
||||||
|
n = t;
|
||||||
|
}
|
||||||
|
m -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rational_best_approximation(31415, 10000,
|
||||||
|
* (1 << 8) - 1, (1 << 5) - 1, &n, &d);
|
||||||
|
*
|
||||||
|
* you may look at given_numerator as a fixed point number,
|
||||||
|
* with the fractional part size described in given_denominator.
|
||||||
|
*
|
||||||
|
* for theoretical background, see:
|
||||||
|
* http://en.wikipedia.org/wiki/Continued_fraction
|
||||||
|
*/
|
||||||
|
void rational_best_approximation(rt_ubase_t given_numerator,
|
||||||
|
rt_ubase_t given_denominator,
|
||||||
|
rt_ubase_t max_numerator,
|
||||||
|
rt_ubase_t max_denominator,
|
||||||
|
rt_ubase_t *best_numerator,
|
||||||
|
rt_ubase_t *best_denominator)
|
||||||
|
{
|
||||||
|
rt_ubase_t n, d, n0, d0, n1, d1;
|
||||||
|
|
||||||
|
n = given_numerator;
|
||||||
|
d = given_denominator;
|
||||||
|
n0 = 0;
|
||||||
|
d1 = 0;
|
||||||
|
n1 = 1;
|
||||||
|
d0 = 1;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
rt_ubase_t t, a;
|
||||||
|
|
||||||
|
if (n1 > max_numerator || d1 > max_denominator)
|
||||||
|
{
|
||||||
|
n1 = n0;
|
||||||
|
d1 = d0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (d == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
t = d;
|
||||||
|
a = n / d;
|
||||||
|
d = n % d;
|
||||||
|
n = t;
|
||||||
|
t = n0 + a * n1;
|
||||||
|
n0 = n1;
|
||||||
|
n1 = t;
|
||||||
|
t = d0 + a * d1;
|
||||||
|
d0 = d1;
|
||||||
|
d1 = t;
|
||||||
|
}
|
||||||
|
*best_numerator = n1;
|
||||||
|
*best_denominator = d1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
|
||||||
|
* Formulas also embedded within the Fractional PLL Verilog model:
|
||||||
|
* If DSMPD = 1 (DSM is disabled, "integer mode")
|
||||||
|
* FOUTVCO = FREF / REFDIV * FBDIV
|
||||||
|
* FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
|
||||||
|
* Where:
|
||||||
|
* FOUTVCO = Fractional PLL non-divided output frequency
|
||||||
|
* FOUTPOSTDIV = Fractional PLL divided output frequency
|
||||||
|
* (output of second post divider)
|
||||||
|
* FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
|
||||||
|
* REFDIV = Fractional PLL input reference clock divider
|
||||||
|
* FBDIV = Integer value programmed into feedback divide
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int rk_pll_clk_set_postdiv(rt_ubase_t fout_hz, rt_uint32_t *postdiv1,
|
||||||
|
rt_uint32_t *postdiv2, rt_uint32_t *foutvco)
|
||||||
|
{
|
||||||
|
rt_ubase_t freq;
|
||||||
|
|
||||||
|
if (fout_hz < MIN_FOUTVCO_FREQ)
|
||||||
|
{
|
||||||
|
for (*postdiv1 = 1; *postdiv1 <= 7; ++(*postdiv1))
|
||||||
|
{
|
||||||
|
for (*postdiv2 = 1; *postdiv2 <= 7; ++(*postdiv2))
|
||||||
|
{
|
||||||
|
freq = fout_hz * (*postdiv1) * (*postdiv2);
|
||||||
|
if (freq >= MIN_FOUTVCO_FREQ && freq <= MAX_FOUTVCO_FREQ)
|
||||||
|
{
|
||||||
|
*foutvco = freq;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*postdiv1 = 1;
|
||||||
|
*postdiv2 = 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rk_pll_rate_table *rk_pll_clk_set_by_auto(rt_ubase_t fin_hz, rt_ubase_t fout_hz)
|
||||||
|
{
|
||||||
|
struct rk_pll_rate_table *rate_table = &auto_table;
|
||||||
|
rt_uint32_t foutvco = fout_hz;
|
||||||
|
rt_ubase_t fin_64, frac_64;
|
||||||
|
rt_uint32_t f_frac, postdiv1, postdiv2;
|
||||||
|
rt_ubase_t clk_gcd = 0;
|
||||||
|
|
||||||
|
if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
|
||||||
|
{
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rk_pll_clk_set_postdiv(fout_hz, &postdiv1, &postdiv2, &foutvco);
|
||||||
|
rate_table->postdiv1 = postdiv1;
|
||||||
|
rate_table->postdiv2 = postdiv2;
|
||||||
|
rate_table->dsmpd = 1;
|
||||||
|
|
||||||
|
if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz)
|
||||||
|
{
|
||||||
|
fin_hz /= MHZ;
|
||||||
|
foutvco /= MHZ;
|
||||||
|
clk_gcd = gcd(fin_hz, foutvco);
|
||||||
|
rate_table->refdiv = fin_hz / clk_gcd;
|
||||||
|
rate_table->fbdiv = foutvco / clk_gcd;
|
||||||
|
|
||||||
|
rate_table->frac = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clk_gcd = gcd(fin_hz / MHZ, foutvco / MHZ);
|
||||||
|
rate_table->refdiv = fin_hz / MHZ / clk_gcd;
|
||||||
|
rate_table->fbdiv = foutvco / MHZ / clk_gcd;
|
||||||
|
|
||||||
|
rate_table->frac = 0;
|
||||||
|
|
||||||
|
f_frac = (foutvco % MHZ);
|
||||||
|
fin_64 = fin_hz;
|
||||||
|
fin_64 = fin_64 / rate_table->refdiv;
|
||||||
|
frac_64 = f_frac << 24;
|
||||||
|
frac_64 = frac_64 / fin_64;
|
||||||
|
rate_table->frac = frac_64;
|
||||||
|
|
||||||
|
if (rate_table->frac > 0)
|
||||||
|
{
|
||||||
|
rate_table->dsmpd = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rate_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rk_pll_rate_table *
|
||||||
|
rk3588_pll_clk_set_by_auto(rt_ubase_t fin_hz,
|
||||||
|
rt_ubase_t fout_hz)
|
||||||
|
{
|
||||||
|
struct rk_pll_rate_table *rate_table = &auto_table;
|
||||||
|
rt_uint32_t p, m, s;
|
||||||
|
rt_ubase_t fvco, fref, fout, ffrac;
|
||||||
|
|
||||||
|
if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (fout_hz > RK3588_FOUT_MAX_HZ || fout_hz < RK3588_FOUT_MIN_HZ)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz)
|
||||||
|
{
|
||||||
|
for (s = 0; s <= 6; s++)
|
||||||
|
{
|
||||||
|
fvco = fout_hz << s;
|
||||||
|
if (fvco < RK3588_VCO_MIN_HZ ||
|
||||||
|
fvco > RK3588_VCO_MAX_HZ)
|
||||||
|
continue;
|
||||||
|
for (p = 2; p <= 4; p++)
|
||||||
|
{
|
||||||
|
for (m = 64; m <= 1023; m++)
|
||||||
|
{
|
||||||
|
if (fvco == m * fin_hz / p)
|
||||||
|
{
|
||||||
|
rate_table->p = p;
|
||||||
|
rate_table->m = m;
|
||||||
|
rate_table->s = s;
|
||||||
|
rate_table->k = 0;
|
||||||
|
return rate_table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_E("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
|
||||||
|
} else {
|
||||||
|
for (s = 0; s <= 6; s++)
|
||||||
|
{
|
||||||
|
fvco = fout_hz << s;
|
||||||
|
if (fvco < RK3588_VCO_MIN_HZ ||
|
||||||
|
fvco > RK3588_VCO_MAX_HZ)
|
||||||
|
continue;
|
||||||
|
for (p = 1; p <= 4; p++)
|
||||||
|
{
|
||||||
|
for (m = 64; m <= 1023; m++)
|
||||||
|
{
|
||||||
|
if ((fvco >= m * fin_hz / p) && (fvco < (m + 1) * fin_hz / p))
|
||||||
|
{
|
||||||
|
rate_table->p = p;
|
||||||
|
rate_table->m = m;
|
||||||
|
rate_table->s = s;
|
||||||
|
fref = fin_hz / p;
|
||||||
|
ffrac = fvco - (m * fref);
|
||||||
|
fout = ffrac * 65536;
|
||||||
|
rate_table->k = fout / fref;
|
||||||
|
return rate_table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_E("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct rk_pll_rate_table *rk_get_pll_settings(struct rk_pll_clock *pll, rt_ubase_t rate)
|
||||||
|
{
|
||||||
|
struct rk_pll_rate_table *rate_table = pll->rate_table;
|
||||||
|
|
||||||
|
while (rate_table->rate)
|
||||||
|
{
|
||||||
|
if (rate_table->rate == rate)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++rate_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rate_table->rate != rate)
|
||||||
|
{
|
||||||
|
if (pll->type == pll_rk3588)
|
||||||
|
return rk3588_pll_clk_set_by_auto(24 * MHZ, rate);
|
||||||
|
else
|
||||||
|
return rk_pll_clk_set_by_auto(24 * MHZ, rate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return rate_table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rk3036_pll_set_rate(struct rk_pll_clock *pll, void *base, rt_ubase_t pll_id, rt_ubase_t drate)
|
||||||
|
{
|
||||||
|
const struct rk_pll_rate_table *rate;
|
||||||
|
|
||||||
|
rate = rk_get_pll_settings(pll, drate);
|
||||||
|
|
||||||
|
if (!rate)
|
||||||
|
{
|
||||||
|
return -RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When power on or changing PLL setting, we must force PLL into slow mode
|
||||||
|
* to ensure output stable clock.
|
||||||
|
*/
|
||||||
|
rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift, RKCLK_PLL_MODE_SLOW << pll->mode_shift);
|
||||||
|
|
||||||
|
/* Power down */
|
||||||
|
rk_setreg(base + pll->con_offset + 0x4, 1 << RK3036_PLLCON1_PWRDOWN_SHIT);
|
||||||
|
|
||||||
|
rk_clrsetreg(base + pll->con_offset, (RK3036_PLLCON0_POSTDIV1_MASK | RK3036_PLLCON0_FBDIV_MASK),
|
||||||
|
(rate->postdiv1 << RK3036_PLLCON0_POSTDIV1_SHIFT) |rate->fbdiv);
|
||||||
|
rk_clrsetreg(base + pll->con_offset + 0x4, (RK3036_PLLCON1_POSTDIV2_MASK | RK3036_PLLCON1_REFDIV_MASK),
|
||||||
|
(rate->postdiv2 << RK3036_PLLCON1_POSTDIV2_SHIFT | rate->refdiv << RK3036_PLLCON1_REFDIV_SHIFT));
|
||||||
|
|
||||||
|
if (!rate->dsmpd)
|
||||||
|
{
|
||||||
|
rt_uint32_t val;
|
||||||
|
|
||||||
|
rk_clrsetreg(base + pll->con_offset + 0x4, RK3036_PLLCON1_DSMPD_MASK,
|
||||||
|
rate->dsmpd << RK3036_PLLCON1_DSMPD_SHIFT);
|
||||||
|
|
||||||
|
val = HWREG32(base + pll->con_offset + 0x8) & (~RK3036_PLLCON2_FRAC_MASK);
|
||||||
|
HWREG32(base + pll->con_offset + 0x8) = val | (rate->frac << RK3036_PLLCON2_FRAC_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Power Up */
|
||||||
|
rk_clrreg(base + pll->con_offset + 0x4, 1 << RK3036_PLLCON1_PWRDOWN_SHIT);
|
||||||
|
|
||||||
|
/* Waiting for pll lock */
|
||||||
|
while (!(HWREG32(base + pll->con_offset + 0x4) & (1 << pll->lock_shift)))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift, RKCLK_PLL_MODE_NORMAL << pll->mode_shift);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_ubase_t rk3036_pll_get_rate(struct rk_pll_clock *pll, void *base, rt_ubase_t pll_id)
|
||||||
|
{
|
||||||
|
rt_uint32_t refdiv, fbdiv, postdiv1, postdiv2, dsmpd, frac;
|
||||||
|
rt_uint32_t con = 0, shift, mask;
|
||||||
|
rt_ubase_t rate;
|
||||||
|
|
||||||
|
pll->mode_mask = PLL_MODE_MASK;
|
||||||
|
|
||||||
|
con = HWREG32(base + pll->mode_offset);
|
||||||
|
shift = pll->mode_shift;
|
||||||
|
mask = pll->mode_mask << shift;
|
||||||
|
|
||||||
|
switch ((con & mask) >> shift)
|
||||||
|
{
|
||||||
|
case RKCLK_PLL_MODE_SLOW:
|
||||||
|
return OSC_HZ;
|
||||||
|
case RKCLK_PLL_MODE_NORMAL:
|
||||||
|
/* normal mode */
|
||||||
|
con = HWREG32(base + pll->con_offset);
|
||||||
|
postdiv1 = (con & RK3036_PLLCON0_POSTDIV1_MASK) >> RK3036_PLLCON0_POSTDIV1_SHIFT;
|
||||||
|
fbdiv = (con & RK3036_PLLCON0_FBDIV_MASK) >> RK3036_PLLCON0_FBDIV_SHIFT;
|
||||||
|
con = HWREG32(base + pll->con_offset + 0x4);
|
||||||
|
postdiv2 = (con & RK3036_PLLCON1_POSTDIV2_MASK) >> RK3036_PLLCON1_POSTDIV2_SHIFT;
|
||||||
|
refdiv = (con & RK3036_PLLCON1_REFDIV_MASK) >> RK3036_PLLCON1_REFDIV_SHIFT;
|
||||||
|
dsmpd = (con & RK3036_PLLCON1_DSMPD_MASK) >> RK3036_PLLCON1_DSMPD_SHIFT;
|
||||||
|
con = HWREG32(base + pll->con_offset + 0x8);
|
||||||
|
frac = (con & RK3036_PLLCON2_FRAC_MASK) >> RK3036_PLLCON2_FRAC_SHIFT;
|
||||||
|
rate = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
|
||||||
|
|
||||||
|
if (dsmpd == 0)
|
||||||
|
{
|
||||||
|
rt_uint64_t frac_rate = OSC_HZ * (rt_uint64_t)frac;
|
||||||
|
|
||||||
|
rt_do_div(frac_rate, refdiv);
|
||||||
|
frac_rate >>= 24;
|
||||||
|
rt_do_div(frac_rate, postdiv1);
|
||||||
|
rt_do_div(frac_rate, postdiv1);
|
||||||
|
rate += frac_rate;
|
||||||
|
}
|
||||||
|
return rate;
|
||||||
|
case RKCLK_PLL_MODE_DEEP:
|
||||||
|
default:
|
||||||
|
return 32768;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rk3588_pll_set_rate(struct rk_pll_clock *pll,
|
||||||
|
void *base, rt_ubase_t pll_id,
|
||||||
|
rt_ubase_t drate)
|
||||||
|
{
|
||||||
|
const struct rk_pll_rate_table *rate;
|
||||||
|
|
||||||
|
rate = rk_get_pll_settings(pll, drate);
|
||||||
|
if (!rate)
|
||||||
|
{
|
||||||
|
LOG_D("%s unsupported rate\n", __func__);
|
||||||
|
return -RT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_D("%s: rate settings for %lu p: %d, m: %d, s: %d, k: %d\n",
|
||||||
|
__func__, rate->rate, rate->p, rate->m, rate->s, rate->k);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When power on or changing PLL setting,
|
||||||
|
* we must force PLL into slow mode to ensure output stable clock.
|
||||||
|
*/
|
||||||
|
if (pll_id == 3)
|
||||||
|
rk_clrsetreg(base + 0x84c, 0x1 << 1, 0x1 << 1);
|
||||||
|
|
||||||
|
rk_clrsetreg(base + pll->mode_offset,
|
||||||
|
pll->mode_mask << pll->mode_shift,
|
||||||
|
RKCLK_PLL_MODE_SLOW << pll->mode_shift);
|
||||||
|
if (pll_id == 0)
|
||||||
|
rk_clrsetreg(base + RK3588_B0PLL_CLKSEL_CON(0),
|
||||||
|
pll->mode_mask << 6,
|
||||||
|
RKCLK_PLL_MODE_SLOW << 6);
|
||||||
|
else if (pll_id == 1)
|
||||||
|
rk_clrsetreg(base + RK3588_B1PLL_CLKSEL_CON(0),
|
||||||
|
pll->mode_mask << 6,
|
||||||
|
RKCLK_PLL_MODE_SLOW << 6);
|
||||||
|
else if (pll_id == 2)
|
||||||
|
rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(5),
|
||||||
|
pll->mode_mask << 14,
|
||||||
|
RKCLK_PLL_MODE_SLOW << 14);
|
||||||
|
|
||||||
|
/* Power down */
|
||||||
|
rk_setreg(base + pll->con_offset + RK3588_PLLCON(1),
|
||||||
|
RK3588_PLLCON1_PWRDOWN);
|
||||||
|
|
||||||
|
rk_clrsetreg(base + pll->con_offset,
|
||||||
|
RK3588_PLLCON0_M_MASK,
|
||||||
|
(rate->m << RK3588_PLLCON0_M_SHIFT));
|
||||||
|
rk_clrsetreg(base + pll->con_offset + RK3588_PLLCON(1),
|
||||||
|
(RK3588_PLLCON1_P_MASK |
|
||||||
|
RK3588_PLLCON1_S_MASK),
|
||||||
|
(rate->p << RK3588_PLLCON1_P_SHIFT |
|
||||||
|
rate->s << RK3588_PLLCON1_S_SHIFT));
|
||||||
|
if (rate->k)
|
||||||
|
{
|
||||||
|
rk_clrsetreg(base + pll->con_offset + RK3588_PLLCON(2),
|
||||||
|
RK3588_PLLCON2_K_MASK,
|
||||||
|
rate->k << RK3588_PLLCON2_K_SHIFT);
|
||||||
|
}
|
||||||
|
/* Power up */
|
||||||
|
rk_clrreg(base + pll->con_offset + RK3588_PLLCON(1),
|
||||||
|
RK3588_PLLCON1_PWRDOWN);
|
||||||
|
|
||||||
|
/* waiting for pll lock */
|
||||||
|
while (!(HWREG32(base + pll->con_offset + RK3588_PLLCON(6)) &
|
||||||
|
RK3588_PLLCON6_LOCK_STATUS))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift,
|
||||||
|
RKCLK_PLL_MODE_NORMAL << pll->mode_shift);
|
||||||
|
if (pll_id == 0)
|
||||||
|
{
|
||||||
|
rk_clrsetreg(base + RK3588_B0PLL_CLKSEL_CON(0),
|
||||||
|
pll->mode_mask << 6,
|
||||||
|
2 << 6);
|
||||||
|
rk_clrsetreg(base + RK3588_B0PLL_CLKSEL_CON(0),
|
||||||
|
RK3588_CORE_DIV_MASK << RK3588_CORE_B02_DIV_SHIFT,
|
||||||
|
0 << RK3588_CORE_B02_DIV_SHIFT);
|
||||||
|
rk_clrsetreg(base + RK3588_B0PLL_CLKSEL_CON(1),
|
||||||
|
RK3588_CORE_DIV_MASK << RK3588_CORE_B13_DIV_SHIFT,
|
||||||
|
0 << RK3588_CORE_B13_DIV_SHIFT);
|
||||||
|
} else if (pll_id == 1)
|
||||||
|
{
|
||||||
|
rk_clrsetreg(base + RK3588_B1PLL_CLKSEL_CON(0),
|
||||||
|
pll->mode_mask << 6,
|
||||||
|
2 << 6);
|
||||||
|
rk_clrsetreg(base + RK3588_B1PLL_CLKSEL_CON(0),
|
||||||
|
RK3588_CORE_DIV_MASK << RK3588_CORE_B02_DIV_SHIFT,
|
||||||
|
0 << RK3588_CORE_B02_DIV_SHIFT);
|
||||||
|
rk_clrsetreg(base + RK3588_B1PLL_CLKSEL_CON(1),
|
||||||
|
RK3588_CORE_DIV_MASK << RK3588_CORE_B13_DIV_SHIFT,
|
||||||
|
0 << RK3588_CORE_B13_DIV_SHIFT);
|
||||||
|
} else if (pll_id == 2)
|
||||||
|
{
|
||||||
|
rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(5),
|
||||||
|
pll->mode_mask << 14,
|
||||||
|
2 << 14);
|
||||||
|
rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(6),
|
||||||
|
RK3588_CORE_DIV_MASK << RK3588_CORE_L13_DIV_SHIFT,
|
||||||
|
0 << RK3588_CORE_L13_DIV_SHIFT);
|
||||||
|
rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(6),
|
||||||
|
RK3588_CORE_DIV_MASK << RK3588_CORE_L02_DIV_SHIFT,
|
||||||
|
0 << RK3588_CORE_L02_DIV_SHIFT);
|
||||||
|
rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(7),
|
||||||
|
RK3588_CORE_DIV_MASK << RK3588_CORE_L13_DIV_SHIFT,
|
||||||
|
0 << RK3588_CORE_L13_DIV_SHIFT);
|
||||||
|
rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(7),
|
||||||
|
RK3588_CORE_DIV_MASK << RK3588_CORE_L02_DIV_SHIFT,
|
||||||
|
0 << RK3588_CORE_L02_DIV_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pll_id == 3)
|
||||||
|
rk_clrsetreg(base + 0x84c, 0x1 << 1, 0);
|
||||||
|
|
||||||
|
LOG_D("PLL at %p: con0=%x con1= %x con2= %x mode= %x\n",
|
||||||
|
pll, HWREG32(base + pll->con_offset),
|
||||||
|
HWREG32(base + pll->con_offset + 0x4),
|
||||||
|
HWREG32(base + pll->con_offset + 0x8),
|
||||||
|
HWREG32(base + pll->mode_offset));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_ubase_t rk3588_pll_get_rate(struct rk_pll_clock *pll,
|
||||||
|
void *base, rt_ubase_t pll_id)
|
||||||
|
{
|
||||||
|
rt_uint32_t m, p, s, k;
|
||||||
|
rt_uint32_t con = 0, shift, mode;
|
||||||
|
rt_uint64_t rate, postdiv;
|
||||||
|
|
||||||
|
con = HWREG32(base + pll->mode_offset);
|
||||||
|
shift = pll->mode_shift;
|
||||||
|
if (pll_id == 8)
|
||||||
|
mode = RKCLK_PLL_MODE_NORMAL;
|
||||||
|
else
|
||||||
|
mode = (con & (pll->mode_mask << shift)) >> shift;
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case RKCLK_PLL_MODE_SLOW:
|
||||||
|
return OSC_HZ;
|
||||||
|
case RKCLK_PLL_MODE_NORMAL:
|
||||||
|
/* normal mode */
|
||||||
|
con = HWREG32(base + pll->con_offset);
|
||||||
|
m = (con & RK3588_PLLCON0_M_MASK) >>
|
||||||
|
RK3588_PLLCON0_M_SHIFT;
|
||||||
|
con = HWREG32(base + pll->con_offset + RK3588_PLLCON(1));
|
||||||
|
p = (con & RK3588_PLLCON1_P_MASK) >>
|
||||||
|
RK3036_PLLCON0_FBDIV_SHIFT;
|
||||||
|
s = (con & RK3588_PLLCON1_S_MASK) >>
|
||||||
|
RK3588_PLLCON1_S_SHIFT;
|
||||||
|
con = HWREG32(base + pll->con_offset + RK3588_PLLCON(2));
|
||||||
|
k = (con & RK3588_PLLCON2_K_MASK) >>
|
||||||
|
RK3588_PLLCON2_K_SHIFT;
|
||||||
|
|
||||||
|
rate = OSC_HZ / p;
|
||||||
|
rate *= m;
|
||||||
|
if (k)
|
||||||
|
{
|
||||||
|
/* fractional mode */
|
||||||
|
rt_uint64_t frac_rate64 = OSC_HZ * k;
|
||||||
|
|
||||||
|
postdiv = p * 65536;
|
||||||
|
rt_do_div(frac_rate64, postdiv);
|
||||||
|
rate += frac_rate64;
|
||||||
|
}
|
||||||
|
rate = rate >> s;
|
||||||
|
return rate;
|
||||||
|
case RKCLK_PLL_MODE_DEEP:
|
||||||
|
default:
|
||||||
|
return 32768;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_ubase_t rk_pll_get_rate(struct rk_pll_clock *pll,
|
||||||
|
void *base,
|
||||||
|
rt_ubase_t pll_id)
|
||||||
|
{
|
||||||
|
rt_ubase_t rate = 0;
|
||||||
|
|
||||||
|
switch (pll->type)
|
||||||
|
{
|
||||||
|
case pll_rk3036:
|
||||||
|
pll->mode_mask = PLL_MODE_MASK;
|
||||||
|
rate = rk3036_pll_get_rate(pll, base, pll_id);
|
||||||
|
break;
|
||||||
|
case pll_rk3328:
|
||||||
|
pll->mode_mask = PLL_RK3328_MODE_MASK;
|
||||||
|
rate = rk3036_pll_get_rate(pll, base, pll_id);
|
||||||
|
break;
|
||||||
|
case pll_rk3588:
|
||||||
|
pll->mode_mask = PLL_MODE_MASK;
|
||||||
|
rate = rk3588_pll_get_rate(pll, base, pll_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_D("%s: Unknown pll type for pll clk %ld\n",
|
||||||
|
__func__, pll_id);
|
||||||
|
}
|
||||||
|
return rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rk_pll_set_rate(struct rk_pll_clock *pll,
|
||||||
|
void *base, rt_ubase_t pll_id,
|
||||||
|
rt_ubase_t drate)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (rk_pll_get_rate(pll, base, pll_id) == drate)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (pll->type)
|
||||||
|
{
|
||||||
|
case pll_rk3036:
|
||||||
|
pll->mode_mask = PLL_MODE_MASK;
|
||||||
|
ret = rk3036_pll_set_rate(pll, base, pll_id, drate);
|
||||||
|
break;
|
||||||
|
case pll_rk3328:
|
||||||
|
pll->mode_mask = PLL_RK3328_MODE_MASK;
|
||||||
|
ret = rk3036_pll_set_rate(pll, base, pll_id, drate);
|
||||||
|
break;
|
||||||
|
case pll_rk3588:
|
||||||
|
pll->mode_mask = PLL_MODE_MASK;
|
||||||
|
ret = rk3588_pll_set_rate(pll, base, pll_id, drate);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_D("%s: Unknown pll type for pll clk %ld\n",
|
||||||
|
__func__, pll_id);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct rk_cpu_rate_table *rk_get_cpu_settings(struct rk_cpu_rate_table *cpu_table, rt_ubase_t rate)
|
||||||
|
{
|
||||||
|
struct rk_cpu_rate_table *ps = cpu_table;
|
||||||
|
|
||||||
|
while (ps->rate)
|
||||||
|
{
|
||||||
|
if (ps->rate == rate)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++ps;
|
||||||
|
}
|
||||||
|
if (ps->rate != rate)
|
||||||
|
{
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_base_t rk_clk_pll_round_rate(const struct rk_pll_rate_table *pll_rates,
|
||||||
|
rt_size_t rate_count, rt_ubase_t drate, rt_ubase_t *prate)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Assumming rate_table is in descending order */
|
||||||
|
for (i = 0; i < rate_count; i++)
|
||||||
|
{
|
||||||
|
if (drate >= pll_rates[i].rate)
|
||||||
|
{
|
||||||
|
return pll_rates[i].rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return minimum supported value */
|
||||||
|
return pll_rates[i - 1].rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rk_clk_set_default_rates(struct rt_clk *clk,
|
||||||
|
rt_err_t (*clk_set_rate)(struct rt_clk *, rt_ubase_t, rt_ubase_t), int id)
|
||||||
|
{
|
||||||
|
rt_uint32_t rate;
|
||||||
|
struct rt_ofw_cell_args clk_args;
|
||||||
|
struct rt_ofw_node *np = clk->fw_node;
|
||||||
|
const char *rate_propname = "assigned-clock-rates";
|
||||||
|
|
||||||
|
if (!rt_ofw_prop_read_bool(np, rate_propname))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; ; ++i)
|
||||||
|
{
|
||||||
|
if (rt_ofw_parse_phandle_cells(np, "assigned-clocks", "#clock-cells", i, &clk_args))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_ofw_node_put(clk_args.data);
|
||||||
|
|
||||||
|
if (clk_args.args[0] != id)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rt_ofw_prop_read_u32_index(np, rate_propname, i, &rate))
|
||||||
|
{
|
||||||
|
clk_set_rate(clk, rate, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-3-08 GuEe-GUI the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ROCKCHIP_CLK3568_H__
|
||||||
|
#define __ROCKCHIP_CLK3568_H__
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
#include "reset/reset.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "../rockchip.h"
|
||||||
|
|
||||||
|
#define HZ 100
|
||||||
|
#define KHZ 1000
|
||||||
|
#define MHZ 1000000
|
||||||
|
#define OSC_HZ (24 * MHZ)
|
||||||
|
|
||||||
|
struct rk_cpu_rate_table
|
||||||
|
{
|
||||||
|
rt_ubase_t rate;
|
||||||
|
rt_uint32_t aclk_div;
|
||||||
|
rt_uint32_t pclk_div;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rk_pll_rate_table
|
||||||
|
{
|
||||||
|
rt_ubase_t rate;
|
||||||
|
rt_uint32_t nr;
|
||||||
|
rt_uint32_t nf;
|
||||||
|
rt_uint32_t no;
|
||||||
|
rt_uint32_t nb;
|
||||||
|
|
||||||
|
rt_uint32_t fbdiv;
|
||||||
|
rt_uint32_t postdiv1;
|
||||||
|
rt_uint32_t refdiv;
|
||||||
|
rt_uint32_t postdiv2;
|
||||||
|
rt_uint32_t dsmpd;
|
||||||
|
rt_uint32_t frac;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rk_pll_clock
|
||||||
|
{
|
||||||
|
rt_uint32_t id;
|
||||||
|
rt_uint32_t con_offset;
|
||||||
|
rt_uint32_t mode_offset;
|
||||||
|
rt_uint32_t mode_shift;
|
||||||
|
rt_uint32_t lock_shift;
|
||||||
|
rt_uint32_t pll_flags;
|
||||||
|
struct rk_pll_rate_table *rate_table;
|
||||||
|
rt_uint32_t mode_mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rk_clk_gate
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
const char *parent_name;
|
||||||
|
|
||||||
|
int con_idx;
|
||||||
|
int con_bit;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GATE(_id, _name, \
|
||||||
|
_pname, _con_idx, _con_bit) \
|
||||||
|
[_id] = \
|
||||||
|
{ \
|
||||||
|
.name = _name, \
|
||||||
|
.parent_name = _pname, \
|
||||||
|
.con_idx = _con_idx, \
|
||||||
|
.con_bit = _con_bit, \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define CPUCLK_RATE(_rate, \
|
||||||
|
_aclk_div, _pclk_div) \
|
||||||
|
{ \
|
||||||
|
.rate = _rate##U, \
|
||||||
|
.aclk_div = _aclk_div, \
|
||||||
|
.pclk_div = _pclk_div, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PLL_RATE(_rate, _refdiv, _fbdiv, \
|
||||||
|
_postdiv1, _postdiv2, _dsmpd, _frac) \
|
||||||
|
{ \
|
||||||
|
.rate = _rate##U, \
|
||||||
|
.fbdiv = _fbdiv, \
|
||||||
|
.postdiv1 = _postdiv1, \
|
||||||
|
.refdiv = _refdiv, \
|
||||||
|
.postdiv2 = _postdiv2, \
|
||||||
|
.dsmpd = _dsmpd, \
|
||||||
|
.frac = _frac, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PLL(_id, _con, _mode, _mshift, \
|
||||||
|
_lshift, _pflags, _rtable) \
|
||||||
|
{ \
|
||||||
|
.id = _id, \
|
||||||
|
.con_offset = _con, \
|
||||||
|
.mode_offset = _mode, \
|
||||||
|
.mode_shift = _mshift, \
|
||||||
|
.lock_shift = _lshift, \
|
||||||
|
.pll_flags = _pflags, \
|
||||||
|
.rate_table = _rtable, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
|
||||||
|
|
||||||
|
#define ROCKCHIP_SOFTRST_HIWORD_MASK RT_BIT(0)
|
||||||
|
|
||||||
|
#endif /* __ROCKCHIP_CLK3568_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-3-08 GuEe-GUI the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ROCKCHIP_CLK_H__
|
||||||
|
#define __ROCKCHIP_CLK_H__
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
#include "reset/reset.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "../rockchip.h"
|
||||||
|
|
||||||
|
#define HZ 100
|
||||||
|
#define KHZ 1000
|
||||||
|
#define MHZ 1000000
|
||||||
|
#define OSC_HZ (24 * MHZ)
|
||||||
|
|
||||||
|
struct rk_cpu_rate_table
|
||||||
|
{
|
||||||
|
rt_ubase_t rate;
|
||||||
|
rt_uint32_t aclk_div;
|
||||||
|
rt_uint32_t pclk_div;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rk_pll_rate_table
|
||||||
|
{
|
||||||
|
rt_ubase_t rate;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
/* for RK3066 */
|
||||||
|
rt_uint32_t nr;
|
||||||
|
rt_uint32_t nf;
|
||||||
|
rt_uint32_t no;
|
||||||
|
rt_uint32_t nb;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
/* for RK3036/RK3399 */
|
||||||
|
rt_uint32_t fbdiv;
|
||||||
|
rt_uint32_t postdiv1;
|
||||||
|
rt_uint32_t refdiv;
|
||||||
|
rt_uint32_t postdiv2;
|
||||||
|
rt_uint32_t dsmpd;
|
||||||
|
rt_uint32_t frac;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
/* for RK3588 */
|
||||||
|
rt_uint32_t m;
|
||||||
|
rt_uint32_t p;
|
||||||
|
rt_uint32_t s;
|
||||||
|
rt_uint32_t k;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
enum rk_pll_type {
|
||||||
|
pll_rk3036,
|
||||||
|
pll_rk3066,
|
||||||
|
pll_rk3328,
|
||||||
|
pll_rk3366,
|
||||||
|
pll_rk3399,
|
||||||
|
pll_rk3588,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef rt_uint32_t rk_pll_type_t;
|
||||||
|
|
||||||
|
struct rk_pll_clock
|
||||||
|
{
|
||||||
|
rt_uint32_t id;
|
||||||
|
rt_uint32_t con_offset;
|
||||||
|
rt_uint32_t mode_offset;
|
||||||
|
rt_uint32_t mode_shift;
|
||||||
|
rt_uint32_t lock_shift;
|
||||||
|
rk_pll_type_t type;
|
||||||
|
rt_uint32_t pll_flags;
|
||||||
|
struct rk_pll_rate_table *rate_table;
|
||||||
|
rt_uint32_t mode_mask;
|
||||||
|
};
|
||||||
|
struct rk_clk_gate
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
const char *parent_name;
|
||||||
|
|
||||||
|
int con_idx;
|
||||||
|
int con_bit;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GATE(_id, _name, \
|
||||||
|
_pname, _con_idx, _con_bit) \
|
||||||
|
[_id] = \
|
||||||
|
{ \
|
||||||
|
.name = _name, \
|
||||||
|
.parent_name = _pname, \
|
||||||
|
.con_idx = _con_idx, \
|
||||||
|
.con_bit = _con_bit, \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define CPUCLK_RATE(_rate, \
|
||||||
|
_aclk_div, _pclk_div) \
|
||||||
|
{ \
|
||||||
|
.rate = _rate##U, \
|
||||||
|
.aclk_div = _aclk_div, \
|
||||||
|
.pclk_div = _pclk_div, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, \
|
||||||
|
_postdiv1, _postdiv2, _dsmpd, _frac) \
|
||||||
|
{ \
|
||||||
|
.rate = _rate##U, \
|
||||||
|
.fbdiv = _fbdiv, \
|
||||||
|
.postdiv1 = _postdiv1, \
|
||||||
|
.refdiv = _refdiv, \
|
||||||
|
.postdiv2 = _postdiv2, \
|
||||||
|
.dsmpd = _dsmpd, \
|
||||||
|
.frac = _frac, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RK3588_PLL_RATE(_rate, _p, _m, _s, _k) \
|
||||||
|
{ \
|
||||||
|
.rate = _rate##U, \
|
||||||
|
.p = _p, \
|
||||||
|
.m = _m, \
|
||||||
|
.s = _s, \
|
||||||
|
.k = _k, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PLL(_type, _id, _con, _mode, _mshift, \
|
||||||
|
_lshift, _pflags, _rtable) \
|
||||||
|
{ \
|
||||||
|
.type = _type, \
|
||||||
|
.id = _id, \
|
||||||
|
.con_offset = _con, \
|
||||||
|
.mode_offset = _mode, \
|
||||||
|
.mode_shift = _mshift, \
|
||||||
|
.lock_shift = _lshift, \
|
||||||
|
.pll_flags = _pflags, \
|
||||||
|
.rate_table = _rtable, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
|
||||||
|
|
||||||
|
#define ROCKCHIP_SOFTRST_HIWORD_MASK RT_BIT(0)
|
||||||
|
|
||||||
|
#endif /* __ROCKCHIP_CLK_H__ */
|
|
@ -0,0 +1,926 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DT_BINDINGS_CLK_ROCKCHIP_RK3568_H__
|
||||||
|
#define __DT_BINDINGS_CLK_ROCKCHIP_RK3568_H__
|
||||||
|
|
||||||
|
/* pmucru-clocks indices */
|
||||||
|
|
||||||
|
/* pmucru plls */
|
||||||
|
#define PLL_PPLL 1
|
||||||
|
#define PLL_HPLL 2
|
||||||
|
|
||||||
|
/* pmucru clocks */
|
||||||
|
#define XIN_OSC0_DIV 4
|
||||||
|
#define CLK_RTC_32K 5
|
||||||
|
#define CLK_PMU 6
|
||||||
|
#define CLK_I2C0 7
|
||||||
|
#define CLK_RTC32K_FRAC 8
|
||||||
|
#define CLK_UART0_DIV 9
|
||||||
|
#define CLK_UART0_FRAC 10
|
||||||
|
#define SCLK_UART0 11
|
||||||
|
#define DBCLK_GPIO0 12
|
||||||
|
#define CLK_PWM0 13
|
||||||
|
#define CLK_CAPTURE_PWM0_NDFT 14
|
||||||
|
#define CLK_PMUPVTM 15
|
||||||
|
#define CLK_CORE_PMUPVTM 16
|
||||||
|
#define CLK_REF24M 17
|
||||||
|
#define XIN_OSC0_USBPHY0_G 18
|
||||||
|
#define CLK_USBPHY0_REF 19
|
||||||
|
#define XIN_OSC0_USBPHY1_G 20
|
||||||
|
#define CLK_USBPHY1_REF 21
|
||||||
|
#define XIN_OSC0_MIPIDSIPHY0_G 22
|
||||||
|
#define CLK_MIPIDSIPHY0_REF 23
|
||||||
|
#define XIN_OSC0_MIPIDSIPHY1_G 24
|
||||||
|
#define CLK_MIPIDSIPHY1_REF 25
|
||||||
|
#define CLK_WIFI_DIV 26
|
||||||
|
#define CLK_WIFI_OSC0 27
|
||||||
|
#define CLK_WIFI 28
|
||||||
|
#define CLK_PCIEPHY0_DIV 29
|
||||||
|
#define CLK_PCIEPHY0_OSC0 30
|
||||||
|
#define CLK_PCIEPHY0_REF 31
|
||||||
|
#define CLK_PCIEPHY1_DIV 32
|
||||||
|
#define CLK_PCIEPHY1_OSC0 33
|
||||||
|
#define CLK_PCIEPHY1_REF 34
|
||||||
|
#define CLK_PCIEPHY2_DIV 35
|
||||||
|
#define CLK_PCIEPHY2_OSC0 36
|
||||||
|
#define CLK_PCIEPHY2_REF 37
|
||||||
|
#define CLK_PCIE30PHY_REF_M 38
|
||||||
|
#define CLK_PCIE30PHY_REF_N 39
|
||||||
|
#define CLK_HDMI_REF 40
|
||||||
|
#define XIN_OSC0_EDPPHY_G 41
|
||||||
|
#define PCLK_PDPMU 42
|
||||||
|
#define PCLK_PMU 43
|
||||||
|
#define PCLK_UART0 44
|
||||||
|
#define PCLK_I2C0 45
|
||||||
|
#define PCLK_GPIO0 46
|
||||||
|
#define PCLK_PMUPVTM 47
|
||||||
|
#define PCLK_PWM0 48
|
||||||
|
#define CLK_PDPMU 49
|
||||||
|
#define SCLK_32K_IOE 50
|
||||||
|
|
||||||
|
#define CLKPMU_NR_CLKS (SCLK_32K_IOE + 1)
|
||||||
|
|
||||||
|
/* cru-clocks indices */
|
||||||
|
|
||||||
|
/* cru plls */
|
||||||
|
#define PLL_APLL 1
|
||||||
|
#define PLL_DPLL 2
|
||||||
|
#define PLL_CPLL 3
|
||||||
|
#define PLL_GPLL 4
|
||||||
|
#define PLL_VPLL 5
|
||||||
|
#define PLL_NPLL 6
|
||||||
|
|
||||||
|
/* cru clocks */
|
||||||
|
#define CPLL_333M 9
|
||||||
|
#define ARMCLK 10
|
||||||
|
#define USB480M 11
|
||||||
|
#define ACLK_CORE_NIU2BUS 18
|
||||||
|
#define CLK_CORE_PVTM 19
|
||||||
|
#define CLK_CORE_PVTM_CORE 20
|
||||||
|
#define CLK_CORE_PVTPLL 21
|
||||||
|
#define CLK_GPU_SRC 22
|
||||||
|
#define CLK_GPU_PRE_NDFT 23
|
||||||
|
#define CLK_GPU_PRE_MUX 24
|
||||||
|
#define ACLK_GPU_PRE 25
|
||||||
|
#define PCLK_GPU_PRE 26
|
||||||
|
#define CLK_GPU 27
|
||||||
|
#define CLK_GPU_NP5 28
|
||||||
|
#define PCLK_GPU_PVTM 29
|
||||||
|
#define CLK_GPU_PVTM 30
|
||||||
|
#define CLK_GPU_PVTM_CORE 31
|
||||||
|
#define CLK_GPU_PVTPLL 32
|
||||||
|
#define CLK_NPU_SRC 33
|
||||||
|
#define CLK_NPU_PRE_NDFT 34
|
||||||
|
#define CLK_NPU 35
|
||||||
|
#define CLK_NPU_NP5 36
|
||||||
|
#define HCLK_NPU_PRE 37
|
||||||
|
#define PCLK_NPU_PRE 38
|
||||||
|
#define ACLK_NPU_PRE 39
|
||||||
|
#define ACLK_NPU 40
|
||||||
|
#define HCLK_NPU 41
|
||||||
|
#define PCLK_NPU_PVTM 42
|
||||||
|
#define CLK_NPU_PVTM 43
|
||||||
|
#define CLK_NPU_PVTM_CORE 44
|
||||||
|
#define CLK_NPU_PVTPLL 45
|
||||||
|
#define CLK_DDRPHY1X_SRC 46
|
||||||
|
#define CLK_DDRPHY1X_HWFFC_SRC 47
|
||||||
|
#define CLK_DDR1X 48
|
||||||
|
#define CLK_MSCH 49
|
||||||
|
#define CLK24_DDRMON 50
|
||||||
|
#define ACLK_GIC_AUDIO 51
|
||||||
|
#define HCLK_GIC_AUDIO 52
|
||||||
|
#define HCLK_SDMMC_BUFFER 53
|
||||||
|
#define DCLK_SDMMC_BUFFER 54
|
||||||
|
#define ACLK_GIC600 55
|
||||||
|
#define ACLK_SPINLOCK 56
|
||||||
|
#define HCLK_I2S0_8CH 57
|
||||||
|
#define HCLK_I2S1_8CH 58
|
||||||
|
#define HCLK_I2S2_2CH 59
|
||||||
|
#define HCLK_I2S3_2CH 60
|
||||||
|
#define CLK_I2S0_8CH_TX_SRC 61
|
||||||
|
#define CLK_I2S0_8CH_TX_FRAC 62
|
||||||
|
#define MCLK_I2S0_8CH_TX 63
|
||||||
|
#define I2S0_MCLKOUT_TX 64
|
||||||
|
#define CLK_I2S0_8CH_RX_SRC 65
|
||||||
|
#define CLK_I2S0_8CH_RX_FRAC 66
|
||||||
|
#define MCLK_I2S0_8CH_RX 67
|
||||||
|
#define I2S0_MCLKOUT_RX 68
|
||||||
|
#define CLK_I2S1_8CH_TX_SRC 69
|
||||||
|
#define CLK_I2S1_8CH_TX_FRAC 70
|
||||||
|
#define MCLK_I2S1_8CH_TX 71
|
||||||
|
#define I2S1_MCLKOUT_TX 72
|
||||||
|
#define CLK_I2S1_8CH_RX_SRC 73
|
||||||
|
#define CLK_I2S1_8CH_RX_FRAC 74
|
||||||
|
#define MCLK_I2S1_8CH_RX 75
|
||||||
|
#define I2S1_MCLKOUT_RX 76
|
||||||
|
#define CLK_I2S2_2CH_SRC 77
|
||||||
|
#define CLK_I2S2_2CH_FRAC 78
|
||||||
|
#define MCLK_I2S2_2CH 79
|
||||||
|
#define I2S2_MCLKOUT 80
|
||||||
|
#define CLK_I2S3_2CH_TX_SRC 81
|
||||||
|
#define CLK_I2S3_2CH_TX_FRAC 82
|
||||||
|
#define MCLK_I2S3_2CH_TX 83
|
||||||
|
#define I2S3_MCLKOUT_TX 84
|
||||||
|
#define CLK_I2S3_2CH_RX_SRC 85
|
||||||
|
#define CLK_I2S3_2CH_RX_FRAC 86
|
||||||
|
#define MCLK_I2S3_2CH_RX 87
|
||||||
|
#define I2S3_MCLKOUT_RX 88
|
||||||
|
#define HCLK_PDM 89
|
||||||
|
#define MCLK_PDM 90
|
||||||
|
#define HCLK_VAD 91
|
||||||
|
#define HCLK_SPDIF_8CH 92
|
||||||
|
#define MCLK_SPDIF_8CH_SRC 93
|
||||||
|
#define MCLK_SPDIF_8CH_FRAC 94
|
||||||
|
#define MCLK_SPDIF_8CH 95
|
||||||
|
#define HCLK_AUDPWM 96
|
||||||
|
#define SCLK_AUDPWM_SRC 97
|
||||||
|
#define SCLK_AUDPWM_FRAC 98
|
||||||
|
#define SCLK_AUDPWM 99
|
||||||
|
#define HCLK_ACDCDIG 100
|
||||||
|
#define CLK_ACDCDIG_I2C 101
|
||||||
|
#define CLK_ACDCDIG_DAC 102
|
||||||
|
#define CLK_ACDCDIG_ADC 103
|
||||||
|
#define ACLK_SECURE_FLASH 104
|
||||||
|
#define HCLK_SECURE_FLASH 105
|
||||||
|
#define ACLK_CRYPTO_NS 106
|
||||||
|
#define HCLK_CRYPTO_NS 107
|
||||||
|
#define CLK_CRYPTO_NS_CORE 108
|
||||||
|
#define CLK_CRYPTO_NS_PKA 109
|
||||||
|
#define CLK_CRYPTO_NS_RNG 110
|
||||||
|
#define HCLK_TRNG_NS 111
|
||||||
|
#define CLK_TRNG_NS 112
|
||||||
|
#define PCLK_OTPC_NS 113
|
||||||
|
#define CLK_OTPC_NS_SBPI 114
|
||||||
|
#define CLK_OTPC_NS_USR 115
|
||||||
|
#define HCLK_NANDC 116
|
||||||
|
#define NCLK_NANDC 117
|
||||||
|
#define HCLK_SFC 118
|
||||||
|
#define HCLK_SFC_XIP 119
|
||||||
|
#define SCLK_SFC 120
|
||||||
|
#define ACLK_EMMC 121
|
||||||
|
#define HCLK_EMMC 122
|
||||||
|
#define BCLK_EMMC 123
|
||||||
|
#define CCLK_EMMC 124
|
||||||
|
#define TCLK_EMMC 125
|
||||||
|
#define ACLK_PIPE 126
|
||||||
|
#define PCLK_PIPE 127
|
||||||
|
#define PCLK_PIPE_GRF 128
|
||||||
|
#define ACLK_PCIE20_MST 129
|
||||||
|
#define ACLK_PCIE20_SLV 130
|
||||||
|
#define ACLK_PCIE20_DBI 131
|
||||||
|
#define PCLK_PCIE20 132
|
||||||
|
#define CLK_PCIE20_AUX_NDFT 133
|
||||||
|
#define CLK_PCIE20_AUX_DFT 134
|
||||||
|
#define CLK_PCIE20_PIPE_DFT 135
|
||||||
|
#define ACLK_PCIE30X1_MST 136
|
||||||
|
#define ACLK_PCIE30X1_SLV 137
|
||||||
|
#define ACLK_PCIE30X1_DBI 138
|
||||||
|
#define PCLK_PCIE30X1 139
|
||||||
|
#define CLK_PCIE30X1_AUX_NDFT 140
|
||||||
|
#define CLK_PCIE30X1_AUX_DFT 141
|
||||||
|
#define CLK_PCIE30X1_PIPE_DFT 142
|
||||||
|
#define ACLK_PCIE30X2_MST 143
|
||||||
|
#define ACLK_PCIE30X2_SLV 144
|
||||||
|
#define ACLK_PCIE30X2_DBI 145
|
||||||
|
#define PCLK_PCIE30X2 146
|
||||||
|
#define CLK_PCIE30X2_AUX_NDFT 147
|
||||||
|
#define CLK_PCIE30X2_AUX_DFT 148
|
||||||
|
#define CLK_PCIE30X2_PIPE_DFT 149
|
||||||
|
#define ACLK_SATA0 150
|
||||||
|
#define CLK_SATA0_PMALIVE 151
|
||||||
|
#define CLK_SATA0_RXOOB 152
|
||||||
|
#define CLK_SATA0_PIPE_NDFT 153
|
||||||
|
#define CLK_SATA0_PIPE_DFT 154
|
||||||
|
#define ACLK_SATA1 155
|
||||||
|
#define CLK_SATA1_PMALIVE 156
|
||||||
|
#define CLK_SATA1_RXOOB 157
|
||||||
|
#define CLK_SATA1_PIPE_NDFT 158
|
||||||
|
#define CLK_SATA1_PIPE_DFT 159
|
||||||
|
#define ACLK_SATA2 160
|
||||||
|
#define CLK_SATA2_PMALIVE 161
|
||||||
|
#define CLK_SATA2_RXOOB 162
|
||||||
|
#define CLK_SATA2_PIPE_NDFT 163
|
||||||
|
#define CLK_SATA2_PIPE_DFT 164
|
||||||
|
#define ACLK_USB3OTG0 165
|
||||||
|
#define CLK_USB3OTG0_REF 166
|
||||||
|
#define CLK_USB3OTG0_SUSPEND 167
|
||||||
|
#define ACLK_USB3OTG1 168
|
||||||
|
#define CLK_USB3OTG1_REF 169
|
||||||
|
#define CLK_USB3OTG1_SUSPEND 170
|
||||||
|
#define CLK_XPCS_EEE 171
|
||||||
|
#define PCLK_XPCS 172
|
||||||
|
#define ACLK_PHP 173
|
||||||
|
#define HCLK_PHP 174
|
||||||
|
#define PCLK_PHP 175
|
||||||
|
#define HCLK_SDMMC0 176
|
||||||
|
#define CLK_SDMMC0 177
|
||||||
|
#define HCLK_SDMMC1 178
|
||||||
|
#define CLK_SDMMC1 179
|
||||||
|
#define ACLK_GMAC0 180
|
||||||
|
#define PCLK_GMAC0 181
|
||||||
|
#define CLK_MAC0_2TOP 182
|
||||||
|
#define CLK_MAC0_OUT 183
|
||||||
|
#define CLK_MAC0_REFOUT 184
|
||||||
|
#define CLK_GMAC0_PTP_REF 185
|
||||||
|
#define ACLK_USB 186
|
||||||
|
#define HCLK_USB 187
|
||||||
|
#define PCLK_USB 188
|
||||||
|
#define HCLK_USB2HOST0 189
|
||||||
|
#define HCLK_USB2HOST0_ARB 190
|
||||||
|
#define HCLK_USB2HOST1 191
|
||||||
|
#define HCLK_USB2HOST1_ARB 192
|
||||||
|
#define HCLK_SDMMC2 193
|
||||||
|
#define CLK_SDMMC2 194
|
||||||
|
#define ACLK_GMAC1 195
|
||||||
|
#define PCLK_GMAC1 196
|
||||||
|
#define CLK_MAC1_2TOP 197
|
||||||
|
#define CLK_MAC1_OUT 198
|
||||||
|
#define CLK_MAC1_REFOUT 199
|
||||||
|
#define CLK_GMAC1_PTP_REF 200
|
||||||
|
#define ACLK_PERIMID 201
|
||||||
|
#define HCLK_PERIMID 202
|
||||||
|
#define ACLK_VI 203
|
||||||
|
#define HCLK_VI 204
|
||||||
|
#define PCLK_VI 205
|
||||||
|
#define ACLK_VICAP 206
|
||||||
|
#define HCLK_VICAP 207
|
||||||
|
#define DCLK_VICAP 208
|
||||||
|
#define ICLK_VICAP_G 209
|
||||||
|
#define ACLK_ISP 210
|
||||||
|
#define HCLK_ISP 211
|
||||||
|
#define CLK_ISP 212
|
||||||
|
#define PCLK_CSI2HOST1 213
|
||||||
|
#define CLK_CIF_OUT 214
|
||||||
|
#define CLK_CAM0_OUT 215
|
||||||
|
#define CLK_CAM1_OUT 216
|
||||||
|
#define ACLK_VO 217
|
||||||
|
#define HCLK_VO 218
|
||||||
|
#define PCLK_VO 219
|
||||||
|
#define ACLK_VOP_PRE 220
|
||||||
|
#define ACLK_VOP 221
|
||||||
|
#define HCLK_VOP 222
|
||||||
|
#define DCLK_VOP0 223
|
||||||
|
#define DCLK_VOP1 224
|
||||||
|
#define DCLK_VOP2 225
|
||||||
|
#define CLK_VOP_PWM 226
|
||||||
|
#define ACLK_HDCP 227
|
||||||
|
#define HCLK_HDCP 228
|
||||||
|
#define PCLK_HDCP 229
|
||||||
|
#define PCLK_HDMI_HOST 230
|
||||||
|
#define CLK_HDMI_SFR 231
|
||||||
|
#define PCLK_DSITX_0 232
|
||||||
|
#define PCLK_DSITX_1 233
|
||||||
|
#define PCLK_EDP_CTRL 234
|
||||||
|
#define CLK_EDP_200M 235
|
||||||
|
#define ACLK_VPU_PRE 236
|
||||||
|
#define HCLK_VPU_PRE 237
|
||||||
|
#define ACLK_VPU 238
|
||||||
|
#define HCLK_VPU 239
|
||||||
|
#define ACLK_RGA_PRE 240
|
||||||
|
#define HCLK_RGA_PRE 241
|
||||||
|
#define PCLK_RGA_PRE 242
|
||||||
|
#define ACLK_RGA 243
|
||||||
|
#define HCLK_RGA 244
|
||||||
|
#define CLK_RGA_CORE 245
|
||||||
|
#define ACLK_IEP 246
|
||||||
|
#define HCLK_IEP 247
|
||||||
|
#define CLK_IEP_CORE 248
|
||||||
|
#define HCLK_EBC 249
|
||||||
|
#define DCLK_EBC 250
|
||||||
|
#define ACLK_JDEC 251
|
||||||
|
#define HCLK_JDEC 252
|
||||||
|
#define ACLK_JENC 253
|
||||||
|
#define HCLK_JENC 254
|
||||||
|
#define PCLK_EINK 255
|
||||||
|
#define HCLK_EINK 256
|
||||||
|
#define ACLK_RKVENC_PRE 257
|
||||||
|
#define HCLK_RKVENC_PRE 258
|
||||||
|
#define ACLK_RKVENC 259
|
||||||
|
#define HCLK_RKVENC 260
|
||||||
|
#define CLK_RKVENC_CORE 261
|
||||||
|
#define ACLK_RKVDEC_PRE 262
|
||||||
|
#define HCLK_RKVDEC_PRE 263
|
||||||
|
#define ACLK_RKVDEC 264
|
||||||
|
#define HCLK_RKVDEC 265
|
||||||
|
#define CLK_RKVDEC_CA 266
|
||||||
|
#define CLK_RKVDEC_CORE 267
|
||||||
|
#define CLK_RKVDEC_HEVC_CA 268
|
||||||
|
#define ACLK_BUS 269
|
||||||
|
#define PCLK_BUS 270
|
||||||
|
#define PCLK_TSADC 271
|
||||||
|
#define CLK_TSADC_TSEN 272
|
||||||
|
#define CLK_TSADC 273
|
||||||
|
#define PCLK_SARADC 274
|
||||||
|
#define CLK_SARADC 275
|
||||||
|
#define PCLK_SCR 276
|
||||||
|
#define PCLK_WDT_NS 277
|
||||||
|
#define TCLK_WDT_NS 278
|
||||||
|
#define ACLK_DMAC0 279
|
||||||
|
#define ACLK_DMAC1 280
|
||||||
|
#define ACLK_MCU 281
|
||||||
|
#define PCLK_INTMUX 282
|
||||||
|
#define PCLK_MAILBOX 283
|
||||||
|
#define PCLK_UART1 284
|
||||||
|
#define CLK_UART1_SRC 285
|
||||||
|
#define CLK_UART1_FRAC 286
|
||||||
|
#define SCLK_UART1 287
|
||||||
|
#define PCLK_UART2 288
|
||||||
|
#define CLK_UART2_SRC 289
|
||||||
|
#define CLK_UART2_FRAC 290
|
||||||
|
#define SCLK_UART2 291
|
||||||
|
#define PCLK_UART3 292
|
||||||
|
#define CLK_UART3_SRC 293
|
||||||
|
#define CLK_UART3_FRAC 294
|
||||||
|
#define SCLK_UART3 295
|
||||||
|
#define PCLK_UART4 296
|
||||||
|
#define CLK_UART4_SRC 297
|
||||||
|
#define CLK_UART4_FRAC 298
|
||||||
|
#define SCLK_UART4 299
|
||||||
|
#define PCLK_UART5 300
|
||||||
|
#define CLK_UART5_SRC 301
|
||||||
|
#define CLK_UART5_FRAC 302
|
||||||
|
#define SCLK_UART5 303
|
||||||
|
#define PCLK_UART6 304
|
||||||
|
#define CLK_UART6_SRC 305
|
||||||
|
#define CLK_UART6_FRAC 306
|
||||||
|
#define SCLK_UART6 307
|
||||||
|
#define PCLK_UART7 308
|
||||||
|
#define CLK_UART7_SRC 309
|
||||||
|
#define CLK_UART7_FRAC 310
|
||||||
|
#define SCLK_UART7 311
|
||||||
|
#define PCLK_UART8 312
|
||||||
|
#define CLK_UART8_SRC 313
|
||||||
|
#define CLK_UART8_FRAC 314
|
||||||
|
#define SCLK_UART8 315
|
||||||
|
#define PCLK_UART9 316
|
||||||
|
#define CLK_UART9_SRC 317
|
||||||
|
#define CLK_UART9_FRAC 318
|
||||||
|
#define SCLK_UART9 319
|
||||||
|
#define PCLK_CAN0 320
|
||||||
|
#define CLK_CAN0 321
|
||||||
|
#define PCLK_CAN1 322
|
||||||
|
#define CLK_CAN1 323
|
||||||
|
#define PCLK_CAN2 324
|
||||||
|
#define CLK_CAN2 325
|
||||||
|
#define CLK_I2C 326
|
||||||
|
#define PCLK_I2C1 327
|
||||||
|
#define CLK_I2C1 328
|
||||||
|
#define PCLK_I2C2 329
|
||||||
|
#define CLK_I2C2 330
|
||||||
|
#define PCLK_I2C3 331
|
||||||
|
#define CLK_I2C3 332
|
||||||
|
#define PCLK_I2C4 333
|
||||||
|
#define CLK_I2C4 334
|
||||||
|
#define PCLK_I2C5 335
|
||||||
|
#define CLK_I2C5 336
|
||||||
|
#define PCLK_SPI0 337
|
||||||
|
#define CLK_SPI0 338
|
||||||
|
#define PCLK_SPI1 339
|
||||||
|
#define CLK_SPI1 340
|
||||||
|
#define PCLK_SPI2 341
|
||||||
|
#define CLK_SPI2 342
|
||||||
|
#define PCLK_SPI3 343
|
||||||
|
#define CLK_SPI3 344
|
||||||
|
#define PCLK_PWM1 345
|
||||||
|
#define CLK_PWM1 346
|
||||||
|
#define CLK_PWM1_CAPTURE 347
|
||||||
|
#define PCLK_PWM2 348
|
||||||
|
#define CLK_PWM2 349
|
||||||
|
#define CLK_PWM2_CAPTURE 350
|
||||||
|
#define PCLK_PWM3 351
|
||||||
|
#define CLK_PWM3 352
|
||||||
|
#define CLK_PWM3_CAPTURE 353
|
||||||
|
#define DBCLK_GPIO 354
|
||||||
|
#define PCLK_GPIO1 355
|
||||||
|
#define DBCLK_GPIO1 356
|
||||||
|
#define PCLK_GPIO2 357
|
||||||
|
#define DBCLK_GPIO2 358
|
||||||
|
#define PCLK_GPIO3 359
|
||||||
|
#define DBCLK_GPIO3 360
|
||||||
|
#define PCLK_GPIO4 361
|
||||||
|
#define DBCLK_GPIO4 362
|
||||||
|
#define OCC_SCAN_CLK_GPIO 363
|
||||||
|
#define PCLK_TIMER 364
|
||||||
|
#define CLK_TIMER0 365
|
||||||
|
#define CLK_TIMER1 366
|
||||||
|
#define CLK_TIMER2 367
|
||||||
|
#define CLK_TIMER3 368
|
||||||
|
#define CLK_TIMER4 369
|
||||||
|
#define CLK_TIMER5 370
|
||||||
|
#define ACLK_TOP_HIGH 371
|
||||||
|
#define ACLK_TOP_LOW 372
|
||||||
|
#define HCLK_TOP 373
|
||||||
|
#define PCLK_TOP 374
|
||||||
|
#define PCLK_PCIE30PHY 375
|
||||||
|
#define CLK_OPTC_ARB 376
|
||||||
|
#define PCLK_MIPICSIPHY 377
|
||||||
|
#define PCLK_MIPIDSIPHY0 378
|
||||||
|
#define PCLK_MIPIDSIPHY1 379
|
||||||
|
#define PCLK_PIPEPHY0 380
|
||||||
|
#define PCLK_PIPEPHY1 381
|
||||||
|
#define PCLK_PIPEPHY2 382
|
||||||
|
#define PCLK_CPU_BOOST 383
|
||||||
|
#define CLK_CPU_BOOST 384
|
||||||
|
#define PCLK_OTPPHY 385
|
||||||
|
#define SCLK_GMAC0 386
|
||||||
|
#define SCLK_GMAC0_RGMII_SPEED 387
|
||||||
|
#define SCLK_GMAC0_RMII_SPEED 388
|
||||||
|
#define SCLK_GMAC0_RX_TX 389
|
||||||
|
#define SCLK_GMAC1 390
|
||||||
|
#define SCLK_GMAC1_RGMII_SPEED 391
|
||||||
|
#define SCLK_GMAC1_RMII_SPEED 392
|
||||||
|
#define SCLK_GMAC1_RX_TX 393
|
||||||
|
#define SCLK_SDMMC0_DRV 394
|
||||||
|
#define SCLK_SDMMC0_SAMPLE 395
|
||||||
|
#define SCLK_SDMMC1_DRV 396
|
||||||
|
#define SCLK_SDMMC1_SAMPLE 397
|
||||||
|
#define SCLK_SDMMC2_DRV 398
|
||||||
|
#define SCLK_SDMMC2_SAMPLE 399
|
||||||
|
#define SCLK_EMMC_DRV 400
|
||||||
|
#define SCLK_EMMC_SAMPLE 401
|
||||||
|
#define PCLK_EDPPHY_GRF 402
|
||||||
|
#define CLK_HDMI_CEC 403
|
||||||
|
#define CLK_I2S0_8CH_TX 404
|
||||||
|
#define CLK_I2S0_8CH_RX 405
|
||||||
|
#define CLK_I2S1_8CH_TX 406
|
||||||
|
#define CLK_I2S1_8CH_RX 407
|
||||||
|
#define CLK_I2S2_2CH 408
|
||||||
|
#define CLK_I2S3_2CH_TX 409
|
||||||
|
#define CLK_I2S3_2CH_RX 410
|
||||||
|
#define CPLL_500M 411
|
||||||
|
#define CPLL_250M 412
|
||||||
|
#define CPLL_125M 413
|
||||||
|
#define CPLL_62P5M 414
|
||||||
|
#define CPLL_50M 415
|
||||||
|
#define CPLL_25M 416
|
||||||
|
#define CPLL_100M 417
|
||||||
|
#define SCLK_DDRCLK 418
|
||||||
|
|
||||||
|
#define PCLK_CORE_PVTM 450
|
||||||
|
|
||||||
|
#define CLK_NR_CLKS (PCLK_CORE_PVTM + 1)
|
||||||
|
|
||||||
|
/* pmu soft-reset indices */
|
||||||
|
/* pmucru_softrst_con0 */
|
||||||
|
#define SRST_P_PDPMU_NIU 0
|
||||||
|
#define SRST_P_PMUCRU 1
|
||||||
|
#define SRST_P_PMUGRF 2
|
||||||
|
#define SRST_P_I2C0 3
|
||||||
|
#define SRST_I2C0 4
|
||||||
|
#define SRST_P_UART0 5
|
||||||
|
#define SRST_S_UART0 6
|
||||||
|
#define SRST_P_PWM0 7
|
||||||
|
#define SRST_PWM0 8
|
||||||
|
#define SRST_P_GPIO0 9
|
||||||
|
#define SRST_GPIO0 10
|
||||||
|
#define SRST_P_PMUPVTM 11
|
||||||
|
#define SRST_PMUPVTM 12
|
||||||
|
|
||||||
|
/* soft-reset indices */
|
||||||
|
|
||||||
|
/* cru_softrst_con0 */
|
||||||
|
#define SRST_NCORERESET0 0
|
||||||
|
#define SRST_NCORERESET1 1
|
||||||
|
#define SRST_NCORERESET2 2
|
||||||
|
#define SRST_NCORERESET3 3
|
||||||
|
#define SRST_NCPUPORESET0 4
|
||||||
|
#define SRST_NCPUPORESET1 5
|
||||||
|
#define SRST_NCPUPORESET2 6
|
||||||
|
#define SRST_NCPUPORESET3 7
|
||||||
|
#define SRST_NSRESET 8
|
||||||
|
#define SRST_NSPORESET 9
|
||||||
|
#define SRST_NATRESET 10
|
||||||
|
#define SRST_NGICRESET 11
|
||||||
|
#define SRST_NPRESET 12
|
||||||
|
#define SRST_NPERIPHRESET 13
|
||||||
|
|
||||||
|
/* cru_softrst_con1 */
|
||||||
|
#define SRST_A_CORE_NIU2DDR 16
|
||||||
|
#define SRST_A_CORE_NIU2BUS 17
|
||||||
|
#define SRST_P_DBG_NIU 18
|
||||||
|
#define SRST_P_DBG 19
|
||||||
|
#define SRST_P_DBG_DAPLITE 20
|
||||||
|
#define SRST_DAP 21
|
||||||
|
#define SRST_A_ADB400_CORE2GIC 22
|
||||||
|
#define SRST_A_ADB400_GIC2CORE 23
|
||||||
|
#define SRST_P_CORE_GRF 24
|
||||||
|
#define SRST_P_CORE_PVTM 25
|
||||||
|
#define SRST_CORE_PVTM 26
|
||||||
|
#define SRST_CORE_PVTPLL 27
|
||||||
|
|
||||||
|
/* cru_softrst_con2 */
|
||||||
|
#define SRST_GPU 32
|
||||||
|
#define SRST_A_GPU_NIU 33
|
||||||
|
#define SRST_P_GPU_NIU 34
|
||||||
|
#define SRST_P_GPU_PVTM 35
|
||||||
|
#define SRST_GPU_PVTM 36
|
||||||
|
#define SRST_GPU_PVTPLL 37
|
||||||
|
#define SRST_A_NPU_NIU 40
|
||||||
|
#define SRST_H_NPU_NIU 41
|
||||||
|
#define SRST_P_NPU_NIU 42
|
||||||
|
#define SRST_A_NPU 43
|
||||||
|
#define SRST_H_NPU 44
|
||||||
|
#define SRST_P_NPU_PVTM 45
|
||||||
|
#define SRST_NPU_PVTM 46
|
||||||
|
#define SRST_NPU_PVTPLL 47
|
||||||
|
|
||||||
|
/* cru_softrst_con3 */
|
||||||
|
#define SRST_A_MSCH 51
|
||||||
|
#define SRST_HWFFC_CTRL 52
|
||||||
|
#define SRST_DDR_ALWAYSON 53
|
||||||
|
#define SRST_A_DDRSPLIT 54
|
||||||
|
#define SRST_DDRDFI_CTL 55
|
||||||
|
#define SRST_A_DMA2DDR 57
|
||||||
|
|
||||||
|
/* cru_softrst_con4 */
|
||||||
|
#define SRST_A_PERIMID_NIU 64
|
||||||
|
#define SRST_H_PERIMID_NIU 65
|
||||||
|
#define SRST_A_GIC_AUDIO_NIU 66
|
||||||
|
#define SRST_H_GIC_AUDIO_NIU 67
|
||||||
|
#define SRST_A_GIC600 68
|
||||||
|
#define SRST_A_GIC600_DEBUG 69
|
||||||
|
#define SRST_A_GICADB_CORE2GIC 70
|
||||||
|
#define SRST_A_GICADB_GIC2CORE 71
|
||||||
|
#define SRST_A_SPINLOCK 72
|
||||||
|
#define SRST_H_SDMMC_BUFFER 73
|
||||||
|
#define SRST_D_SDMMC_BUFFER 74
|
||||||
|
#define SRST_H_I2S0_8CH 75
|
||||||
|
#define SRST_H_I2S1_8CH 76
|
||||||
|
#define SRST_H_I2S2_2CH 77
|
||||||
|
#define SRST_H_I2S3_2CH 78
|
||||||
|
|
||||||
|
/* cru_softrst_con5 */
|
||||||
|
#define SRST_M_I2S0_8CH_TX 80
|
||||||
|
#define SRST_M_I2S0_8CH_RX 81
|
||||||
|
#define SRST_M_I2S1_8CH_TX 82
|
||||||
|
#define SRST_M_I2S1_8CH_RX 83
|
||||||
|
#define SRST_M_I2S2_2CH 84
|
||||||
|
#define SRST_M_I2S3_2CH_TX 85
|
||||||
|
#define SRST_M_I2S3_2CH_RX 86
|
||||||
|
#define SRST_H_PDM 87
|
||||||
|
#define SRST_M_PDM 88
|
||||||
|
#define SRST_H_VAD 89
|
||||||
|
#define SRST_H_SPDIF_8CH 90
|
||||||
|
#define SRST_M_SPDIF_8CH 91
|
||||||
|
#define SRST_H_AUDPWM 92
|
||||||
|
#define SRST_S_AUDPWM 93
|
||||||
|
#define SRST_H_ACDCDIG 94
|
||||||
|
#define SRST_ACDCDIG 95
|
||||||
|
|
||||||
|
/* cru_softrst_con6 */
|
||||||
|
#define SRST_A_SECURE_FLASH_NIU 96
|
||||||
|
#define SRST_H_SECURE_FLASH_NIU 97
|
||||||
|
#define SRST_A_CRYPTO_NS 103
|
||||||
|
#define SRST_H_CRYPTO_NS 104
|
||||||
|
#define SRST_CRYPTO_NS_CORE 105
|
||||||
|
#define SRST_CRYPTO_NS_PKA 106
|
||||||
|
#define SRST_CRYPTO_NS_RNG 107
|
||||||
|
#define SRST_H_TRNG_NS 108
|
||||||
|
#define SRST_TRNG_NS 109
|
||||||
|
|
||||||
|
/* cru_softrst_con7 */
|
||||||
|
#define SRST_H_NANDC 112
|
||||||
|
#define SRST_N_NANDC 113
|
||||||
|
#define SRST_H_SFC 114
|
||||||
|
#define SRST_H_SFC_XIP 115
|
||||||
|
#define SRST_S_SFC 116
|
||||||
|
#define SRST_A_EMMC 117
|
||||||
|
#define SRST_H_EMMC 118
|
||||||
|
#define SRST_B_EMMC 119
|
||||||
|
#define SRST_C_EMMC 120
|
||||||
|
#define SRST_T_EMMC 121
|
||||||
|
|
||||||
|
/* cru_softrst_con8 */
|
||||||
|
#define SRST_A_PIPE_NIU 128
|
||||||
|
#define SRST_P_PIPE_NIU 130
|
||||||
|
#define SRST_P_PIPE_GRF 133
|
||||||
|
#define SRST_A_SATA0 134
|
||||||
|
#define SRST_SATA0_PIPE 135
|
||||||
|
#define SRST_SATA0_PMALIVE 136
|
||||||
|
#define SRST_SATA0_RXOOB 137
|
||||||
|
#define SRST_A_SATA1 138
|
||||||
|
#define SRST_SATA1_PIPE 139
|
||||||
|
#define SRST_SATA1_PMALIVE 140
|
||||||
|
#define SRST_SATA1_RXOOB 141
|
||||||
|
|
||||||
|
/* cru_softrst_con9 */
|
||||||
|
#define SRST_A_SATA2 144
|
||||||
|
#define SRST_SATA2_PIPE 145
|
||||||
|
#define SRST_SATA2_PMALIVE 146
|
||||||
|
#define SRST_SATA2_RXOOB 147
|
||||||
|
#define SRST_USB3OTG0 148
|
||||||
|
#define SRST_USB3OTG1 149
|
||||||
|
#define SRST_XPCS 150
|
||||||
|
#define SRST_XPCS_TX_DIV10 151
|
||||||
|
#define SRST_XPCS_RX_DIV10 152
|
||||||
|
#define SRST_XPCS_XGXS_RX 153
|
||||||
|
|
||||||
|
/* cru_softrst_con10 */
|
||||||
|
#define SRST_P_PCIE20 160
|
||||||
|
#define SRST_PCIE20_POWERUP 161
|
||||||
|
#define SRST_MSTR_ARESET_PCIE20 162
|
||||||
|
#define SRST_SLV_ARESET_PCIE20 163
|
||||||
|
#define SRST_DBI_ARESET_PCIE20 164
|
||||||
|
#define SRST_BRESET_PCIE20 165
|
||||||
|
#define SRST_PERST_PCIE20 166
|
||||||
|
#define SRST_CORE_RST_PCIE20 167
|
||||||
|
#define SRST_NSTICKY_RST_PCIE20 168
|
||||||
|
#define SRST_STICKY_RST_PCIE20 169
|
||||||
|
#define SRST_PWR_RST_PCIE20 170
|
||||||
|
|
||||||
|
/* cru_softrst_con11 */
|
||||||
|
#define SRST_P_PCIE30X1 176
|
||||||
|
#define SRST_PCIE30X1_POWERUP 177
|
||||||
|
#define SRST_M_ARESET_PCIE30X1 178
|
||||||
|
#define SRST_S_ARESET_PCIE30X1 179
|
||||||
|
#define SRST_D_ARESET_PCIE30X1 180
|
||||||
|
#define SRST_BRESET_PCIE30X1 181
|
||||||
|
#define SRST_PERST_PCIE30X1 182
|
||||||
|
#define SRST_CORE_RST_PCIE30X1 183
|
||||||
|
#define SRST_NSTC_RST_PCIE30X1 184
|
||||||
|
#define SRST_STC_RST_PCIE30X1 185
|
||||||
|
#define SRST_PWR_RST_PCIE30X1 186
|
||||||
|
|
||||||
|
/* cru_softrst_con12 */
|
||||||
|
#define SRST_P_PCIE30X2 192
|
||||||
|
#define SRST_PCIE30X2_POWERUP 193
|
||||||
|
#define SRST_M_ARESET_PCIE30X2 194
|
||||||
|
#define SRST_S_ARESET_PCIE30X2 195
|
||||||
|
#define SRST_D_ARESET_PCIE30X2 196
|
||||||
|
#define SRST_BRESET_PCIE30X2 197
|
||||||
|
#define SRST_PERST_PCIE30X2 198
|
||||||
|
#define SRST_CORE_RST_PCIE30X2 199
|
||||||
|
#define SRST_NSTC_RST_PCIE30X2 200
|
||||||
|
#define SRST_STC_RST_PCIE30X2 201
|
||||||
|
#define SRST_PWR_RST_PCIE30X2 202
|
||||||
|
|
||||||
|
/* cru_softrst_con13 */
|
||||||
|
#define SRST_A_PHP_NIU 208
|
||||||
|
#define SRST_H_PHP_NIU 209
|
||||||
|
#define SRST_P_PHP_NIU 210
|
||||||
|
#define SRST_H_SDMMC0 211
|
||||||
|
#define SRST_SDMMC0 212
|
||||||
|
#define SRST_H_SDMMC1 213
|
||||||
|
#define SRST_SDMMC1 214
|
||||||
|
#define SRST_A_GMAC0 215
|
||||||
|
#define SRST_GMAC0_TIMESTAMP 216
|
||||||
|
|
||||||
|
/* cru_softrst_con14 */
|
||||||
|
#define SRST_A_USB_NIU 224
|
||||||
|
#define SRST_H_USB_NIU 225
|
||||||
|
#define SRST_P_USB_NIU 226
|
||||||
|
#define SRST_P_USB_GRF 227
|
||||||
|
#define SRST_H_USB2HOST0 228
|
||||||
|
#define SRST_H_USB2HOST0_ARB 229
|
||||||
|
#define SRST_USB2HOST0_UTMI 230
|
||||||
|
#define SRST_H_USB2HOST1 231
|
||||||
|
#define SRST_H_USB2HOST1_ARB 232
|
||||||
|
#define SRST_USB2HOST1_UTMI 233
|
||||||
|
#define SRST_H_SDMMC2 234
|
||||||
|
#define SRST_SDMMC2 235
|
||||||
|
#define SRST_A_GMAC1 236
|
||||||
|
#define SRST_GMAC1_TIMESTAMP 237
|
||||||
|
|
||||||
|
/* cru_softrst_con15 */
|
||||||
|
#define SRST_A_VI_NIU 240
|
||||||
|
#define SRST_H_VI_NIU 241
|
||||||
|
#define SRST_P_VI_NIU 242
|
||||||
|
#define SRST_A_VICAP 247
|
||||||
|
#define SRST_H_VICAP 248
|
||||||
|
#define SRST_D_VICAP 249
|
||||||
|
#define SRST_I_VICAP 250
|
||||||
|
#define SRST_P_VICAP 251
|
||||||
|
#define SRST_H_ISP 252
|
||||||
|
#define SRST_ISP 253
|
||||||
|
#define SRST_P_CSI2HOST1 255
|
||||||
|
|
||||||
|
/* cru_softrst_con16 */
|
||||||
|
#define SRST_A_VO_NIU 256
|
||||||
|
#define SRST_H_VO_NIU 257
|
||||||
|
#define SRST_P_VO_NIU 258
|
||||||
|
#define SRST_A_VOP_NIU 259
|
||||||
|
#define SRST_A_VOP 260
|
||||||
|
#define SRST_H_VOP 261
|
||||||
|
#define SRST_VOP0 262
|
||||||
|
#define SRST_VOP1 263
|
||||||
|
#define SRST_VOP2 264
|
||||||
|
#define SRST_VOP_PWM 265
|
||||||
|
#define SRST_A_HDCP 266
|
||||||
|
#define SRST_H_HDCP 267
|
||||||
|
#define SRST_P_HDCP 268
|
||||||
|
#define SRST_P_HDMI_HOST 270
|
||||||
|
#define SRST_HDMI_HOST 271
|
||||||
|
|
||||||
|
/* cru_softrst_con17 */
|
||||||
|
#define SRST_P_DSITX_0 272
|
||||||
|
#define SRST_P_DSITX_1 273
|
||||||
|
#define SRST_P_EDP_CTRL 274
|
||||||
|
#define SRST_EDP_24M 275
|
||||||
|
#define SRST_A_VPU_NIU 280
|
||||||
|
#define SRST_H_VPU_NIU 281
|
||||||
|
#define SRST_A_VPU 282
|
||||||
|
#define SRST_H_VPU 283
|
||||||
|
#define SRST_H_EINK 286
|
||||||
|
#define SRST_P_EINK 287
|
||||||
|
|
||||||
|
/* cru_softrst_con18 */
|
||||||
|
#define SRST_A_RGA_NIU 288
|
||||||
|
#define SRST_H_RGA_NIU 289
|
||||||
|
#define SRST_P_RGA_NIU 290
|
||||||
|
#define SRST_A_RGA 292
|
||||||
|
#define SRST_H_RGA 293
|
||||||
|
#define SRST_RGA_CORE 294
|
||||||
|
#define SRST_A_IEP 295
|
||||||
|
#define SRST_H_IEP 296
|
||||||
|
#define SRST_IEP_CORE 297
|
||||||
|
#define SRST_H_EBC 298
|
||||||
|
#define SRST_D_EBC 299
|
||||||
|
#define SRST_A_JDEC 300
|
||||||
|
#define SRST_H_JDEC 301
|
||||||
|
#define SRST_A_JENC 302
|
||||||
|
#define SRST_H_JENC 303
|
||||||
|
|
||||||
|
/* cru_softrst_con19 */
|
||||||
|
#define SRST_A_VENC_NIU 304
|
||||||
|
#define SRST_H_VENC_NIU 305
|
||||||
|
#define SRST_A_RKVENC 307
|
||||||
|
#define SRST_H_RKVENC 308
|
||||||
|
#define SRST_RKVENC_CORE 309
|
||||||
|
|
||||||
|
/* cru_softrst_con20 */
|
||||||
|
#define SRST_A_RKVDEC_NIU 320
|
||||||
|
#define SRST_H_RKVDEC_NIU 321
|
||||||
|
#define SRST_A_RKVDEC 322
|
||||||
|
#define SRST_H_RKVDEC 323
|
||||||
|
#define SRST_RKVDEC_CA 324
|
||||||
|
#define SRST_RKVDEC_CORE 325
|
||||||
|
#define SRST_RKVDEC_HEVC_CA 326
|
||||||
|
|
||||||
|
/* cru_softrst_con21 */
|
||||||
|
#define SRST_A_BUS_NIU 336
|
||||||
|
#define SRST_P_BUS_NIU 338
|
||||||
|
#define SRST_P_CAN0 340
|
||||||
|
#define SRST_CAN0 341
|
||||||
|
#define SRST_P_CAN1 342
|
||||||
|
#define SRST_CAN1 343
|
||||||
|
#define SRST_P_CAN2 344
|
||||||
|
#define SRST_CAN2 345
|
||||||
|
#define SRST_P_GPIO1 346
|
||||||
|
#define SRST_GPIO1 347
|
||||||
|
#define SRST_P_GPIO2 348
|
||||||
|
#define SRST_GPIO2 349
|
||||||
|
#define SRST_P_GPIO3 350
|
||||||
|
#define SRST_GPIO3 351
|
||||||
|
|
||||||
|
/* cru_softrst_con22 */
|
||||||
|
#define SRST_P_GPIO4 352
|
||||||
|
#define SRST_GPIO4 353
|
||||||
|
#define SRST_P_I2C1 354
|
||||||
|
#define SRST_I2C1 355
|
||||||
|
#define SRST_P_I2C2 356
|
||||||
|
#define SRST_I2C2 357
|
||||||
|
#define SRST_P_I2C3 358
|
||||||
|
#define SRST_I2C3 359
|
||||||
|
#define SRST_P_I2C4 360
|
||||||
|
#define SRST_I2C4 361
|
||||||
|
#define SRST_P_I2C5 362
|
||||||
|
#define SRST_I2C5 363
|
||||||
|
#define SRST_P_OTPC_NS 364
|
||||||
|
#define SRST_OTPC_NS_SBPI 365
|
||||||
|
#define SRST_OTPC_NS_USR 366
|
||||||
|
|
||||||
|
/* cru_softrst_con23 */
|
||||||
|
#define SRST_P_PWM1 368
|
||||||
|
#define SRST_PWM1 369
|
||||||
|
#define SRST_P_PWM2 370
|
||||||
|
#define SRST_PWM2 371
|
||||||
|
#define SRST_P_PWM3 372
|
||||||
|
#define SRST_PWM3 373
|
||||||
|
#define SRST_P_SPI0 374
|
||||||
|
#define SRST_SPI0 375
|
||||||
|
#define SRST_P_SPI1 376
|
||||||
|
#define SRST_SPI1 377
|
||||||
|
#define SRST_P_SPI2 378
|
||||||
|
#define SRST_SPI2 379
|
||||||
|
#define SRST_P_SPI3 380
|
||||||
|
#define SRST_SPI3 381
|
||||||
|
|
||||||
|
/* cru_softrst_con24 */
|
||||||
|
#define SRST_P_SARADC 384
|
||||||
|
#define SRST_P_TSADC 385
|
||||||
|
#define SRST_TSADC 386
|
||||||
|
#define SRST_P_TIMER 387
|
||||||
|
#define SRST_TIMER0 388
|
||||||
|
#define SRST_TIMER1 389
|
||||||
|
#define SRST_TIMER2 390
|
||||||
|
#define SRST_TIMER3 391
|
||||||
|
#define SRST_TIMER4 392
|
||||||
|
#define SRST_TIMER5 393
|
||||||
|
#define SRST_P_UART1 394
|
||||||
|
#define SRST_S_UART1 395
|
||||||
|
|
||||||
|
/* cru_softrst_con25 */
|
||||||
|
#define SRST_P_UART2 400
|
||||||
|
#define SRST_S_UART2 401
|
||||||
|
#define SRST_P_UART3 402
|
||||||
|
#define SRST_S_UART3 403
|
||||||
|
#define SRST_P_UART4 404
|
||||||
|
#define SRST_S_UART4 405
|
||||||
|
#define SRST_P_UART5 406
|
||||||
|
#define SRST_S_UART5 407
|
||||||
|
#define SRST_P_UART6 408
|
||||||
|
#define SRST_S_UART6 409
|
||||||
|
#define SRST_P_UART7 410
|
||||||
|
#define SRST_S_UART7 411
|
||||||
|
#define SRST_P_UART8 412
|
||||||
|
#define SRST_S_UART8 413
|
||||||
|
#define SRST_P_UART9 414
|
||||||
|
#define SRST_S_UART9 415
|
||||||
|
|
||||||
|
/* cru_softrst_con26 */
|
||||||
|
#define SRST_P_GRF 416
|
||||||
|
#define SRST_P_GRF_VCCIO12 417
|
||||||
|
#define SRST_P_GRF_VCCIO34 418
|
||||||
|
#define SRST_P_GRF_VCCIO567 419
|
||||||
|
#define SRST_P_SCR 420
|
||||||
|
#define SRST_P_WDT_NS 421
|
||||||
|
#define SRST_T_WDT_NS 422
|
||||||
|
#define SRST_P_DFT2APB 423
|
||||||
|
#define SRST_A_MCU 426
|
||||||
|
#define SRST_P_INTMUX 427
|
||||||
|
#define SRST_P_MAILBOX 428
|
||||||
|
|
||||||
|
/* cru_softrst_con27 */
|
||||||
|
#define SRST_A_TOP_HIGH_NIU 432
|
||||||
|
#define SRST_A_TOP_LOW_NIU 433
|
||||||
|
#define SRST_H_TOP_NIU 434
|
||||||
|
#define SRST_P_TOP_NIU 435
|
||||||
|
#define SRST_P_TOP_CRU 438
|
||||||
|
#define SRST_P_DDRPHY 439
|
||||||
|
#define SRST_DDRPHY 440
|
||||||
|
#define SRST_P_MIPICSIPHY 442
|
||||||
|
#define SRST_P_MIPIDSIPHY0 443
|
||||||
|
#define SRST_P_MIPIDSIPHY1 444
|
||||||
|
#define SRST_P_PCIE30PHY 445
|
||||||
|
#define SRST_PCIE30PHY 446
|
||||||
|
#define SRST_P_PCIE30PHY_GRF 447
|
||||||
|
|
||||||
|
/* cru_softrst_con28 */
|
||||||
|
#define SRST_P_APB2ASB_LEFT 448
|
||||||
|
#define SRST_P_APB2ASB_BOTTOM 449
|
||||||
|
#define SRST_P_ASB2APB_LEFT 450
|
||||||
|
#define SRST_P_ASB2APB_BOTTOM 451
|
||||||
|
#define SRST_P_PIPEPHY0 452
|
||||||
|
#define SRST_PIPEPHY0 453
|
||||||
|
#define SRST_P_PIPEPHY1 454
|
||||||
|
#define SRST_PIPEPHY1 455
|
||||||
|
#define SRST_P_PIPEPHY2 456
|
||||||
|
#define SRST_PIPEPHY2 457
|
||||||
|
#define SRST_P_USB2PHY0_GRF 458
|
||||||
|
#define SRST_P_USB2PHY1_GRF 459
|
||||||
|
#define SRST_P_CPU_BOOST 460
|
||||||
|
#define SRST_CPU_BOOST 461
|
||||||
|
#define SRST_P_OTPPHY 462
|
||||||
|
#define SRST_OTPPHY 463
|
||||||
|
|
||||||
|
/* cru_softrst_con29 */
|
||||||
|
#define SRST_USB2PHY0_POR 464
|
||||||
|
#define SRST_USB2PHY0_USB3OTG0 465
|
||||||
|
#define SRST_USB2PHY0_USB3OTG1 466
|
||||||
|
#define SRST_USB2PHY1_POR 467
|
||||||
|
#define SRST_USB2PHY1_USB2HOST0 468
|
||||||
|
#define SRST_USB2PHY1_USB2HOST1 469
|
||||||
|
#define SRST_P_EDPPHY_GRF 470
|
||||||
|
#define SRST_TSADCPHY 471
|
||||||
|
#define SRST_GMAC0_DELAYLINE 472
|
||||||
|
#define SRST_GMAC1_DELAYLINE 473
|
||||||
|
#define SRST_OTPC_ARB 474
|
||||||
|
#define SRST_P_PIPEPHY0_GRF 475
|
||||||
|
#define SRST_P_PIPEPHY1_GRF 476
|
||||||
|
#define SRST_P_PIPEPHY2_GRF 477
|
||||||
|
|
||||||
|
#endif /* __DT_BINDINGS_CLK_ROCKCHIP_RK3568_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-11-26 GuEe-GUI first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct rockchip_softrst
|
||||||
|
{
|
||||||
|
void *regs;
|
||||||
|
int num_per_reg;
|
||||||
|
rt_uint8_t flags;
|
||||||
|
|
||||||
|
struct rt_spinlock lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
static rt_err_t rockchip_softrst_assert(struct rt_reset_control *rstc)
|
||||||
|
{
|
||||||
|
int bank, offset;
|
||||||
|
struct rockchip_softrst *softrst = rstc->rstcer->priv;
|
||||||
|
|
||||||
|
bank = rstc->id / softrst->num_per_reg;
|
||||||
|
offset = rstc->id % softrst->num_per_reg;
|
||||||
|
|
||||||
|
if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK)
|
||||||
|
{
|
||||||
|
HWREG32(softrst->regs + (bank * 4)) = RT_BIT(offset) | (RT_BIT(offset) << 16);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_uint32_t reg;
|
||||||
|
rt_ubase_t level;
|
||||||
|
|
||||||
|
level = rt_spin_lock_irqsave(&softrst->lock);
|
||||||
|
|
||||||
|
reg = HWREG32(softrst->regs + (bank * 4));
|
||||||
|
HWREG32(softrst->regs + (bank * 4)) = reg | RT_BIT(offset);
|
||||||
|
|
||||||
|
rt_spin_unlock_irqrestore(&softrst->lock, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rockchip_softrst_deassert(struct rt_reset_control *rstc)
|
||||||
|
{
|
||||||
|
int bank, offset;
|
||||||
|
struct rockchip_softrst *softrst = rstc->rstcer->priv;
|
||||||
|
|
||||||
|
bank = rstc->id / softrst->num_per_reg;
|
||||||
|
offset = rstc->id % softrst->num_per_reg;
|
||||||
|
|
||||||
|
if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK)
|
||||||
|
{
|
||||||
|
HWREG32(softrst->regs + (bank * 4)) = (RT_BIT(offset) << 16);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_uint32_t reg;
|
||||||
|
rt_ubase_t level;
|
||||||
|
|
||||||
|
level = rt_spin_lock_irqsave(&softrst->lock);
|
||||||
|
|
||||||
|
reg = HWREG32(softrst->regs + (bank * 4));
|
||||||
|
HWREG32(softrst->regs + (bank * 4)) = reg & ~RT_BIT(offset);
|
||||||
|
|
||||||
|
rt_spin_unlock_irqrestore(&softrst->lock, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct rt_reset_control_ops rockchip_softrst_ops =
|
||||||
|
{
|
||||||
|
.assert = rockchip_softrst_assert,
|
||||||
|
.deassert = rockchip_softrst_deassert,
|
||||||
|
};
|
||||||
|
|
||||||
|
static rt_err_t rk_register_softrst(struct rt_reset_controller *rstcer,
|
||||||
|
struct rt_ofw_node *np, void *regs, rt_uint8_t flags)
|
||||||
|
{
|
||||||
|
rt_err_t err;
|
||||||
|
struct rockchip_softrst *softrst = rt_calloc(1, sizeof(*softrst));
|
||||||
|
|
||||||
|
if (!softrst)
|
||||||
|
{
|
||||||
|
return -RT_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
rstcer->priv = softrst;
|
||||||
|
|
||||||
|
rt_spin_lock_init(&softrst->lock);
|
||||||
|
|
||||||
|
softrst->regs = regs;
|
||||||
|
softrst->flags = flags;
|
||||||
|
softrst->num_per_reg = (flags & ROCKCHIP_SOFTRST_HIWORD_MASK) ? 16 : 32;
|
||||||
|
|
||||||
|
rstcer->ofw_node = np;
|
||||||
|
rstcer->ops = &rockchip_softrst_ops;
|
||||||
|
|
||||||
|
if ((err = rt_reset_controller_register(rstcer)))
|
||||||
|
{
|
||||||
|
rt_free(softrst);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
config RT_HWTIMER_ROCKCHIP
|
||||||
|
bool "RockChip Timer"
|
||||||
|
depends on RT_USING_DM
|
||||||
|
depends on RT_USING_HWTIMER
|
||||||
|
default n
|
|
@ -0,0 +1,13 @@
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
src = []
|
||||||
|
|
||||||
|
if GetDepend(['RT_HWTIMER_ROCKCHIP']):
|
||||||
|
src += ['hwtimer-rockchip_timer.c']
|
||||||
|
|
||||||
|
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
Return('group')
|
|
@ -0,0 +1,393 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-12-06 GuEe-GUI first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DBG_TAG "drv.rk_timer"
|
||||||
|
#define DBG_LVL DBG_INFO
|
||||||
|
#include <rtdbg.h>
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
|
||||||
|
#ifdef RT_USING_KTIME
|
||||||
|
#include <ktime.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HZ 100
|
||||||
|
#define KHZ 1000
|
||||||
|
#define MHZ 1000000
|
||||||
|
#define OSC_HZ (24 * MHZ)
|
||||||
|
|
||||||
|
#define TIMER_LOAD_COUNT0 0x00
|
||||||
|
#define TIMER_LOAD_COUNT1 0x04
|
||||||
|
#define TIMER_CURRENT_VALUE0 0x08
|
||||||
|
#define TIMER_CURRENT_VALUE1 0x0c
|
||||||
|
#define TIMER_CONTROL_REG3288 0x10
|
||||||
|
#define TIMER_CONTROL_REG3399 0x1c
|
||||||
|
#define TIMER_INT_STATUS 0x18
|
||||||
|
|
||||||
|
#define TIMER_DISABLE 0x0
|
||||||
|
#define TIMER_ENABLE 0x1
|
||||||
|
#define TIMER_MODE_FREE_RUNNING (0 << 1)
|
||||||
|
#define TIMER_MODE_USER_DEFINED_COUNT (1 << 1)
|
||||||
|
#define TIMER_INT_UNMASK (1 << 2)
|
||||||
|
|
||||||
|
struct rk_timer
|
||||||
|
{
|
||||||
|
struct rt_hwtimer_device parent;
|
||||||
|
|
||||||
|
void *base;
|
||||||
|
void *ctrl;
|
||||||
|
struct rt_clk *clk;
|
||||||
|
struct rt_clk *pclk;
|
||||||
|
|
||||||
|
int irq;
|
||||||
|
rt_uint32_t freq;
|
||||||
|
rt_uint32_t cycle;
|
||||||
|
rt_bool_t status;
|
||||||
|
|
||||||
|
struct rt_hwtimer_info info;
|
||||||
|
};
|
||||||
|
#ifdef RT_USING_KTIME
|
||||||
|
struct hrt_timer
|
||||||
|
{
|
||||||
|
struct rk_timer *timer;
|
||||||
|
uint64_t cnt;
|
||||||
|
void (*outcb)(void *param);
|
||||||
|
void *param;
|
||||||
|
};
|
||||||
|
static struct hrt_timer _timer0 = {0};
|
||||||
|
static struct rt_spinlock _spinlock;
|
||||||
|
#endif
|
||||||
|
#define raw_to_rk_timer(raw) rt_container_of(raw, struct rk_timer, parent)
|
||||||
|
|
||||||
|
struct rk_timer_data
|
||||||
|
{
|
||||||
|
rt_uint32_t ctrl_reg;
|
||||||
|
};
|
||||||
|
|
||||||
|
rt_inline void rk_timer_disable(struct rk_timer *timer)
|
||||||
|
{
|
||||||
|
HWREG32(timer->ctrl) = TIMER_DISABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline void rk_timer_enable(struct rk_timer *timer, rt_uint32_t flags)
|
||||||
|
{
|
||||||
|
HWREG32(timer->ctrl) = TIMER_ENABLE | flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline rt_uint32_t rk_timer_current_value(struct rk_timer *timer)
|
||||||
|
{
|
||||||
|
return HWREG32(timer->base + TIMER_CURRENT_VALUE0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rk_timer_update_counter(unsigned long cycles, struct rk_timer *timer)
|
||||||
|
{
|
||||||
|
HWREG32(timer->base + TIMER_LOAD_COUNT0) = cycles;
|
||||||
|
HWREG32(timer->base + TIMER_LOAD_COUNT1) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rk_timer_interrupt_clear(struct rk_timer *timer)
|
||||||
|
{
|
||||||
|
HWREG32(timer->base + TIMER_INT_STATUS) = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rk_timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rk_timer_start(struct rt_hwtimer_device *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
|
||||||
|
{
|
||||||
|
rt_err_t err = RT_EOK;
|
||||||
|
struct rk_timer *rk_timer = raw_to_rk_timer(timer);
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case HWTIMER_MODE_ONESHOT:
|
||||||
|
rk_timer_disable(rk_timer);
|
||||||
|
rk_timer_update_counter(cnt, rk_timer);
|
||||||
|
rk_timer_enable(rk_timer, TIMER_MODE_USER_DEFINED_COUNT | TIMER_INT_UNMASK);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HWTIMER_MODE_PERIOD:
|
||||||
|
rk_timer_disable(rk_timer);
|
||||||
|
rk_timer_update_counter(rk_timer->freq / HZ - 1, rk_timer);
|
||||||
|
rk_timer_enable(rk_timer, TIMER_MODE_FREE_RUNNING | TIMER_INT_UNMASK);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
err = -RT_EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
rk_timer->cycle = cnt;
|
||||||
|
rk_timer->status = RT_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rk_timer_stop(struct rt_hwtimer_device *timer)
|
||||||
|
{
|
||||||
|
struct rk_timer *rk_timer = raw_to_rk_timer(timer);
|
||||||
|
|
||||||
|
rk_timer->status = RT_FALSE;
|
||||||
|
rk_timer_disable(rk_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_uint32_t rk_timer_count_get(struct rt_hwtimer_device *timer)
|
||||||
|
{
|
||||||
|
struct rk_timer *rk_timer = raw_to_rk_timer(timer);
|
||||||
|
|
||||||
|
return rk_timer_current_value(rk_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rk_timer_ctrl(struct rt_hwtimer_device *timer, rt_uint32_t cmd, void *args)
|
||||||
|
{
|
||||||
|
rt_err_t err = RT_EOK;
|
||||||
|
struct rk_timer *rk_timer = raw_to_rk_timer(timer);
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case HWTIMER_CTRL_FREQ_SET:
|
||||||
|
err = -RT_ENOSYS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HWTIMER_CTRL_STOP:
|
||||||
|
rk_timer_stop(timer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HWTIMER_CTRL_INFO_GET:
|
||||||
|
if (args)
|
||||||
|
{
|
||||||
|
rt_memcpy(args, &rk_timer->info, sizeof(rk_timer->info));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = -RT_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HWTIMER_CTRL_MODE_SET:
|
||||||
|
err = rk_timer_start(timer, rk_timer->cycle, (rt_hwtimer_mode_t)args);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
err = -RT_EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
const static struct rt_hwtimer_ops rk_timer_ops =
|
||||||
|
{
|
||||||
|
.init = rk_timer_init,
|
||||||
|
.start = rk_timer_start,
|
||||||
|
.stop = rk_timer_stop,
|
||||||
|
.count_get = rk_timer_count_get,
|
||||||
|
.control = rk_timer_ctrl,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void rk_timer_isr(int irqno, void *param)
|
||||||
|
{
|
||||||
|
struct hrt_timer *timer = &_timer0;
|
||||||
|
struct rk_timer *time = timer->timer;
|
||||||
|
|
||||||
|
rk_timer_interrupt_clear(time);
|
||||||
|
|
||||||
|
rt_ktime_hrtimer_process();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_ktime_hrtimer_bind(rt_bitmap_t *affinity)
|
||||||
|
{
|
||||||
|
struct rk_timer *timer = _timer0.timer;
|
||||||
|
|
||||||
|
if (rt_pic_irq_set_affinity(timer->irq, affinity) == -RT_ENOSYS)
|
||||||
|
{
|
||||||
|
LOG_E("timer irq affinity init fail\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_D("timer irq(%d) binding done\n", timer->irq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rk_timer_probe(struct rt_platform_device *pdev)
|
||||||
|
{
|
||||||
|
rt_err_t err = RT_EOK;
|
||||||
|
const char *dev_name;
|
||||||
|
struct rt_device *dev = &pdev->parent;
|
||||||
|
struct rk_timer *timer = rt_calloc(1, sizeof(*timer));
|
||||||
|
const struct rk_timer_data *timer_data = pdev->id->data;
|
||||||
|
if (!timer)
|
||||||
|
{
|
||||||
|
return -RT_ENOMEM;
|
||||||
|
}
|
||||||
|
#ifdef RT_USING_KTIME
|
||||||
|
_timer0.timer = timer;
|
||||||
|
rt_spin_lock_init(&_spinlock);
|
||||||
|
#endif
|
||||||
|
if (!(timer->pclk = rt_clk_get_by_name(dev, "pclk")))
|
||||||
|
{
|
||||||
|
err = -RT_EIO;
|
||||||
|
|
||||||
|
goto _fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(timer->clk = rt_clk_get_by_name(dev, "timer")))
|
||||||
|
{
|
||||||
|
err = -RT_EIO;
|
||||||
|
|
||||||
|
goto _fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->base = rt_dm_dev_iomap(dev, 0);
|
||||||
|
|
||||||
|
if (!timer->base)
|
||||||
|
{
|
||||||
|
err = -RT_EIO;
|
||||||
|
|
||||||
|
goto _fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->ctrl = timer->base + timer_data->ctrl_reg;
|
||||||
|
|
||||||
|
rt_clk_enable(timer->pclk);
|
||||||
|
rt_clk_enable(timer->clk);
|
||||||
|
timer->freq = rt_clk_get_rate(timer->clk);
|
||||||
|
timer->irq = rt_dm_dev_get_irq(dev, 0);
|
||||||
|
|
||||||
|
rk_timer_interrupt_clear(timer);
|
||||||
|
rk_timer_disable(timer);
|
||||||
|
|
||||||
|
timer->parent.ops = &rk_timer_ops;
|
||||||
|
timer->parent.info = &timer->info;
|
||||||
|
|
||||||
|
timer->info.maxfreq = timer->freq;
|
||||||
|
timer->info.minfreq = timer->freq;
|
||||||
|
timer->info.maxcnt = 0xffffffff;
|
||||||
|
timer->info.cntmode = HWTIMER_CNTMODE_DW;
|
||||||
|
|
||||||
|
rt_dm_dev_set_name_auto(&timer->parent.parent, "timer");
|
||||||
|
dev_name = rt_dm_dev_get_name(&timer->parent.parent);
|
||||||
|
|
||||||
|
rt_device_hwtimer_register(&timer->parent, dev_name, RT_NULL);
|
||||||
|
|
||||||
|
RT_BITMAP_DECLARE(affinity, RT_CPUS_NR) = { 0 };
|
||||||
|
rt_bitmap_set_bit(affinity, RT_CPUS_NR - 1);
|
||||||
|
rt_ktime_hrtimer_bind(affinity);
|
||||||
|
|
||||||
|
rt_pic_attach_irq(timer->irq, rk_timer_isr, timer, dev_name, RT_IRQ_F_NONE);
|
||||||
|
rt_pic_irq_unmask(timer->irq);
|
||||||
|
|
||||||
|
#if KTIMER_BIND_CPU
|
||||||
|
RT_BITMAP_DECLARE(affinity, RT_CPUS_NR) = {0};
|
||||||
|
rt_bitmap_set_bit(affinity, 1);
|
||||||
|
rt_pic_irq_set_affinity(timer->irq, affinity);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return err;
|
||||||
|
|
||||||
|
_fail:
|
||||||
|
if (timer->base)
|
||||||
|
{
|
||||||
|
rt_iounmap(timer->base);
|
||||||
|
}
|
||||||
|
if (timer->pclk)
|
||||||
|
{
|
||||||
|
rt_clk_put(timer->pclk);
|
||||||
|
}
|
||||||
|
if (timer->clk)
|
||||||
|
{
|
||||||
|
rt_clk_put(timer->clk);
|
||||||
|
}
|
||||||
|
rt_free(timer);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct rk_timer_data rk3288_timer_data =
|
||||||
|
{
|
||||||
|
.ctrl_reg = TIMER_CONTROL_REG3288,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rk_timer_data rk3399_timer_data =
|
||||||
|
{
|
||||||
|
.ctrl_reg = TIMER_CONTROL_REG3399,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef RT_USING_KTIME
|
||||||
|
|
||||||
|
uint64_t rt_ktime_hrtimer_getfrq(void)
|
||||||
|
{
|
||||||
|
return (24 * 1000 * 1000UL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t rt_ktime_hrtimer_getres(void)
|
||||||
|
{
|
||||||
|
return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / (24 * 1000 * 1000UL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t rt_ktime_hrtimer_getcnt(void)
|
||||||
|
{
|
||||||
|
return rk_timer_current_value(_timer0.timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief set the timeout function for hrtimer framework
|
||||||
|
*
|
||||||
|
* @warning application should not call this API directly
|
||||||
|
*
|
||||||
|
* @param cnt the count of timer dealy
|
||||||
|
* @return rt_err_t 0 forever
|
||||||
|
*/
|
||||||
|
rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt)
|
||||||
|
{
|
||||||
|
struct hrt_timer *timer = &_timer0;
|
||||||
|
struct rk_timer *time = timer->timer;
|
||||||
|
|
||||||
|
timer->cnt = cnt;
|
||||||
|
|
||||||
|
if (cnt)
|
||||||
|
{
|
||||||
|
rk_timer_disable(time);
|
||||||
|
rk_timer_update_counter(cnt, time);
|
||||||
|
rk_timer_enable(time, TIMER_MODE_USER_DEFINED_COUNT | TIMER_INT_UNMASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct rt_ofw_node_id rk_timer_ofw_ids[] =
|
||||||
|
{
|
||||||
|
{ .compatible = "rockchip,rk3288-timer", .data = &rk3288_timer_data },
|
||||||
|
{ .compatible = "rockchip,rk3399-timer", .data = &rk3399_timer_data },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct rt_platform_driver rk_timer_driver =
|
||||||
|
{
|
||||||
|
.name = "hwtimer-rockchip",
|
||||||
|
.ids = rk_timer_ofw_ids,
|
||||||
|
|
||||||
|
.probe = rk_timer_probe,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rk_timer_drv_register(void)
|
||||||
|
{
|
||||||
|
rt_platform_driver_register(&rk_timer_driver);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_DRIVER_EARLY_EXPORT(rk_timer_drv_register);
|
|
@ -0,0 +1,5 @@
|
||||||
|
config RT_USING_RESET
|
||||||
|
bool "Using Reset Controller support"
|
||||||
|
depends on RT_USING_DM
|
||||||
|
select RT_USING_OFW
|
||||||
|
default n
|
|
@ -0,0 +1,13 @@
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
src = []
|
||||||
|
|
||||||
|
if GetDepend(['RT_USING_RESET']):
|
||||||
|
src += ['reset.c']
|
||||||
|
|
||||||
|
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
Return('group')
|
|
@ -0,0 +1,429 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-11-26 GuEe-GUI first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtservice.h>
|
||||||
|
|
||||||
|
#define DBG_TAG "rtdm.reset"
|
||||||
|
#define DBG_LVL DBG_INFO
|
||||||
|
#include <rtdbg.h>
|
||||||
|
|
||||||
|
#include <drivers/ofw.h>
|
||||||
|
#include "reset.h"
|
||||||
|
|
||||||
|
struct reset_control_array
|
||||||
|
{
|
||||||
|
struct rt_reset_control captain;
|
||||||
|
|
||||||
|
rt_size_t count;
|
||||||
|
struct rt_reset_control *rstcs[];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define reset_control_to_array(rstc) rt_container_of(rstc, struct reset_control_array, captain)
|
||||||
|
|
||||||
|
static struct rt_spinlock _rstcer_lock = { 0 };
|
||||||
|
static rt_list_t _rstcer_nodes = RT_LIST_OBJECT_INIT(_rstcer_nodes);
|
||||||
|
|
||||||
|
rt_err_t rt_reset_controller_register(struct rt_reset_controller *rstcer)
|
||||||
|
{
|
||||||
|
rt_ubase_t level;
|
||||||
|
|
||||||
|
if (!rstcer)
|
||||||
|
{
|
||||||
|
return -RT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_list_init(&rstcer->list);
|
||||||
|
rt_list_init(&rstcer->rstc_nodes);
|
||||||
|
rt_spin_lock_init(&rstcer->spinlock);
|
||||||
|
|
||||||
|
level = rt_spin_lock_irqsave(&_rstcer_lock);
|
||||||
|
|
||||||
|
rt_list_insert_after(&_rstcer_nodes, &rstcer->list);
|
||||||
|
|
||||||
|
rt_spin_unlock_irqrestore(&_rstcer_lock, level);
|
||||||
|
|
||||||
|
if (rstcer->ofw_node)
|
||||||
|
{
|
||||||
|
if (!rt_ofw_data(rstcer->ofw_node))
|
||||||
|
{
|
||||||
|
rt_ofw_data(rstcer->ofw_node) = rstcer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t rt_reset_controller_unregister(struct rt_reset_controller *rstcer)
|
||||||
|
{
|
||||||
|
if (rstcer)
|
||||||
|
{
|
||||||
|
rt_spin_lock(&_rstcer_lock);
|
||||||
|
|
||||||
|
rt_list_remove(&rstcer->list);
|
||||||
|
|
||||||
|
rt_spin_unlock(&_rstcer_lock);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -RT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t rt_reset_control_reset(struct rt_reset_control *rstc)
|
||||||
|
{
|
||||||
|
rt_err_t err;
|
||||||
|
|
||||||
|
if (!rstc)
|
||||||
|
{
|
||||||
|
return -RT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rstc->rstcer->ops->reset)
|
||||||
|
{
|
||||||
|
if ((err = rstc->rstcer->ops->reset(rstc)))
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rstc->is_array)
|
||||||
|
{
|
||||||
|
struct reset_control_array *rstc_arr = reset_control_to_array(rstc);
|
||||||
|
|
||||||
|
for (int i = 0; i < rstc_arr->count; ++i)
|
||||||
|
{
|
||||||
|
if ((err = rt_reset_control_reset(rstc_arr->rstcs[i])))
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t rt_reset_control_assert(struct rt_reset_control *rstc)
|
||||||
|
{
|
||||||
|
rt_err_t err;
|
||||||
|
|
||||||
|
if (!rstc)
|
||||||
|
{
|
||||||
|
return -RT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rstc->deassert && rstc->rstcer->ops->assert)
|
||||||
|
{
|
||||||
|
if ((err = rstc->rstcer->ops->assert(rstc)))
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
rstc->deassert = RT_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rstc->is_array)
|
||||||
|
{
|
||||||
|
struct reset_control_array *rstc_arr = reset_control_to_array(rstc);
|
||||||
|
|
||||||
|
for (int i = 0; i < rstc_arr->count; ++i)
|
||||||
|
{
|
||||||
|
if ((err = rt_reset_control_assert(rstc_arr->rstcs[i])))
|
||||||
|
{
|
||||||
|
if (rstc->rstcer->ops->deassert)
|
||||||
|
{
|
||||||
|
rstc->rstcer->ops->deassert(rstc);
|
||||||
|
|
||||||
|
rstc->deassert = RT_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i --> 0)
|
||||||
|
{
|
||||||
|
rt_reset_control_deassert(rstc_arr->rstcs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t rt_reset_control_deassert(struct rt_reset_control *rstc)
|
||||||
|
{
|
||||||
|
rt_err_t err;
|
||||||
|
|
||||||
|
if (!rstc)
|
||||||
|
{
|
||||||
|
return -RT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rstc->deassert && rstc->rstcer->ops->deassert)
|
||||||
|
{
|
||||||
|
if ((err = rstc->rstcer->ops->deassert(rstc)))
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
rstc->deassert = RT_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rstc->is_array)
|
||||||
|
{
|
||||||
|
struct reset_control_array *rstc_arr = reset_control_to_array(rstc);
|
||||||
|
|
||||||
|
for (int i = 0; i < rstc_arr->count; ++i)
|
||||||
|
{
|
||||||
|
if ((err = rt_reset_control_deassert(rstc_arr->rstcs[i])))
|
||||||
|
{
|
||||||
|
if (rstc->rstcer->ops->assert)
|
||||||
|
{
|
||||||
|
rstc->rstcer->ops->assert(rstc);
|
||||||
|
|
||||||
|
rstc->deassert = RT_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i --> 0)
|
||||||
|
{
|
||||||
|
rt_reset_control_assert(rstc_arr->rstcs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rt_reset_control_status(struct rt_reset_control *rstc)
|
||||||
|
{
|
||||||
|
if (!rstc)
|
||||||
|
{
|
||||||
|
return -RT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rstc->rstcer->ops->status)
|
||||||
|
{
|
||||||
|
return rstc->rstcer->ops->status(rstc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset_free(struct rt_reset_control *rstc)
|
||||||
|
{
|
||||||
|
if (rstc->is_array)
|
||||||
|
{
|
||||||
|
struct reset_control_array *rstc_arr = reset_control_to_array(rstc);
|
||||||
|
|
||||||
|
for (int i = 0; i < rstc_arr->count; ++i)
|
||||||
|
{
|
||||||
|
rt_reset_control_put(rstc_arr->rstcs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_free(rstc);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rt_reset_control *rt_reset_control_get_array(struct rt_device *dev)
|
||||||
|
{
|
||||||
|
return rt_ofw_get_reset_control_array(dev->ofw_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rt_reset_control *rt_reset_control_get_by_index(struct rt_device *dev, int index)
|
||||||
|
{
|
||||||
|
return rt_ofw_get_reset_control_by_index(dev->ofw_node, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rt_reset_control *rt_reset_control_get_by_name(struct rt_device *dev, const char *name)
|
||||||
|
{
|
||||||
|
return rt_ofw_get_reset_control_by_name(dev->ofw_node, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_reset_control_put(struct rt_reset_control *rstc)
|
||||||
|
{
|
||||||
|
struct rt_reset_controller *rstcer;
|
||||||
|
|
||||||
|
if (!rstc)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rstcer = rstc->rstcer;
|
||||||
|
|
||||||
|
rt_spin_lock(&rstcer->spinlock);
|
||||||
|
|
||||||
|
rt_list_remove(&rstc->list);
|
||||||
|
|
||||||
|
rt_spin_unlock(&rstcer->spinlock);
|
||||||
|
|
||||||
|
reset_free(rstc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rt_reset_control *ofw_get_reset_control(struct rt_ofw_node *np, int index,
|
||||||
|
const char *name, rt_bool_t is_array)
|
||||||
|
{
|
||||||
|
struct rt_reset_control *rstc;
|
||||||
|
struct rt_ofw_cell_args reset_args = {};
|
||||||
|
struct rt_reset_controller *rstcer = RT_NULL;
|
||||||
|
|
||||||
|
if (is_array)
|
||||||
|
{
|
||||||
|
rt_size_t rstc_nr;
|
||||||
|
struct reset_control_array *rstc_arr;
|
||||||
|
|
||||||
|
rstc_nr = rt_ofw_count_phandle_cells(np, "resets", "#reset-cells");
|
||||||
|
|
||||||
|
if (!rstc_nr)
|
||||||
|
{
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rstc_arr = rt_calloc(1, sizeof(*rstc_arr) + sizeof(struct rt_reset_control *) * rstc_nr);
|
||||||
|
|
||||||
|
if (!rstc_arr)
|
||||||
|
{
|
||||||
|
LOG_E("No memory to create %s[%d] reset control",
|
||||||
|
rt_ofw_node_full_name(np), index);
|
||||||
|
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rstc_arr->count = rstc_nr - 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < rstc_arr->count; ++i)
|
||||||
|
{
|
||||||
|
rstc_arr->rstcs[i] = ofw_get_reset_control(np, i + 1, RT_NULL, RT_FALSE);
|
||||||
|
|
||||||
|
if (!rstc_arr->rstcs[i])
|
||||||
|
{
|
||||||
|
while (i --> 0)
|
||||||
|
{
|
||||||
|
rt_reset_control_put(rstc_arr->rstcs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_free(rstc_arr);
|
||||||
|
rstc_arr = RT_NULL;
|
||||||
|
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rstc = &rstc_arr->captain;
|
||||||
|
rstc->is_array = RT_TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rstc = rt_calloc(1, sizeof(*rstc));
|
||||||
|
|
||||||
|
if (!rstc)
|
||||||
|
{
|
||||||
|
LOG_E("No memory to create %s[%d] reset control",
|
||||||
|
rt_ofw_node_full_name(np), index);
|
||||||
|
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rt_ofw_parse_phandle_cells(np, "resets", "#reset-cells", index, &reset_args))
|
||||||
|
{
|
||||||
|
void *rt_data = rt_ofw_data(reset_args.data);
|
||||||
|
|
||||||
|
if (rt_data)
|
||||||
|
{
|
||||||
|
/* check is clk */
|
||||||
|
if (rt_ofw_prop_read_bool(reset_args.data, "#clock-cells"))
|
||||||
|
{
|
||||||
|
struct rt_reset_controller_clk_node *rstcer_clk = rt_data;
|
||||||
|
|
||||||
|
rstcer = &rstcer_clk->rstcer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rstcer = rt_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_ofw_node_put(reset_args.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rstcer)
|
||||||
|
{
|
||||||
|
goto _fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name && rt_ofw_prop_read_bool(np, "reset-names"))
|
||||||
|
{
|
||||||
|
rt_ofw_prop_read_string_index(np, "reset-names", index, &name);
|
||||||
|
}
|
||||||
|
|
||||||
|
rstc->con_id = name;
|
||||||
|
rstc->rstcer = rstcer;
|
||||||
|
|
||||||
|
if (rstcer->ops->ofw_parse)
|
||||||
|
{
|
||||||
|
rt_err_t err = rstcer->ops->ofw_parse(rstc, &reset_args);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
LOG_E("Parse %s reset control error = %s",
|
||||||
|
rt_ofw_node_full_name(np), rt_strerror(err));
|
||||||
|
|
||||||
|
goto _fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rstc->id = reset_args.args[0];
|
||||||
|
|
||||||
|
rt_list_init(&rstc->list);
|
||||||
|
|
||||||
|
rt_spin_lock(&rstcer->spinlock);
|
||||||
|
|
||||||
|
rt_list_insert_after(&rstcer->rstc_nodes, &rstc->list);
|
||||||
|
|
||||||
|
rt_spin_unlock(&rstcer->spinlock);
|
||||||
|
|
||||||
|
return rstc;
|
||||||
|
|
||||||
|
_fail:
|
||||||
|
if (rstc && !rstc->is_array)
|
||||||
|
{
|
||||||
|
rt_free(rstc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rt_reset_control *rt_ofw_get_reset_control_array(struct rt_ofw_node *np)
|
||||||
|
{
|
||||||
|
return ofw_get_reset_control(np, 0, RT_NULL, RT_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rt_reset_control *rt_ofw_get_reset_control_by_index(struct rt_ofw_node *np, int index)
|
||||||
|
{
|
||||||
|
return ofw_get_reset_control(np, index, RT_NULL, RT_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rt_reset_control *rt_ofw_get_reset_control_by_name(struct rt_ofw_node *np, const char *name)
|
||||||
|
{
|
||||||
|
if (np)
|
||||||
|
{
|
||||||
|
int index = rt_ofw_prop_index_of_string(np, "reset-names", name);
|
||||||
|
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
return ofw_get_reset_control(np, index, name, RT_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-11-26 GuEe-GUI first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RESET_H__
|
||||||
|
#define __RESET_H__
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <drivers/ofw.h>
|
||||||
|
#include <drivers/clk.h>
|
||||||
|
|
||||||
|
struct rt_reset_control_ops;
|
||||||
|
|
||||||
|
struct rt_reset_controller
|
||||||
|
{
|
||||||
|
rt_list_t list;
|
||||||
|
rt_list_t rstc_nodes;
|
||||||
|
|
||||||
|
const char *name;
|
||||||
|
const struct rt_reset_control_ops *ops;
|
||||||
|
|
||||||
|
struct rt_ofw_node *ofw_node;
|
||||||
|
void *priv;
|
||||||
|
|
||||||
|
struct rt_spinlock spinlock;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It seems that most reset controllers are coupled to CLK.
|
||||||
|
* So we need a generic extends object.
|
||||||
|
*/
|
||||||
|
struct rt_reset_controller_clk_node
|
||||||
|
{
|
||||||
|
struct rt_clk_node parent;
|
||||||
|
|
||||||
|
struct rt_reset_controller rstcer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rt_reset_control
|
||||||
|
{
|
||||||
|
rt_list_t list;
|
||||||
|
|
||||||
|
struct rt_reset_controller *rstcer;
|
||||||
|
|
||||||
|
int id;
|
||||||
|
const char *con_id;
|
||||||
|
rt_bool_t is_array;
|
||||||
|
rt_bool_t deassert;
|
||||||
|
|
||||||
|
void *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rt_reset_control_ops
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* rt_ofw_cell_args return:
|
||||||
|
* args[0] = rstc.id
|
||||||
|
*/
|
||||||
|
rt_err_t (*ofw_parse)(struct rt_reset_control *, struct rt_ofw_cell_args *args);
|
||||||
|
/* API */
|
||||||
|
rt_err_t (*reset)(struct rt_reset_control *rstc);
|
||||||
|
rt_err_t (*assert)(struct rt_reset_control *rstc);
|
||||||
|
rt_err_t (*deassert)(struct rt_reset_control *rstc);
|
||||||
|
int (*status)(struct rt_reset_control *rstc);
|
||||||
|
};
|
||||||
|
|
||||||
|
rt_err_t rt_reset_controller_register(struct rt_reset_controller *rstcer);
|
||||||
|
rt_err_t rt_reset_controller_unregister(struct rt_reset_controller *rstcer);
|
||||||
|
|
||||||
|
rt_err_t rt_reset_control_reset(struct rt_reset_control *rstc);
|
||||||
|
rt_err_t rt_reset_control_assert(struct rt_reset_control *rstc);
|
||||||
|
rt_err_t rt_reset_control_deassert(struct rt_reset_control *rstc);
|
||||||
|
int rt_reset_control_status(struct rt_reset_control *rstc);
|
||||||
|
|
||||||
|
rt_ssize_t rt_reset_control_get_count(struct rt_device *dev);
|
||||||
|
struct rt_reset_control *rt_reset_control_get_array(struct rt_device *dev);
|
||||||
|
struct rt_reset_control *rt_reset_control_get_by_index(struct rt_device *dev, int index);
|
||||||
|
struct rt_reset_control *rt_reset_control_get_by_name(struct rt_device *dev, const char *name);
|
||||||
|
void rt_reset_control_put(struct rt_reset_control *rstc);
|
||||||
|
|
||||||
|
struct rt_reset_control *rt_ofw_get_reset_control_array(struct rt_ofw_node *np);
|
||||||
|
struct rt_reset_control *rt_ofw_get_reset_control_by_index(struct rt_ofw_node *np, int index);
|
||||||
|
struct rt_reset_control *rt_ofw_get_reset_control_by_name(struct rt_ofw_node *np, const char *name);
|
||||||
|
|
||||||
|
#endif /* __RESET_H__ */
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-3-08 GuEe-GUI the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ROCKCHIP_H__
|
||||||
|
#define __ROCKCHIP_H__
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
|
||||||
|
#define rk_clrsetreg(addr, clr, set) HWREG32(addr) = (((clr) | (set)) << 16 | (set))
|
||||||
|
#define rk_clrreg(addr, clr) HWREG32(addr) = ((clr) << 16)
|
||||||
|
#define rk_setreg(addr, set) HWREG32(addr) = ((set) << 16 | (set))
|
||||||
|
|
||||||
|
#define HIWORD_UPDATE(val, mask, shift) ((val) << (shift) | (mask) << ((shift) + 16))
|
||||||
|
|
||||||
|
#endif /* __ROCKCHIP_H__ */
|
|
@ -0,0 +1,341 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-11-22 GuEe-GUI first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Synopsys DesignWare 8250 has an extra feature whereby it detects if the
|
||||||
|
* LCR is written whilst busy. If it is, then a busy detect interrupt is
|
||||||
|
* raised, the LCR needs to be rewritten and the uart status register read.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#include "8250.h"
|
||||||
|
|
||||||
|
/* Offsets for the DesignWare specific registers */
|
||||||
|
#define DW_UART_USR 0x1f /* UART Status Register */
|
||||||
|
#define DW_UART_DMASA 0xa8 /* DMA Software Ack */
|
||||||
|
|
||||||
|
#define OCTEON_UART_USR 0x27 /* UART Status Register */
|
||||||
|
|
||||||
|
#define RZN1_UART_TDMACR 0x10c /* DMA Control Register Transmit Mode */
|
||||||
|
#define RZN1_UART_RDMACR 0x110 /* DMA Control Register Receive Mode */
|
||||||
|
|
||||||
|
/* DesignWare specific register fields */
|
||||||
|
#define DW_UART_MCR_SIRE RT_BIT(6)
|
||||||
|
|
||||||
|
/* Renesas specific register fields */
|
||||||
|
#define RZN1_UART_xDMACR_DMA_EN RT_BIT(0)
|
||||||
|
#define RZN1_UART_xDMACR_1_WORD_BURST (0 << 1)
|
||||||
|
#define RZN1_UART_xDMACR_4_WORD_BURST (1 << 1)
|
||||||
|
#define RZN1_UART_xDMACR_8_WORD_BURST (2 << 1)
|
||||||
|
#define RZN1_UART_xDMACR_BLK_SZ(x) ((x) << 3)
|
||||||
|
|
||||||
|
/* Quirks */
|
||||||
|
#define DW_UART_QUIRK_OCTEON RT_BIT(0)
|
||||||
|
#define DW_UART_QUIRK_ARMADA_38X RT_BIT(1)
|
||||||
|
#define DW_UART_QUIRK_SKIP_SET_RATE RT_BIT(2)
|
||||||
|
#define DW_UART_QUIRK_IS_DMA_FC RT_BIT(3)
|
||||||
|
|
||||||
|
struct dw8250_platform_data
|
||||||
|
{
|
||||||
|
rt_uint8_t usr_reg;
|
||||||
|
rt_uint32_t cpr_val;
|
||||||
|
rt_uint32_t quirks;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dw8250
|
||||||
|
{
|
||||||
|
struct serial8250 parent;
|
||||||
|
struct rt_spinlock spinlock;
|
||||||
|
|
||||||
|
struct rt_clk *pclk;
|
||||||
|
|
||||||
|
rt_bool_t uart_16550_compatible;
|
||||||
|
struct dw8250_platform_data *platform_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define to_dw8250(serial8250) rt_container_of(serial8250, struct dw8250, parent)
|
||||||
|
|
||||||
|
static void dw8250_check_lcr(struct serial8250 *serial, int value)
|
||||||
|
{
|
||||||
|
void *offset = (void *)(serial->base + (UART_LCR << serial->regshift));
|
||||||
|
int tries = 1000;
|
||||||
|
|
||||||
|
/* Make sure LCR write wasn't ignored */
|
||||||
|
while (tries--)
|
||||||
|
{
|
||||||
|
rt_uint32_t lcr = serial->serial_in(serial, UART_LCR);
|
||||||
|
|
||||||
|
if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial->serial_out(serial, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
|
||||||
|
serial->serial_in(serial, UART_RX);
|
||||||
|
|
||||||
|
if (serial->iotype == PORT_MMIO32)
|
||||||
|
{
|
||||||
|
HWREG32(offset) = value;
|
||||||
|
}
|
||||||
|
else if (serial->iotype == PORT_MMIO32BE)
|
||||||
|
{
|
||||||
|
HWREG32(offset) = rt_cpu_to_be32(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HWREG8(offset) = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dw8250_serial_out32(struct serial8250 *serial, int offset, int value)
|
||||||
|
{
|
||||||
|
struct dw8250 *dw8250 = to_dw8250(serial);
|
||||||
|
|
||||||
|
HWREG32(serial->base + (offset << serial->regshift)) = value;
|
||||||
|
|
||||||
|
if (offset == UART_LCR && !dw8250->uart_16550_compatible)
|
||||||
|
{
|
||||||
|
dw8250_check_lcr(serial, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_uint32_t dw8250_serial_in32(struct serial8250 *serial, int offset)
|
||||||
|
{
|
||||||
|
return HWREG32(serial->base + (offset << serial->regshift));
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t dw8250_isr(struct serial8250 *serial, int irq)
|
||||||
|
{
|
||||||
|
unsigned int iir, status;
|
||||||
|
struct dw8250 *dw8250 = to_dw8250(serial);
|
||||||
|
|
||||||
|
iir = serial8250_in(serial, UART_IIR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If don't do this in non-DMA mode then the "RX TIMEOUT" interrupt will
|
||||||
|
* fire forever.
|
||||||
|
*/
|
||||||
|
if ((iir & 0x3f) == UART_IIR_RX_TIMEOUT)
|
||||||
|
{
|
||||||
|
rt_base_t level = rt_spin_lock_irqsave(&dw8250->spinlock);
|
||||||
|
|
||||||
|
status = serial8250_in(serial, UART_LSR);
|
||||||
|
|
||||||
|
if (!(status & (UART_LSR_DR | UART_LSR_BI)))
|
||||||
|
{
|
||||||
|
serial8250_in(serial, UART_RX);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_spin_unlock_irqrestore(&dw8250->spinlock, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(iir & UART_IIR_NO_INT))
|
||||||
|
{
|
||||||
|
rt_hw_serial_isr(&serial->parent, RT_SERIAL_EVENT_RX_IND);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY)
|
||||||
|
{
|
||||||
|
/* Clear the USR */
|
||||||
|
serial8250_in(serial, dw8250->platform_data->usr_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dw8250_free_resource(struct dw8250 *dw8250)
|
||||||
|
{
|
||||||
|
struct serial8250 *serial = &dw8250->parent;
|
||||||
|
|
||||||
|
if (serial->base)
|
||||||
|
{
|
||||||
|
rt_iounmap(serial->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serial->clk)
|
||||||
|
{
|
||||||
|
rt_clk_disable_unprepare(serial->clk);
|
||||||
|
rt_clk_put(serial->clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dw8250->pclk)
|
||||||
|
{
|
||||||
|
rt_clk_disable_unprepare(dw8250->pclk);
|
||||||
|
rt_clk_put(dw8250->pclk);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_free(dw8250);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dw8250_remove(struct serial8250 *serial)
|
||||||
|
{
|
||||||
|
struct dw8250 *dw8250 = to_dw8250(serial);
|
||||||
|
|
||||||
|
dw8250_free_resource(dw8250);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t dw8250_probe(struct rt_platform_device *pdev)
|
||||||
|
{
|
||||||
|
rt_err_t err;
|
||||||
|
rt_uint32_t val;
|
||||||
|
struct serial8250 *serial;
|
||||||
|
struct rt_device *dev = &pdev->parent;
|
||||||
|
struct dw8250 *dw8250 = serial8250_alloc(dw8250);
|
||||||
|
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
||||||
|
|
||||||
|
if (!dw8250)
|
||||||
|
{
|
||||||
|
return -RT_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial = &dw8250->parent;
|
||||||
|
serial->base = rt_dm_dev_iomap(dev, 0);
|
||||||
|
|
||||||
|
if (!serial->base)
|
||||||
|
{
|
||||||
|
err = -RT_EIO;
|
||||||
|
|
||||||
|
goto _free_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial->irq = rt_dm_dev_get_irq(dev, 0);
|
||||||
|
|
||||||
|
if (serial->irq < 0)
|
||||||
|
{
|
||||||
|
err = serial->irq;
|
||||||
|
|
||||||
|
goto _free_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial->clk = rt_clk_get_by_name(dev, "baudclk");
|
||||||
|
dw8250->pclk = rt_clk_get_by_name(dev, "apb_pclk");
|
||||||
|
|
||||||
|
if (!serial->clk)
|
||||||
|
{
|
||||||
|
if ((err = rt_dm_dev_prop_read_u32(dev, "clock-frequency", &serial->freq)))
|
||||||
|
{
|
||||||
|
goto _free_res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((err = rt_clk_prepare_enable(serial->clk)))
|
||||||
|
{
|
||||||
|
goto _free_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial->freq = rt_clk_get_rate(serial->clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dw8250->pclk)
|
||||||
|
{
|
||||||
|
err = -RT_EIO;
|
||||||
|
|
||||||
|
goto _free_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((err = rt_clk_prepare_enable(dw8250->pclk)))
|
||||||
|
{
|
||||||
|
goto _free_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_dm_dev_prop_read_u32(dev, "reg-shift", &serial->regshift);
|
||||||
|
|
||||||
|
if (!rt_dm_dev_prop_read_u32(dev, "reg-io-width", &val) && val == 4)
|
||||||
|
{
|
||||||
|
serial->iotype = PORT_MMIO32;
|
||||||
|
serial->serial_in = &dw8250_serial_in32;
|
||||||
|
serial->serial_out = &dw8250_serial_out32;
|
||||||
|
}
|
||||||
|
|
||||||
|
dw8250->uart_16550_compatible = rt_dm_dev_prop_read_bool(dev, "snps,uart-16550-compatible");
|
||||||
|
dw8250->platform_data = (struct dw8250_platform_data *)pdev->id->data;
|
||||||
|
|
||||||
|
rt_dm_dev_bind_fwdata(&serial->parent.parent, pdev->parent.ofw_node, &serial->parent);
|
||||||
|
|
||||||
|
serial = &dw8250->parent;
|
||||||
|
serial->parent.ops = &serial8250_uart_ops;
|
||||||
|
serial->parent.config = config;
|
||||||
|
serial->handle_irq = &dw8250_isr;
|
||||||
|
serial->remove = &dw8250_remove;
|
||||||
|
serial->data = dw8250;
|
||||||
|
|
||||||
|
rt_spin_lock_init(&dw8250->spinlock);
|
||||||
|
|
||||||
|
if ((err = serial8250_setup(serial)))
|
||||||
|
{
|
||||||
|
goto _free_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
|
||||||
|
_free_res:
|
||||||
|
dw8250_free_resource(dw8250);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dw8250_platform_data dw8250_dw_apb =
|
||||||
|
{
|
||||||
|
.usr_reg = DW_UART_USR,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dw8250_platform_data dw8250_octeon_3860_data =
|
||||||
|
{
|
||||||
|
.usr_reg = OCTEON_UART_USR,
|
||||||
|
.quirks = DW_UART_QUIRK_OCTEON,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dw8250_platform_data dw8250_armada_38x_data =
|
||||||
|
{
|
||||||
|
.usr_reg = DW_UART_USR,
|
||||||
|
.quirks = DW_UART_QUIRK_ARMADA_38X,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dw8250_platform_data dw8250_renesas_rzn1_data =
|
||||||
|
{
|
||||||
|
.usr_reg = DW_UART_USR,
|
||||||
|
.cpr_val = 0x00012f32,
|
||||||
|
.quirks = DW_UART_QUIRK_IS_DMA_FC,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dw8250_platform_data dw8250_starfive_jh7100_data =
|
||||||
|
{
|
||||||
|
.usr_reg = DW_UART_USR,
|
||||||
|
.quirks = DW_UART_QUIRK_SKIP_SET_RATE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rt_ofw_node_id dw8250_ofw_ids[] =
|
||||||
|
{
|
||||||
|
{ .type = "ttyS", .compatible = "snps,dw-apb-uart", .data = &dw8250_dw_apb },
|
||||||
|
{ .type = "ttyS", .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
|
||||||
|
{ .type = "ttyS", .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
|
||||||
|
{ .type = "ttyS", .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
|
||||||
|
{ .type = "ttyS", .compatible = "starfive,jh7100-uart", .data = &dw8250_starfive_jh7100_data },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct rt_platform_driver dw8250_driver =
|
||||||
|
{
|
||||||
|
.name = "dw-apb-uart",
|
||||||
|
.ids = dw8250_ofw_ids,
|
||||||
|
|
||||||
|
.probe = dw8250_probe,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int dw8250_drv_register(void)
|
||||||
|
{
|
||||||
|
rt_platform_driver_register(&dw8250_driver);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_DRIVER_EARLY_EXPORT(dw8250_drv_register);
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-11-16 GuEe-GUI first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SERIAL_8250_H__
|
||||||
|
#define __SERIAL_8250_H__
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
#include <ioremap.h>
|
||||||
|
#include "regs.h"
|
||||||
|
#include "serial_dm.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PORT_IO,
|
||||||
|
PORT_MMIO,
|
||||||
|
PORT_MMIO16,
|
||||||
|
PORT_MMIO32,
|
||||||
|
PORT_MMIO32BE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct serial8250
|
||||||
|
{
|
||||||
|
struct rt_serial_device parent;
|
||||||
|
struct rt_clk *clk;
|
||||||
|
|
||||||
|
int irq;
|
||||||
|
void *base;
|
||||||
|
rt_size_t size;
|
||||||
|
rt_uint32_t freq; /* frequency */
|
||||||
|
rt_uint32_t regshift; /* reg offset shift */
|
||||||
|
rt_uint8_t iotype; /* io access style */
|
||||||
|
|
||||||
|
struct rt_spinlock spinlock;
|
||||||
|
|
||||||
|
rt_uint32_t (*serial_in)(struct serial8250 *, int offset);
|
||||||
|
void (*serial_out)(struct serial8250 *, int offset, int value);
|
||||||
|
rt_err_t (*handle_irq)(struct serial8250 *, int irq);
|
||||||
|
|
||||||
|
/* Free all resource (and parent) by child */
|
||||||
|
void (*remove)(struct serial8250 *);
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define serial8250_alloc(obj) rt_calloc(1, sizeof(typeof(*obj)))
|
||||||
|
#define raw_to_serial8250(raw_serial) rt_container_of(raw_serial, struct serial8250, parent)
|
||||||
|
|
||||||
|
rt_err_t serial8250_config(struct serial8250 *serial, const char *options);
|
||||||
|
rt_err_t serial8250_setup(struct serial8250 *serial);
|
||||||
|
rt_err_t serial8250_remove(struct serial8250 *serial);
|
||||||
|
|
||||||
|
rt_uint32_t serial8250_in(struct serial8250 *serial, int offset);
|
||||||
|
void serial8250_out(struct serial8250 *serial, int offset, int value);
|
||||||
|
|
||||||
|
rt_err_t serial8250_uart_configure(struct rt_serial_device *raw_serial, struct serial_configure *cfg);
|
||||||
|
rt_err_t serial8250_uart_control(struct rt_serial_device *raw_serial, int cmd, void *arg);
|
||||||
|
int serial8250_uart_putc(struct rt_serial_device *raw_serial, char c);
|
||||||
|
int serial8250_uart_getc(struct rt_serial_device *raw_serial);
|
||||||
|
|
||||||
|
int serial8250_early_putc(struct rt_serial_device *raw_serial, char c);
|
||||||
|
rt_err_t serial8250_early_fdt_setup(struct serial8250 *serial, struct rt_fdt_earlycon *con, const char *options);
|
||||||
|
|
||||||
|
extern struct serial8250 early_serial8250;
|
||||||
|
extern const struct rt_uart_ops serial8250_uart_ops;
|
||||||
|
|
||||||
|
#endif /* __SERIAL_8250_H__ */
|
|
@ -0,0 +1,3 @@
|
||||||
|
config RT_SERIAL_8250
|
||||||
|
bool "8250 Serila Family"
|
||||||
|
default n
|
|
@ -0,0 +1,13 @@
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
CPPPATH = [cwd]
|
||||||
|
|
||||||
|
src = ['core.c', 'early.c']
|
||||||
|
|
||||||
|
if GetDepend(['RT_SERIAL_8250']):
|
||||||
|
src += ['8250-dw.c']
|
||||||
|
src += ['fiq-debugger.c']
|
||||||
|
|
||||||
|
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||||
|
Return('group')
|
|
@ -0,0 +1,303 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-11-16 GuEe-GUI first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "8250.h"
|
||||||
|
|
||||||
|
rt_err_t serial8250_config(struct serial8250 *serial, const char *options)
|
||||||
|
{
|
||||||
|
rt_err_t ret = -RT_EINVAL;
|
||||||
|
|
||||||
|
if (serial)
|
||||||
|
{
|
||||||
|
char *arg;
|
||||||
|
rt_bool_t has_iotype = RT_FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* uart8250,io,<addr>[,options]
|
||||||
|
* uart8250,mmio,<addr>[,options]
|
||||||
|
* uart8250,mmio16,<addr>[,options]
|
||||||
|
* uart8250,mmio32,<addr>[,options]
|
||||||
|
* uart8250,mmio32be,<addr>[,options]
|
||||||
|
* uart8250,0x<addr>[,options]
|
||||||
|
*/
|
||||||
|
serial_for_each_args(arg, options)
|
||||||
|
{
|
||||||
|
if (!rt_strcmp(arg, "uart8250"))
|
||||||
|
{
|
||||||
|
ret = RT_EOK;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* user call error */
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!rt_strncmp(arg, "0x", 2))
|
||||||
|
{
|
||||||
|
serial->base = serial_base_from_args(arg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!has_iotype)
|
||||||
|
{
|
||||||
|
const struct
|
||||||
|
{
|
||||||
|
char *param;
|
||||||
|
int type;
|
||||||
|
} iotype_table[] =
|
||||||
|
{
|
||||||
|
{ "io", PORT_IO },
|
||||||
|
{ "mmio", PORT_MMIO },
|
||||||
|
{ "mmio16", PORT_MMIO16 },
|
||||||
|
{ "mmio32", PORT_MMIO32 },
|
||||||
|
{ "mmio32be", PORT_MMIO32BE },
|
||||||
|
};
|
||||||
|
|
||||||
|
serial->iotype = PORT_MMIO32;
|
||||||
|
|
||||||
|
for (int i = 0; i < RT_ARRAY_SIZE(iotype_table); ++i)
|
||||||
|
{
|
||||||
|
if (!rt_strcmp(arg, iotype_table[i].param))
|
||||||
|
{
|
||||||
|
serial->iotype = iotype_table[i].type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
has_iotype = RT_TRUE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial->parent.config = serial_cfg_from_args(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!serial->size)
|
||||||
|
{
|
||||||
|
serial->size = 0x1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void serial8250_isr(int irqno, void *param)
|
||||||
|
{
|
||||||
|
struct serial8250 *serial = (struct serial8250 *)param;
|
||||||
|
|
||||||
|
if (serial->handle_irq)
|
||||||
|
{
|
||||||
|
serial->handle_irq(serial, irqno);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_hw_serial_isr(&serial->parent, RT_SERIAL_EVENT_RX_IND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t serial8250_setup(struct serial8250 *serial)
|
||||||
|
{
|
||||||
|
rt_err_t ret = RT_EOK;
|
||||||
|
const char *uart_name;
|
||||||
|
char dev_name[RT_NAME_MAX];
|
||||||
|
|
||||||
|
if (serial)
|
||||||
|
{
|
||||||
|
rt_spin_lock_init(&serial->spinlock);
|
||||||
|
|
||||||
|
serial->serial_in = serial->serial_in ? : &serial8250_in;
|
||||||
|
serial->serial_out = serial->serial_out ? : &serial8250_out;
|
||||||
|
|
||||||
|
serial_dev_set_name(&serial->parent);
|
||||||
|
uart_name = rt_dm_dev_get_name(&serial->parent.parent);
|
||||||
|
|
||||||
|
rt_hw_serial_register(&serial->parent, uart_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, serial->data);
|
||||||
|
|
||||||
|
rt_snprintf(dev_name, sizeof(dev_name), "%s-8250", uart_name);
|
||||||
|
rt_pic_attach_irq(serial->irq, serial8250_isr, serial, dev_name, RT_IRQ_F_NONE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = -RT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t serial8250_remove(struct serial8250 *serial)
|
||||||
|
{
|
||||||
|
rt_err_t err;
|
||||||
|
|
||||||
|
rt_iounmap((void *)serial->base);
|
||||||
|
serial->base = RT_NULL;
|
||||||
|
|
||||||
|
rt_pic_irq_mask(serial->irq);
|
||||||
|
rt_pic_detach_irq(serial->irq, serial);
|
||||||
|
|
||||||
|
err = rt_device_unregister(&serial->parent.parent);
|
||||||
|
|
||||||
|
if (!err && serial->remove)
|
||||||
|
{
|
||||||
|
serial->remove(serial);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_uint32_t serial8250_in(struct serial8250 *serial, int offset)
|
||||||
|
{
|
||||||
|
rt_uint32_t ret = 0;
|
||||||
|
offset <<= serial->regshift;
|
||||||
|
|
||||||
|
switch (serial->iotype)
|
||||||
|
{
|
||||||
|
case PORT_MMIO:
|
||||||
|
ret = HWREG8(serial->base + offset);
|
||||||
|
break;
|
||||||
|
case PORT_MMIO16:
|
||||||
|
ret = HWREG16(serial->base + offset);
|
||||||
|
break;
|
||||||
|
case PORT_MMIO32:
|
||||||
|
ret = HWREG32(serial->base + offset);
|
||||||
|
break;
|
||||||
|
case PORT_MMIO32BE:
|
||||||
|
ret = rt_cpu_to_be32(HWREG32(serial->base + offset));
|
||||||
|
break;
|
||||||
|
#ifdef ARCH_SUPPORT_PIO
|
||||||
|
case PORT_IO:
|
||||||
|
ret = inb(serial->base + offset, value);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial8250_out(struct serial8250 *serial, int offset, int value)
|
||||||
|
{
|
||||||
|
offset <<= serial->regshift;
|
||||||
|
|
||||||
|
switch (serial->iotype)
|
||||||
|
{
|
||||||
|
case PORT_MMIO:
|
||||||
|
HWREG8(serial->base + offset) = value;
|
||||||
|
break;
|
||||||
|
case PORT_MMIO16:
|
||||||
|
HWREG16(serial->base + offset) = value;
|
||||||
|
break;
|
||||||
|
case PORT_MMIO32:
|
||||||
|
HWREG32(serial->base + offset) = value;
|
||||||
|
break;
|
||||||
|
case PORT_MMIO32BE:
|
||||||
|
HWREG32(serial->base + offset) = rt_cpu_to_be32(value);
|
||||||
|
break;
|
||||||
|
#ifdef ARCH_SUPPORT_PIO
|
||||||
|
case PORT_IO:
|
||||||
|
outb(serial->base + offset, value);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t serial8250_uart_configure(struct rt_serial_device *raw_serial, struct serial_configure *cfg)
|
||||||
|
{
|
||||||
|
rt_err_t err = RT_EOK;
|
||||||
|
struct serial8250 *serial = raw_to_serial8250(raw_serial);
|
||||||
|
|
||||||
|
/* Disable interrupt */
|
||||||
|
serial->serial_out(serial, UART_IER, !UART_IER_RDI);
|
||||||
|
|
||||||
|
/* Enable FIFO, Clear FIFO*/
|
||||||
|
serial->serial_out(serial, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
|
||||||
|
|
||||||
|
/* DTR + RTS */
|
||||||
|
serial->serial_out(serial, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
|
||||||
|
|
||||||
|
if (serial->freq)
|
||||||
|
{
|
||||||
|
rt_uint32_t wlen = cfg->data_bits - DATA_BITS_5 + UART_LCR_WLEN5;
|
||||||
|
rt_uint32_t divisor = serial->freq / 16 / cfg->baud_rate;
|
||||||
|
|
||||||
|
/* Enable access DLL & DLH */
|
||||||
|
serial->serial_out(serial, UART_LCR, serial->serial_in(serial, UART_LCR) | UART_LCR_DLAB);
|
||||||
|
serial->serial_out(serial, UART_DLL, (divisor & 0xff));
|
||||||
|
serial->serial_out(serial, UART_DLM, (divisor >> 8) & 0xff);
|
||||||
|
/* Clear DLAB bit */
|
||||||
|
serial->serial_out(serial, UART_LCR, serial->serial_in(serial, UART_LCR) & (~UART_LCR_DLAB));
|
||||||
|
|
||||||
|
serial->serial_out(serial, UART_LCR, (serial->serial_in(serial, UART_LCR) & (~wlen)) | wlen);
|
||||||
|
serial->serial_out(serial, UART_LCR, serial->serial_in(serial, UART_LCR) & (~UART_LCR_STOP));
|
||||||
|
serial->serial_out(serial, UART_LCR, serial->serial_in(serial, UART_LCR) & (~UART_LCR_PARITY));
|
||||||
|
}
|
||||||
|
|
||||||
|
serial->serial_out(serial, UART_IER, UART_IER_RDI);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t serial8250_uart_control(struct rt_serial_device *raw_serial, int cmd, void *arg)
|
||||||
|
{
|
||||||
|
rt_err_t err = RT_EOK;
|
||||||
|
struct serial8250 *serial = raw_to_serial8250(raw_serial);
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case RT_DEVICE_CTRL_CLR_INT:
|
||||||
|
/* disable rx irq */
|
||||||
|
serial->serial_out(serial, UART_IER, !UART_IER_RDI);
|
||||||
|
rt_pic_irq_mask(serial->irq);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RT_DEVICE_CTRL_SET_INT:
|
||||||
|
/* enable rx irq */
|
||||||
|
serial->serial_out(serial, UART_IER, UART_IER_RDI);
|
||||||
|
rt_pic_irq_unmask(serial->irq);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial8250_uart_putc(struct rt_serial_device *raw_serial, char c)
|
||||||
|
{
|
||||||
|
struct serial8250 *serial = raw_to_serial8250(raw_serial);
|
||||||
|
|
||||||
|
while (!(serial->serial_in(serial, UART_LSR) & 0x20))
|
||||||
|
{
|
||||||
|
rt_hw_cpu_relax();
|
||||||
|
}
|
||||||
|
|
||||||
|
serial->serial_out(serial, UART_TX, c);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial8250_uart_getc(struct rt_serial_device *raw_serial)
|
||||||
|
{
|
||||||
|
int ch = -1;
|
||||||
|
struct serial8250 *serial = raw_to_serial8250(raw_serial);
|
||||||
|
|
||||||
|
if ((serial->serial_in(serial, UART_LSR) & 0x1))
|
||||||
|
{
|
||||||
|
ch = serial->serial_in(serial, UART_RX) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct rt_uart_ops serial8250_uart_ops =
|
||||||
|
{
|
||||||
|
.configure = serial8250_uart_configure,
|
||||||
|
.control = serial8250_uart_control,
|
||||||
|
.putc = serial8250_uart_putc,
|
||||||
|
.getc = serial8250_uart_getc,
|
||||||
|
};
|
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-11-16 GuEe-GUI first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "8250.h"
|
||||||
|
|
||||||
|
struct serial8250 early_serial8250 = { 0 };
|
||||||
|
|
||||||
|
static rt_uint32_t serial8250_early_in(struct serial8250 *serial, int offset)
|
||||||
|
{
|
||||||
|
return serial8250_in(serial, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void serial8250_early_out(struct serial8250 *serial, int offset, int value)
|
||||||
|
{
|
||||||
|
serial8250_out(serial, offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial8250_early_putc(struct rt_serial_device *raw_serial, char c)
|
||||||
|
{
|
||||||
|
if (raw_serial)
|
||||||
|
{
|
||||||
|
/* FIFO and shifting register empty */
|
||||||
|
const int uart_lsr_both_empty = (UART_LSR_TEMT | UART_LSR_THRE);
|
||||||
|
struct serial8250 *serial = rt_container_of(raw_serial, struct serial8250, parent);
|
||||||
|
|
||||||
|
serial8250_early_out(serial, UART_TX, c);
|
||||||
|
|
||||||
|
while ((serial8250_early_in(serial, UART_LSR) & uart_lsr_both_empty) != uart_lsr_both_empty)
|
||||||
|
{
|
||||||
|
rt_hw_cpu_relax();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_serial(struct serial8250 *serial)
|
||||||
|
{
|
||||||
|
unsigned char c;
|
||||||
|
rt_uint32_t ier, divisor;
|
||||||
|
|
||||||
|
serial8250_early_out(serial, UART_LCR, 0x3); /* 8n1 */
|
||||||
|
ier = serial8250_early_in(serial, UART_IER);
|
||||||
|
serial8250_early_out(serial, UART_IER, ier & UART_IER_UUE); /* no interrupt */
|
||||||
|
serial8250_early_out(serial, UART_FCR, 0); /* no fifo */
|
||||||
|
serial8250_early_out(serial, UART_MCR, 0x3); /* DTR + RTS */
|
||||||
|
|
||||||
|
if (serial->freq)
|
||||||
|
{
|
||||||
|
divisor = RT_DIV_ROUND_CLOSEST(serial->freq, 16 * serial->parent.config.baud_rate);
|
||||||
|
c = serial8250_early_in(serial, UART_LCR);
|
||||||
|
serial8250_early_out(serial, UART_LCR, c | UART_LCR_DLAB);
|
||||||
|
serial8250_early_out(serial, UART_DLL, divisor & 0xff);
|
||||||
|
serial8250_early_out(serial, UART_DLM, (divisor >> 8) & 0xff);
|
||||||
|
serial8250_early_out(serial, UART_LCR, c & ~UART_LCR_DLAB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void serial8250_early_kick(struct rt_fdt_earlycon *con, int why)
|
||||||
|
{
|
||||||
|
struct serial8250 *serial = raw_to_serial8250(con->data);
|
||||||
|
|
||||||
|
switch (why)
|
||||||
|
{
|
||||||
|
case FDT_EARLYCON_KICK_UPDATE:
|
||||||
|
serial->base = rt_ioremap((void *)con->mmio, con->size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FDT_EARLYCON_KICK_COMPLETED:
|
||||||
|
rt_iounmap(serial->base);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t serial8250_early_fdt_setup(struct serial8250 *serial, struct rt_fdt_earlycon *con, const char *options)
|
||||||
|
{
|
||||||
|
rt_err_t ret = RT_EOK;
|
||||||
|
|
||||||
|
if (!serial->base && con)
|
||||||
|
{
|
||||||
|
serial8250_config(serial, options);
|
||||||
|
con->mmio = (rt_ubase_t)serial->base;
|
||||||
|
con->size = serial->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serial->base && con)
|
||||||
|
{
|
||||||
|
serial->base = rt_ioremap_early((void *)serial->base, serial->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serial->base && con)
|
||||||
|
{
|
||||||
|
con->console_putc = (typeof(con->console_putc))&serial8250_early_putc;
|
||||||
|
con->console_kick = serial8250_early_kick;
|
||||||
|
con->data = &serial->parent;
|
||||||
|
|
||||||
|
if (!serial->parent.config.baud_rate)
|
||||||
|
{
|
||||||
|
/* assume the device was initialized, only mask interrupts */
|
||||||
|
rt_uint32_t ier = serial8250_early_in(serial, UART_IER);
|
||||||
|
serial8250_early_out(serial, UART_IER, ier & UART_IER_UUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
init_serial(serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = -RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void common_init(struct serial8250 *serial, struct rt_fdt_earlycon *con)
|
||||||
|
{
|
||||||
|
serial->base = (void *)con->mmio;
|
||||||
|
serial->size = con->size;
|
||||||
|
serial->iotype = PORT_MMIO32;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t common_early_setup(struct rt_fdt_earlycon *con, const char *options)
|
||||||
|
{
|
||||||
|
struct serial8250 *serial = &early_serial8250;
|
||||||
|
|
||||||
|
common_init(serial, con);
|
||||||
|
serial->regshift = 2;
|
||||||
|
fdt_getprop_u32(con->fdt, con->nodeoffset, "reg-shift", &serial->regshift, RT_NULL);
|
||||||
|
|
||||||
|
return serial8250_early_fdt_setup(serial, con, options);
|
||||||
|
}
|
||||||
|
RT_FDT_EARLYCON_EXPORT(bcm2835aux, "uart8250", "brcm,bcm2835-aux-uart", common_early_setup);
|
||||||
|
RT_FDT_EARLYCON_EXPORT(tegra20, "uart8250", "nvidia,tegra20-uart", common_early_setup);
|
||||||
|
RT_FDT_EARLYCON_EXPORT(dw8250, "uart8250", "snps,dw-apb-uart", common_early_setup);
|
||||||
|
RT_FDT_EARLYCON_EXPORT(ns16550a, "uart8250", "ns16550a", common_early_setup);
|
||||||
|
RT_FDT_EARLYCON_EXPORT(ns16550, "uart8250", "ns16550", common_early_setup);
|
||||||
|
|
||||||
|
#ifdef RT_USING_8250_OMAP
|
||||||
|
static rt_err_t omap8250_early_setup(struct rt_fdt_earlycon *con, const char *options)
|
||||||
|
{
|
||||||
|
struct serial8250 *serial = &early_serial8250;
|
||||||
|
|
||||||
|
common_init(serial, con);
|
||||||
|
serial->regshift = 2;
|
||||||
|
|
||||||
|
return serial8250_early_fdt_setup(serial, con, options);
|
||||||
|
}
|
||||||
|
RT_FDT_EARLYCON_EXPORT(omap8250, "uart8250", "ti,omap2-uart", omap8250_early_setup);
|
||||||
|
RT_FDT_EARLYCON_EXPORT(omap8250, "uart8250", "ti,omap3-uart", omap8250_early_setup);
|
||||||
|
RT_FDT_EARLYCON_EXPORT(omap8250, "uart8250", "ti,omap4-uart", omap8250_early_setup);
|
||||||
|
#endif /* RT_USING_8250_OMAP */
|
|
@ -0,0 +1,378 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-11-21 GuEe-GUI first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
|
||||||
|
#include <ioremap.h>
|
||||||
|
#include <cpuport.h>
|
||||||
|
|
||||||
|
#include "regs.h"
|
||||||
|
#include "serial_dm.h"
|
||||||
|
|
||||||
|
#define UART_USR 0x1f /* In: UART Status Register */
|
||||||
|
#define UART_USR_RX_FIFO_FULL 0x10 /* Receive FIFO full */
|
||||||
|
#define UART_USR_RX_FIFO_NOT_EMPTY 0x08 /* Receive FIFO not empty */
|
||||||
|
#define UART_USR_TX_FIFO_EMPTY 0x04 /* Transmit FIFO empty */
|
||||||
|
#define UART_USR_TX_FIFO_NOT_FULL 0x02 /* Transmit FIFO not full */
|
||||||
|
#define UART_USR_BUSY 0x01 /* UART busy indicator */
|
||||||
|
#define UART_SRR 0x22 /* software reset register */
|
||||||
|
|
||||||
|
#define FIQ_DEBUGGER_NO_CHAR -1
|
||||||
|
#define FIQ_DEBUGGER_BREAK -2
|
||||||
|
|
||||||
|
struct rockchip_fiq_debugger
|
||||||
|
{
|
||||||
|
struct rt_serial_device parent;
|
||||||
|
|
||||||
|
int irq;
|
||||||
|
int baudrate;
|
||||||
|
void *debug_port_base;
|
||||||
|
rt_bool_t break_seen;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define raw_to_fiq_debugger(raw) rt_container_of(raw, struct rockchip_fiq_debugger, parent)
|
||||||
|
|
||||||
|
rt_inline void rockchip_fiq_write(struct rockchip_fiq_debugger *t, rt_uint32_t val, int off)
|
||||||
|
{
|
||||||
|
HWREG32(t->debug_port_base + off * 4) = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline rt_uint32_t rockchip_fiq_read(struct rockchip_fiq_debugger *t, int off)
|
||||||
|
{
|
||||||
|
return HWREG32(t->debug_port_base + off * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline rt_uint32_t rockchip_fiq_read_lsr(struct rockchip_fiq_debugger *t)
|
||||||
|
{
|
||||||
|
rt_uint32_t ret = rockchip_fiq_read(t, UART_LSR);
|
||||||
|
|
||||||
|
if (ret & UART_LSR_BI)
|
||||||
|
{
|
||||||
|
t->break_seen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fiq_debugger_isr(int irqno, void *param)
|
||||||
|
{
|
||||||
|
rt_uint32_t usr;
|
||||||
|
struct rt_serial_device *serial = (struct rt_serial_device*)param;
|
||||||
|
struct rockchip_fiq_debugger *t = raw_to_fiq_debugger(serial);
|
||||||
|
|
||||||
|
usr = rockchip_fiq_read(t, UART_USR);
|
||||||
|
|
||||||
|
if ((usr & UART_USR_RX_FIFO_NOT_EMPTY) == UART_USR_RX_FIFO_NOT_EMPTY)
|
||||||
|
{
|
||||||
|
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((usr & UART_USR_BUSY) == UART_USR_BUSY)
|
||||||
|
{
|
||||||
|
/* Clear the USR */
|
||||||
|
(void)rockchip_fiq_read(t, UART_USR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t fiq_debugger_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
|
||||||
|
{
|
||||||
|
int dll = 0, dlm = 0;
|
||||||
|
rt_uint32_t count = 10000;
|
||||||
|
struct rockchip_fiq_debugger *t = raw_to_fiq_debugger(serial);
|
||||||
|
|
||||||
|
if (rockchip_fiq_read(t, UART_LSR) & UART_LSR_DR)
|
||||||
|
{
|
||||||
|
(void)rockchip_fiq_read(t, UART_RX);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!(rockchip_fiq_read(t, UART_LSR) & UART_LSR_TEMT) && count--)
|
||||||
|
{
|
||||||
|
rt_hw_us_delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (t->baudrate)
|
||||||
|
{
|
||||||
|
case 1500000:
|
||||||
|
dll = 0x1;
|
||||||
|
break;
|
||||||
|
case 115200:
|
||||||
|
default:
|
||||||
|
dll = 0xd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* reset uart */
|
||||||
|
rockchip_fiq_write(t, (1 << 1) | (1 << 2), UART_SRR);
|
||||||
|
rt_hw_us_delay(10);
|
||||||
|
/* set uart to loop back mode */
|
||||||
|
rockchip_fiq_write(t, 0x10, UART_MCR);
|
||||||
|
|
||||||
|
rockchip_fiq_write(t, 0x83, UART_LCR);
|
||||||
|
/* set baud rate */
|
||||||
|
rockchip_fiq_write(t, dll, UART_DLL);
|
||||||
|
rockchip_fiq_write(t, dlm, UART_DLM);
|
||||||
|
rockchip_fiq_write(t, 0x03, UART_LCR);
|
||||||
|
|
||||||
|
/* enable rx interrupt */
|
||||||
|
rockchip_fiq_write(t, UART_IER_RDI, UART_IER);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* interrupt on every character when received, but we can enable fifo for TX
|
||||||
|
* I found that if we enable the RX fifo, some problem may vanish such as
|
||||||
|
* when you continuously input characters in the command line the uart irq
|
||||||
|
* may be disable because of the uart irq is served when CPU is at IRQ
|
||||||
|
* exception, but it is found unregistered, so it is disable.
|
||||||
|
*/
|
||||||
|
rockchip_fiq_write(t, 0x01, UART_FCR);
|
||||||
|
|
||||||
|
/* disbale loop back mode */
|
||||||
|
rockchip_fiq_write(t, 0x0, UART_MCR);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t fiq_debugger_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
|
||||||
|
{
|
||||||
|
struct rockchip_fiq_debugger *t = raw_to_fiq_debugger(serial);
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case RT_DEVICE_CTRL_CLR_INT:
|
||||||
|
rt_pic_irq_mask(t->irq);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RT_DEVICE_CTRL_SET_INT:
|
||||||
|
rt_pic_irq_unmask(t->irq);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fiq_debugger_uart_putc(struct rt_serial_device *serial, char c)
|
||||||
|
{
|
||||||
|
struct rockchip_fiq_debugger *t = raw_to_fiq_debugger(serial);
|
||||||
|
rt_uint32_t count = 10000;
|
||||||
|
|
||||||
|
while (!(rockchip_fiq_read(t, UART_USR) & UART_USR_TX_FIFO_NOT_FULL) && count--)
|
||||||
|
{
|
||||||
|
rt_hw_cpu_relax();
|
||||||
|
}
|
||||||
|
|
||||||
|
rockchip_fiq_write(t, c, UART_TX);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fiq_debugger_uart_getc(struct rt_serial_device *serial)
|
||||||
|
{
|
||||||
|
int ch = FIQ_DEBUGGER_NO_CHAR;
|
||||||
|
rt_uint32_t lsr, temp;
|
||||||
|
static rt_uint32_t n = 0;
|
||||||
|
static char buf[32] = {};
|
||||||
|
struct rockchip_fiq_debugger *t = raw_to_fiq_debugger(serial);
|
||||||
|
|
||||||
|
/* Clear uart interrupt status */
|
||||||
|
rockchip_fiq_read(t, UART_USR);
|
||||||
|
lsr = rockchip_fiq_read_lsr(t);
|
||||||
|
|
||||||
|
if (lsr & UART_LSR_DR)
|
||||||
|
{
|
||||||
|
temp = rockchip_fiq_read(t, UART_RX);
|
||||||
|
buf[n & 0x1f] = temp;
|
||||||
|
n++;
|
||||||
|
|
||||||
|
if (temp == 'q' && n > 2)
|
||||||
|
{
|
||||||
|
if ((buf[(n - 2) & 0x1f] == 'i') && (buf[(n - 3) & 0x1f] == 'f'))
|
||||||
|
{
|
||||||
|
ch = FIQ_DEBUGGER_BREAK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct rt_uart_ops fiq_debugger_uart_ops =
|
||||||
|
{
|
||||||
|
.configure = fiq_debugger_uart_configure,
|
||||||
|
.control = fiq_debugger_uart_control,
|
||||||
|
.putc = fiq_debugger_uart_putc,
|
||||||
|
.getc = fiq_debugger_uart_getc,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rockchip_fiq_debugger *rk_serial_debug_init(void *base, rt_ubase_t paddr,
|
||||||
|
int irq, int signal_irq, int wakeup_irq, rt_uint32_t baudrate)
|
||||||
|
{
|
||||||
|
struct rockchip_fiq_debugger *t = rt_calloc(1, sizeof(*t));
|
||||||
|
|
||||||
|
if (t)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
t->parent.ops = &fiq_debugger_uart_ops;
|
||||||
|
t->parent.config = (struct serial_configure)RT_SERIAL_CONFIG_DEFAULT;
|
||||||
|
t->parent.config.baud_rate = baudrate;
|
||||||
|
t->irq = irq;
|
||||||
|
t->baudrate = baudrate;
|
||||||
|
t->debug_port_base = base;
|
||||||
|
t->break_seen = RT_FALSE;
|
||||||
|
|
||||||
|
serial_dev_set_name(&t->parent);
|
||||||
|
name = rt_dm_dev_get_name(&t->parent.parent);
|
||||||
|
|
||||||
|
rt_hw_serial_register(&t->parent, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, t);
|
||||||
|
rt_pic_attach_irq(t->irq, fiq_debugger_isr, &t->parent, name, RT_IRQ_F_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rockchip_fiq_debugger_probe(struct rt_platform_device *pdev)
|
||||||
|
{
|
||||||
|
rt_err_t err = RT_EOK;
|
||||||
|
void *base;
|
||||||
|
rt_uint64_t regs[2];
|
||||||
|
struct rt_clk *clk, *pclk;
|
||||||
|
rt_bool_t found = RT_FALSE;
|
||||||
|
char dev_name[RT_NAME_MAX];
|
||||||
|
int irq, signal_irq = -1;
|
||||||
|
rt_uint32_t serial_id, baudrate = 0, irq_mode = 0, wake_irq = -1;
|
||||||
|
struct rt_ofw_node *np = pdev->parent.ofw_node;
|
||||||
|
|
||||||
|
if (rt_ofw_prop_read_u32(np, "rockchip,serial-id", &serial_id) || serial_id == -1)
|
||||||
|
{
|
||||||
|
return -RT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rt_ofw_prop_read_u32(np, "rockchip,irq-mode-enable", &irq_mode))
|
||||||
|
{
|
||||||
|
irq_mode = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (irq_mode == 1)
|
||||||
|
{
|
||||||
|
signal_irq = -1;
|
||||||
|
}
|
||||||
|
else if (!(signal_irq = rt_ofw_get_irq(np, 0)))
|
||||||
|
{
|
||||||
|
return -RT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rt_ofw_prop_read_u32(np, "rockchip,wake-irq", &wake_irq))
|
||||||
|
{
|
||||||
|
wake_irq = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rt_ofw_prop_read_u32(np, "rockchip,baudrate", &baudrate))
|
||||||
|
{
|
||||||
|
baudrate = 1500000;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_snprintf(dev_name, RT_NAME_MAX, "serial%d", serial_id);
|
||||||
|
|
||||||
|
np = RT_NULL;
|
||||||
|
|
||||||
|
do {
|
||||||
|
np = rt_ofw_find_node_by_tag(np, "serial");
|
||||||
|
|
||||||
|
if (np && rt_ofw_get_alias_id(np, "serial") == serial_id)
|
||||||
|
{
|
||||||
|
found = RT_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while(np);
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
return -RT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_memset(regs, 0, sizeof(regs));
|
||||||
|
rt_ofw_get_address_array(np, 1, regs);
|
||||||
|
|
||||||
|
pclk = rt_ofw_get_clk_by_name(np, "apb_pclk");
|
||||||
|
clk = rt_ofw_get_clk_by_name(np, "baudclk");
|
||||||
|
|
||||||
|
if (!pclk || !clk)
|
||||||
|
{
|
||||||
|
err = -RT_ERROR;
|
||||||
|
goto _fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_clk_enable(clk);
|
||||||
|
rt_clk_enable(pclk);
|
||||||
|
|
||||||
|
if ((irq = rt_ofw_get_irq(np, 0)) < 0)
|
||||||
|
{
|
||||||
|
err = -RT_ERROR;
|
||||||
|
goto _fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((base = rt_ioremap((void *)regs[0], regs[1])))
|
||||||
|
{
|
||||||
|
struct rockchip_fiq_debugger *t = rk_serial_debug_init(base,
|
||||||
|
(rt_ubase_t)regs[0], irq, signal_irq, wake_irq, baudrate);
|
||||||
|
|
||||||
|
if (t)
|
||||||
|
{
|
||||||
|
rt_dm_dev_bind_fwdata(&t->parent.parent, pdev->parent.ofw_node, &t->parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
|
||||||
|
_fail:
|
||||||
|
if (clk)
|
||||||
|
{
|
||||||
|
rt_clk_disable(clk);
|
||||||
|
rt_clk_put(clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pclk)
|
||||||
|
{
|
||||||
|
rt_clk_disable(pclk);
|
||||||
|
rt_clk_put(pclk);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct rt_ofw_node_id rockchip_fiq_debugger_ofw_ids[] =
|
||||||
|
{
|
||||||
|
{ .type = "ttyFIQ", .compatible = "rockchip,fiq-debugger" },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct rt_platform_driver rockchip_fiq_debugger_driver =
|
||||||
|
{
|
||||||
|
.name = "rockchip-fiq-debugger",
|
||||||
|
.ids = rockchip_fiq_debugger_ofw_ids,
|
||||||
|
|
||||||
|
.probe = rockchip_fiq_debugger_probe,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rockchip_fiq_debugger_drv_register(void)
|
||||||
|
{
|
||||||
|
rt_platform_driver_register(&rockchip_fiq_debugger_driver);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_DRIVER_EARLY_EXPORT(rockchip_fiq_debugger_drv_register);
|
|
@ -0,0 +1,365 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SERIAL_8250_REGS_H__
|
||||||
|
#define __SERIAL_8250_REGS_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DLAB=0
|
||||||
|
*/
|
||||||
|
#define UART_RX 0 /* In: Receive buffer */
|
||||||
|
#define UART_TX 0 /* Out: Transmit buffer */
|
||||||
|
|
||||||
|
#define UART_IER 1 /* Out: Interrupt Enable Register */
|
||||||
|
#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
|
||||||
|
#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
|
||||||
|
#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
|
||||||
|
#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
|
||||||
|
/*
|
||||||
|
* Sleep mode for ST16650 and TI16750. For the ST16650, EFR[4]=1
|
||||||
|
*/
|
||||||
|
#define UART_IERX_SLEEP 0x10 /* Enable sleep mode */
|
||||||
|
|
||||||
|
#define UART_IIR 2 /* In: Interrupt ID Register */
|
||||||
|
#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
|
||||||
|
#define UART_IIR_ID 0x0e /* Mask for the interrupt ID */
|
||||||
|
#define UART_IIR_MSI 0x00 /* Modem status interrupt */
|
||||||
|
#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
|
||||||
|
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
|
||||||
|
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
|
||||||
|
|
||||||
|
#define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */
|
||||||
|
|
||||||
|
#define UART_IIR_RX_TIMEOUT 0x0c /* OMAP RX Timeout interrupt */
|
||||||
|
#define UART_IIR_XOFF 0x10 /* OMAP XOFF/Special Character */
|
||||||
|
#define UART_IIR_CTS_RTS_DSR 0x20 /* OMAP CTS/RTS/DSR Change */
|
||||||
|
|
||||||
|
#define UART_FCR 2 /* Out: FIFO Control Register */
|
||||||
|
#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
|
||||||
|
#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
|
||||||
|
#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */
|
||||||
|
#define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */
|
||||||
|
/*
|
||||||
|
* Note: The FIFO trigger levels are chip specific:
|
||||||
|
* RX:76 = 00 01 10 11 TX:54 = 00 01 10 11
|
||||||
|
* PC16550D: 1 4 8 14 xx xx xx xx
|
||||||
|
* TI16C550A: 1 4 8 14 xx xx xx xx
|
||||||
|
* TI16C550C: 1 4 8 14 xx xx xx xx
|
||||||
|
* ST16C550: 1 4 8 14 xx xx xx xx
|
||||||
|
* ST16C650: 8 16 24 28 16 8 24 30 PORT_16650V2
|
||||||
|
* NS16C552: 1 4 8 14 xx xx xx xx
|
||||||
|
* ST16C654: 8 16 56 60 8 16 32 56 PORT_16654
|
||||||
|
* TI16C750: 1 16 32 56 xx xx xx xx PORT_16750
|
||||||
|
* TI16C752: 8 16 56 60 8 16 32 56
|
||||||
|
* OX16C950: 16 32 112 120 16 32 64 112 PORT_16C950
|
||||||
|
* Tegra: 1 4 8 14 16 8 4 1 PORT_TEGRA
|
||||||
|
*/
|
||||||
|
#define UART_FCR_R_TRIG_00 0x00
|
||||||
|
#define UART_FCR_R_TRIG_01 0x40
|
||||||
|
#define UART_FCR_R_TRIG_10 0x80
|
||||||
|
#define UART_FCR_R_TRIG_11 0xc0
|
||||||
|
#define UART_FCR_T_TRIG_00 0x00
|
||||||
|
#define UART_FCR_T_TRIG_01 0x10
|
||||||
|
#define UART_FCR_T_TRIG_10 0x20
|
||||||
|
#define UART_FCR_T_TRIG_11 0x30
|
||||||
|
|
||||||
|
#define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */
|
||||||
|
#define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */
|
||||||
|
#define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */
|
||||||
|
#define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */
|
||||||
|
#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */
|
||||||
|
/* 16650 definitions */
|
||||||
|
#define UART_FCR6_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 1 */
|
||||||
|
#define UART_FCR6_R_TRIGGER_16 0x40 /* Mask for receive trigger set at 4 */
|
||||||
|
#define UART_FCR6_R_TRIGGER_24 0x80 /* Mask for receive trigger set at 8 */
|
||||||
|
#define UART_FCR6_R_TRIGGER_28 0xC0 /* Mask for receive trigger set at 14 */
|
||||||
|
#define UART_FCR6_T_TRIGGER_16 0x00 /* Mask for transmit trigger set at 16 */
|
||||||
|
#define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */
|
||||||
|
#define UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */
|
||||||
|
#define UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */
|
||||||
|
#define UART_FCR7_64BYTE 0x20 /* Go into 64 byte mode (TI16C750 and some Freescale UARTs) */
|
||||||
|
|
||||||
|
#define UART_FCR_R_TRIG_SHIFT 6
|
||||||
|
#define UART_FCR_R_TRIG_BITS(x) (((x) & UART_FCR_TRIGGER_MASK) >> UART_FCR_R_TRIG_SHIFT)
|
||||||
|
#define UART_FCR_R_TRIG_MAX_STATE 4
|
||||||
|
|
||||||
|
#define UART_LCR 3 /* Out: Line Control Register */
|
||||||
|
/*
|
||||||
|
* Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting
|
||||||
|
* UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
|
||||||
|
*/
|
||||||
|
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
|
||||||
|
#define UART_LCR_SBC 0x40 /* Set break control */
|
||||||
|
#define UART_LCR_SPAR 0x20 /* Stick parity (?) */
|
||||||
|
#define UART_LCR_EPAR 0x10 /* Even parity select */
|
||||||
|
#define UART_LCR_PARITY 0x08 /* Parity Enable */
|
||||||
|
#define UART_LCR_STOP 0x04 /* Stop bits: 0=1 bit, 1=2 bits */
|
||||||
|
#define UART_LCR_WLEN5 0x00 /* Wordlength: 5 bits */
|
||||||
|
#define UART_LCR_WLEN6 0x01 /* Wordlength: 6 bits */
|
||||||
|
#define UART_LCR_WLEN7 0x02 /* Wordlength: 7 bits */
|
||||||
|
#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access to some registers depends on register access / configuration mode.
|
||||||
|
*/
|
||||||
|
#define UART_LCR_CONF_MODE_A UART_LCR_DLAB /* Configutation mode A */
|
||||||
|
#define UART_LCR_CONF_MODE_B 0xBF /* Configutation mode B */
|
||||||
|
|
||||||
|
#define UART_MCR 4 /* Out: Modem Control Register */
|
||||||
|
#define UART_MCR_CLKSEL 0x80 /* Divide clock by 4 (TI16C752, EFR[4]=1) */
|
||||||
|
#define UART_MCR_TCRTLR 0x40 /* Access TCR/TLR (TI16C752, EFR[4]=1) */
|
||||||
|
#define UART_MCR_XONANY 0x20 /* Enable Xon Any (TI16C752, EFR[4]=1) */
|
||||||
|
#define UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS (TI16C550C/TI16C750) */
|
||||||
|
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
|
||||||
|
#define UART_MCR_OUT2 0x08 /* Out2 complement */
|
||||||
|
#define UART_MCR_OUT1 0x04 /* Out1 complement */
|
||||||
|
#define UART_MCR_RTS 0x02 /* RTS complement */
|
||||||
|
#define UART_MCR_DTR 0x01 /* DTR complement */
|
||||||
|
|
||||||
|
#define UART_LSR 5 /* In: Line Status Register */
|
||||||
|
#define UART_LSR_FIFOE 0x80 /* Fifo error */
|
||||||
|
#define UART_LSR_TEMT 0x40 /* Transmitter empty */
|
||||||
|
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
|
||||||
|
#define UART_LSR_BI 0x10 /* Break interrupt indicator */
|
||||||
|
#define UART_LSR_FE 0x08 /* Frame error indicator */
|
||||||
|
#define UART_LSR_PE 0x04 /* Parity error indicator */
|
||||||
|
#define UART_LSR_OE 0x02 /* Overrun error indicator */
|
||||||
|
#define UART_LSR_DR 0x01 /* Receiver data ready */
|
||||||
|
#define UART_LSR_BRK_ERROR_BITS (UART_LSR_BI|UART_LSR_FE|UART_LSR_PE|UART_LSR_OE)
|
||||||
|
|
||||||
|
#define UART_MSR 6 /* In: Modem Status Register */
|
||||||
|
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
|
||||||
|
#define UART_MSR_RI 0x40 /* Ring Indicator */
|
||||||
|
#define UART_MSR_DSR 0x20 /* Data Set Ready */
|
||||||
|
#define UART_MSR_CTS 0x10 /* Clear to Send */
|
||||||
|
#define UART_MSR_DDCD 0x08 /* Delta DCD */
|
||||||
|
#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
|
||||||
|
#define UART_MSR_DDSR 0x02 /* Delta DSR */
|
||||||
|
#define UART_MSR_DCTS 0x01 /* Delta CTS */
|
||||||
|
#define UART_MSR_ANY_DELTA (UART_MSR_DDCD|UART_MSR_TERI|UART_MSR_DDSR|UART_MSR_DCTS)
|
||||||
|
|
||||||
|
#define UART_SCR 7 /* I/O: Scratch Register */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DLAB=1
|
||||||
|
*/
|
||||||
|
#define UART_DLL 0 /* Out: Divisor Latch Low */
|
||||||
|
#define UART_DLM 1 /* Out: Divisor Latch High */
|
||||||
|
#define UART_DIV_MAX 0xFFFF /* Max divisor value */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LCR=0xBF (or DLAB=1 for 16C660)
|
||||||
|
*/
|
||||||
|
#define UART_EFR 2 /* I/O: Extended Features Register */
|
||||||
|
#define UART_XR_EFR 9 /* I/O: Extended Features Register (XR17D15x) */
|
||||||
|
#define UART_EFR_CTS 0x80 /* CTS flow control */
|
||||||
|
#define UART_EFR_RTS 0x40 /* RTS flow control */
|
||||||
|
#define UART_EFR_SCD 0x20 /* Special character detect */
|
||||||
|
#define UART_EFR_ECB 0x10 /* Enhanced control bit */
|
||||||
|
/*
|
||||||
|
* the low four bits control software flow control
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LCR=0xBF, TI16C752, ST16650, ST16650A, ST16654
|
||||||
|
*/
|
||||||
|
#define UART_XON1 4 /* I/O: Xon character 1 */
|
||||||
|
#define UART_XON2 5 /* I/O: Xon character 2 */
|
||||||
|
#define UART_XOFF1 6 /* I/O: Xoff character 1 */
|
||||||
|
#define UART_XOFF2 7 /* I/O: Xoff character 2 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EFR[4]=1 MCR[6]=1, TI16C752
|
||||||
|
*/
|
||||||
|
#define UART_TI752_TCR 6 /* I/O: transmission control register */
|
||||||
|
#define UART_TI752_TLR 7 /* I/O: trigger level register */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LCR=0xBF, XR16C85x
|
||||||
|
*/
|
||||||
|
#define UART_TRG 0 /* FCTR bit 7 selects Rx or Tx In: Fifo count Out: Fifo custom trigger levels */
|
||||||
|
/*
|
||||||
|
* These are the definitions for the Programmable Trigger Register
|
||||||
|
*/
|
||||||
|
#define UART_TRG_1 0x01
|
||||||
|
#define UART_TRG_4 0x04
|
||||||
|
#define UART_TRG_8 0x08
|
||||||
|
#define UART_TRG_16 0x10
|
||||||
|
#define UART_TRG_32 0x20
|
||||||
|
#define UART_TRG_64 0x40
|
||||||
|
#define UART_TRG_96 0x60
|
||||||
|
#define UART_TRG_120 0x78
|
||||||
|
#define UART_TRG_128 0x80
|
||||||
|
|
||||||
|
#define UART_FCTR 1 /* Feature Control Register */
|
||||||
|
#define UART_FCTR_RTS_NODELAY 0x00 /* RTS flow control delay */
|
||||||
|
#define UART_FCTR_RTS_4DELAY 0x01
|
||||||
|
#define UART_FCTR_RTS_6DELAY 0x02
|
||||||
|
#define UART_FCTR_RTS_8DELAY 0x03
|
||||||
|
#define UART_FCTR_IRDA 0x04 /* IrDa data encode select */
|
||||||
|
#define UART_FCTR_TX_INT 0x08 /* Tx interrupt type select */
|
||||||
|
#define UART_FCTR_TRGA 0x00 /* Tx/Rx 550 trigger table select */
|
||||||
|
#define UART_FCTR_TRGB 0x10 /* Tx/Rx 650 trigger table select */
|
||||||
|
#define UART_FCTR_TRGC 0x20 /* Tx/Rx 654 trigger table select */
|
||||||
|
#define UART_FCTR_TRGD 0x30 /* Tx/Rx 850 programmable trigger select */
|
||||||
|
#define UART_FCTR_SCR_SWAP 0x40 /* Scratch pad register swap */
|
||||||
|
#define UART_FCTR_RX 0x00 /* Programmable trigger mode select */
|
||||||
|
#define UART_FCTR_TX 0x80 /* Programmable trigger mode select */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LCR=0xBF, FCTR[6]=1
|
||||||
|
*/
|
||||||
|
#define UART_EMSR 7 /* Extended Mode Select Register */
|
||||||
|
#define UART_EMSR_FIFO_COUNT 0x01 /* Rx/Tx select */
|
||||||
|
#define UART_EMSR_ALT_COUNT 0x02 /* Alternating count select */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Intel XScale on-chip UARTs define these bits
|
||||||
|
*/
|
||||||
|
#define UART_IER_DMAE 0x80 /* DMA Requests Enable */
|
||||||
|
#define UART_IER_UUE 0x40 /* UART Unit Enable */
|
||||||
|
#define UART_IER_NRZE 0x20 /* NRZ coding Enable */
|
||||||
|
#define UART_IER_RTOIE 0x10 /* Receiver Time Out Interrupt Enable */
|
||||||
|
|
||||||
|
#define UART_IIR_TOD 0x08 /* Character Timeout Indication Detected */
|
||||||
|
|
||||||
|
#define UART_FCR_PXAR1 0x00 /* receive FIFO threshold = 1 */
|
||||||
|
#define UART_FCR_PXAR8 0x40 /* receive FIFO threshold = 8 */
|
||||||
|
#define UART_FCR_PXAR16 0x80 /* receive FIFO threshold = 16 */
|
||||||
|
#define UART_FCR_PXAR32 0xc0 /* receive FIFO threshold = 32 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These register definitions are for the 16C950
|
||||||
|
*/
|
||||||
|
#define UART_ASR 0x01 /* Additional Status Register */
|
||||||
|
#define UART_RFL 0x03 /* Receiver FIFO level */
|
||||||
|
#define UART_TFL 0x04 /* Transmitter FIFO level */
|
||||||
|
#define UART_ICR 0x05 /* Index Control Register */
|
||||||
|
|
||||||
|
/* The 16950 ICR registers */
|
||||||
|
#define UART_ACR 0x00 /* Additional Control Register */
|
||||||
|
#define UART_CPR 0x01 /* Clock Prescalar Register */
|
||||||
|
#define UART_TCR 0x02 /* Times Clock Register */
|
||||||
|
#define UART_CKS 0x03 /* Clock Select Register */
|
||||||
|
#define UART_TTL 0x04 /* Transmitter Interrupt Trigger Level */
|
||||||
|
#define UART_RTL 0x05 /* Receiver Interrupt Trigger Level */
|
||||||
|
#define UART_FCL 0x06 /* Flow Control Level Lower */
|
||||||
|
#define UART_FCH 0x07 /* Flow Control Level Higher */
|
||||||
|
#define UART_ID1 0x08 /* ID #1 */
|
||||||
|
#define UART_ID2 0x09 /* ID #2 */
|
||||||
|
#define UART_ID3 0x0A /* ID #3 */
|
||||||
|
#define UART_REV 0x0B /* Revision */
|
||||||
|
#define UART_CSR 0x0C /* Channel Software Reset */
|
||||||
|
#define UART_NMR 0x0D /* Nine-bit Mode Register */
|
||||||
|
#define UART_CTR 0xFF
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 16C950 Additional Control Register
|
||||||
|
*/
|
||||||
|
#define UART_ACR_RXDIS 0x01 /* Receiver disable */
|
||||||
|
#define UART_ACR_TXDIS 0x02 /* Transmitter disable */
|
||||||
|
#define UART_ACR_DSRFC 0x04 /* DSR Flow Control */
|
||||||
|
#define UART_ACR_TLENB 0x20 /* 950 trigger levels enable */
|
||||||
|
#define UART_ACR_ICRRD 0x40 /* ICR Read enable */
|
||||||
|
#define UART_ACR_ASREN 0x80 /* Additional status enable */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These definitions are for the RSA-DV II/S card, from
|
||||||
|
*
|
||||||
|
* Kiyokazu SUTO <suto@ks-and-ks.ne.jp>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define UART_RSA_BASE (-8)
|
||||||
|
|
||||||
|
#define UART_RSA_MSR ((UART_RSA_BASE) + 0) /* I/O: Mode Select Register */
|
||||||
|
|
||||||
|
#define UART_RSA_MSR_SWAP (1 << 0) /* Swap low/high 8 bytes in I/O port addr */
|
||||||
|
#define UART_RSA_MSR_FIFO (1 << 2) /* Enable the external FIFO */
|
||||||
|
#define UART_RSA_MSR_FLOW (1 << 3) /* Enable the auto RTS/CTS flow control */
|
||||||
|
#define UART_RSA_MSR_ITYP (1 << 4) /* Level (1) / Edge triger (0) */
|
||||||
|
|
||||||
|
#define UART_RSA_IER ((UART_RSA_BASE) + 1) /* I/O: Interrupt Enable Register */
|
||||||
|
|
||||||
|
#define UART_RSA_IER_Rx_FIFO_H (1 << 0) /* Enable Rx FIFO half full int. */
|
||||||
|
#define UART_RSA_IER_Tx_FIFO_H (1 << 1) /* Enable Tx FIFO half full int. */
|
||||||
|
#define UART_RSA_IER_Tx_FIFO_E (1 << 2) /* Enable Tx FIFO empty int. */
|
||||||
|
#define UART_RSA_IER_Rx_TOUT (1 << 3) /* Enable char receive timeout int */
|
||||||
|
#define UART_RSA_IER_TIMER (1 << 4) /* Enable timer interrupt */
|
||||||
|
|
||||||
|
#define UART_RSA_SRR ((UART_RSA_BASE) + 2) /* IN: Status Read Register */
|
||||||
|
|
||||||
|
#define UART_RSA_SRR_Tx_FIFO_NEMP (1 << 0) /* Tx FIFO is not empty (1) */
|
||||||
|
#define UART_RSA_SRR_Tx_FIFO_NHFL (1 << 1) /* Tx FIFO is not half full (1) */
|
||||||
|
#define UART_RSA_SRR_Tx_FIFO_NFUL (1 << 2) /* Tx FIFO is not full (1) */
|
||||||
|
#define UART_RSA_SRR_Rx_FIFO_NEMP (1 << 3) /* Rx FIFO is not empty (1) */
|
||||||
|
#define UART_RSA_SRR_Rx_FIFO_NHFL (1 << 4) /* Rx FIFO is not half full (1) */
|
||||||
|
#define UART_RSA_SRR_Rx_FIFO_NFUL (1 << 5) /* Rx FIFO is not full (1) */
|
||||||
|
#define UART_RSA_SRR_Rx_TOUT (1 << 6) /* Character reception timeout occurred (1) */
|
||||||
|
#define UART_RSA_SRR_TIMER (1 << 7) /* Timer interrupt occurred */
|
||||||
|
|
||||||
|
#define UART_RSA_FRR ((UART_RSA_BASE) + 2) /* OUT: FIFO Reset Register */
|
||||||
|
|
||||||
|
#define UART_RSA_TIVSR ((UART_RSA_BASE) + 3) /* I/O: Timer Interval Value Set Register */
|
||||||
|
|
||||||
|
#define UART_RSA_TCR ((UART_RSA_BASE) + 4) /* OUT: Timer Control Register */
|
||||||
|
|
||||||
|
#define UART_RSA_TCR_SWITCH (1 << 0) /* Timer on */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The RSA DSV/II board has two fixed clock frequencies. One is the
|
||||||
|
* standard rate, and the other is 8 times faster.
|
||||||
|
*/
|
||||||
|
#define SERIAL_RSA_BAUD_BASE (921600)
|
||||||
|
#define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8)
|
||||||
|
|
||||||
|
/* Extra registers for TI DA8xx/66AK2x */
|
||||||
|
#define UART_DA830_PWREMU_MGMT 12
|
||||||
|
|
||||||
|
/* PWREMU_MGMT register bits */
|
||||||
|
#define UART_DA830_PWREMU_MGMT_FREE (1 << 0) /* Free-running mode */
|
||||||
|
#define UART_DA830_PWREMU_MGMT_URRST (1 << 13) /* Receiver reset/enable */
|
||||||
|
#define UART_DA830_PWREMU_MGMT_UTRST (1 << 14) /* Transmitter reset/enable */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra serial register definitions for the internal UARTs
|
||||||
|
* in TI OMAP processors.
|
||||||
|
*/
|
||||||
|
#define OMAP1_UART1_BASE 0xfffb0000
|
||||||
|
#define OMAP1_UART2_BASE 0xfffb0800
|
||||||
|
#define OMAP1_UART3_BASE 0xfffb9800
|
||||||
|
#define UART_OMAP_MDR1 0x08 /* Mode definition register */
|
||||||
|
#define UART_OMAP_MDR2 0x09 /* Mode definition register 2 */
|
||||||
|
#define UART_OMAP_SCR 0x10 /* Supplementary control register */
|
||||||
|
#define UART_OMAP_SSR 0x11 /* Supplementary status register */
|
||||||
|
#define UART_OMAP_EBLR 0x12 /* BOF length register */
|
||||||
|
#define UART_OMAP_OSC_12M_SEL 0x13 /* OMAP1510 12MHz osc select */
|
||||||
|
#define UART_OMAP_MVER 0x14 /* Module version register */
|
||||||
|
#define UART_OMAP_SYSC 0x15 /* System configuration register */
|
||||||
|
#define UART_OMAP_SYSS 0x16 /* System status register */
|
||||||
|
#define UART_OMAP_WER 0x17 /* Wake-up enable register */
|
||||||
|
#define UART_OMAP_TX_LVL 0x1a /* TX FIFO level register */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are the definitions for the MDR1 register
|
||||||
|
*/
|
||||||
|
#define UART_OMAP_MDR1_16X_MODE 0x00 /* UART 16x mode */
|
||||||
|
#define UART_OMAP_MDR1_SIR_MODE 0x01 /* SIR mode */
|
||||||
|
#define UART_OMAP_MDR1_16X_ABAUD_MODE 0x02 /* UART 16x auto-baud */
|
||||||
|
#define UART_OMAP_MDR1_13X_MODE 0x03 /* UART 13x mode */
|
||||||
|
#define UART_OMAP_MDR1_MIR_MODE 0x04 /* MIR mode */
|
||||||
|
#define UART_OMAP_MDR1_FIR_MODE 0x05 /* FIR mode */
|
||||||
|
#define UART_OMAP_MDR1_CIR_MODE 0x06 /* CIR mode */
|
||||||
|
#define UART_OMAP_MDR1_DISABLE 0x07 /* Disable (default state) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are definitions for the Altera ALTR_16550_F32/F64/F128
|
||||||
|
* Normalized from 0x100 to 0x40 because of shift by 2 (32 bit regs).
|
||||||
|
*/
|
||||||
|
#define UART_ALTR_AFR 0x40 /* Additional Features Register */
|
||||||
|
#define UART_ALTR_EN_TXFIFO_LW 0x01 /* Enable the TX FIFO Low Watermark */
|
||||||
|
#define UART_ALTR_TX_LOW 0x41 /* Tx FIFO Low Watermark */
|
||||||
|
|
||||||
|
#endif /* __SERIAL_8250_REGS_H__ */
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-11-16 GuEe-GUI first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SERIAL_DM_H__
|
||||||
|
#define __SERIAL_DM_H__
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
#include <posix/string.h>
|
||||||
|
|
||||||
|
int serial_dev_set_name(struct rt_serial_device *sdev);
|
||||||
|
|
||||||
|
void *serial_base_from_args(char *str);
|
||||||
|
struct serial_configure serial_cfg_from_args(char *str);
|
||||||
|
|
||||||
|
#define serial_for_each_args(arg, args) \
|
||||||
|
for (char *context = (arg = (typeof(arg))args, (void *)RT_NULL), \
|
||||||
|
*context_end = strchrnul((char *)args, ' '); \
|
||||||
|
(arg = strtok_r(arg, ",", &context)) && arg < context_end; \
|
||||||
|
arg = RT_NULL)
|
||||||
|
|
||||||
|
#endif /* __SERIAL_DM_H__ */
|
|
@ -0,0 +1,568 @@
|
||||||
|
#ifndef RT_CONFIG_H__
|
||||||
|
#define RT_CONFIG_H__
|
||||||
|
|
||||||
|
/* RT-Thread Kernel */
|
||||||
|
|
||||||
|
#define RT_NAME_MAX 8
|
||||||
|
#define RT_USING_SMART
|
||||||
|
#define RT_USING_SMP
|
||||||
|
#define RT_CPUS_NR 4
|
||||||
|
#define RT_ALIGN_SIZE 8
|
||||||
|
#define RT_THREAD_PRIORITY_32
|
||||||
|
#define RT_THREAD_PRIORITY_MAX 32
|
||||||
|
#define RT_TICK_PER_SECOND 1000
|
||||||
|
#define RT_USING_HOOK
|
||||||
|
#define RT_HOOK_USING_FUNC_PTR
|
||||||
|
#define RT_USING_HOOKLIST
|
||||||
|
#define RT_USING_IDLE_HOOK
|
||||||
|
#define RT_IDLE_HOOK_LIST_SIZE 4
|
||||||
|
#define IDLE_THREAD_STACK_SIZE 16384
|
||||||
|
#define SYSTEM_THREAD_STACK_SIZE 16384
|
||||||
|
#define RT_USING_TIMER_SOFT
|
||||||
|
#define RT_TIMER_THREAD_PRIO 4
|
||||||
|
#define RT_TIMER_THREAD_STACK_SIZE 32768
|
||||||
|
#define RT_USING_TIMER_ALL_SOFT
|
||||||
|
#define RT_USING_CPU_USAGE_TRACER
|
||||||
|
|
||||||
|
/* kservice optimization */
|
||||||
|
|
||||||
|
/* end of kservice optimization */
|
||||||
|
|
||||||
|
/* klibc optimization */
|
||||||
|
|
||||||
|
#define RT_KLIBC_USING_PRINTF_LONGLONG
|
||||||
|
/* end of klibc optimization */
|
||||||
|
#define RT_USING_DEBUG
|
||||||
|
#define RT_DEBUGING_COLOR
|
||||||
|
|
||||||
|
/* Inter-Thread communication */
|
||||||
|
|
||||||
|
#define RT_USING_SEMAPHORE
|
||||||
|
#define RT_USING_MUTEX
|
||||||
|
#define RT_USING_EVENT
|
||||||
|
#define RT_USING_MAILBOX
|
||||||
|
#define RT_USING_MESSAGEQUEUE
|
||||||
|
#define RT_USING_MESSAGEQUEUE_PRIORITY
|
||||||
|
/* end of Inter-Thread communication */
|
||||||
|
|
||||||
|
/* Memory Management */
|
||||||
|
|
||||||
|
#define RT_PAGE_MAX_ORDER 11
|
||||||
|
#define RT_USING_SLAB
|
||||||
|
#define RT_USING_MEMHEAP
|
||||||
|
#define RT_MEMHEAP_FAST_MODE
|
||||||
|
#define RT_USING_MEMHEAP_AS_HEAP
|
||||||
|
#define RT_USING_MEMHEAP_AUTO_BINDING
|
||||||
|
#define RT_USING_HEAP
|
||||||
|
/* end of Memory Management */
|
||||||
|
#define RT_USING_DEVICE
|
||||||
|
#define RT_USING_DEVICE_OPS
|
||||||
|
#define RT_USING_THREADSAFE_PRINTF
|
||||||
|
#define RT_USING_CONSOLE
|
||||||
|
#define RT_CONSOLEBUF_SIZE 1024
|
||||||
|
#define RT_CONSOLE_DEVICE_NAME "uart2"
|
||||||
|
#define RT_VER_NUM 0x50200
|
||||||
|
#define RT_USING_STDC_ATOMIC
|
||||||
|
#define RT_BACKTRACE_LEVEL_MAX_NR 32
|
||||||
|
/* end of RT-Thread Kernel */
|
||||||
|
|
||||||
|
/* AArch64 Architecture Configuration */
|
||||||
|
|
||||||
|
#define ARCH_TEXT_OFFSET 0x00480000
|
||||||
|
#define ARCH_RAM_OFFSET 0x200000
|
||||||
|
#define ARCH_SECONDARY_CPU_STACK_SIZE 16384
|
||||||
|
#define ARCH_HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||||
|
#define ARCH_USING_GENERIC_CPUID
|
||||||
|
#define ARCH_HEAP_SIZE 0x4000000
|
||||||
|
#define ARCH_INIT_PAGE_SIZE 0x200000
|
||||||
|
/* end of AArch64 Architecture Configuration */
|
||||||
|
#define ARCH_CPU_64BIT
|
||||||
|
#define RT_USING_CACHE
|
||||||
|
#define ARCH_ARM_BOOTWITH_FLUSH_CACHE
|
||||||
|
#define RT_USING_CPU_FFS
|
||||||
|
#define ARCH_MM_MMU
|
||||||
|
#define ARCH_ARM
|
||||||
|
#define ARCH_ARM_MMU
|
||||||
|
#define KERNEL_VADDR_START 0xffff000000000000
|
||||||
|
#define ARCH_ARMV8
|
||||||
|
#define ARCH_USING_HW_THREAD_SELF
|
||||||
|
#define ARCH_USING_IRQ_CTX_LIST
|
||||||
|
|
||||||
|
/* RT-Thread Components */
|
||||||
|
|
||||||
|
#define RT_USING_COMPONENTS_INIT
|
||||||
|
#define RT_USING_USER_MAIN
|
||||||
|
#define RT_MAIN_THREAD_STACK_SIZE 16384
|
||||||
|
#define RT_MAIN_THREAD_PRIORITY 10
|
||||||
|
#define RT_USING_MSH
|
||||||
|
#define RT_USING_FINSH
|
||||||
|
#define FINSH_USING_MSH
|
||||||
|
#define FINSH_THREAD_NAME "tshell"
|
||||||
|
#define FINSH_THREAD_PRIORITY 20
|
||||||
|
#define FINSH_THREAD_STACK_SIZE 16384
|
||||||
|
#define FINSH_USING_HISTORY
|
||||||
|
#define FINSH_HISTORY_LINES 5
|
||||||
|
#define FINSH_USING_SYMTAB
|
||||||
|
#define FINSH_CMD_SIZE 80
|
||||||
|
#define MSH_USING_BUILT_IN_COMMANDS
|
||||||
|
#define FINSH_USING_DESCRIPTION
|
||||||
|
#define FINSH_ARG_MAX 10
|
||||||
|
#define FINSH_USING_OPTION_COMPLETION
|
||||||
|
|
||||||
|
/* DFS: device virtual file system */
|
||||||
|
|
||||||
|
#define RT_USING_DFS
|
||||||
|
#define DFS_USING_POSIX
|
||||||
|
#define DFS_USING_WORKDIR
|
||||||
|
#define DFS_FD_MAX 512
|
||||||
|
#define RT_USING_DFS_V2
|
||||||
|
#define RT_USING_DFS_DEVFS
|
||||||
|
#define RT_USING_DFS_PTYFS
|
||||||
|
#define RT_USING_DFS_CROMFS
|
||||||
|
#define RT_USING_DFS_TMPFS
|
||||||
|
#define RT_USING_DFS_MQUEUE
|
||||||
|
#define RT_USING_PAGECACHE
|
||||||
|
|
||||||
|
/* page cache config */
|
||||||
|
|
||||||
|
#define RT_PAGECACHE_COUNT 128
|
||||||
|
#define RT_PAGECACHE_ASPACE_COUNT 32
|
||||||
|
#define RT_PAGECACHE_PRELOAD 4
|
||||||
|
#define RT_PAGECACHE_HASH_NR 180
|
||||||
|
#define RT_PAGECACHE_GC_WORK_LEVEL 90
|
||||||
|
#define RT_PAGECACHE_GC_STOP_LEVEL 70
|
||||||
|
/* end of page cache config */
|
||||||
|
/* end of DFS: device virtual file system */
|
||||||
|
|
||||||
|
/* Device Drivers */
|
||||||
|
|
||||||
|
#define RT_USING_DM
|
||||||
|
#define RT_USING_DEV_BUS
|
||||||
|
#define RT_USING_DEVICE_IPC
|
||||||
|
#define RT_UNAMED_PIPE_NUMBER 64
|
||||||
|
#define RT_USING_SYSTEM_WORKQUEUE
|
||||||
|
#define RT_SYSTEM_WORKQUEUE_STACKSIZE 16384
|
||||||
|
#define RT_SYSTEM_WORKQUEUE_PRIORITY 23
|
||||||
|
#define RT_USING_SERIAL
|
||||||
|
#define RT_USING_SERIAL_V1
|
||||||
|
#define RT_SERIAL_RB_BUFSZ 64
|
||||||
|
#define RT_USING_NULL
|
||||||
|
#define RT_USING_ZERO
|
||||||
|
#define RT_USING_RANDOM
|
||||||
|
#define RT_USING_RTC
|
||||||
|
#define RT_USING_SOFT_RTC
|
||||||
|
#define RT_USING_SDIO
|
||||||
|
#define RT_SDIO_STACK_SIZE 16384
|
||||||
|
#define RT_SDIO_THREAD_PRIORITY 15
|
||||||
|
#define RT_MMCSD_STACK_SIZE 16384
|
||||||
|
#define RT_MMCSD_THREAD_PREORITY 22
|
||||||
|
#define RT_MMCSD_MAX_PARTITION 16
|
||||||
|
#define RT_USING_OFW
|
||||||
|
#define RT_FDT_EARLYCON_MSG_SIZE 128
|
||||||
|
#define RT_USING_OFW_BUS_RANGES_NUMBER 8
|
||||||
|
#define RT_USING_PIC
|
||||||
|
#define MAX_HANDLERS 1024
|
||||||
|
#define RT_PIC_ARM_GIC_V3
|
||||||
|
#define RT_USING_PIN
|
||||||
|
#define RT_USING_PINCTRL
|
||||||
|
#define RT_USING_KTIME
|
||||||
|
#define RT_USING_CLK
|
||||||
|
#define RT_USING_HWTIMER
|
||||||
|
#define RT_HWTIMER_ARM_ARCH
|
||||||
|
/* end of Device Drivers */
|
||||||
|
|
||||||
|
/* C/C++ and POSIX layer */
|
||||||
|
|
||||||
|
/* ISO-ANSI C layer */
|
||||||
|
|
||||||
|
/* Timezone and Daylight Saving Time */
|
||||||
|
|
||||||
|
#define RT_LIBC_USING_LIGHT_TZ_DST
|
||||||
|
#define RT_LIBC_TZ_DEFAULT_HOUR 8
|
||||||
|
#define RT_LIBC_TZ_DEFAULT_MIN 0
|
||||||
|
#define RT_LIBC_TZ_DEFAULT_SEC 0
|
||||||
|
/* end of Timezone and Daylight Saving Time */
|
||||||
|
/* end of ISO-ANSI C layer */
|
||||||
|
|
||||||
|
/* POSIX (Portable Operating System Interface) layer */
|
||||||
|
|
||||||
|
#define RT_USING_POSIX_FS
|
||||||
|
#define RT_USING_POSIX_DEVIO
|
||||||
|
#define RT_USING_POSIX_STDIO
|
||||||
|
#define RT_USING_POSIX_POLL
|
||||||
|
#define RT_USING_POSIX_SELECT
|
||||||
|
#define RT_USING_POSIX_EVENTFD
|
||||||
|
#define RT_USING_POSIX_EPOLL
|
||||||
|
#define RT_USING_POSIX_SIGNALFD
|
||||||
|
#define RT_SIGNALFD_MAX_NUM 10
|
||||||
|
#define RT_USING_POSIX_TIMERFD
|
||||||
|
#define RT_USING_POSIX_SOCKET
|
||||||
|
#define RT_USING_POSIX_TERMIOS
|
||||||
|
#define RT_USING_POSIX_MMAN
|
||||||
|
#define RT_USING_POSIX_DELAY
|
||||||
|
#define RT_USING_POSIX_CLOCK
|
||||||
|
#define RT_USING_POSIX_TIMER
|
||||||
|
|
||||||
|
/* Interprocess Communication (IPC) */
|
||||||
|
|
||||||
|
#define RT_USING_POSIX_PIPE
|
||||||
|
#define RT_USING_POSIX_PIPE_SIZE 2048
|
||||||
|
#define RT_USING_POSIX_MESSAGE_QUEUE
|
||||||
|
|
||||||
|
/* Socket is in the 'Network' category */
|
||||||
|
|
||||||
|
/* end of Interprocess Communication (IPC) */
|
||||||
|
/* end of POSIX (Portable Operating System Interface) layer */
|
||||||
|
/* end of C/C++ and POSIX layer */
|
||||||
|
|
||||||
|
/* Network */
|
||||||
|
|
||||||
|
#define RT_USING_SAL
|
||||||
|
#define SAL_INTERNET_CHECK
|
||||||
|
|
||||||
|
/* Docking with protocol stacks */
|
||||||
|
|
||||||
|
#define SAL_USING_LWIP
|
||||||
|
/* end of Docking with protocol stacks */
|
||||||
|
#define SAL_USING_POSIX
|
||||||
|
#define RT_USING_NETDEV
|
||||||
|
#define NETDEV_USING_IFCONFIG
|
||||||
|
#define NETDEV_USING_PING
|
||||||
|
#define NETDEV_USING_NETSTAT
|
||||||
|
#define NETDEV_USING_AUTO_DEFAULT
|
||||||
|
#define NETDEV_IPV4 1
|
||||||
|
#define NETDEV_IPV6 0
|
||||||
|
#define RT_USING_LWIP
|
||||||
|
#define RT_USING_LWIP212
|
||||||
|
#define RT_USING_LWIP_VER_NUM 0x20102
|
||||||
|
#define RT_LWIP_MEM_ALIGNMENT 8
|
||||||
|
#define RT_LWIP_IGMP
|
||||||
|
#define RT_LWIP_ICMP
|
||||||
|
#define RT_LWIP_DNS
|
||||||
|
#define RT_LWIP_DHCP
|
||||||
|
#define IP_SOF_BROADCAST 1
|
||||||
|
#define IP_SOF_BROADCAST_RECV 1
|
||||||
|
|
||||||
|
/* Static IPv4 Address */
|
||||||
|
|
||||||
|
#define RT_LWIP_IPADDR "192.168.1.30"
|
||||||
|
#define RT_LWIP_GWADDR "192.168.1.1"
|
||||||
|
#define RT_LWIP_MSKADDR "255.255.255.0"
|
||||||
|
/* end of Static IPv4 Address */
|
||||||
|
#define RT_LWIP_UDP
|
||||||
|
#define RT_LWIP_TCP
|
||||||
|
#define RT_LWIP_RAW
|
||||||
|
#define RT_MEMP_NUM_NETCONN 64
|
||||||
|
#define RT_LWIP_PBUF_NUM 320
|
||||||
|
#define RT_LWIP_RAW_PCB_NUM 32
|
||||||
|
#define RT_LWIP_UDP_PCB_NUM 32
|
||||||
|
#define RT_LWIP_TCP_PCB_NUM 64
|
||||||
|
#define RT_LWIP_TCP_SEG_NUM 480
|
||||||
|
#define RT_LWIP_TCP_SND_BUF 65535
|
||||||
|
#define RT_LWIP_TCP_WND 49512
|
||||||
|
#define RT_LWIP_TCPTHREAD_PRIORITY 8
|
||||||
|
#define RT_LWIP_TCPTHREAD_MBOX_SIZE 256
|
||||||
|
#define RT_LWIP_TCPTHREAD_STACKSIZE 65536
|
||||||
|
#define LWIP_NO_TX_THREAD
|
||||||
|
#define RT_LWIP_ETHTHREAD_PRIORITY 9
|
||||||
|
#define RT_LWIP_ETHTHREAD_STACKSIZE 16384
|
||||||
|
#define RT_LWIP_ETHTHREAD_MBOX_SIZE 256
|
||||||
|
#define LWIP_NETIF_STATUS_CALLBACK 1
|
||||||
|
#define LWIP_NETIF_LINK_CALLBACK 1
|
||||||
|
#define RT_LWIP_NETIF_NAMESIZE 6
|
||||||
|
#define SO_REUSE 1
|
||||||
|
#define LWIP_SO_RCVTIMEO 1
|
||||||
|
#define LWIP_SO_SNDTIMEO 1
|
||||||
|
#define LWIP_SO_RCVBUF 1
|
||||||
|
#define LWIP_SO_LINGER 0
|
||||||
|
#define RT_LWIP_NETIF_LOOPBACK
|
||||||
|
#define LWIP_NETIF_LOOPBACK 1
|
||||||
|
#define RT_LWIP_USING_HW_CHECKSUM
|
||||||
|
#define RT_LWIP_USING_PING
|
||||||
|
/* end of Network */
|
||||||
|
|
||||||
|
/* Memory protection */
|
||||||
|
|
||||||
|
/* end of Memory protection */
|
||||||
|
|
||||||
|
/* Utilities */
|
||||||
|
|
||||||
|
#define RT_USING_UTEST
|
||||||
|
#define UTEST_THR_STACK_SIZE 32768
|
||||||
|
#define UTEST_THR_PRIORITY 20
|
||||||
|
#define RT_USING_RESOURCE_ID
|
||||||
|
#define RT_USING_ADT
|
||||||
|
#define RT_USING_ADT_AVL
|
||||||
|
#define RT_USING_ADT_BITMAP
|
||||||
|
#define RT_USING_ADT_HASHMAP
|
||||||
|
#define RT_USING_ADT_REF
|
||||||
|
/* end of Utilities */
|
||||||
|
#define RT_USING_LWP
|
||||||
|
#define LWP_DEBUG
|
||||||
|
#define LWP_DEBUG_INIT
|
||||||
|
#define RT_LWP_MAX_NR 128
|
||||||
|
#define LWP_TASK_STACK_SIZE 32768
|
||||||
|
#define RT_CH_MSG_MAX_NR 1024
|
||||||
|
#define LWP_TID_MAX_NR 128
|
||||||
|
#define RT_LWP_SHM_MAX_NR 64
|
||||||
|
#define RT_USING_LDSO
|
||||||
|
#define LWP_USING_TERMINAL
|
||||||
|
#define LWP_PTY_MAX_PARIS_LIMIT 64
|
||||||
|
#define RT_USING_VDSO
|
||||||
|
|
||||||
|
/* Memory management */
|
||||||
|
|
||||||
|
#define RT_USING_MEMBLOCK
|
||||||
|
#define RT_INIT_MEMORY_REGIONS 128
|
||||||
|
/* end of Memory management */
|
||||||
|
|
||||||
|
/* Using USB legacy version */
|
||||||
|
|
||||||
|
/* end of Using USB legacy version */
|
||||||
|
/* end of RT-Thread Components */
|
||||||
|
|
||||||
|
/* RT-Thread Utestcases */
|
||||||
|
|
||||||
|
#define RT_USING_UTESTCASES
|
||||||
|
|
||||||
|
/* Utest Self Testcase */
|
||||||
|
|
||||||
|
/* end of Utest Self Testcase */
|
||||||
|
|
||||||
|
/* Kernel Testcase */
|
||||||
|
|
||||||
|
|
||||||
|
/* Kernel SMP Testcase */
|
||||||
|
|
||||||
|
/* end of Kernel SMP Testcase */
|
||||||
|
/* end of Kernel Testcase */
|
||||||
|
|
||||||
|
/* CPP11 Testcase */
|
||||||
|
|
||||||
|
/* end of CPP11 Testcase */
|
||||||
|
|
||||||
|
/* Utest Serial Testcase */
|
||||||
|
|
||||||
|
/* end of Utest Serial Testcase */
|
||||||
|
|
||||||
|
/* Utest IPC Testcase */
|
||||||
|
|
||||||
|
/* end of Utest IPC Testcase */
|
||||||
|
|
||||||
|
/* RTT Posix Testcase */
|
||||||
|
|
||||||
|
/* end of RTT Posix Testcase */
|
||||||
|
|
||||||
|
/* Memory Management Subsytem Testcase */
|
||||||
|
|
||||||
|
/* end of Memory Management Subsytem Testcase */
|
||||||
|
|
||||||
|
/* Tmpfs Testcase */
|
||||||
|
|
||||||
|
/* end of Tmpfs Testcase */
|
||||||
|
|
||||||
|
/* SMP-Call Testcase */
|
||||||
|
|
||||||
|
#define UTEST_SMP_CALL_FUNC
|
||||||
|
/* end of SMP-Call Testcase */
|
||||||
|
/* end of RT-Thread Utestcases */
|
||||||
|
|
||||||
|
/* RT-Thread online packages */
|
||||||
|
|
||||||
|
/* IoT - internet of things */
|
||||||
|
|
||||||
|
|
||||||
|
/* Wi-Fi */
|
||||||
|
|
||||||
|
/* Marvell WiFi */
|
||||||
|
|
||||||
|
/* end of Marvell WiFi */
|
||||||
|
|
||||||
|
/* Wiced WiFi */
|
||||||
|
|
||||||
|
/* end of Wiced WiFi */
|
||||||
|
|
||||||
|
/* CYW43012 WiFi */
|
||||||
|
|
||||||
|
/* end of CYW43012 WiFi */
|
||||||
|
|
||||||
|
/* BL808 WiFi */
|
||||||
|
|
||||||
|
/* end of BL808 WiFi */
|
||||||
|
|
||||||
|
/* CYW43439 WiFi */
|
||||||
|
|
||||||
|
/* end of CYW43439 WiFi */
|
||||||
|
/* end of Wi-Fi */
|
||||||
|
|
||||||
|
/* IoT Cloud */
|
||||||
|
|
||||||
|
/* end of IoT Cloud */
|
||||||
|
/* end of IoT - internet of things */
|
||||||
|
|
||||||
|
/* security packages */
|
||||||
|
|
||||||
|
/* end of security packages */
|
||||||
|
|
||||||
|
/* language packages */
|
||||||
|
|
||||||
|
/* JSON: JavaScript Object Notation, a lightweight data-interchange format */
|
||||||
|
|
||||||
|
/* end of JSON: JavaScript Object Notation, a lightweight data-interchange format */
|
||||||
|
|
||||||
|
/* XML: Extensible Markup Language */
|
||||||
|
|
||||||
|
/* end of XML: Extensible Markup Language */
|
||||||
|
/* end of language packages */
|
||||||
|
|
||||||
|
/* multimedia packages */
|
||||||
|
|
||||||
|
/* LVGL: powerful and easy-to-use embedded GUI library */
|
||||||
|
|
||||||
|
/* end of LVGL: powerful and easy-to-use embedded GUI library */
|
||||||
|
|
||||||
|
/* u8g2: a monochrome graphic library */
|
||||||
|
|
||||||
|
/* end of u8g2: a monochrome graphic library */
|
||||||
|
/* end of multimedia packages */
|
||||||
|
|
||||||
|
/* tools packages */
|
||||||
|
|
||||||
|
/* end of tools packages */
|
||||||
|
|
||||||
|
/* system packages */
|
||||||
|
|
||||||
|
/* enhanced kernel services */
|
||||||
|
|
||||||
|
/* end of enhanced kernel services */
|
||||||
|
|
||||||
|
/* acceleration: Assembly language or algorithmic acceleration packages */
|
||||||
|
|
||||||
|
/* end of acceleration: Assembly language or algorithmic acceleration packages */
|
||||||
|
|
||||||
|
/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
|
||||||
|
|
||||||
|
/* end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
|
||||||
|
|
||||||
|
/* Micrium: Micrium software products porting for RT-Thread */
|
||||||
|
|
||||||
|
/* end of Micrium: Micrium software products porting for RT-Thread */
|
||||||
|
/* end of system packages */
|
||||||
|
|
||||||
|
/* peripheral libraries and drivers */
|
||||||
|
|
||||||
|
/* HAL & SDK Drivers */
|
||||||
|
|
||||||
|
/* STM32 HAL & SDK Drivers */
|
||||||
|
|
||||||
|
/* end of STM32 HAL & SDK Drivers */
|
||||||
|
|
||||||
|
/* Kendryte SDK */
|
||||||
|
|
||||||
|
/* end of Kendryte SDK */
|
||||||
|
/* end of HAL & SDK Drivers */
|
||||||
|
|
||||||
|
/* sensors drivers */
|
||||||
|
|
||||||
|
/* end of sensors drivers */
|
||||||
|
|
||||||
|
/* touch drivers */
|
||||||
|
|
||||||
|
/* end of touch drivers */
|
||||||
|
/* end of peripheral libraries and drivers */
|
||||||
|
|
||||||
|
/* AI packages */
|
||||||
|
|
||||||
|
/* end of AI packages */
|
||||||
|
|
||||||
|
/* Signal Processing and Control Algorithm Packages */
|
||||||
|
|
||||||
|
/* end of Signal Processing and Control Algorithm Packages */
|
||||||
|
|
||||||
|
/* miscellaneous packages */
|
||||||
|
|
||||||
|
/* project laboratory */
|
||||||
|
|
||||||
|
/* end of project laboratory */
|
||||||
|
|
||||||
|
/* samples: kernel and components samples */
|
||||||
|
|
||||||
|
/* end of samples: kernel and components samples */
|
||||||
|
|
||||||
|
/* entertainment: terminal games and other interesting software packages */
|
||||||
|
|
||||||
|
/* end of entertainment: terminal games and other interesting software packages */
|
||||||
|
#define PKG_USING_ZLIB
|
||||||
|
#define PKG_USING_ZLIB_LATEST_VERSION
|
||||||
|
/* end of miscellaneous packages */
|
||||||
|
|
||||||
|
/* Arduino libraries */
|
||||||
|
|
||||||
|
|
||||||
|
/* Projects and Demos */
|
||||||
|
|
||||||
|
/* end of Projects and Demos */
|
||||||
|
|
||||||
|
/* Sensors */
|
||||||
|
|
||||||
|
/* end of Sensors */
|
||||||
|
|
||||||
|
/* Display */
|
||||||
|
|
||||||
|
/* end of Display */
|
||||||
|
|
||||||
|
/* Timing */
|
||||||
|
|
||||||
|
/* end of Timing */
|
||||||
|
|
||||||
|
/* Data Processing */
|
||||||
|
|
||||||
|
/* end of Data Processing */
|
||||||
|
|
||||||
|
/* Data Storage */
|
||||||
|
|
||||||
|
/* Communication */
|
||||||
|
|
||||||
|
/* end of Communication */
|
||||||
|
|
||||||
|
/* Device Control */
|
||||||
|
|
||||||
|
/* end of Device Control */
|
||||||
|
|
||||||
|
/* Other */
|
||||||
|
|
||||||
|
/* end of Other */
|
||||||
|
|
||||||
|
/* Signal IO */
|
||||||
|
|
||||||
|
/* end of Signal IO */
|
||||||
|
|
||||||
|
/* Uncategorized */
|
||||||
|
|
||||||
|
/* end of Arduino libraries */
|
||||||
|
/* end of RT-Thread online packages */
|
||||||
|
|
||||||
|
/* Privated Packages of RealThread */
|
||||||
|
|
||||||
|
|
||||||
|
/* Network Utilities */
|
||||||
|
|
||||||
|
/* end of Network Utilities */
|
||||||
|
|
||||||
|
/* RT-Thread Smart */
|
||||||
|
|
||||||
|
/* end of RT-Thread Smart */
|
||||||
|
/* end of Privated Packages of RealThread */
|
||||||
|
|
||||||
|
/* RT-Thread rockchip RK3500 drivers */
|
||||||
|
|
||||||
|
#define RT_CLK_ROCKCHIP
|
||||||
|
#define RT_CLK_ROCKCHIP_RK3568
|
||||||
|
#define RT_CLK_ROCKCHIP_RK3588
|
||||||
|
#define RT_SERIAL_8250
|
||||||
|
#define RT_USING_RESET
|
||||||
|
#define RT_HWTIMER_ROCKCHIP
|
||||||
|
/* end of RT-Thread rockchip RK3500 drivers */
|
||||||
|
#define SOC_RK3568
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,57 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
# toolchains options
|
||||||
|
ARCH ='aarch64'
|
||||||
|
CPU ='cortex-a'
|
||||||
|
CROSS_TOOL ='gcc'
|
||||||
|
|
||||||
|
if os.getenv('RTT_ROOT'):
|
||||||
|
RTT_ROOT = os.getenv('RTT_ROOT')
|
||||||
|
else:
|
||||||
|
RTT_ROOT = os.path.join(os.getcwd(), '..', '..', '..')
|
||||||
|
|
||||||
|
if os.getenv('RTT_CC'):
|
||||||
|
CROSS_TOOL = os.getenv('RTT_CC')
|
||||||
|
|
||||||
|
PLATFORM = 'gcc'
|
||||||
|
EXEC_PATH = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/'
|
||||||
|
|
||||||
|
EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin'
|
||||||
|
|
||||||
|
BUILD = 'release'
|
||||||
|
|
||||||
|
if PLATFORM == 'gcc':
|
||||||
|
# toolchains
|
||||||
|
PREFIX = os.getenv('RTT_CC_PREFIX') or 'aarch64-none-elf-'
|
||||||
|
CC = PREFIX + 'gcc'
|
||||||
|
CXX = PREFIX + 'g++'
|
||||||
|
CPP = PREFIX + 'cpp'
|
||||||
|
AS = PREFIX + 'gcc'
|
||||||
|
AR = PREFIX + 'ar'
|
||||||
|
LINK = PREFIX + 'gcc'
|
||||||
|
TARGET_EXT = 'elf'
|
||||||
|
SIZE = PREFIX + 'size'
|
||||||
|
OBJDUMP = PREFIX + 'objdump'
|
||||||
|
OBJCPY = PREFIX + 'objcopy'
|
||||||
|
|
||||||
|
DEVICE = ' -g -march=armv8.2-a -mtune=cortex-a55 -fdiagnostics-color=always'
|
||||||
|
CPPFLAGS= ' -E -P -x assembler-with-cpp'
|
||||||
|
CFLAGS = DEVICE + ' -Wall -Wno-cpp'
|
||||||
|
AFLAGS = ' -c' + ' -x assembler-with-cpp -D__ASSEMBLY__'
|
||||||
|
LFLAGS = DEVICE + ' -nostartfiles -Wl,--no-warn-rwx-segments -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds'
|
||||||
|
CPATH = ''
|
||||||
|
LPATH = ''
|
||||||
|
|
||||||
|
if BUILD == 'debug':
|
||||||
|
CFLAGS += ' -O0 -ggdb'
|
||||||
|
CPPFLAGS += ' -O0 -ggdb'
|
||||||
|
AFLAGS += ' -ggdb'
|
||||||
|
else:
|
||||||
|
CFLAGS += ' -O2 -ggdb'
|
||||||
|
CPPFLAGS += ' -O2 -ggdb'
|
||||||
|
|
||||||
|
CXXFLAGS = CFLAGS
|
||||||
|
|
||||||
|
DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n'
|
||||||
|
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
|
||||||
|
POST_ACTION += 'md5sum rtthread.bin\n'
|
Loading…
Reference in New Issue