mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-28 02:35:28 +00:00
nuc: Adjust core clock from 16/12 MHz to 15/13 MHz.
We found the deviation of 115200 UART baud-rate is too large when core clock is 16 or 12MHz. It causes failure during FAFT since sometime EC could not receive correct commands to proceed test. We adjusted core clock from 16/12 to 15/13 to reduce the deviation of 115200. Both of them have run FAFT and stress tests for weeks and no UART issues were found. Since the lowest source clock of i2c is 6.5MHz, we modified tSCLL, tSCLH and hold time directly for better i2c timing when freq is 400K. And if freq is 100K, we introduced normal mode to handle it. Modified sources: 1. clock.c: Adjust core clock from 16/12 MHz to 15/13 MHz. 2. clock_chip.h: Set target core clock as 15 MHz. 3. uart.c: Add baud-rate support for 15/13 MHz. 4. register.h: Add new register definitions of SMBus. 5. i2c.c: Modified tSCLL, tSCLH and hold time directly for better i2c timing. BUG=chrome-os-partner:34346 TEST=make buildall -j; test nuvoton IC specific drivers BRANCH=none Change-Id: Ie5d22e87875c064b49338046c99a178f8fadf32b Signed-off-by: Mulin Chao <mlchao@nuvoton.com> Reviewed-on: https://chromium-review.googlesource.com/322320 Reviewed-by: Shawn N <shawnn@chromium.org>
This commit is contained in:
@@ -47,11 +47,14 @@
|
||||
#define HFCGMH 0x07
|
||||
#define HFCGML 0xDE
|
||||
#elif (OSC_CLK == 24000000)
|
||||
#define HFCGMH 0x05
|
||||
#define HFCGML 0xB8
|
||||
#elif (OSC_CLK == 16000000)
|
||||
#define HFCGMH 0x03
|
||||
#define HFCGML 0xDC
|
||||
#define HFCGMH 0x0B
|
||||
#define HFCGML 0x71
|
||||
#elif (OSC_CLK == 15000000)
|
||||
#define HFCGMH 0x07
|
||||
#define HFCGML 0x27
|
||||
#elif (OSC_CLK == 13000000)
|
||||
#define HFCGMH 0x06
|
||||
#define HFCGML 0x33
|
||||
#else
|
||||
#error "Unsupported FMCLK Clock Frequency"
|
||||
#endif
|
||||
@@ -135,8 +138,14 @@ void clock_init(void)
|
||||
while (IS_BIT_SET(NPCX_HFCGCTRL, NPCX_HFCGCTRL_CLK_CHNG))
|
||||
;
|
||||
|
||||
/* Keep FMCLK in 33-50 MHz which is tested strictly. */
|
||||
#if (OSC_CLK >= 33000000)
|
||||
/* Keep Core CLK & FMCLK are the same */
|
||||
NPCX_HFCGP = 0x00;
|
||||
#else
|
||||
/* Keep Core CLK = 0.5 * FMCLK */
|
||||
NPCX_HFCGP = 0x10;
|
||||
#endif
|
||||
|
||||
freq = OSC_CLK;
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#ifndef __CROS_EC_CLOCK_CHIP_H
|
||||
#define __CROS_EC_CLOCK_CHIP_H
|
||||
|
||||
/* Default is 40MHz (target is 16MHz) */
|
||||
#define OSC_CLK 16000000
|
||||
/* Default is 40MHz (target is 15MHz) */
|
||||
#define OSC_CLK 15000000
|
||||
|
||||
/**
|
||||
* Return the current APB1 clock frequency in Hz.
|
||||
|
||||
@@ -658,7 +658,7 @@ static void i2c_freq_changed(void)
|
||||
for (i = 0; i < i2c_ports_used; i++) {
|
||||
int bus_freq = i2c_ports[i].kbps;
|
||||
int ctrl = i2c_port_to_controller(i2c_ports[i].port);
|
||||
int scl_time;
|
||||
int scl_freq;
|
||||
|
||||
/* SMB0/1 use core clock & SMB2/3 use apb2 clock */
|
||||
if (ctrl < 2)
|
||||
@@ -666,21 +666,78 @@ static void i2c_freq_changed(void)
|
||||
else
|
||||
freq = clock_get_apb2_freq();
|
||||
|
||||
/* use Fast Mode */
|
||||
SET_BIT(NPCX_SMBCTL3(ctrl) , NPCX_SMBCTL3_400K);
|
||||
|
||||
/*
|
||||
* Set SCLLT/SCLHT:
|
||||
* tSCLL = 2 * SCLLT7-0 * tCLK
|
||||
* tSCLH = 2 * SCLHT7-0 * tCLK
|
||||
* (tSCLL+tSCLH) = 4 * SCLH(L)T * tCLK if tSCLL == tSCLH
|
||||
* SCLH(L)T = T(SCL)/4/T(CLK) = FREQ(CLK)/4/FREQ(SCL)
|
||||
* Set SCL frequency by formula:
|
||||
* tSCL = 4 * SCLFRQ * tCLK
|
||||
* fSCL = fCLK / (4*SCLFRQ)
|
||||
* SCLFRQ = fSCL/(4*fSCL)
|
||||
*/
|
||||
scl_time = (freq/1000) / (bus_freq * 4); /* bus_freq is KHz */
|
||||
scl_freq = (freq/1000) / (bus_freq*4); /* bus_freq is KHz */
|
||||
|
||||
/* set SCL High/Low time */
|
||||
NPCX_SMBSCLLT(ctrl) = scl_time;
|
||||
NPCX_SMBSCLHT(ctrl) = scl_time;
|
||||
/* Normal mode if i2c freq is under 100kHz */
|
||||
if (bus_freq <= 100) {
|
||||
/* Set divider value of SCL */
|
||||
SET_FIELD(NPCX_SMBCTL2(ctrl), NPCX_SMBCTL2_SCLFRQ7_FIELD
|
||||
, (scl_freq & 0x7F));
|
||||
SET_FIELD(NPCX_SMBCTL3(ctrl), NPCX_SMBCTL3_SCLFRQ2_FIELD
|
||||
, (scl_freq >> 7));
|
||||
} else {
|
||||
/* use Fast Mode */
|
||||
SET_BIT(NPCX_SMBCTL3(ctrl) , NPCX_SMBCTL3_400K);
|
||||
#if (OSC_CLK > 15000000)
|
||||
/*
|
||||
* Set SCLLT/SCLHT:
|
||||
* tSCLL = 2 * SCLLT7-0 * tCLK
|
||||
* tSCLH = 2 * SCLHT7-0 * tCLK
|
||||
* (tSCLL+tSCLH) = 4 * SCLH(L)T * tCLK if tSCLL == tSCLH
|
||||
* SCLH(L)T = tSCL/(4*tCLK) = fCLK/(4*fSCL)
|
||||
* The same formula as SCLFRQ
|
||||
*/
|
||||
NPCX_SMBSCLLT(ctrl) = scl_freq;
|
||||
NPCX_SMBSCLHT(ctrl) = scl_freq;
|
||||
#else
|
||||
/*
|
||||
* Set SCLH(L)T and hold-time directly for best i2c
|
||||
* timing condition if core clock is low. Please refer
|
||||
* Section 7.5.9 "SMBus Timing - Fast Mode" for detail.
|
||||
*/
|
||||
if (bus_freq == 400) {
|
||||
if (freq == 15000000) {
|
||||
NPCX_SMBSCLLT(ctrl) = 12;
|
||||
NPCX_SMBSCLHT(ctrl) = 9;
|
||||
SET_FIELD(NPCX_SMBCTL4(ctrl),
|
||||
NPCX_SMBCTL4_HLDT_FIELD, 7);
|
||||
} else if (freq == 15000000/2) {
|
||||
NPCX_SMBSCLLT(ctrl) = 7;
|
||||
NPCX_SMBSCLHT(ctrl) = 5;
|
||||
SET_FIELD(NPCX_SMBCTL4(ctrl),
|
||||
NPCX_SMBCTL4_HLDT_FIELD, 7);
|
||||
} else if (freq == 13000000) {
|
||||
NPCX_SMBSCLLT(ctrl) = 11;
|
||||
NPCX_SMBSCLHT(ctrl) = 8;
|
||||
SET_FIELD(NPCX_SMBCTL4(ctrl),
|
||||
NPCX_SMBCTL4_HLDT_FIELD, 7);
|
||||
} else if (freq == 13000000/2) {
|
||||
NPCX_SMBSCLLT(ctrl) = 7;
|
||||
NPCX_SMBSCLHT(ctrl) = 4;
|
||||
SET_FIELD(NPCX_SMBCTL4(ctrl),
|
||||
NPCX_SMBCTL4_HLDT_FIELD, 7);
|
||||
} else {
|
||||
/* Set value from formula */
|
||||
NPCX_SMBSCLLT(ctrl) = scl_freq;
|
||||
NPCX_SMBSCLHT(ctrl) = scl_freq;
|
||||
cprints(CC_I2C, "Warning: Not ",
|
||||
"optimized timing for i2c %d", ctrl);
|
||||
}
|
||||
} else {
|
||||
/* Set value from formula */
|
||||
NPCX_SMBSCLLT(ctrl) = scl_freq;
|
||||
NPCX_SMBSCLHT(ctrl) = scl_freq;
|
||||
cprints(CC_I2C, "Warning: I2c %d don't support",
|
||||
" over 400kHz if src clock is low.", ctrl);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
DECLARE_HOOK(HOOK_FREQ_CHANGE, i2c_freq_changed, HOOK_PRIO_DEFAULT);
|
||||
|
||||
@@ -670,11 +670,14 @@ enum {
|
||||
#define NPCX_SMBCTL1_NMINTE 6
|
||||
#define NPCX_SMBCTL1_STASTRE 7
|
||||
#define NPCX_SMBCTL2_ENABLE 0
|
||||
#define NPCX_SMBCTL2_SCLFRQ7_FIELD FIELD(1, 7)
|
||||
#define NPCX_SMBCTL3_ARPMEN 2
|
||||
#define NPCX_SMBCTL3_SCLFRQ2_FIELD FIELD(0, 2)
|
||||
#define NPCX_SMBCTL3_IDL_START 3
|
||||
#define NPCX_SMBCTL3_400K 4
|
||||
#define NPCX_SMBCTL3_SDA_LVL 6
|
||||
#define NPCX_SMBCTL3_SCL_LVL 7
|
||||
#define NPCX_SMBCTL4_HLDT_FIELD FIELD(0, 6)
|
||||
#define NPCX_SMBADDR1_SAEN 7
|
||||
#define NPCX_SMBADDR2_SAEN 7
|
||||
#define NPCX_SMBADDR3_SAEN 7
|
||||
|
||||
@@ -171,11 +171,14 @@ static void uart_config(void)
|
||||
#elif (OSC_CLK == 24000000)
|
||||
NPCX_UPSR = 0x60;
|
||||
NPCX_UBAUD = 0x00;
|
||||
#elif (OSC_CLK == 16000000)
|
||||
NPCX_UPSR = 0x10;
|
||||
NPCX_UBAUD = 0x02;
|
||||
#elif (OSC_CLK == 15000000)
|
||||
NPCX_UPSR = 0x38;
|
||||
NPCX_UBAUD = 0x00;
|
||||
#elif (OSC_CLK == 13000000)
|
||||
NPCX_UPSR = 0x30;
|
||||
NPCX_UBAUD = 0x00;
|
||||
#else
|
||||
#error "Unsupported FMCLK Clock Frequency"
|
||||
#error "Unsupported Core Clock Frequency"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user