soc/mediatek/mt8192: add clkbuf and srclken_rc MT6359P driver
Add clkbuf and srclken_rc init for low power. Reference datasheet: Document No: RH-D-2018-0205. TEST=boot asurada Signed-off-by: Ran Bi <ran.bi@mediatek.com> Change-Id: I947bf14df7a307bf359c590c2a20265882b3f1be Reviewed-on: https://review.coreboot.org/c/coreboot/+/46878 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Yu-Ping Wu <yupingso@google.com>
This commit is contained in:
parent
68cb9ed068
commit
ec39cb3a80
|
@ -82,4 +82,11 @@ config FLASH_DUAL_READ
|
|||
When this option is enabled, the flash controller provides the ability
|
||||
to dual read mode.
|
||||
|
||||
config SRCLKEN_RC_SUPPORT
|
||||
bool
|
||||
default y
|
||||
help
|
||||
This option enables clock buffer remote controller module
|
||||
to control PMIC 26MHz clock output.
|
||||
|
||||
endif
|
||||
|
|
|
@ -2,6 +2,7 @@ ifeq ($(CONFIG_SOC_MEDIATEK_MT8192),y)
|
|||
|
||||
bootblock-y += ../common/auxadc.c
|
||||
bootblock-y += bootblock.c
|
||||
bootblock-y += clkbuf.c srclken_rc.c
|
||||
bootblock-y += eint_event.c
|
||||
bootblock-y += ../common/flash_controller.c
|
||||
bootblock-y += ../common/gpio.c gpio.c
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <bootblock_common.h>
|
||||
#include <soc/clkbuf.h>
|
||||
#include <soc/eint_event.h>
|
||||
#include <soc/mmu_operations.h>
|
||||
#include <soc/mt6315.h>
|
||||
|
@ -8,6 +9,7 @@
|
|||
#include <soc/pll.h>
|
||||
#include <soc/pmif.h>
|
||||
#include <soc/rtc.h>
|
||||
#include <soc/srclken_rc.h>
|
||||
#include <soc/wdt.h>
|
||||
|
||||
void bootblock_soc_init(void)
|
||||
|
@ -18,6 +20,8 @@ void bootblock_soc_init(void)
|
|||
mtk_pmif_init();
|
||||
mt6359p_init();
|
||||
mt6315_init();
|
||||
srclken_rc_init();
|
||||
clk_buf_init();
|
||||
rtc_boot();
|
||||
unmask_eint_event_mask();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <device/mmio.h>
|
||||
#include <soc/clkbuf.h>
|
||||
#include <soc/pmif.h>
|
||||
#include <soc/srclken_rc.h>
|
||||
|
||||
|
||||
#define BUFTAG "[CLKBUF]"
|
||||
#define buf_info(fmt, arg ...) printk(BIOS_INFO, BUFTAG "%s,%d: " fmt, \
|
||||
__func__, __LINE__, ## arg)
|
||||
|
||||
#define _buf_clrset32_impl(addr, clear, set) \
|
||||
buf_write(addr, (buf_read(addr) & ~((uint32_t)(clear))) | (set))
|
||||
|
||||
#define BUF_SET_FIELDS(addr, ...) \
|
||||
_BF_IMPL(_buf_clrset32_impl, addr, __VA_ARGS__)
|
||||
#define BUF_READ_FIELD(addr, name) \
|
||||
EXTRACT_BITFIELD(buf_read(addr), name)
|
||||
|
||||
#define PMIC_CW00_INIT_VAL 0x4005 /* 0100 0000 0000 0101 */
|
||||
#define PMIC_CW09_INIT_VAL 0x01F0 /* 0000 0001 1111 0000 */
|
||||
|
||||
static struct pmif *pmif_arb;
|
||||
|
||||
static u32 buf_read(u32 addr)
|
||||
{
|
||||
u32 rdata;
|
||||
|
||||
if (pmif_arb == NULL)
|
||||
pmif_arb = get_pmif_controller(PMIF_SPI, 0);
|
||||
pmif_arb->read(pmif_arb, 0, addr, &rdata);
|
||||
|
||||
return rdata;
|
||||
}
|
||||
|
||||
static void buf_write(u32 addr, u32 wdata)
|
||||
{
|
||||
if (pmif_arb == NULL)
|
||||
pmif_arb = get_pmif_controller(PMIF_SPI, 0);
|
||||
pmif_arb->write(pmif_arb, 0, addr, wdata);
|
||||
}
|
||||
|
||||
static void dump_clkbuf_log(void)
|
||||
{
|
||||
u32 pmic_cw00, pmic_cw09, pmic_cw12, pmic_cw13, pmic_cw15, pmic_cw19,
|
||||
top_spi_con1, ldo_vrfck_op_en, ldo_vbbck_op_en, ldo_vrfck_en,
|
||||
ldo_vbbck_en, vrfck_hv_en;
|
||||
|
||||
pmic_cw00 = BUF_READ_FIELD(PMIC_RG_DCXO_CW00, PMIC_REG_COMMON);
|
||||
pmic_cw09 = BUF_READ_FIELD(PMIC_RG_DCXO_CW09, PMIC_REG_COMMON);
|
||||
pmic_cw12 = BUF_READ_FIELD(PMIC_RG_DCXO_CW12, PMIC_REG_COMMON);
|
||||
pmic_cw13 = BUF_READ_FIELD(PMIC_RG_DCXO_CW13, PMIC_REG_COMMON);
|
||||
pmic_cw15 = BUF_READ_FIELD(PMIC_RG_DCXO_CW15, PMIC_REG_COMMON);
|
||||
pmic_cw19 = BUF_READ_FIELD(PMIC_RG_DCXO_CW19, PMIC_REG_COMMON);
|
||||
buf_info("DCXO_CW00/09/12/13/15/19=%#x %#x %#x %#x %#x %#x\n",
|
||||
pmic_cw00, pmic_cw09, pmic_cw12,
|
||||
pmic_cw13, pmic_cw15, pmic_cw19);
|
||||
|
||||
top_spi_con1 = BUF_READ_FIELD(PMIC_RG_TOP_SPI_CON1, PMIC_RG_SRCLKEN_IN3_EN);
|
||||
ldo_vrfck_op_en = BUF_READ_FIELD(PMIC_RG_LDO_VRFCK_OP_EN,
|
||||
PMIC_RG_LDO_VRFCK_HW14_OP_EN);
|
||||
ldo_vbbck_op_en = BUF_READ_FIELD(PMIC_RG_LDO_VBBCK_OP_EN,
|
||||
PMIC_RG_LDO_VBBCK_HW14_OP_EN);
|
||||
ldo_vrfck_en = BUF_READ_FIELD(PMIC_RG_LDO_VRFCK_CON0, PMIC_RG_LDO_VRFCK_EN);
|
||||
ldo_vbbck_en = BUF_READ_FIELD(PMIC_RG_LDO_VBBCK_CON0, PMIC_RG_LDO_VBBCK_EN);
|
||||
buf_info("spi_con1/ldo_rf_op/ldo_bb_op/ldo_rf_en/ldo_bb_en=%#x %#x %#x %#x %#x\n",
|
||||
top_spi_con1, ldo_vrfck_op_en, ldo_vbbck_op_en,
|
||||
ldo_vrfck_en, ldo_vbbck_en);
|
||||
|
||||
vrfck_hv_en = BUF_READ_FIELD(PMIC_RG_DCXO_ADLDO_BIAS_ELR_0, PMIC_RG_VRFCK_HV_EN);
|
||||
buf_info("clk buf vrfck_hv_en=%#x\n", vrfck_hv_en);
|
||||
}
|
||||
|
||||
int clk_buf_init(void)
|
||||
{
|
||||
/* Dump registers before setting */
|
||||
dump_clkbuf_log();
|
||||
|
||||
/* Unlock pmic key */
|
||||
BUF_SET_FIELDS(PMIC_TOP_TMA_KEY, PMIC_REG_COMMON, PMIC_TOP_TMA_KEY_UNLOCK);
|
||||
|
||||
/* 1.1 Set VRFCK input supply(11.ac mode) */
|
||||
BUF_SET_FIELDS(PMIC_RG_DCXO_ADLDO_BIAS_ELR_0, PMIC_RG_VRFCK_HV_EN, 0x0);
|
||||
|
||||
/* 1.2.0 Set VRFCK En = 0 */
|
||||
BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_CON0, PMIC_RG_LDO_VRFCK_EN, 0x0);
|
||||
/* 1.2.1 Set VRFCK1 as power src */
|
||||
BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_ELR, PMIC_RG_LDO_VRFCK_ANA_SEL, 0x1);
|
||||
|
||||
/* 1.2.2 Switch LDO-RFCK to LDO-RFCK1 */
|
||||
BUF_SET_FIELDS(PMIC_RG_DCXO_ADLDO_BIAS_ELR_0, PMIC_RG_VRFCK_NDIS_EN, 0x0);
|
||||
BUF_SET_FIELDS(PMIC_RG_DCXO_ADLDO_BIAS_ELR_1, PMIC_RG_VRFCK_1_NDIS_EN, 0x1);
|
||||
|
||||
/* 1.2.0 Set VRFCK En = 1 */
|
||||
BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_CON0, PMIC_RG_LDO_VRFCK_EN, 0x1);
|
||||
|
||||
/* 1.2.3 Lock pmic key */
|
||||
BUF_SET_FIELDS(PMIC_TOP_TMA_KEY, PMIC_REG_COMMON, 0x0);
|
||||
|
||||
/* Enable XO LDO */
|
||||
BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_OP_EN_SET, PMIC_RG_LDO_VRFCK_HW14_OP_EN, 0x1);
|
||||
BUF_SET_FIELDS(PMIC_RG_LDO_VBBCK_OP_EN_SET, PMIC_RG_LDO_VBBCK_HW14_OP_EN, 0x1);
|
||||
BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_CON0, PMIC_RG_LDO_VRFCK_EN, 0x0);
|
||||
BUF_SET_FIELDS(PMIC_RG_LDO_VBBCK_CON0, PMIC_RG_LDO_VBBCK_EN, 0x0);
|
||||
|
||||
/* Enable 26M control */
|
||||
if (!CONFIG(SRCLKEN_RC_SUPPORT)) {
|
||||
/* Legacy co-clock mode */
|
||||
BUF_SET_FIELDS(PMIC_RG_TOP_SPI_CON1, PMIC_RG_SRCLKEN_IN3_EN, 0x0);
|
||||
|
||||
BUF_SET_FIELDS(PMIC_RG_DCXO_CW00, PMIC_REG_COMMON, PMIC_CW00_INIT_VAL);
|
||||
BUF_SET_FIELDS(PMIC_RG_DCXO_CW09, PMIC_REG_COMMON, PMIC_CW09_INIT_VAL);
|
||||
} else {
|
||||
/* New co-clock mode */
|
||||
/* All XO mode should set to 2'b01 */
|
||||
BUF_SET_FIELDS(PMIC_RG_DCXO_CW00, PMIC_REG_COMMON, PMIC_CW00_INIT_VAL);
|
||||
BUF_SET_FIELDS(PMIC_RG_DCXO_CW09, PMIC_REG_COMMON, PMIC_CW09_INIT_VAL);
|
||||
|
||||
/* 1. Update control mapping table */
|
||||
BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL0, PMIC_RG_XO_VOTE, 0x005);
|
||||
BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL1, PMIC_RG_XO_VOTE, 0x0);
|
||||
BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL2, PMIC_RG_XO_VOTE, 0x0);
|
||||
BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL3, PMIC_RG_XO_VOTE, 0x0);
|
||||
BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL4, PMIC_RG_XO_VOTE, 0x0);
|
||||
/* Wait 100us */
|
||||
udelay(100);
|
||||
|
||||
/* 2. Switch to new control mode */
|
||||
BUF_SET_FIELDS(PMIC_RG_DCXO_CW08, PMIC_RG_XO_PMIC_TOP_DIG_SW, 0x0);
|
||||
}
|
||||
|
||||
/* Check if the setting is ok */
|
||||
dump_clkbuf_log();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -20,6 +20,8 @@ enum {
|
|||
INFRACFG_AO_MEM_BASE = IO_PHYS + 0x00002000,
|
||||
GPIO_BASE = IO_PHYS + 0x00005000,
|
||||
SPM_BASE = IO_PHYS + 0x00006000,
|
||||
RC_BASE = IO_PHYS + 0x00006500,
|
||||
RC_STATUS_BASE = IO_PHYS + 0x00006E00,
|
||||
RGU_BASE = IO_PHYS + 0x00007000,
|
||||
GPT_BASE = IO_PHYS + 0x00008000,
|
||||
EINT_BASE = IO_PHYS + 0x0000B000,
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef SOC_MEDIATEK_MT8192_CLKBUF_H
|
||||
#define SOC_MEDIATEK_MT8192_CLKBUF_H
|
||||
|
||||
#include <device/mmio.h>
|
||||
|
||||
enum {
|
||||
PMIC_RG_DCXO_CW00 = 0x0788,
|
||||
PMIC_RG_DCXO_CW02 = 0x0790,
|
||||
PMIC_RG_DCXO_CW08 = 0x079C,
|
||||
PMIC_RG_DCXO_CW09 = 0x079E,
|
||||
PMIC_RG_DCXO_CW09_CLR = 0x07A2,
|
||||
PMIC_RG_DCXO_CW10 = 0x07A4,
|
||||
PMIC_RG_DCXO_CW12 = 0x07A8,
|
||||
PMIC_RG_DCXO_CW13 = 0x07AA,
|
||||
PMIC_RG_DCXO_CW15 = 0x07AE,
|
||||
PMIC_RG_DCXO_CW19 = 0x07B6,
|
||||
};
|
||||
|
||||
enum {
|
||||
PMIC_TOP_TMA_KEY = 0x3A8,
|
||||
PMIC_RG_TOP_SPI_CON1 = 0x458,
|
||||
};
|
||||
|
||||
enum {
|
||||
PMIC_TOP_TMA_KEY_UNLOCK = 0x9CA6,
|
||||
};
|
||||
|
||||
enum {
|
||||
PMIC_RG_LDO_VRFCK_ELR = 0x1B40,
|
||||
PMIC_RG_LDO_VRFCK_CON0 = 0x1D1C,
|
||||
PMIC_RG_LDO_VRFCK_OP_EN = 0x1D22,
|
||||
PMIC_RG_LDO_VRFCK_OP_EN_SET = 0x1D24,
|
||||
PMIC_RG_LDO_VBBCK_CON0 = 0x1D2E,
|
||||
PMIC_RG_LDO_VBBCK_OP_EN = 0x1D34,
|
||||
PMIC_RG_LDO_VBBCK_OP_EN_SET = 0x1D36,
|
||||
};
|
||||
|
||||
enum {
|
||||
PMIC_RG_DCXO_ADLDO_BIAS_ELR_0 = 0x209C,
|
||||
PMIC_RG_DCXO_ADLDO_BIAS_ELR_1 = 0x209E,
|
||||
};
|
||||
|
||||
enum {
|
||||
PMIC_RG_XO_BUF_CTL0 = 0x54C,
|
||||
PMIC_RG_XO_BUF_CTL1 = 0x54E,
|
||||
PMIC_RG_XO_BUF_CTL2 = 0x550,
|
||||
PMIC_RG_XO_BUF_CTL3 = 0x552,
|
||||
PMIC_RG_XO_BUF_CTL4 = 0x554,
|
||||
PMIC_RG_XO_CONN_BT0 = 0x556,
|
||||
};
|
||||
|
||||
DEFINE_BITFIELD(PMIC_REG_COMMON, 15, 0)
|
||||
DEFINE_BIT(PMIC_RG_VRFCK_HV_EN, 9)
|
||||
DEFINE_BIT(PMIC_RG_LDO_VRFCK_EN, 0)
|
||||
DEFINE_BIT(PMIC_RG_LDO_VRFCK_ANA_SEL, 0)
|
||||
DEFINE_BIT(PMIC_RG_LDO_VBBCK_EN, 0)
|
||||
DEFINE_BIT(PMIC_RG_VRFCK_NDIS_EN, 11)
|
||||
DEFINE_BIT(PMIC_RG_VRFCK_1_NDIS_EN, 0)
|
||||
DEFINE_BIT(PMIC_RG_LDO_VRFCK_HW14_OP_EN, 14)
|
||||
DEFINE_BIT(PMIC_RG_LDO_VBBCK_HW14_OP_EN, 14)
|
||||
DEFINE_BIT(PMIC_RG_SRCLKEN_IN3_EN, 0)
|
||||
DEFINE_BIT(PMIC_RG_XO_PMIC_TOP_DIG_SW, 2)
|
||||
DEFINE_BITFIELD(PMIC_RG_XO_VOTE, 10, 0)
|
||||
|
||||
int clk_buf_init(void);
|
||||
|
||||
#endif /* SOC_MEDIATEK_MT8192_CLKBUF_H */
|
|
@ -3,6 +3,7 @@
|
|||
#ifndef __MT8192_SOC_PMIF_H__
|
||||
#define __MT8192_SOC_PMIF_H__
|
||||
|
||||
#include <device/mmio.h>
|
||||
#include <types.h>
|
||||
|
||||
enum {
|
||||
|
@ -167,6 +168,36 @@ enum {
|
|||
E_SPI_INIT_SIDLY, /* SPI edge calibration fail */
|
||||
};
|
||||
|
||||
enum pmic_interface {
|
||||
PMIF_VLD_RDY = 0,
|
||||
PMIF_SLP_REQ,
|
||||
};
|
||||
|
||||
DEFINE_BIT(PMIFSPI_INF_EN_SRCLKEN_RC_HW, 4)
|
||||
|
||||
DEFINE_BIT(PMIFSPI_OTHER_INF_DXCO0_EN, 0)
|
||||
DEFINE_BIT(PMIFSPI_OTHER_INF_DXCO1_EN, 1)
|
||||
|
||||
DEFINE_BIT(PMIFSPI_ARB_EN_SRCLKEN_RC_HW, 4)
|
||||
DEFINE_BIT(PMIFSPI_ARB_EN_DCXO_CONN, 15)
|
||||
DEFINE_BIT(PMIFSPI_ARB_EN_DCXO_NFC, 16)
|
||||
|
||||
DEFINE_BITFIELD(PMIFSPI_SPM_SLEEP_REQ_SEL, 1, 0)
|
||||
DEFINE_BITFIELD(PMIFSPI_SCP_SLEEP_REQ_SEL, 10, 9)
|
||||
|
||||
DEFINE_BIT(PMIFSPI_MD_CTL_PMIF_RDY, 9)
|
||||
DEFINE_BIT(PMIFSPI_MD_CTL_SRCLK_EN, 10)
|
||||
DEFINE_BIT(PMIFSPI_MD_CTL_SRVOL_EN, 11)
|
||||
|
||||
DEFINE_BITFIELD(PMIFSPMI_SPM_SLEEP_REQ_SEL, 1, 0)
|
||||
DEFINE_BITFIELD(PMIFSPMI_SCP_SLEEP_REQ_SEL, 10, 9)
|
||||
|
||||
DEFINE_BIT(PMIFSPMI_MD_CTL_PMIF_RDY, 9)
|
||||
DEFINE_BIT(PMIFSPMI_MD_CTL_SRCLK_EN, 10)
|
||||
DEFINE_BIT(PMIFSPMI_MD_CTL_SRVOL_EN, 11)
|
||||
|
||||
/* External API */
|
||||
extern struct pmif *get_pmif_controller(int inf, int mstid);
|
||||
extern void pmwrap_interface_init(void);
|
||||
extern int mtk_pmif_init(void);
|
||||
#endif /*__MT8192_SOC_PMIF_H__*/
|
||||
|
|
|
@ -149,19 +149,6 @@ enum {
|
|||
PMIC_RG_BANK_FQMTR_RST_SHIFT = 6,
|
||||
};
|
||||
|
||||
/* PMIC DCXO Register Definition */
|
||||
enum {
|
||||
PMIC_RG_DCXO_CW00 = 0x0788,
|
||||
PMIC_RG_DCXO_CW00_SET = 0x078A,
|
||||
PMIC_RG_DCXO_CW00_CLR = 0x078C,
|
||||
PMIC_RG_DCXO_CW02 = 0x0790,
|
||||
PMIC_RG_DCXO_CW08 = 0x079C,
|
||||
PMIC_RG_DCXO_CW09 = 0x079E,
|
||||
PMIC_RG_DCXO_CW09_SET = 0x07A0,
|
||||
PMIC_RG_DCXO_CW09_CLR = 0x07A2,
|
||||
PMIC_RG_DCXO_CW12 = 0x07A8,
|
||||
};
|
||||
|
||||
/* PMIC Frequency Meter Definition */
|
||||
enum {
|
||||
PMIC_RG_FQMTR_CKSEL = 0x0118,
|
||||
|
@ -228,5 +215,4 @@ int rtc_init(int recover);
|
|||
bool rtc_gpio_init(void);
|
||||
void rtc_boot(void);
|
||||
u16 rtc_get_frequency_meter(u16 val, u16 measure_src, u16 window_size);
|
||||
void mt6359_dcxo_disable_unused(void);
|
||||
#endif /* SOC_MEDIATEK_MT8192_RTC_H */
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef SOC_MEDIATEK_MT8192_SRCLKEN_RC_H
|
||||
#define SOC_MEDIATEK_MT8192_SRCLKEN_RC_H
|
||||
|
||||
#include <device/mmio.h>
|
||||
|
||||
struct mtk_rc_regs {
|
||||
u32 srclken_rc_cfg;
|
||||
u32 rc_central_cfg1;
|
||||
u32 rc_central_cfg2;
|
||||
u32 rc_cmd_arb_cfg;
|
||||
u32 rc_pmic_rcen_addr;
|
||||
u32 rc_pmic_rcen_set_clr_addr;
|
||||
u32 rc_dcxo_fpm_cfg;
|
||||
u32 rc_central_cfg3;
|
||||
u32 rc_mxx_srclken_cfg[13];
|
||||
u32 srclken_sw_con_cfg;
|
||||
u32 rc_central_cfg4;
|
||||
u32 reserved1;
|
||||
u32 rc_protocol_chk_cfg;
|
||||
u32 rc_debug_cfg;
|
||||
u32 reserved2[19];
|
||||
u32 rc_misc_0;
|
||||
u32 rc_spm_ctrl;
|
||||
u32 rc_subsys_intf_cfg;
|
||||
};
|
||||
|
||||
check_member(mtk_rc_regs, rc_central_cfg1, 0x4);
|
||||
check_member(mtk_rc_regs, rc_mxx_srclken_cfg[0], 0x20);
|
||||
check_member(mtk_rc_regs, rc_mxx_srclken_cfg[12], 0x50);
|
||||
check_member(mtk_rc_regs, rc_central_cfg4, 0x58);
|
||||
check_member(mtk_rc_regs, rc_protocol_chk_cfg, 0x60);
|
||||
check_member(mtk_rc_regs, rc_misc_0, 0xb4);
|
||||
check_member(mtk_rc_regs, rc_subsys_intf_cfg, 0xbc);
|
||||
|
||||
struct mtk_rc_status_regs {
|
||||
u32 rc_fsm_sta_0;
|
||||
u32 rc_cmd_sta_0;
|
||||
u32 rc_cmd_sta_1;
|
||||
u32 rc_spi_sta_0;
|
||||
u32 rc_pi_po_sta_0;
|
||||
u32 rc_mxx_req_sta_0[14];
|
||||
u32 reserved2[2];
|
||||
u32 rc_debug_trace;
|
||||
};
|
||||
|
||||
check_member(mtk_rc_status_regs, rc_cmd_sta_1, 0x8);
|
||||
check_member(mtk_rc_status_regs, rc_mxx_req_sta_0[0], 0x14);
|
||||
check_member(mtk_rc_status_regs, rc_mxx_req_sta_0[13], 0x48);
|
||||
check_member(mtk_rc_status_regs, rc_debug_trace, 0x54);
|
||||
|
||||
/* SPM Register */
|
||||
/* SRCLKEN_RC_CFG */
|
||||
DEFINE_BIT(SW_RESET, 0)
|
||||
DEFINE_BIT(CG_32K_EN, 1)
|
||||
DEFINE_BIT(CG_FCLK_EN, 2)
|
||||
DEFINE_BIT(CG_FCLK_FR_EN, 3)
|
||||
DEFINE_BIT(MUX_FCLK_FR, 4)
|
||||
|
||||
/* RC_CENTRAL_CFG1 */
|
||||
DEFINE_BIT(SRCLKEN_RC_EN, 0)
|
||||
DEFINE_BIT(RCEN_ISSUE_M, 1)
|
||||
DEFINE_BIT(RC_SPI_ACTIVE, 2)
|
||||
DEFINE_BIT(SRCLKEN_RC_EN_SEL, 3)
|
||||
DEFINE_BITFIELD(VCORE_SETTLE_T, 7, 5)
|
||||
DEFINE_BITFIELD(ULPOSC_SETTLE_T, 11, 8)
|
||||
DEFINE_BITFIELD(NON_DCXO_SETTLE_T, 21, 12)
|
||||
DEFINE_BITFIELD(DCXO_SETTLE_T, 31, 22)
|
||||
|
||||
/* RC_CENTRAL_CFG2 */
|
||||
DEFINE_BITFIELD(SRCVOLTEN_CTRL, 3, 0)
|
||||
DEFINE_BITFIELD(VREQ_CTRL, 7, 4)
|
||||
DEFINE_BIT(SRCVOLTEN_VREQ_SEL, 8)
|
||||
DEFINE_BIT(SRCVOLTEN_VREQ_M, 9)
|
||||
DEFINE_BITFIELD(ULPOSC_CTRL_M, 15, 12)
|
||||
DEFINE_BITFIELD(PWRAP_SLP_CTRL_M, 24, 21)
|
||||
DEFINE_BIT(PWRAP_SLP_MUX_SEL, 25)
|
||||
|
||||
/* RC_DCXO_FPM_CFG */
|
||||
DEFINE_BITFIELD(DCXO_FPM_CTRL_M, 3, 0)
|
||||
DEFINE_BIT(SRCVOLTEN_FPM_MSK_B, 4)
|
||||
DEFINE_BITFIELD(SUB_SRCLKEN_FPM_MSK_B, 28, 16)
|
||||
|
||||
/* RC_CENTRAL_CFG3 */
|
||||
DEFINE_BIT(TO_LPM_SETTLE_EN, 0)
|
||||
DEFINE_BIT(BLK_SCP_DXCO_MD_TARGET, 1)
|
||||
DEFINE_BIT(BLK_COANT_DXCO_MD_TARGET, 2)
|
||||
DEFINE_BIT(TO_BBLPM_SETTLE_EN, 3)
|
||||
DEFINE_BITFIELD(TO_LPM_SETTLE_T, 21, 12)
|
||||
|
||||
/* RC_CENTRAL_CFG4 */
|
||||
DEFINE_BITFIELD(KEEP_RC_SPI_ACTIVE, 8, 0)
|
||||
DEFINE_BIT(PWRAP_VLD_FORCE, 16)
|
||||
DEFINE_BIT(SLEEP_VLD_MODE, 17)
|
||||
|
||||
/* RC_MXX_SRCLKEN_CFG */
|
||||
DEFINE_BIT(DCXO_SETTLE_BLK_EN, 1)
|
||||
DEFINE_BIT(BYPASS_CMD_EN, 2)
|
||||
DEFINE_BIT(SW_SRCLKEN_RC, 3)
|
||||
DEFINE_BIT(SW_SRCLKEN_FPM, 4)
|
||||
DEFINE_BIT(SW_SRCLKEN_BBLPM, 5)
|
||||
DEFINE_BIT(XO_SOC_LINK_EN, 6)
|
||||
DEFINE_BIT(REQ_ACK_LOW_IMD_EN, 7)
|
||||
DEFINE_BIT(SRCLKEN_TRACK_M_EN, 8)
|
||||
DEFINE_BITFIELD(CNT_PRD_STEP, 11, 10)
|
||||
DEFINE_BITFIELD(XO_STABLE_PRD, 21, 12)
|
||||
DEFINE_BITFIELD(DCXO_STABLE_PRD, 31, 22)
|
||||
|
||||
enum {
|
||||
SW_SRCLKEN_FPM_MSK = 0x1,
|
||||
SW_SRCLKEN_BBLPM_MSK = 0x1,
|
||||
};
|
||||
|
||||
/* RC_DEBUG_CFG */
|
||||
DEFINE_BIT(TRACE_MODE_EN, 24)
|
||||
|
||||
/* SUBSYS_INTF_CFG */
|
||||
DEFINE_BITFIELD(SRCLKEN_FPM_MASK_B, 12, 0)
|
||||
DEFINE_BITFIELD(SRCLKEN_BBLPM_MASK_B, 28, 16)
|
||||
|
||||
enum {
|
||||
PMIC_PMRC_CON0 = 0x1A6,
|
||||
PMIC_PMRC_CON0_SET = 0x1A8,
|
||||
PMIC_PMRC_CON0_CLR = 0x1AA,
|
||||
};
|
||||
|
||||
enum chn_id {
|
||||
CHN_SUSPEND = 0,
|
||||
CHN_RF = 1,
|
||||
CHN_DEEPIDLE = 2,
|
||||
CHN_MD = 3,
|
||||
CHN_GPS = 4,
|
||||
CHN_BT = 5,
|
||||
CHN_WIFI = 6,
|
||||
CHN_MCU = 7,
|
||||
CHN_COANT = 8,
|
||||
CHN_NFC = 9,
|
||||
CHN_UFS = 10,
|
||||
CHN_SCP = 11,
|
||||
CHN_RESERVE = 12,
|
||||
MAX_CHN_NUM,
|
||||
};
|
||||
|
||||
enum {
|
||||
SRCLKENAO_MODE,
|
||||
VREQ_MODE,
|
||||
};
|
||||
|
||||
enum {
|
||||
MERGE_OR_MODE = 0x0,
|
||||
BYPASS_MODE = 0x1,
|
||||
MERGE_AND_MODE = 0x1 << 1,
|
||||
BYPASS_RC_MODE = 0x2 << 1,
|
||||
BYPASS_OTHER_MODE = 0x3 << 1,
|
||||
ASYNC_MODE = 0x1 << 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
RC_32K = 0,
|
||||
RC_ULPOSC1,
|
||||
};
|
||||
|
||||
enum rc_ctrl_m {
|
||||
HW_MODE = 0,
|
||||
SW_MODE = 1,
|
||||
INIT_MODE = 0xff,
|
||||
};
|
||||
|
||||
enum rc_support {
|
||||
SRCLKEN_RC_ENABLE = 0,
|
||||
SRCLKEN_RC_DISABLE,
|
||||
};
|
||||
|
||||
struct subsys_rc_con {
|
||||
unsigned int dcxo_prd;
|
||||
unsigned int xo_prd;
|
||||
unsigned int cnt_step;
|
||||
unsigned int track_en;
|
||||
unsigned int req_ack_imd_en;
|
||||
unsigned int xo_soc_link_en;
|
||||
unsigned int sw_bblpm;
|
||||
unsigned int sw_fpm;
|
||||
unsigned int sw_rc;
|
||||
unsigned int bypass_cmd;
|
||||
unsigned int dcxo_settle_blk_en;
|
||||
};
|
||||
|
||||
extern int srclken_rc_init(void);
|
||||
|
||||
#endif /* SOC_MEDIATEK_MT8192_SRCLKEN_RC_H */
|
|
@ -177,6 +177,120 @@ struct pmif *get_pmif_controller(int inf, int mstid)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void pmif_select(enum pmic_interface mode)
|
||||
{
|
||||
unsigned int spi_spm_sleep_req, spi_scp_sleep_req,
|
||||
spmi_spm_sleep_req, spmi_scp_sleep_req,
|
||||
spi_md_ctl_pmif_rdy, spi_md_ctl_srclk_en, spi_md_ctl_srvol_en,
|
||||
spmi_md_ctl_pmif_rdy, spmi_md_ctl_srclk_en, spmi_md_ctl_srvol_en,
|
||||
spi_inf_srclken_rc_en, spi_other_inf_dcxo0_en, spi_other_inf_dcxo1_en,
|
||||
spi_arb_srclken_rc_en, spi_arb_dcxo_conn_en, spi_arb_dcxo_nfc_en;
|
||||
|
||||
switch (mode) {
|
||||
case PMIF_VLD_RDY:
|
||||
/* spm and scp sleep request disable spi and spmi */
|
||||
spi_spm_sleep_req = 1;
|
||||
spi_scp_sleep_req = 1;
|
||||
spmi_spm_sleep_req = 1;
|
||||
spmi_scp_sleep_req = 1;
|
||||
|
||||
/*
|
||||
* pmic vld/rdy control spi mode enable
|
||||
* srclken control spi mode disable
|
||||
* vreq control spi mode disable
|
||||
*/
|
||||
spi_md_ctl_pmif_rdy = 1;
|
||||
spi_md_ctl_srclk_en = 0;
|
||||
spi_md_ctl_srvol_en = 0;
|
||||
spmi_md_ctl_pmif_rdy = 1;
|
||||
spmi_md_ctl_srclk_en = 0;
|
||||
spmi_md_ctl_srvol_en = 0;
|
||||
|
||||
/* srclken rc interface enable */
|
||||
spi_inf_srclken_rc_en = 1;
|
||||
|
||||
/* dcxo interface disable */
|
||||
spi_other_inf_dcxo0_en = 0;
|
||||
spi_other_inf_dcxo1_en = 0;
|
||||
|
||||
/* srclken enable, dcxo0,1 disable */
|
||||
spi_arb_srclken_rc_en = 1;
|
||||
spi_arb_dcxo_conn_en = 0;
|
||||
spi_arb_dcxo_nfc_en = 0;
|
||||
break;
|
||||
|
||||
case PMIF_SLP_REQ:
|
||||
/* spm and scp sleep request enable spi and spmi */
|
||||
spi_spm_sleep_req = 0;
|
||||
spi_scp_sleep_req = 0;
|
||||
spmi_spm_sleep_req = 0;
|
||||
spmi_scp_sleep_req = 0;
|
||||
|
||||
/*
|
||||
* pmic vld/rdy control spi mode disable
|
||||
* srclken control spi mode enable
|
||||
* vreq control spi mode enable
|
||||
*/
|
||||
spi_md_ctl_pmif_rdy = 0;
|
||||
spi_md_ctl_srclk_en = 1;
|
||||
spi_md_ctl_srvol_en = 1;
|
||||
spmi_md_ctl_pmif_rdy = 0;
|
||||
spmi_md_ctl_srclk_en = 1;
|
||||
spmi_md_ctl_srvol_en = 1;
|
||||
|
||||
/* srclken rc interface disable */
|
||||
spi_inf_srclken_rc_en = 0;
|
||||
|
||||
/* dcxo interface enable */
|
||||
spi_other_inf_dcxo0_en = 1;
|
||||
spi_other_inf_dcxo1_en = 1;
|
||||
|
||||
/* srclken disable, dcxo0,1 enable */
|
||||
spi_arb_srclken_rc_en = 0;
|
||||
spi_arb_dcxo_conn_en = 1;
|
||||
spi_arb_dcxo_nfc_en = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
die("Can't support pmif mode %d\n", mode);
|
||||
}
|
||||
|
||||
SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->sleep_protection_ctrl,
|
||||
PMIFSPI_SPM_SLEEP_REQ_SEL, spi_spm_sleep_req,
|
||||
PMIFSPI_SCP_SLEEP_REQ_SEL, spi_scp_sleep_req);
|
||||
SET32_BITFIELDS(&pmif_spmi_arb[0].mtk_pmif->sleep_protection_ctrl,
|
||||
PMIFSPMI_SPM_SLEEP_REQ_SEL, spmi_spm_sleep_req,
|
||||
PMIFSPMI_SCP_SLEEP_REQ_SEL, spmi_scp_sleep_req);
|
||||
SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->spi_mode_ctrl,
|
||||
PMIFSPI_MD_CTL_PMIF_RDY, spi_md_ctl_pmif_rdy,
|
||||
PMIFSPI_MD_CTL_SRCLK_EN, spi_md_ctl_srclk_en,
|
||||
PMIFSPI_MD_CTL_SRVOL_EN, spi_md_ctl_srvol_en);
|
||||
SET32_BITFIELDS(&pmif_spmi_arb[0].mtk_pmif->spi_mode_ctrl,
|
||||
PMIFSPMI_MD_CTL_PMIF_RDY, spmi_md_ctl_pmif_rdy,
|
||||
PMIFSPMI_MD_CTL_SRCLK_EN, spmi_md_ctl_srclk_en,
|
||||
PMIFSPMI_MD_CTL_SRVOL_EN, spmi_md_ctl_srvol_en);
|
||||
SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->inf_en,
|
||||
PMIFSPI_INF_EN_SRCLKEN_RC_HW, spi_inf_srclken_rc_en);
|
||||
SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->other_inf_en,
|
||||
PMIFSPI_OTHER_INF_DXCO0_EN, spi_other_inf_dcxo0_en,
|
||||
PMIFSPI_OTHER_INF_DXCO1_EN, spi_other_inf_dcxo1_en);
|
||||
SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->arb_en,
|
||||
PMIFSPI_ARB_EN_SRCLKEN_RC_HW, spi_arb_srclken_rc_en,
|
||||
PMIFSPI_ARB_EN_DCXO_CONN, spi_arb_dcxo_conn_en,
|
||||
PMIFSPI_ARB_EN_DCXO_NFC, spi_arb_dcxo_nfc_en);
|
||||
}
|
||||
|
||||
void pmwrap_interface_init(void)
|
||||
{
|
||||
if (CONFIG(SRCLKEN_RC_SUPPORT)) {
|
||||
printk(BIOS_INFO, "%s: Select PMIF_VLD_RDY\n", __func__);
|
||||
pmif_select(PMIF_VLD_RDY);
|
||||
} else {
|
||||
printk(BIOS_INFO, "%s: Select PMIF_SLP_REQ\n", __func__);
|
||||
pmif_select(PMIF_SLP_REQ);
|
||||
}
|
||||
}
|
||||
|
||||
int mtk_pmif_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <delay.h>
|
||||
#include <halt.h>
|
||||
#include <soc/clkbuf.h>
|
||||
#include <soc/mt6359p.h>
|
||||
#include <soc/pmif.h>
|
||||
#include <soc/rtc.h>
|
||||
|
@ -312,43 +313,11 @@ void poweroff(void)
|
|||
halt();
|
||||
}
|
||||
|
||||
static void dcxo_init(void)
|
||||
{
|
||||
u16 tmp;
|
||||
|
||||
rtc_read(PMIC_RG_DCXO_CW00, &tmp);
|
||||
rtc_info("CW00,%#x:%#x\n", PMIC_RG_DCXO_CW00, tmp);
|
||||
rtc_read(PMIC_RG_DCXO_CW09, &tmp);
|
||||
rtc_info("CW09,%#x:%#x\n", PMIC_RG_DCXO_CW09, tmp);
|
||||
rtc_read(PMIC_RG_DCXO_CW08, &tmp);
|
||||
rtc_info("CW08,%#x:%#x\n", PMIC_RG_DCXO_CW08, tmp);
|
||||
/* 26M enable control */
|
||||
/* enable clock buffer XO_SOC */
|
||||
rtc_write_field(PMIC_RG_DCXO_CW00, 0x4005, 0xFFFF, 0);
|
||||
rtc_read(PMIC_RG_DCXO_CW00, &tmp);
|
||||
rtc_info("CW0,%#x:%#x\n", PMIC_RG_DCXO_CW00, tmp);
|
||||
rtc_write_field(PMIC_RG_DCXO_CW09_CLR, 0x3f, 0x3f, 9);
|
||||
rtc_read(PMIC_RG_DCXO_CW09, &tmp);
|
||||
rtc_info("PMIC_RG_DCXO_CW09,%#x:%#x\n", PMIC_RG_DCXO_CW09, tmp);
|
||||
/* mode and buffer controlled by srclken0 */
|
||||
rtc_write_field(PMIC_RG_DCXO_CW08, 0x1, 0x1, 2);
|
||||
rtc_read(PMIC_RG_DCXO_CW08, &tmp);
|
||||
rtc_info("PMIC_RG_DCXO_CW08,%#x:%#x\n", PMIC_RG_DCXO_CW08, tmp);
|
||||
}
|
||||
|
||||
void mt6359_dcxo_disable_unused(void)
|
||||
{
|
||||
/* disable HW BBLPM arbiter */
|
||||
rtc_write_field(PMIC_RG_DCXO_CW12, 0x2, 0x3, 0);
|
||||
}
|
||||
|
||||
/* the rtc boot flow entry */
|
||||
void rtc_boot(void)
|
||||
{
|
||||
u16 tmp;
|
||||
|
||||
/* dcxo clock init settings */
|
||||
dcxo_init();
|
||||
/* dcxo 32k init settings */
|
||||
rtc_write_field(PMIC_RG_DCXO_CW02, 0xF, 0xF, 0);
|
||||
rtc_read(PMIC_RG_SCK_TOP_CON0, &tmp);
|
||||
|
|
|
@ -0,0 +1,388 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/pmif.h>
|
||||
#include <soc/srclken_rc.h>
|
||||
|
||||
#define RCTAG "[SRCLKEN_RC]"
|
||||
#define rc_info(fmt, arg ...) printk(BIOS_INFO, RCTAG "%s,%d: " fmt, \
|
||||
__func__, __LINE__, ## arg)
|
||||
|
||||
#define SRCLKEN_DBG 1
|
||||
|
||||
/* RC settle time setting */
|
||||
enum {
|
||||
FULL_SET_HW_MODE = 0, /* dcxo mode use pmrc_en */
|
||||
VCORE_SETTLE_TIME = 1, /* ~= 30us */
|
||||
ULPOSC_SETTLE_TIME = 4, /* ~= 150us */
|
||||
XO_SETTLE_TIME = 0x1, /* 2 ^ (step_sz + 5) * 0x33 * 30.77ns ~= 400us */
|
||||
DCXO_SETTLE_TIME = 0x1, /* 2 ^ (step_sz + 5) * 0x87 * 30.77ns ~= 1063us */
|
||||
CENTROL_CNT_STEP = 0x3, /* fix in 3, central align with Mxx channel */
|
||||
DCXO_STABLE_TIME = 0x70,
|
||||
XO_STABLE_TIME = 0x70,
|
||||
KEEP_RC_SPI_ACTIVE_VAL = 1,
|
||||
SRCLKEN_RC_EN_SEL_VAL = 0,
|
||||
};
|
||||
|
||||
enum {
|
||||
INIT_SUBSYS_FPM_TO_LPM = 1 << CHN_RF | 1 << CHN_DEEPIDLE | 1 << CHN_MD
|
||||
| 1 << CHN_GPS | 1 << CHN_BT | 1 << CHN_WIFI
|
||||
| 1 << CHN_MCU | 1 << CHN_COANT | 1 << CHN_NFC
|
||||
| 1 << CHN_UFS | 1 << CHN_SCP | 1 << CHN_RESERVE,
|
||||
INIT_SUBSYS_FPM_TO_BBLPM = 1 << CHN_DEEPIDLE,
|
||||
INIT_SUBSYS_TO_HW = 1 << CHN_SUSPEND | 1 << CHN_DEEPIDLE | 1 << CHN_MCU,
|
||||
};
|
||||
|
||||
/* RC central setting */
|
||||
enum {
|
||||
RC_CENTRAL_ENABLE = 1,
|
||||
RC_CENTRAL_DISABLE = 0,
|
||||
SPI_TRIG_MODE = SRCLKENAO_MODE, /* use srlckenao to set vcore */
|
||||
IS_SPI_DONE_RELEASE = 0, /* release vcore when spi request done */
|
||||
IS_SPI2PMIC_SET_CLR = 0, /* register direct write */
|
||||
SRCLKENO_0_CTRL_M = MERGE_OR_MODE, /* merge with spm */
|
||||
VREQ_CTRL_M = BYPASS_MODE, /* merge with vreq */
|
||||
ULPOSC_CTRL_M_VAL = BYPASS_MODE, /* merge with ulposc */
|
||||
PWRAP_CTRL_M = MERGE_OR_MODE, /* merge with pwrap_scp */
|
||||
SPI_CLK_SRC = RC_32K, /* pmic spec under 200us */
|
||||
};
|
||||
|
||||
/* Other setting */
|
||||
enum {
|
||||
DCXO_FPM_CTRL_MODE = MERGE_OR_MODE | ASYNC_MODE, /* merge with spm */
|
||||
PWRAP_TMOUT_VAL = 0xA, /* 31us * 0xa ~= 310us */
|
||||
FPM_MSK_B = FULL_SET_HW_MODE,
|
||||
MD0_SRCLKENO_0_MASK_B = 0, /* md0 control by pmrc */
|
||||
};
|
||||
|
||||
enum {
|
||||
SUB_BBLPM_SET = 1 << CHN_COANT | 1 << CHN_DEEPIDLE,
|
||||
SUB_FPM_SET = 1 << CHN_SUSPEND | 1 << CHN_RF | 1 << CHN_MD
|
||||
| 1 << CHN_GPS | 1 << CHN_BT | 1 << CHN_WIFI
|
||||
| 1 << CHN_MCU | 1 << CHN_NFC | 1 << CHN_UFS
|
||||
| 1 << CHN_SCP | 1 << CHN_RESERVE,
|
||||
};
|
||||
|
||||
enum {
|
||||
SW_FPM_LOW = 0,
|
||||
SW_FPM_HIGH = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
SW_BBLPM_LOW = 0,
|
||||
SW_BBLPM_HIGH = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
DXCO_SETTLE_BLK_DIS = 0,
|
||||
DXCO_SETTLE_BLK_EN = 1,
|
||||
};
|
||||
|
||||
#define SUB_CTRL_CON(_dcxo_prd, _xo_prd, _bypass_cmd, _dcxo_settle_blk_en) { \
|
||||
.dcxo_prd = _dcxo_prd, \
|
||||
.xo_prd = _xo_prd, \
|
||||
.cnt_step = CENTROL_CNT_STEP, \
|
||||
.track_en = 0x0, \
|
||||
.req_ack_imd_en = 0x1, \
|
||||
.xo_soc_link_en = 0x0, \
|
||||
.sw_bblpm = SW_BBLPM_LOW, \
|
||||
.sw_fpm = SW_FPM_HIGH, \
|
||||
.sw_rc = SW_MODE, \
|
||||
.bypass_cmd = _bypass_cmd, \
|
||||
.dcxo_settle_blk_en = _dcxo_settle_blk_en, \
|
||||
}
|
||||
|
||||
static struct mtk_rc_regs *rc_regs = (struct mtk_rc_regs *)RC_BASE;
|
||||
static struct mtk_rc_status_regs *rc_sta_regs = (struct mtk_rc_status_regs *)RC_STATUS_BASE;
|
||||
|
||||
static struct subsys_rc_con rc_ctrl[MAX_CHN_NUM] = {
|
||||
[CHN_SUSPEND] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN),
|
||||
[CHN_RF] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN),
|
||||
[CHN_DEEPIDLE] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME,
|
||||
0x0, DXCO_SETTLE_BLK_EN),
|
||||
[CHN_MD] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN),
|
||||
[CHN_GPS] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN),
|
||||
[CHN_BT] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN),
|
||||
[CHN_WIFI] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN),
|
||||
[CHN_MCU] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN),
|
||||
[CHN_COANT] = SUB_CTRL_CON(0x0, 0x0, 0x1, DXCO_SETTLE_BLK_DIS),
|
||||
[CHN_NFC] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN),
|
||||
[CHN_UFS] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN),
|
||||
[CHN_SCP] = SUB_CTRL_CON(0x0, 0x0, 0x1, DXCO_SETTLE_BLK_DIS),
|
||||
[CHN_RESERVE] = SUB_CTRL_CON(0x0, 0x0, 0x1, DXCO_SETTLE_BLK_DIS),
|
||||
};
|
||||
|
||||
static void pmic_read(u32 addr, u32 *rdata)
|
||||
{
|
||||
static struct pmif *pmif_arb;
|
||||
|
||||
if (pmif_arb == NULL)
|
||||
pmif_arb = get_pmif_controller(PMIF_SPI, 0);
|
||||
|
||||
pmif_arb->read(pmif_arb, 0, addr, rdata);
|
||||
}
|
||||
|
||||
static void rc_dump_reg_info(void)
|
||||
{
|
||||
unsigned int chn_n;
|
||||
|
||||
if (SRCLKEN_DBG) {
|
||||
rc_info("SRCLKEN_RC_CFG:%#x\n", read32(&rc_regs->srclken_rc_cfg));
|
||||
rc_info("RC_CENTRAL_CFG1:%#x\n", read32(&rc_regs->rc_central_cfg1));
|
||||
rc_info("RC_CENTRAL_CFG2:%#x\n", read32(&rc_regs->rc_central_cfg2));
|
||||
rc_info("RC_CENTRAL_CFG3:%#x\n", read32(&rc_regs->rc_central_cfg3));
|
||||
rc_info("RC_CENTRAL_CFG4:%#x\n", read32(&rc_regs->rc_central_cfg4));
|
||||
rc_info("RC_DCXO_FPM_CFG:%#x\n", read32(&rc_regs->rc_dcxo_fpm_cfg));
|
||||
rc_info("SUBSYS_INTF_CFG:%#x\n", read32(&rc_regs->rc_subsys_intf_cfg));
|
||||
rc_info("RC_SPI_STA_0:%#x\n", read32(&rc_sta_regs->rc_spi_sta_0));
|
||||
rc_info("RC_PI_PO_STA:%#x\n", read32(&rc_sta_regs->rc_pi_po_sta_0));
|
||||
|
||||
for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) {
|
||||
rc_info("M%02d: %#x\n", chn_n,
|
||||
read32(&rc_regs->rc_mxx_srclken_cfg[chn_n]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* RC initial flow and relative setting */
|
||||
static void __rc_ctrl_mode_switch(enum chn_id id, enum rc_ctrl_m mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case INIT_MODE:
|
||||
SET32_BITFIELDS(&rc_regs->rc_mxx_srclken_cfg[id],
|
||||
DCXO_SETTLE_BLK_EN, rc_ctrl[id].dcxo_settle_blk_en,
|
||||
BYPASS_CMD_EN, rc_ctrl[id].bypass_cmd,
|
||||
SW_SRCLKEN_RC, rc_ctrl[id].sw_rc,
|
||||
SW_SRCLKEN_FPM, rc_ctrl[id].sw_fpm,
|
||||
SW_SRCLKEN_BBLPM, rc_ctrl[id].sw_bblpm,
|
||||
XO_SOC_LINK_EN, rc_ctrl[id].xo_soc_link_en,
|
||||
REQ_ACK_LOW_IMD_EN, rc_ctrl[id].req_ack_imd_en,
|
||||
SRCLKEN_TRACK_M_EN, rc_ctrl[id].track_en,
|
||||
CNT_PRD_STEP, rc_ctrl[id].cnt_step,
|
||||
XO_STABLE_PRD, rc_ctrl[id].xo_prd,
|
||||
DCXO_STABLE_PRD, rc_ctrl[id].dcxo_prd);
|
||||
break;
|
||||
case SW_MODE:
|
||||
SET32_BITFIELDS(&rc_regs->rc_mxx_srclken_cfg[id], SW_SRCLKEN_RC, 1);
|
||||
break;
|
||||
case HW_MODE:
|
||||
SET32_BITFIELDS(&rc_regs->rc_mxx_srclken_cfg[id], SW_SRCLKEN_RC, 0);
|
||||
break;
|
||||
default:
|
||||
die("Can't support rc_mode %d\n", mode);
|
||||
}
|
||||
|
||||
rc_info("M%02d: %#x\n", id, read32(&rc_regs->rc_mxx_srclken_cfg[id]));
|
||||
}
|
||||
|
||||
|
||||
/* RC subsys FPM control */
|
||||
static void __rc_ctrl_fpm_switch(enum chn_id id, unsigned int mode)
|
||||
{
|
||||
SET32_BITFIELDS(&rc_regs->rc_mxx_srclken_cfg[id], SW_SRCLKEN_FPM, !!mode);
|
||||
rc_ctrl[id].sw_fpm = mode;
|
||||
rc_info("M%02d FPM SWITCH: %#x\n", id, read32(&rc_regs->rc_mxx_srclken_cfg[id]));
|
||||
}
|
||||
|
||||
static void __rc_ctrl_bblpm_switch(enum chn_id id, unsigned int mode)
|
||||
{
|
||||
SET32_BITFIELDS(&rc_regs->rc_mxx_srclken_cfg[id], SW_SRCLKEN_BBLPM, !!mode);
|
||||
rc_ctrl[id].sw_bblpm = mode;
|
||||
rc_info("M%02d BBLPM SWITCH: %#x\n", id, read32(&rc_regs->rc_mxx_srclken_cfg[id]));
|
||||
}
|
||||
|
||||
static void rc_init_subsys_hw_mode(void)
|
||||
{
|
||||
unsigned int chn_n;
|
||||
|
||||
for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) {
|
||||
if (INIT_SUBSYS_TO_HW & (1 << chn_n))
|
||||
__rc_ctrl_mode_switch(chn_n, HW_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
static void rc_init_subsys_lpm(void)
|
||||
{
|
||||
unsigned int chn_n;
|
||||
|
||||
for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) {
|
||||
if (INIT_SUBSYS_FPM_TO_LPM & (1 << chn_n))
|
||||
__rc_ctrl_fpm_switch(chn_n, SW_FPM_LOW);
|
||||
}
|
||||
for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) {
|
||||
if (INIT_SUBSYS_FPM_TO_BBLPM & (1 << chn_n))
|
||||
__rc_ctrl_bblpm_switch(chn_n, SW_BBLPM_HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
static void rc_ctrl_mode_switch_init(enum chn_id id)
|
||||
{
|
||||
__rc_ctrl_mode_switch(id, INIT_MODE);
|
||||
}
|
||||
|
||||
static enum rc_support srclken_rc_chk_init_cfg(void)
|
||||
{
|
||||
pmwrap_interface_init();
|
||||
if (!CONFIG(SRCLKEN_RC_SUPPORT)) {
|
||||
rc_info("Bring-UP : skip srclken_rc init\n");
|
||||
return SRCLKEN_RC_DISABLE;
|
||||
}
|
||||
if (SRCLKEN_DBG) {
|
||||
/* Enable debug trace */
|
||||
write32(&rc_sta_regs->rc_debug_trace, 1);
|
||||
SET32_BITFIELDS(&rc_regs->rc_debug_cfg, TRACE_MODE_EN, 1);
|
||||
}
|
||||
return SRCLKEN_RC_ENABLE;
|
||||
}
|
||||
|
||||
int srclken_rc_init(void)
|
||||
{
|
||||
/* New co-clock architecture srclkenrc implement here */
|
||||
unsigned int chn_n;
|
||||
int ret = 0;
|
||||
|
||||
/* Check platform config to proceed init flow */
|
||||
if (srclken_rc_chk_init_cfg() != SRCLKEN_RC_ENABLE)
|
||||
return ret;
|
||||
|
||||
/* Set SW RESET 1 */
|
||||
SET32_BITFIELDS(&rc_regs->srclken_rc_cfg, SW_RESET, 1);
|
||||
|
||||
/* Wait 100us */
|
||||
udelay(100);
|
||||
|
||||
/* Set SW CG 1 */
|
||||
write32(&rc_regs->srclken_rc_cfg,
|
||||
_BF_VALUE(SW_RESET, 1) | _BF_VALUE(CG_32K_EN, 1) |
|
||||
_BF_VALUE(CG_FCLK_EN, 1) | _BF_VALUE(CG_FCLK_FR_EN, 1));
|
||||
|
||||
/* Wait 100us */
|
||||
udelay(100);
|
||||
|
||||
/* Set Clock Mux */
|
||||
write32(&rc_regs->srclken_rc_cfg,
|
||||
_BF_VALUE(SW_RESET, 1) | _BF_VALUE(CG_32K_EN, 1) |
|
||||
_BF_VALUE(CG_FCLK_EN, 1) | _BF_VALUE(CG_FCLK_FR_EN, 1) |
|
||||
_BF_VALUE(MUX_FCLK_FR, 1));
|
||||
|
||||
/* Set req_filter m00~m12 as default SW_FPM */
|
||||
for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++)
|
||||
rc_ctrl_mode_switch_init(chn_n);
|
||||
|
||||
/* Set PMIC addr for SPI CMD */
|
||||
write32(&rc_regs->rc_pmic_rcen_addr, PMIC_PMRC_CON0);
|
||||
|
||||
write32(&rc_regs->rc_pmic_rcen_set_clr_addr,
|
||||
(PMIC_PMRC_CON0_CLR << 16) | PMIC_PMRC_CON0_SET);
|
||||
|
||||
write32(&rc_regs->rc_cmd_arb_cfg, 0);
|
||||
|
||||
/* CFG1 setting for spi cmd config */
|
||||
write32(&rc_regs->rc_central_cfg1,
|
||||
_BF_VALUE(DCXO_SETTLE_T, DCXO_SETTLE_TIME) |
|
||||
_BF_VALUE(NON_DCXO_SETTLE_T, XO_SETTLE_TIME) |
|
||||
_BF_VALUE(ULPOSC_SETTLE_T, ULPOSC_SETTLE_TIME) |
|
||||
_BF_VALUE(VCORE_SETTLE_T, VCORE_SETTLE_TIME) |
|
||||
_BF_VALUE(SRCLKEN_RC_EN_SEL, SRCLKEN_RC_EN_SEL_VAL) |
|
||||
_BF_VALUE(RC_SPI_ACTIVE, KEEP_RC_SPI_ACTIVE_VAL) |
|
||||
_BF_VALUE(RCEN_ISSUE_M, IS_SPI2PMIC_SET_CLR) |
|
||||
_BF_VALUE(SRCLKEN_RC_EN, RC_CENTRAL_DISABLE));
|
||||
|
||||
/* CFG2 setting for signal mode of each control mux */
|
||||
write32(&rc_regs->rc_central_cfg2,
|
||||
_BF_VALUE(PWRAP_SLP_MUX_SEL, SPI_CLK_SRC) |
|
||||
_BF_VALUE(PWRAP_SLP_CTRL_M, PWRAP_CTRL_M) |
|
||||
_BF_VALUE(ULPOSC_CTRL_M, ULPOSC_CTRL_M_VAL) |
|
||||
_BF_VALUE(SRCVOLTEN_VREQ_M, IS_SPI_DONE_RELEASE) |
|
||||
_BF_VALUE(SRCVOLTEN_VREQ_SEL, SPI_TRIG_MODE) |
|
||||
_BF_VALUE(VREQ_CTRL, VREQ_CTRL_M) |
|
||||
_BF_VALUE(SRCVOLTEN_CTRL, SRCLKENO_0_CTRL_M));
|
||||
|
||||
write32(&rc_regs->rc_central_cfg3,
|
||||
_BF_VALUE(TO_LPM_SETTLE_T, 0x4) |
|
||||
_BF_VALUE(TO_BBLPM_SETTLE_EN, 1) |
|
||||
_BF_VALUE(BLK_COANT_DXCO_MD_TARGET, 1) |
|
||||
_BF_VALUE(BLK_SCP_DXCO_MD_TARGET, 1) |
|
||||
_BF_VALUE(TO_LPM_SETTLE_EN, 1));
|
||||
|
||||
/* Set srclkeno_0/conn_bt as factor to allow dcxo change to FPM */
|
||||
write32(&rc_regs->rc_dcxo_fpm_cfg,
|
||||
_BF_VALUE(SUB_SRCLKEN_FPM_MSK_B, FPM_MSK_B) |
|
||||
_BF_VALUE(SRCVOLTEN_FPM_MSK_B, MD0_SRCLKENO_0_MASK_B) |
|
||||
_BF_VALUE(DCXO_FPM_CTRL_M, DCXO_FPM_CTRL_MODE));
|
||||
|
||||
/* Set bblpm/fpm channel */
|
||||
write32(&rc_regs->rc_subsys_intf_cfg,
|
||||
_BF_VALUE(SRCLKEN_BBLPM_MASK_B, SUB_BBLPM_SET) |
|
||||
_BF_VALUE(SRCLKEN_FPM_MASK_B, SUB_FPM_SET));
|
||||
|
||||
/* Trigger srclken_rc enable */
|
||||
SET32_BITFIELDS(&rc_regs->rc_central_cfg1,
|
||||
SRCLKEN_RC_EN, RC_CENTRAL_ENABLE);
|
||||
|
||||
write32(&rc_regs->rc_central_cfg4,
|
||||
_BF_VALUE(SLEEP_VLD_MODE, 0x1) |
|
||||
_BF_VALUE(PWRAP_VLD_FORCE, 0x1) |
|
||||
_BF_VALUE(KEEP_RC_SPI_ACTIVE, 0x800));
|
||||
|
||||
|
||||
/* Wait 100us */
|
||||
udelay(100);
|
||||
|
||||
/* Set SW RESET 0 */
|
||||
write32(&rc_regs->srclken_rc_cfg,
|
||||
_BF_VALUE(CG_32K_EN, 1) | _BF_VALUE(CG_FCLK_EN, 1) |
|
||||
_BF_VALUE(CG_FCLK_FR_EN, 1) | _BF_VALUE(MUX_FCLK_FR, 1));
|
||||
|
||||
/* Wait 100us */
|
||||
udelay(100);
|
||||
|
||||
/* Set SW CG 0 */
|
||||
write32(&rc_regs->srclken_rc_cfg, _BF_VALUE(MUX_FCLK_FR, 1));
|
||||
|
||||
/* Wait 500us */
|
||||
udelay(500);
|
||||
|
||||
/* Set req_filter m00~m12 FPM to LPM */
|
||||
rc_init_subsys_lpm();
|
||||
|
||||
/* Polling ACK of Initial Subsys Input */
|
||||
for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) {
|
||||
unsigned int chk_sta, shift_chn_n = 0;
|
||||
int retry;
|
||||
u32 temp;
|
||||
|
||||
/* Fix RC_MXX_REQ_STA_0 register shift */
|
||||
if (chn_n > 0)
|
||||
shift_chn_n = 1;
|
||||
|
||||
chk_sta = (rc_ctrl[chn_n].sw_fpm & SW_SRCLKEN_FPM_MSK) << 1 |
|
||||
(rc_ctrl[chn_n].sw_bblpm & SW_SRCLKEN_BBLPM_MSK) << 3;
|
||||
retry = 200;
|
||||
while ((read32(&rc_sta_regs->rc_mxx_req_sta_0[chn_n + shift_chn_n]) & 0xa)
|
||||
!= chk_sta && retry-- > 0)
|
||||
udelay(10);
|
||||
if (retry < 0) {
|
||||
pmic_read(PMIC_PMRC_CON0, &temp);
|
||||
rc_info("polling M%02d failed.(R:%#x)(C:%#x)(PMRC:%#x)\n",
|
||||
chn_n,
|
||||
read32(&rc_sta_regs->rc_mxx_req_sta_0[chn_n + shift_chn_n]),
|
||||
read32(&rc_regs->rc_mxx_srclken_cfg[chn_n]), temp);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set req_filter m00~m12 */
|
||||
rc_init_subsys_hw_mode();
|
||||
|
||||
/* Release force pmic req signal */
|
||||
write32(&rc_regs->rc_central_cfg4,
|
||||
_BF_VALUE(SLEEP_VLD_MODE, 0x1) |
|
||||
_BF_VALUE(KEEP_RC_SPI_ACTIVE, 0x800));
|
||||
|
||||
rc_dump_reg_info();
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue