soc/mediatek: Use MRC cache API for asurada
Use the MRC cache API for asurada, and sync dramc_param.h with dram blob (CL:*3674585). With this change, the checksum, originally stored in flash, is replaced with a hash in TPM. In addition, in recovery boot, full calibration will always ne performed, and the cached calibration data will be cleared from flash. This change increases ROMSTAGE size from 236K to 264K. Most of the increase is caused by TPM-related functions. Add new API mtk_dram_init() to emi.h, so that 'dramc_parameter' can be moved to soc folder. With this CL, there is no significant change in boot time. Normal AP reboot time (fast calibration) is consistently 0.98s as before, so this change should not affect the result of platform_BootPerf. BUG=b:170687062 TEST=emerge-asurada coreboot TEST=Hayato boots with both full and fast calibration BRANCH=none Cq-Depend: chrome-internal:3674585, chrome-internal:3704751 Change-Id: Ief942048ce530433a57e8205d3a68ad56235b427 Signed-off-by: Yu-Ping Wu <yupingso@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/51620 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Hung-Te Lin <hungte@chromium.org>
This commit is contained in:
parent
25ef410423
commit
71c5ca764f
|
@ -29,7 +29,7 @@ FLASH@0x0 8M {
|
||||||
RW_MISC 36K {
|
RW_MISC 36K {
|
||||||
RW_VPD(PRESERVE) 16K # At least 8K.
|
RW_VPD(PRESERVE) 16K # At least 8K.
|
||||||
RW_NVRAM(PRESERVE) 8K
|
RW_NVRAM(PRESERVE) 8K
|
||||||
RW_DDR_TRAINING(PRESERVE) 8K
|
RW_MRC_CACHE(PRESERVE) 8K
|
||||||
RW_ELOG(PRESERVE) 4K # ELOG driver hard-coded size in 4K.
|
RW_ELOG(PRESERVE) 4K # ELOG driver hard-coded size in 4K.
|
||||||
}
|
}
|
||||||
RW_SECTION_B 1500K {
|
RW_SECTION_B 1500K {
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
#include <arch/stages.h>
|
#include <arch/stages.h>
|
||||||
#include <console/console.h>
|
|
||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
#include <fmap.h>
|
|
||||||
#include <soc/clkbuf.h>
|
#include <soc/clkbuf.h>
|
||||||
#include <soc/dramc_param.h>
|
|
||||||
#include <soc/emi.h>
|
#include <soc/emi.h>
|
||||||
#include <soc/mmu_operations.h>
|
|
||||||
#include <soc/mt6315.h>
|
#include <soc/mt6315.h>
|
||||||
#include <soc/mt6359p.h>
|
#include <soc/mt6359p.h>
|
||||||
#include <soc/pll_common.h>
|
#include <soc/pll_common.h>
|
||||||
|
@ -15,40 +11,6 @@
|
||||||
#include <soc/rtc.h>
|
#include <soc/rtc.h>
|
||||||
#include <soc/srclken_rc.h>
|
#include <soc/srclken_rc.h>
|
||||||
|
|
||||||
/* This must be defined in chromeos.fmd in same name and size. */
|
|
||||||
#define CALIBRATION_REGION "RW_DDR_TRAINING"
|
|
||||||
#define CALIBRATION_REGION_SIZE 0x2000
|
|
||||||
|
|
||||||
_Static_assert(sizeof(struct dramc_param) <= CALIBRATION_REGION_SIZE,
|
|
||||||
"sizeof(struct dramc_param) exceeds " CALIBRATION_REGION);
|
|
||||||
|
|
||||||
static bool read_calibration_data_from_flash(struct dramc_param *dparam)
|
|
||||||
{
|
|
||||||
const size_t length = sizeof(*dparam);
|
|
||||||
size_t ret = fmap_read_area(CALIBRATION_REGION, dparam, length);
|
|
||||||
printk(BIOS_DEBUG, "read data from flash, ret=%#zx, length=%#zx\n", ret, length);
|
|
||||||
|
|
||||||
return ret == length;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_calibration_data_to_flash(const struct dramc_param *dparam)
|
|
||||||
{
|
|
||||||
const size_t length = sizeof(*dparam);
|
|
||||||
size_t ret = fmap_overwrite_area(CALIBRATION_REGION, dparam, length);
|
|
||||||
printk(BIOS_DEBUG, "write data from flash, ret=%#zx, length=%#zx\n", ret, length);
|
|
||||||
|
|
||||||
return ret == length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dramc_param is ~2K and too large to fit in stack. */
|
|
||||||
static struct dramc_param dramc_parameter;
|
|
||||||
|
|
||||||
static struct dramc_param_ops dparam_ops = {
|
|
||||||
.param = &dramc_parameter,
|
|
||||||
.read_from_flash = &read_calibration_data_from_flash,
|
|
||||||
.write_to_flash = &write_calibration_data_to_flash,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void raise_little_cpu_freq(void)
|
static void raise_little_cpu_freq(void)
|
||||||
{
|
{
|
||||||
mt6359p_buck_set_voltage(MT6359P_SRAM_PROC2, 1000 * 1000);
|
mt6359p_buck_set_voltage(MT6359P_SRAM_PROC2, 1000 * 1000);
|
||||||
|
@ -67,6 +29,5 @@ void platform_romstage_main(void)
|
||||||
clk_buf_init();
|
clk_buf_init();
|
||||||
rtc_boot();
|
rtc_boot();
|
||||||
raise_little_cpu_freq();
|
raise_little_cpu_freq();
|
||||||
mt_mem_init(&dparam_ops);
|
mtk_dram_init();
|
||||||
mtk_mmu_after_dram();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,26 +22,6 @@ void dump_param_header(const void *blob)
|
||||||
print("header.size = %#x (expected: %#lx)\n",
|
print("header.size = %#x (expected: %#lx)\n",
|
||||||
header->size, sizeof(*dparam));
|
header->size, sizeof(*dparam));
|
||||||
print("header.flags = %#x\n", header->flags);
|
print("header.flags = %#x\n", header->flags);
|
||||||
print("header.checksum = %#x\n", header->checksum);
|
|
||||||
}
|
|
||||||
|
|
||||||
int validate_dramc_param(const void *blob)
|
|
||||||
{
|
|
||||||
const struct dramc_param *param = blob;
|
|
||||||
const struct dramc_param_header *hdr = ¶m->header;
|
|
||||||
|
|
||||||
if (hdr->version != DRAMC_PARAM_HEADER_VERSION)
|
|
||||||
return DRAMC_ERR_INVALID_VERSION;
|
|
||||||
|
|
||||||
if (hdr->size != sizeof(*param))
|
|
||||||
return DRAMC_ERR_INVALID_SIZE;
|
|
||||||
|
|
||||||
return DRAMC_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int is_valid_dramc_param(const void *blob)
|
|
||||||
{
|
|
||||||
return validate_dramc_param(blob) == DRAMC_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int initialize_dramc_param(void *blob)
|
int initialize_dramc_param(void *blob)
|
||||||
|
|
|
@ -3,21 +3,21 @@
|
||||||
#ifndef __SOC_MEDIATEK_DRAMC_PARAM_H__
|
#ifndef __SOC_MEDIATEK_DRAMC_PARAM_H__
|
||||||
#define __SOC_MEDIATEK_DRAMC_PARAM_H__
|
#define __SOC_MEDIATEK_DRAMC_PARAM_H__
|
||||||
|
|
||||||
/* any change in this file should sync to blob dramc_param.h */
|
/*
|
||||||
|
* This file is shared between coreboot and dram blob. Any change in this file
|
||||||
|
* should be synced to the other repository.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <soc/dramc_soc.h>
|
#include <soc/dramc_soc.h>
|
||||||
|
|
||||||
enum {
|
#define DRAMC_PARAM_HEADER_VERSION 6
|
||||||
DRAMC_PARAM_HEADER_VERSION = 5,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DRAMC_PARAM_STATUS_CODES {
|
enum DRAMC_PARAM_STATUS_CODES {
|
||||||
DRAMC_SUCCESS = 0,
|
DRAMC_SUCCESS = 0,
|
||||||
DRAMC_ERR_INVALID_VERSION,
|
DRAMC_ERR_INVALID_VERSION,
|
||||||
DRAMC_ERR_INVALID_SIZE,
|
DRAMC_ERR_INVALID_SIZE,
|
||||||
DRAMC_ERR_INVALID_CHECKSUM,
|
|
||||||
DRAMC_ERR_INVALID_FLAGS,
|
DRAMC_ERR_INVALID_FLAGS,
|
||||||
DRAMC_ERR_RECALIBRATE,
|
DRAMC_ERR_RECALIBRATE,
|
||||||
DRAMC_ERR_INIT_DRAM,
|
DRAMC_ERR_INIT_DRAM,
|
||||||
|
@ -41,7 +41,6 @@ enum DRAMC_PARAM_DDR_TYPE {
|
||||||
DDR_TYPE_EMCP,
|
DDR_TYPE_EMCP,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Don't change the order, which is matched with blob */
|
|
||||||
enum DRAMC_PARAM_GEOMETRY_TYPE {
|
enum DRAMC_PARAM_GEOMETRY_TYPE {
|
||||||
DDR_TYPE_2CH_2RK_4GB_2_2,
|
DDR_TYPE_2CH_2RK_4GB_2_2,
|
||||||
DDR_TYPE_2CH_2RK_6GB_3_3,
|
DDR_TYPE_2CH_2RK_6GB_3_3,
|
||||||
|
@ -58,7 +57,6 @@ enum DRAM_PARAM_VOLTAGE_TYPE {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dramc_param_header {
|
struct dramc_param_header {
|
||||||
u32 checksum; /* checksum of dramc_datas, update in the coreboot */
|
|
||||||
u16 version; /* DRAMC_PARAM_HEADER_VERSION, update in the coreboot */
|
u16 version; /* DRAMC_PARAM_HEADER_VERSION, update in the coreboot */
|
||||||
u16 size; /* size of whole dramc_param, update in the coreboot */
|
u16 size; /* size of whole dramc_param, update in the coreboot */
|
||||||
u16 status; /* DRAMC_PARAM_STATUS_CODES, update in the dram blob */
|
u16 status; /* DRAMC_PARAM_STATUS_CODES, update in the dram blob */
|
||||||
|
@ -141,12 +139,6 @@ struct dramc_param {
|
||||||
struct dramc_data dramc_datas;
|
struct dramc_data dramc_datas;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dramc_param_ops {
|
|
||||||
struct dramc_param *param;
|
|
||||||
bool (*read_from_flash)(struct dramc_param *dparam);
|
|
||||||
bool (*write_to_flash)(const struct dramc_param *dparam);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sdram_info {
|
struct sdram_info {
|
||||||
u32 ddr_geometry; /* DRAMC_PARAM_GEOMETRY_TYPE */
|
u32 ddr_geometry; /* DRAMC_PARAM_GEOMETRY_TYPE */
|
||||||
u32 ddr_type; /* DRAMC_PARAM_DDR_TYPE */
|
u32 ddr_type; /* DRAMC_PARAM_DDR_TYPE */
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
|
|
||||||
size_t sdram_size(void);
|
size_t sdram_size(void);
|
||||||
void mt_set_emi(struct dramc_param *dparam);
|
void mt_set_emi(struct dramc_param *dparam);
|
||||||
void mt_mem_init(struct dramc_param_ops *dparam_ops);
|
void mt_mem_init(struct dramc_param *dparam);
|
||||||
|
void mtk_dram_init(void);
|
||||||
int complex_mem_test(u8 *start, unsigned int len);
|
int complex_mem_test(u8 *start, unsigned int len);
|
||||||
|
|
||||||
bool is_dvfs_enabled(void);
|
bool is_dvfs_enabled(void);
|
||||||
|
|
|
@ -5,10 +5,20 @@
|
||||||
#include <cbfs.h>
|
#include <cbfs.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <ip_checksum.h>
|
#include <ip_checksum.h>
|
||||||
|
#include <mrc_cache.h>
|
||||||
|
#include <soc/dramc_param.h>
|
||||||
#include <soc/emi.h>
|
#include <soc/emi.h>
|
||||||
|
#include <soc/mmu_operations.h>
|
||||||
#include <symbols.h>
|
#include <symbols.h>
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
|
|
||||||
|
/* This must be defined in chromeos.fmd in same name and size. */
|
||||||
|
#define CALIBRATION_REGION "RW_MRC_CACHE"
|
||||||
|
#define CALIBRATION_REGION_SIZE 0x2000
|
||||||
|
|
||||||
|
_Static_assert(sizeof(struct dramc_param) <= CALIBRATION_REGION_SIZE,
|
||||||
|
"sizeof(struct dramc_param) exceeds " CALIBRATION_REGION);
|
||||||
|
|
||||||
const char *get_dram_geometry_str(u32 ddr_geometry);
|
const char *get_dram_geometry_str(u32 ddr_geometry);
|
||||||
const char *get_dram_type_str(u32 ddr_type);
|
const char *get_dram_type_str(u32 ddr_type);
|
||||||
|
|
||||||
|
@ -35,12 +45,6 @@ static int mt_mem_test(const struct dramc_data *dparam)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 compute_checksum(const struct dramc_param *dparam)
|
|
||||||
{
|
|
||||||
return (u32)compute_ip_checksum(&dparam->dramc_datas,
|
|
||||||
sizeof(dparam->dramc_datas));
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *get_dram_geometry_str(u32 ddr_geometry)
|
const char *get_dram_geometry_str(u32 ddr_geometry)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
|
@ -93,21 +97,6 @@ const char *get_dram_type_str(u32 ddr_type)
|
||||||
|
|
||||||
static int dram_run_fast_calibration(struct dramc_param *dparam)
|
static int dram_run_fast_calibration(struct dramc_param *dparam)
|
||||||
{
|
{
|
||||||
if (!is_valid_dramc_param(dparam)) {
|
|
||||||
printk(BIOS_WARNING, "DRAM-K: Invalid DRAM calibration data from flash\n");
|
|
||||||
dump_param_header((void *)dparam);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const u32 checksum = compute_checksum(dparam);
|
|
||||||
if (dparam->header.checksum != checksum) {
|
|
||||||
printk(BIOS_ERR,
|
|
||||||
"DRAM-K: Invalid DRAM calibration checksum from flash "
|
|
||||||
"(expected: %#x, saved: %#x)\n",
|
|
||||||
checksum, dparam->header.checksum);
|
|
||||||
return DRAMC_ERR_INVALID_CHECKSUM;
|
|
||||||
}
|
|
||||||
|
|
||||||
const u16 config = CONFIG(MEDIATEK_DRAM_DVFS) ? DRAMC_ENABLE_DVFS : DRAMC_DISABLE_DVFS;
|
const u16 config = CONFIG(MEDIATEK_DRAM_DVFS) ? DRAMC_ENABLE_DVFS : DRAMC_DISABLE_DVFS;
|
||||||
if (dparam->dramc_datas.ddr_info.config_dvfs != config) {
|
if (dparam->dramc_datas.ddr_info.config_dvfs != config) {
|
||||||
printk(BIOS_WARNING,
|
printk(BIOS_WARNING,
|
||||||
|
@ -131,6 +120,7 @@ static int dram_run_full_calibration(struct dramc_param *dparam)
|
||||||
struct prog dram = PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX "/dram");
|
struct prog dram = PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX "/dram");
|
||||||
|
|
||||||
initialize_dramc_param(dparam);
|
initialize_dramc_param(dparam);
|
||||||
|
dump_param_header(dparam);
|
||||||
|
|
||||||
if (cbfs_prog_stage_load(&dram)) {
|
if (cbfs_prog_stage_load(&dram)) {
|
||||||
printk(BIOS_ERR, "DRAM-K: CBFS load program failed\n");
|
printk(BIOS_ERR, "DRAM-K: CBFS load program failed\n");
|
||||||
|
@ -179,16 +169,21 @@ static void mem_init_set_default_config(struct dramc_param *dparam,
|
||||||
get_dram_geometry_str(geometry));
|
get_dram_geometry_str(geometry));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mt_mem_init_run(struct dramc_param_ops *dparam_ops,
|
static void mt_mem_init_run(struct dramc_param *dparam,
|
||||||
const struct sdram_info *dram_info)
|
const struct sdram_info *dram_info)
|
||||||
{
|
{
|
||||||
struct dramc_param *dparam = dparam_ops->param;
|
const ssize_t mrc_cache_size = sizeof(dparam->dramc_datas);
|
||||||
|
ssize_t data_size;
|
||||||
struct stopwatch sw;
|
struct stopwatch sw;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Load calibration params from flash and run fast calibration */
|
/* Load calibration params from flash and run fast calibration */
|
||||||
mem_init_set_default_config(dparam, dram_info);
|
mem_init_set_default_config(dparam, dram_info);
|
||||||
if (dparam_ops->read_from_flash(dparam)) {
|
data_size = mrc_cache_load_current(MRC_TRAINING_DATA,
|
||||||
|
DRAMC_PARAM_HEADER_VERSION,
|
||||||
|
&dparam->dramc_datas,
|
||||||
|
mrc_cache_size);
|
||||||
|
if (data_size == mrc_cache_size) {
|
||||||
printk(BIOS_INFO, "DRAM-K: Running fast calibration\n");
|
printk(BIOS_INFO, "DRAM-K: Running fast calibration\n");
|
||||||
stopwatch_init(&sw);
|
stopwatch_init(&sw);
|
||||||
|
|
||||||
|
@ -199,15 +194,20 @@ static void mt_mem_init_run(struct dramc_param_ops *dparam_ops,
|
||||||
stopwatch_duration_msecs(&sw), ret);
|
stopwatch_duration_msecs(&sw), ret);
|
||||||
|
|
||||||
/* Erase flash data after fast calibration failed */
|
/* Erase flash data after fast calibration failed */
|
||||||
memset(dparam, 0xa5, sizeof(*dparam));
|
memset(&dparam->dramc_datas, 0xa5, mrc_cache_size);
|
||||||
dparam_ops->write_to_flash(dparam);
|
if (mrc_cache_stash_data(MRC_TRAINING_DATA,
|
||||||
|
DRAMC_PARAM_HEADER_VERSION,
|
||||||
|
&dparam->dramc_datas, mrc_cache_size))
|
||||||
|
printk(BIOS_ERR, "DRAM-K: Failed to erase "
|
||||||
|
"calibration data\n");
|
||||||
} else {
|
} else {
|
||||||
printk(BIOS_INFO, "DRAM-K: Fast calibration passed in %ld msecs\n",
|
printk(BIOS_INFO, "DRAM-K: Fast calibration passed in %ld msecs\n",
|
||||||
stopwatch_duration_msecs(&sw));
|
stopwatch_duration_msecs(&sw));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printk(BIOS_WARNING, "DRAM-K: Failed to read calibration data from flash\n");
|
printk(BIOS_WARNING, "DRAM-K: Invalid data in flash (size: %#zx, expected: %#zx)\n",
|
||||||
|
data_size, mrc_cache_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run full calibration */
|
/* Run full calibration */
|
||||||
|
@ -220,20 +220,32 @@ static void mt_mem_init_run(struct dramc_param_ops *dparam_ops,
|
||||||
printk(BIOS_INFO, "DRAM-K: Full calibration passed in %ld msecs\n",
|
printk(BIOS_INFO, "DRAM-K: Full calibration passed in %ld msecs\n",
|
||||||
stopwatch_duration_msecs(&sw));
|
stopwatch_duration_msecs(&sw));
|
||||||
|
|
||||||
dparam->header.checksum = compute_checksum(dparam);
|
if (mrc_cache_stash_data(MRC_TRAINING_DATA,
|
||||||
dparam_ops->write_to_flash(dparam);
|
DRAMC_PARAM_HEADER_VERSION,
|
||||||
printk(BIOS_DEBUG, "DRAM-K: Calibration params saved to flash: "
|
&dparam->dramc_datas, mrc_cache_size) == 0)
|
||||||
"version=%#x, size=%#x\n",
|
printk(BIOS_DEBUG, "DRAM-K: Calibration params saved "
|
||||||
dparam->header.version, dparam->header.size);
|
"to flash: version=%#x, size=%#zx\n",
|
||||||
|
DRAMC_PARAM_HEADER_VERSION, sizeof(*dparam));
|
||||||
|
else
|
||||||
|
printk(BIOS_ERR, "DRAM-K: Failed to save calibration "
|
||||||
|
"data to flash\n");
|
||||||
} else {
|
} else {
|
||||||
printk(BIOS_ERR, "DRAM-K: Full calibration failed in %ld msecs\n",
|
printk(BIOS_ERR, "DRAM-K: Full calibration failed in %ld msecs\n",
|
||||||
stopwatch_duration_msecs(&sw));
|
stopwatch_duration_msecs(&sw));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mt_mem_init(struct dramc_param_ops *dparam_ops)
|
void mt_mem_init(struct dramc_param *dparam)
|
||||||
{
|
{
|
||||||
const struct sdram_info *sdram_param = get_sdram_config();
|
const struct sdram_info *sdram_param = get_sdram_config();
|
||||||
|
|
||||||
mt_mem_init_run(dparam_ops, sdram_param);
|
mt_mem_init_run(dparam, sdram_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_dram_init(void)
|
||||||
|
{
|
||||||
|
/* dramc_param is too large to fit in stack. */
|
||||||
|
static struct dramc_param dramc_parameter;
|
||||||
|
mt_mem_init(&dramc_parameter);
|
||||||
|
mtk_mmu_after_dram();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ config SOC_MEDIATEK_MT8192
|
||||||
select ARCH_ROMSTAGE_ARMV8_64
|
select ARCH_ROMSTAGE_ARMV8_64
|
||||||
select ARCH_RAMSTAGE_ARMV8_64
|
select ARCH_RAMSTAGE_ARMV8_64
|
||||||
select ARM64_USE_ARM_TRUSTED_FIRMWARE
|
select ARM64_USE_ARM_TRUSTED_FIRMWARE
|
||||||
|
select CACHE_MRC_SETTINGS
|
||||||
select HAVE_DEBUG_RAM_SETUP
|
select HAVE_DEBUG_RAM_SETUP
|
||||||
select HAVE_UART_SPECIAL
|
select HAVE_UART_SPECIAL
|
||||||
select SOC_MEDIATEK_COMMON
|
select SOC_MEDIATEK_COMMON
|
||||||
|
|
Loading…
Reference in New Issue