Commit b8bf0adc authored by Shaveta Leekha's avatar Shaveta Leekha Committed by York Sun

powerpc/mpc85xx: Add DSP side awareness for Freescale Heterogeneous SoCs

The code provides framework for heterogeneous multicore chips based on StarCore
and Power Architecture which are chasis-2 compliant, like B4860 and B4420

It will make u-boot recognize all non-ppc cores and peripherals like
SC3900/DSP CPUs, MAPLE, CPRI and print their configuration in u-boot logs.
Example boot logs of B4860QDS:

U-Boot 2015.01-00232-geef6e36-dirty (Jan 19 2015 - 11:58:45)

CPU0:  B4860E, Version: 2.2, (0x86880022)
Core:  e6500, Version: 2.0, (0x80400120)
Clock Configuration:
       CPU0:1600 MHz, CPU1:1600 MHz, CPU2:1600 MHz, CPU3:1600 MHz,
       DSP CPU0:1200 MHz, DSP CPU1:1200 MHz, DSP CPU2:1200 MHz, DSP CPU3:1200 MHz,
       DSP CPU4:1200 MHz, DSP CPU5:1200 MHz,
       CCB:666.667 MHz,
       DDR:933.333 MHz (1866.667 MT/s data rate) (Asynchronous), IFC:166.667 MHz
       CPRI:600  MHz
       MAPLE:600  MHz, MAPLE-ULB:800  MHz, MAPLE-eTVPE:1000 MHz
       FMAN1: 666.667 MHz
       QMAN:  333.333 MHz

Top level changes include:
(1) Top level CONFIG to identify HETEROGENUOUS clusters
(2) CONFIGS for SC3900/DSP components
(3) Global structures like "cpu_type" and "MPC85xx_SYS_INFO"
    updated for dsp cores and other components
(3) APIs to get DSP num cores and their Mask like:
        cpu_dsp_mask, cpu_num_dspcores etc same as that of PowerPC
(5) Code to fetch and print SC cores and other heterogenous
    device's frequencies
(6) README added for the same
Signed-off-by: 's avatarShaveta Leekha <shaveta@freescale.com>
Reviewed-by: 's avatarYork Sun <yorksun@freescale.com>
parent 8176a874
......@@ -73,6 +73,11 @@ int checkcpu (void)
unsigned int i, core, nr_cores = cpu_numcores();
u32 mask = cpu_mask();
#ifdef CONFIG_HETROGENOUS_CLUSTERS
unsigned int j, dsp_core, dsp_numcores = cpu_num_dspcores();
u32 dsp_mask = cpu_dsp_mask();
#endif
svr = get_svr();
major = SVR_MAJ(svr);
minor = SVR_MIN(svr);
......@@ -166,6 +171,16 @@ int checkcpu (void)
printf("CPU%d:%-4s MHz, ", core,
strmhz(buf1, sysinfo.freq_processor[core]));
}
#ifdef CONFIG_HETROGENOUS_CLUSTERS
for_each_cpu(j, dsp_core, dsp_numcores, dsp_mask) {
if (!(j & 3))
printf("\n ");
printf("DSP CPU%d:%-4s MHz, ", j,
strmhz(buf1, sysinfo.freq_processor_dsp[dsp_core]));
}
#endif
printf("\n CCB:%-4s MHz,", strmhz(buf1, sysinfo.freq_systembus));
printf("\n");
......@@ -224,6 +239,19 @@ int checkcpu (void)
printf(" QE:%-4s MHz\n", strmhz(buf1, sysinfo.freq_qe));
#endif
#if defined(CONFIG_SYS_CPRI)
printf(" ");
printf("CPRI:%-4s MHz", strmhz(buf1, sysinfo.freq_cpri));
#endif
#if defined(CONFIG_SYS_MAPLE)
printf("\n ");
printf("MAPLE:%-4s MHz, ", strmhz(buf1, sysinfo.freq_maple));
printf("MAPLE-ULB:%-4s MHz, ", strmhz(buf1, sysinfo.freq_maple_ulb));
printf("MAPLE-eTVPE:%-4s MHz\n",
strmhz(buf1, sysinfo.freq_maple_etvpe));
#endif
#ifdef CONFIG_SYS_DPAA_FMAN
for (i = 0; i < CONFIG_SYS_NUM_FMAN; i++) {
printf(" FMAN%d: %s MHz\n", i + 1,
......
......@@ -34,6 +34,10 @@ void get_sys_info(sys_info_t *sys_info)
#ifdef CONFIG_FSL_CORENET
volatile ccsr_clk_t *clk = (void *)(CONFIG_SYS_FSL_CORENET_CLK_ADDR);
unsigned int cpu;
#ifdef CONFIG_HETROGENOUS_CLUSTERS
unsigned int dsp_cpu;
uint rcw_tmp1, rcw_tmp2;
#endif
#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
int cc_group[12] = CONFIG_SYS_FSL_CLUSTER_CLOCKS;
#endif
......@@ -157,6 +161,7 @@ void get_sys_info(sys_info_t *sys_info)
else
freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
}
#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
/*
* As per CHASSIS2 architeture total 12 clusters are posible and
......@@ -181,6 +186,20 @@ void get_sys_info(sys_info_t *sys_info)
sys_info->freq_processor[cpu] =
freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
}
#ifdef CONFIG_HETROGENOUS_CLUSTERS
for_each_cpu(i, dsp_cpu, cpu_num_dspcores(), cpu_dsp_mask()) {
int dsp_cluster = fsl_qoriq_dsp_core_to_cluster(dsp_cpu);
u32 c_pll_sel = (in_be32
(&clk->clkcsr[dsp_cluster].clkcncsr) >> 27)
& 0xf;
u32 cplx_pll = core_cplx_PLL[c_pll_sel];
cplx_pll += cc_group[dsp_cluster] - 1;
sys_info->freq_processor_dsp[dsp_cpu] =
freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
}
#endif
#if defined(CONFIG_PPC_B4860) || defined(CONFIG_PPC_B4420) || \
defined(CONFIG_PPC_T2080) || defined(CONFIG_PPC_T2081)
#define FM1_CLK_SEL 0xe0000000
......@@ -243,6 +262,127 @@ void get_sys_info(sys_info_t *sys_info)
sys_info->freq_qman = sys_info->freq_systembus / CONFIG_QBMAN_CLK_DIV;
#endif
#if defined(CONFIG_SYS_MAPLE)
#define CPRI_CLK_SEL 0x1C000000
#define CPRI_CLK_SHIFT 26
#define CPRI_ALT_CLK_SEL 0x00007000
#define CPRI_ALT_CLK_SHIFT 12
rcw_tmp1 = in_be32(&gur->rcwsr[7]); /* Reading RCW bits: 224-255*/
rcw_tmp2 = in_be32(&gur->rcwsr[15]); /* Reading RCW bits: 480-511*/
/* For MAPLE and CPRI frequency */
switch ((rcw_tmp1 & CPRI_CLK_SEL) >> CPRI_CLK_SHIFT) {
case 1:
sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK];
sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK];
break;
case 2:
sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 2;
sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 2;
break;
case 3:
sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 3;
sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 3;
break;
case 4:
sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 4;
sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 4;
break;
case 5:
if (((rcw_tmp2 & CPRI_ALT_CLK_SEL)
>> CPRI_ALT_CLK_SHIFT) == 6) {
sys_info->freq_maple =
freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 2;
sys_info->freq_cpri =
freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 2;
}
if (((rcw_tmp2 & CPRI_ALT_CLK_SEL)
>> CPRI_ALT_CLK_SHIFT) == 7) {
sys_info->freq_maple =
freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 3;
sys_info->freq_cpri =
freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 3;
}
break;
case 6:
sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 2;
sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 2;
break;
case 7:
sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 3;
sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 3;
break;
default:
printf("Error: Unknown MAPLE/CPRI clock select!\n");
}
/* For MAPLE ULB and eTVPE frequencies */
#define ULB_CLK_SEL 0x00000038
#define ULB_CLK_SHIFT 3
#define ETVPE_CLK_SEL 0x00000007
#define ETVPE_CLK_SHIFT 0
switch ((rcw_tmp2 & ULB_CLK_SEL) >> ULB_CLK_SHIFT) {
case 1:
sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK];
break;
case 2:
sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 2;
break;
case 3:
sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 3;
break;
case 4:
sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 4;
break;
case 5:
sys_info->freq_maple_ulb = sys_info->freq_systembus;
break;
case 6:
sys_info->freq_maple_ulb =
freq_c_pll[CONFIG_SYS_ULB_CLK - 1] / 2;
break;
case 7:
sys_info->freq_maple_ulb =
freq_c_pll[CONFIG_SYS_ULB_CLK - 1] / 3;
break;
default:
printf("Error: Unknown MAPLE ULB clock select!\n");
}
switch ((rcw_tmp2 & ETVPE_CLK_SEL) >> ETVPE_CLK_SHIFT) {
case 1:
sys_info->freq_maple_etvpe = freq_c_pll[CONFIG_SYS_ETVPE_CLK];
break;
case 2:
sys_info->freq_maple_etvpe =
freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 2;
break;
case 3:
sys_info->freq_maple_etvpe =
freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 3;
break;
case 4:
sys_info->freq_maple_etvpe =
freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 4;
break;
case 5:
sys_info->freq_maple_etvpe = sys_info->freq_systembus;
break;
case 6:
sys_info->freq_maple_etvpe =
freq_c_pll[CONFIG_SYS_ETVPE_CLK - 1] / 2;
break;
case 7:
sys_info->freq_maple_etvpe =
freq_c_pll[CONFIG_SYS_ETVPE_CLK - 1] / 3;
break;
default:
printf("Error: Unknown MAPLE eTVPE clock select!\n");
}
#endif
#ifdef CONFIG_SYS_DPAA_FMAN
#ifndef CONFIG_FM_PLAT_CLK_DIV
switch ((rcw_tmp & FM1_CLK_SEL) >> FM1_CLK_SHIFT) {
......
......@@ -133,6 +133,53 @@ u32 compute_ppc_cpumask(void)
return mask;
}
#ifdef CONFIG_HETROGENOUS_CLUSTERS
u32 compute_dsp_cpumask(void)
{
ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
int i = CONFIG_DSP_CLUSTER_START, count = 0;
u32 cluster, type, dsp_mask = 0;
do {
int j;
cluster = in_be32(&gur->tp_cluster[i].lower);
for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
type = init_type(cluster, j);
if (type) {
if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_SC)
dsp_mask |= 1 << count;
count++;
}
}
i++;
} while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC);
return dsp_mask;
}
int fsl_qoriq_dsp_core_to_cluster(unsigned int core)
{
ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
int count = 0, i = CONFIG_DSP_CLUSTER_START;
u32 cluster;
do {
int j;
cluster = in_be32(&gur->tp_cluster[i].lower);
for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
if (init_type(cluster, j)) {
if (count == core)
return i;
count++;
}
}
i++;
} while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC);
return -1; /* cannot identify the cluster */
}
#endif
int fsl_qoriq_core_to_cluster(unsigned int core)
{
ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
......@@ -198,8 +245,43 @@ __weak u32 cpu_mask(void)
return cpu->mask;
}
#ifdef CONFIG_HETROGENOUS_CLUSTERS
__weak u32 cpu_dsp_mask(void)
{
ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR;
struct cpu_type *cpu = gd->arch.cpu;
/* better to query feature reporting register than just assume 1 */
if (cpu == &cpu_type_unknown)
return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >>
MPC8xxx_PICFRR_NCPU_SHIFT) + 1;
if (cpu->dsp_num_cores == 0)
return compute_dsp_cpumask();
return cpu->dsp_mask;
}
/*
* Return the number of cores on this SOC.
* Return the number of SC/DSP cores on this SOC.
*/
__weak int cpu_num_dspcores(void)
{
struct cpu_type *cpu = gd->arch.cpu;
/*
* Report # of cores in terms of the cpu_mask if we haven't
* figured out how many there are yet
*/
if (cpu->dsp_num_cores == 0)
return hweight32(cpu_dsp_mask());
return cpu->dsp_num_cores;
}
#endif
/*
* Return the number of PPC cores on this SOC.
*/
__weak int cpu_numcores(void)
{
......@@ -215,6 +297,7 @@ __weak int cpu_numcores(void)
return cpu->num_cores;
}
/*
* Check if the given core ID is valid
*
......@@ -248,6 +331,12 @@ int fixup_cpu(void)
cpu->num_cores = cpu_numcores();
}
#ifdef CONFIG_HETROGENOUS_CLUSTERS
if (cpu->dsp_num_cores == 0) {
cpu->dsp_mask = cpu_dsp_mask();
cpu->dsp_num_cores = cpu_num_dspcores();
}
#endif
return 0;
}
......
......@@ -689,13 +689,22 @@
#define CONFIG_FSL_CORENET /* Freescale CoreNet platform */
#define CONFIG_SYS_FSL_QORIQ_CHASSIS2 /* Freescale Chassis generation 2 */
#define CONFIG_SYS_FSL_QMAN_V3 /* QMAN version 3 */
#define CONFIG_HETROGENOUS_CLUSTERS /* DSP/SC3900 core clusters */
#define CONFIG_PPC_CLUSTER_START 0 /*Start index of ppc clusters*/
#define CONFIG_DSP_CLUSTER_START 1 /*Start index of dsp clusters*/
#define CONFIG_SYS_FSL_NUM_LAWS 32
#define CONFIG_SYS_FSL_SRDS_1
#define CONFIG_SYS_FSL_SRDS_2
#define CONFIG_SYS_MAPLE
#define CONFIG_SYS_CPRI
#define CONFIG_SYS_FSL_NUM_CC_PLLS 5
#define CONFIG_SYS_FSL_SEC_COMPAT 4
#define CONFIG_SYS_NUM_FMAN 1
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#define CONFIG_SYS_FM1_CLK 0
#define CONFIG_SYS_CPRI_CLK 3
#define CONFIG_SYS_ULB_CLK 4
#define CONFIG_SYS_ETVPE_CLK 1
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_7
#define CONFIG_SYS_FSL_IFC_BANK_COUNT 4
#define CONFIG_SYS_FMAN_V3
......@@ -718,8 +727,9 @@
#ifdef CONFIG_PPC_B4860
#define CONFIG_SYS_FSL_CORES_PER_CLUSTER 4
#define CONFIG_MAX_CPUS 4
#define CONFIG_MAX_DSP_CPUS 12
#define CONFIG_NUM_DSP_CPUS 6
#define CONFIG_SYS_FSL_SRDS_NUM_PLLS 2
#define CONFIG_SYS_FSL_NUM_CC_PLLS 4
#define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 4, 4, 4 }
#define CONFIG_SYS_NUM_FM1_DTSEC 6
#define CONFIG_SYS_NUM_FM1_10GEC 2
......@@ -731,9 +741,9 @@
#define CONFIG_SYS_FSL_SRIO_LIODN
#else
#define CONFIG_MAX_CPUS 2
#define CONFIG_MAX_DSP_CPUS 2
#define CONFIG_SYS_FSL_SRDS_NUM_PLLS 1
#define CONFIG_SYS_FSL_CORES_PER_CLUSTER 2
#define CONFIG_SYS_FSL_NUM_CC_PLLS 4
#define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 4 }
#define CONFIG_SYS_NUM_FM1_DTSEC 4
#define CONFIG_SYS_NUM_FM1_10GEC 0
......
......@@ -1202,12 +1202,17 @@ struct cpu_type {
u32 soc_ver;
u32 num_cores;
u32 mask; /* which cpu(s) actually exist */
#ifdef CONFIG_HETROGENOUS_CLUSTERS
u32 dsp_num_cores;
u32 dsp_mask; /* which DSP cpu(s) actually exist */
#endif
};
struct cpu_type *identify_cpu(u32 ver);
int fixup_cpu(void);
int fsl_qoriq_core_to_cluster(unsigned int core);
int fsl_qoriq_dsp_core_to_cluster(unsigned int core);
#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
#define CPU_TYPE_ENTRY(n, v, nc) \
......
DSP side awareness for Freescale heterogeneous multicore chips based on
StarCore and Power Architecture
===============================================================
powerpc/mpc85xx code ve APIs and function to get the number,
configuration and frequencies of all PowerPC cores and devices
connected to them, but it didnt have the similar code ofr HEterogeneous
SC3900/DSP cores and such devices like CPRI, MAPLE, MAPLE-ULB etc.
Code for DSP side awareness provides such functionality for Freescale
Heterogeneous SoCs which are chasis-2 compliant like B4860 and B4420
As part of this feature, following changes have been made:
==========================================================
1. Changed files:
=================
- arch/powerpc/cpu/mpc85xx/cpu.c
Code added in this file to print the DSP cores and other device's(CPRI,
MAPLE etc) frequencies
- arch/powerpc/cpu/mpc85xx/speed.c
Added Defines and code to extract the frequncy information for all
required cores and devices from RCW and System frequency
- arch/powerpc/cpu/mpc8xxx/cpu.c
Added API to get the number of SC cores in running system and Their BIT
MASK, similar to the code written for PowerPC
- arch/powerpc/include/asm/config_mpc85xx.h
Added top level CONFIG to identify presence of HETEROGENUOUS clusters
in the system and CONFIGS for SC3900/DSP components
- arch/powerpc/include/asm/processor.h
- include/common.h
Added newly added Functions Declaration
- include/e500.h
Global structure updated for dsp cores and other components
2. CONFIGs ADDED
================
CONFIG_HETROGENOUS_CLUSTERS - Define for checking the presence of
DSP/SC3900 core clusters
CONFIG_SYS_FSL_NUM_CC_PLLS - Define for number of PLLs
Though there are only 4 PLLs in B4, but in sequence of PLLs from PLL1 -
PLL5, PLL3 is Reserved(as mentioned in RM), so this define contains the
value as 5 not 4, to iterate over all PLLs while coding
CONFIG_SYS_MAPLE - Define for MAPLE Baseband Accelerator
CONFIG_SYS_CPRI - Define for CPRI Interface
CONFIG_PPC_CLUSTER_START - Start index of ppc clusters
CONFIG_DSP_CLUSTER_START - Start index of dsp clusters
Following are the defines for PLL's index that provide the Clocking to
CPRI, ULB and ETVE components
CONFIG_SYS_CPRI_CLK - Define PLL index for CPRI clock
CONFIG_SYS_ULB_CLK - Define PLL index for ULB clock
CONFIG_SYS_ETVPE_CLK - Define PLL index for ETVPE clock
3. Changes in MPC85xx_SYS_INFO Global structure
===============================================
DSP cores and other device's components have been added in this structure.
freq_processor_dsp[CONFIG_MAX_DSP_CPUS] - Array to contain the DSP core's frequencies
freq_cpri - To store CPRI frequency
freq_maple - To store MAPLE frequency
freq_maple_ulb - To store MAPLE-ULB frequency
freq_maple_etvpe - To store MAPLE-eTVPE frequency
4. U-BOOT LOGS
==============
4.1 B4860QDS board
Boot from NOR flash
U-Boot 2014.07-00222-g70587a8-dirty (Aug 07 2014 - 13:15:47)
CPU0: B4860E, Version: 2.0, (0x86880020)
Core: e6500, Version: 2.0, (0x80400020) Clock Configuration:
CPU0:1600 MHz, CPU1:1600 MHz, CPU2:1600 MHz, CPU3:1600 MHz,
DSP CPU0:1200 MHz, DSP CPU1:1200 MHz, DSP CPU2:1200 MHz, DSP CPU3:1200 MHz,
DSP CPU4:1200 MHz, DSP CPU5:1200 MHz,
CCB:666.667 MHz,
DDR:933.333 MHz (1866.667 MT/s data rate) (Asynchronous), IFC:166.667 MHz
CPRI:600 MHz
MAPLE:600 MHz, MAPLE-ULB:800 MHz, MAPLE-eTVPE:1000 MHz
FMAN1: 666.667 MHz
QMAN: 333.333 MHz
CPUn - PowerPC core
DSP CPUn - SC3900 core
Shaveta Leekha(shaveta@freescale.com)
Created August 7, 2014
===========================================
......@@ -553,7 +553,9 @@ static inline int cpumask_next(int cpu, unsigned int mask)
iter++, cpu = cpumask_next(cpu, mask)) \
int cpu_numcores (void);
int cpu_num_dspcores(void);
u32 cpu_mask (void);
u32 cpu_dsp_mask(void);
int is_core_valid (unsigned int);
int probecpu (void);
int checkcpu (void);
......
......@@ -11,6 +11,9 @@
typedef struct
{
unsigned long freq_processor[CONFIG_MAX_CPUS];
#ifdef CONFIG_HETROGENOUS_CLUSTERS
unsigned long freq_processor_dsp[CONFIG_MAX_DSP_CPUS];
#endif
unsigned long freq_systembus;
unsigned long freq_ddrbus;
unsigned long freq_localbus;
......@@ -24,6 +27,14 @@ typedef struct
#ifdef CONFIG_SYS_DPAA_PME
unsigned long freq_pme;
#endif
#ifdef CONFIG_SYS_CPRI
unsigned long freq_cpri;
#endif
#ifdef CONFIG_SYS_MAPLE
unsigned long freq_maple;
unsigned long freq_maple_ulb;
unsigned long freq_maple_etvpe;
#endif
#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
unsigned char diff_sysclk;
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment