From c9d7e79f02ef8184ab854fef5decc2f100447cef Mon Sep 17 00:00:00 2001 From: Fabien Parent Date: Sat, 17 Oct 2020 12:52:15 +0200 Subject: clk: mediatek: Add MT8183 clock driver Add the topckgen, apmixedsys and infracfg clock driver for the MT8183 SoC. Signed-off-by: Fabien Parent --- include/dt-bindings/clock/mt8183-clk.h | 329 +++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 include/dt-bindings/clock/mt8183-clk.h (limited to 'include') diff --git a/include/dt-bindings/clock/mt8183-clk.h b/include/dt-bindings/clock/mt8183-clk.h new file mode 100644 index 00000000000..f7e6367ce84 --- /dev/null +++ b/include/dt-bindings/clock/mt8183-clk.h @@ -0,0 +1,329 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + * Author: Weiyi Lu + */ + +#ifndef _DT_BINDINGS_CLK_MT8183_H +#define _DT_BINDINGS_CLK_MT8183_H + +/* APMIXED */ +#define CLK_APMIXED_ARMPLL_LL 0 +#define CLK_APMIXED_ARMPLL_L 1 +#define CLK_APMIXED_CCIPLL 2 +#define CLK_APMIXED_MAINPLL 3 +#define CLK_APMIXED_UNIV2PLL 4 +#define CLK_APMIXED_MSDCPLL 5 +#define CLK_APMIXED_MMPLL 6 +#define CLK_APMIXED_MFGPLL 7 +#define CLK_APMIXED_TVDPLL 8 +#define CLK_APMIXED_APLL1 9 +#define CLK_APMIXED_APLL2 10 +#define CLK_APMIXED_SSUSB_26M 11 +#define CLK_APMIXED_APPLL_26M 12 +#define CLK_APMIXED_MIPIC0_26M 13 +#define CLK_APMIXED_MDPLLGP_26M 14 +#define CLK_APMIXED_MMSYS_26M 15 +#define CLK_APMIXED_UFS_26M 16 +#define CLK_APMIXED_MIPIC1_26M 17 +#define CLK_APMIXED_MEMPLL_26M 18 +#define CLK_APMIXED_CLKSQ_LVPLL_26M 19 +#define CLK_APMIXED_MIPID0_26M 20 +#define CLK_APMIXED_MIPID1_26M 21 +#define CLK_APMIXED_NR_CLK 22 + +/* TOPCKGEN */ +#define CLK_TOP_CLK26M 0 +#define CLK_TOP_ULPOSC 1 +#define CLK_TOP_UNIVP_192M 2 +#define CLK_TOP_CLK13M 3 +#define CLK_TOP_F26M_CK_D2 4 +#define CLK_TOP_SYSPLL_CK 5 +#define CLK_TOP_SYSPLL_D2 6 +#define CLK_TOP_SYSPLL_D3 7 +#define CLK_TOP_SYSPLL_D5 8 +#define CLK_TOP_SYSPLL_D7 9 +#define CLK_TOP_SYSPLL_D2_D2 10 +#define CLK_TOP_SYSPLL_D2_D4 11 +#define CLK_TOP_SYSPLL_D2_D8 12 +#define CLK_TOP_SYSPLL_D2_D16 13 +#define CLK_TOP_SYSPLL_D3_D2 14 +#define CLK_TOP_SYSPLL_D3_D4 15 +#define CLK_TOP_SYSPLL_D3_D8 16 +#define CLK_TOP_SYSPLL_D5_D2 17 +#define CLK_TOP_SYSPLL_D5_D4 18 +#define CLK_TOP_SYSPLL_D7_D2 19 +#define CLK_TOP_SYSPLL_D7_D4 20 +#define CLK_TOP_UNIVPLL_CK 21 +#define CLK_TOP_UNIVPLL_D2 22 +#define CLK_TOP_UNIVPLL_D3 23 +#define CLK_TOP_UNIVPLL_D5 24 +#define CLK_TOP_UNIVPLL_D7 25 +#define CLK_TOP_UNIVPLL_D2_D2 26 +#define CLK_TOP_UNIVPLL_D2_D4 27 +#define CLK_TOP_UNIVPLL_D2_D8 28 +#define CLK_TOP_UNIVPLL_D3_D2 29 +#define CLK_TOP_UNIVPLL_D3_D4 30 +#define CLK_TOP_UNIVPLL_D3_D8 31 +#define CLK_TOP_UNIVPLL_D5_D2 32 +#define CLK_TOP_UNIVPLL_D5_D4 33 +#define CLK_TOP_UNIVPLL_D5_D8 34 +#define CLK_TOP_UNIVP_192M_CK 35 +#define CLK_TOP_UNIVP_192M_D2 36 +#define CLK_TOP_UNIVP_192M_D4 37 +#define CLK_TOP_UNIVP_192M_D8 38 +#define CLK_TOP_UNIVP_192M_D16 39 +#define CLK_TOP_UNIVP_192M_D32 40 +#define CLK_TOP_APLL1_CK 41 +#define CLK_TOP_APLL1_D2 42 +#define CLK_TOP_APLL1_D4 43 +#define CLK_TOP_APLL1_D8 44 +#define CLK_TOP_APLL2_CK 45 +#define CLK_TOP_APLL2_D2 46 +#define CLK_TOP_APLL2_D4 47 +#define CLK_TOP_APLL2_D8 48 +#define CLK_TOP_TVDPLL_CK 49 +#define CLK_TOP_TVDPLL_D2 50 +#define CLK_TOP_TVDPLL_D4 51 +#define CLK_TOP_TVDPLL_D8 52 +#define CLK_TOP_TVDPLL_D16 53 +#define CLK_TOP_MMPLL_CK 54 +#define CLK_TOP_MMPLL_D4 55 +#define CLK_TOP_MMPLL_D4_D2 56 +#define CLK_TOP_MMPLL_D4_D4 57 +#define CLK_TOP_MMPLL_D5 58 +#define CLK_TOP_MMPLL_D5_D2 59 +#define CLK_TOP_MMPLL_D5_D4 60 +#define CLK_TOP_MMPLL_D6 61 +#define CLK_TOP_MMPLL_D7 62 +#define CLK_TOP_MFGPLL_CK 63 +#define CLK_TOP_MSDCPLL_CK 64 +#define CLK_TOP_MSDCPLL_D2 65 +#define CLK_TOP_MSDCPLL_D4 66 +#define CLK_TOP_MSDCPLL_D8 67 +#define CLK_TOP_MSDCPLL_D16 68 +#define CLK_TOP_AD_OSC_CK 69 +#define CLK_TOP_OSC_D2 70 +#define CLK_TOP_OSC_D4 71 +#define CLK_TOP_OSC_D8 72 +#define CLK_TOP_OSC_D16 73 +#define CLK_TOP_UNIVPLL 74 +#define CLK_TOP_UNIVPLL_D3_D16 75 +#define CLK_TOP_APLL12_DIV0 76 +#define CLK_TOP_APLL12_DIV1 77 +#define CLK_TOP_APLL12_DIV2 78 +#define CLK_TOP_APLL12_DIV3 79 +#define CLK_TOP_APLL12_DIV4 80 +#define CLK_TOP_APLL12_DIVB 81 +#define CLK_TOP_ARMPLL_DIV_PLL1 82 +#define CLK_TOP_ARMPLL_DIV_PLL2 83 +#define CLK_TOP_MUX_AXI 84 +#define CLK_TOP_MUX_MM 85 +#define CLK_TOP_MUX_IMG 86 +#define CLK_TOP_MUX_CAM 87 +#define CLK_TOP_MUX_DSP 88 +#define CLK_TOP_MUX_DSP1 89 +#define CLK_TOP_MUX_DSP2 90 +#define CLK_TOP_MUX_IPU_IF 91 +#define CLK_TOP_MUX_MFG 92 +#define CLK_TOP_MUX_F52M_MFG 93 +#define CLK_TOP_MUX_CAMTG 94 +#define CLK_TOP_MUX_CAMTG2 95 +#define CLK_TOP_MUX_CAMTG3 96 +#define CLK_TOP_MUX_CAMTG4 97 +#define CLK_TOP_MUX_UART 98 +#define CLK_TOP_MUX_SPI 99 +#define CLK_TOP_MUX_MSDC50_0_HCLK 100 +#define CLK_TOP_MUX_MSDC50_0 101 +#define CLK_TOP_MUX_MSDC30_1 102 +#define CLK_TOP_MUX_MSDC30_2 103 +#define CLK_TOP_MUX_AUDIO 104 +#define CLK_TOP_MUX_AUD_INTBUS 105 +#define CLK_TOP_MUX_PMICSPI 106 +#define CLK_TOP_MUX_FPWRAP_ULPOSC 107 +#define CLK_TOP_MUX_ATB 108 +#define CLK_TOP_MUX_SSPM 109 +#define CLK_TOP_MUX_DPI0 110 +#define CLK_TOP_MUX_SCAM 111 +#define CLK_TOP_MUX_DISP_PWM 112 +#define CLK_TOP_MUX_USB_TOP 113 +#define CLK_TOP_MUX_SSUSB_TOP_XHCI 114 +#define CLK_TOP_MUX_SPM 115 +#define CLK_TOP_MUX_I2C 116 +#define CLK_TOP_MUX_SCP 117 +#define CLK_TOP_MUX_SENINF 118 +#define CLK_TOP_MUX_DXCC 119 +#define CLK_TOP_MUX_AUD_ENG1 120 +#define CLK_TOP_MUX_AUD_ENG2 121 +#define CLK_TOP_MUX_FAES_UFSFDE 122 +#define CLK_TOP_MUX_FUFS 123 +#define CLK_TOP_MUX_AUD_1 124 +#define CLK_TOP_MUX_AUD_2 125 +#define CLK_TOP_MUX_APLL_I2S0 126 +#define CLK_TOP_MUX_APLL_I2S1 127 +#define CLK_TOP_MUX_APLL_I2S2 128 +#define CLK_TOP_MUX_APLL_I2S3 129 +#define CLK_TOP_MUX_APLL_I2S4 130 +#define CLK_TOP_MUX_APLL_I2S5 131 +#define CLK_TOP_NR_CLK 132 + +/* INFRACFG_AO */ +#define CLK_INFRA_PMIC_TMR 0 +#define CLK_INFRA_PMIC_AP 1 +#define CLK_INFRA_PMIC_MD 2 +#define CLK_INFRA_PMIC_CONN 3 +#define CLK_INFRA_SCPSYS 4 +#define CLK_INFRA_SEJ 5 +#define CLK_INFRA_APXGPT 6 +#define CLK_INFRA_ICUSB 7 +#define CLK_INFRA_GCE 8 +#define CLK_INFRA_THERM 9 +#define CLK_INFRA_I2C0 10 +#define CLK_INFRA_I2C1 11 +#define CLK_INFRA_I2C2 12 +#define CLK_INFRA_I2C3 13 +#define CLK_INFRA_PWM_HCLK 14 +#define CLK_INFRA_PWM1 15 +#define CLK_INFRA_PWM2 16 +#define CLK_INFRA_PWM3 17 +#define CLK_INFRA_PWM4 18 +#define CLK_INFRA_PWM 19 +#define CLK_INFRA_UART0 20 +#define CLK_INFRA_UART1 21 +#define CLK_INFRA_UART2 22 +#define CLK_INFRA_UART3 23 +#define CLK_INFRA_GCE_26M 24 +#define CLK_INFRA_CQ_DMA_FPC 25 +#define CLK_INFRA_BTIF 26 +#define CLK_INFRA_SPI0 27 +#define CLK_INFRA_MSDC0 28 +#define CLK_INFRA_MSDC1 29 +#define CLK_INFRA_MSDC2 30 +#define CLK_INFRA_MSDC0_SCK 31 +#define CLK_INFRA_DVFSRC 32 +#define CLK_INFRA_GCPU 33 +#define CLK_INFRA_TRNG 34 +#define CLK_INFRA_AUXADC 35 +#define CLK_INFRA_CPUM 36 +#define CLK_INFRA_CCIF1_AP 37 +#define CLK_INFRA_CCIF1_MD 38 +#define CLK_INFRA_AUXADC_MD 39 +#define CLK_INFRA_MSDC1_SCK 40 +#define CLK_INFRA_MSDC2_SCK 41 +#define CLK_INFRA_AP_DMA 42 +#define CLK_INFRA_XIU 43 +#define CLK_INFRA_DEVICE_APC 44 +#define CLK_INFRA_CCIF_AP 45 +#define CLK_INFRA_DEBUGSYS 46 +#define CLK_INFRA_AUDIO 47 +#define CLK_INFRA_CCIF_MD 48 +#define CLK_INFRA_DXCC_SEC_CORE 49 +#define CLK_INFRA_DXCC_AO 50 +#define CLK_INFRA_DRAMC_F26M 51 +#define CLK_INFRA_IRTX 52 +#define CLK_INFRA_DISP_PWM 53 +#define CLK_INFRA_CLDMA_BCLK 54 +#define CLK_INFRA_AUDIO_26M_BCLK 55 +#define CLK_INFRA_SPI1 56 +#define CLK_INFRA_I2C4 57 +#define CLK_INFRA_MODEM_TEMP_SHARE 58 +#define CLK_INFRA_SPI2 59 +#define CLK_INFRA_SPI3 60 +#define CLK_INFRA_UNIPRO_SCK 61 +#define CLK_INFRA_UNIPRO_TICK 62 +#define CLK_INFRA_UFS_MP_SAP_BCLK 63 +#define CLK_INFRA_MD32_BCLK 64 +#define CLK_INFRA_SSPM 65 +#define CLK_INFRA_UNIPRO_MBIST 66 +#define CLK_INFRA_SSPM_BUS_HCLK 67 +#define CLK_INFRA_I2C5 68 +#define CLK_INFRA_I2C5_ARBITER 69 +#define CLK_INFRA_I2C5_IMM 70 +#define CLK_INFRA_I2C1_ARBITER 71 +#define CLK_INFRA_I2C1_IMM 72 +#define CLK_INFRA_I2C2_ARBITER 73 +#define CLK_INFRA_I2C2_IMM 74 +#define CLK_INFRA_SPI4 75 +#define CLK_INFRA_SPI5 76 +#define CLK_INFRA_CQ_DMA 77 +#define CLK_INFRA_UFS 78 +#define CLK_INFRA_AES_UFSFDE 79 +#define CLK_INFRA_UFS_TICK 80 +#define CLK_INFRA_MSDC0_SELF 81 +#define CLK_INFRA_MSDC1_SELF 82 +#define CLK_INFRA_MSDC2_SELF 83 +#define CLK_INFRA_SSPM_26M_SELF 84 +#define CLK_INFRA_SSPM_32K_SELF 85 +#define CLK_INFRA_UFS_AXI 86 +#define CLK_INFRA_I2C6 87 +#define CLK_INFRA_AP_MSDC0 88 +#define CLK_INFRA_MD_MSDC0 89 +#define CLK_INFRA_USB 90 +#define CLK_INFRA_DEVMPU_BCLK 91 +#define CLK_INFRA_CCIF2_AP 92 +#define CLK_INFRA_CCIF2_MD 93 +#define CLK_INFRA_CCIF3_AP 94 +#define CLK_INFRA_CCIF3_MD 95 +#define CLK_INFRA_SEJ_F13M 96 +#define CLK_INFRA_AES_BCLK 97 +#define CLK_INFRA_I2C7 98 +#define CLK_INFRA_I2C8 99 +#define CLK_INFRA_FBIST2FPC 100 +#define CLK_INFRA_NR_CLK 101 + +/* MMSYS_CONFIG */ +#define CLK_MM_SMI_COMMON 0 +#define CLK_MM_SMI_LARB0 1 +#define CLK_MM_SMI_LARB1 2 +#define CLK_MM_GALS_COMM0 3 +#define CLK_MM_GALS_COMM1 4 +#define CLK_MM_GALS_CCU2MM 5 +#define CLK_MM_GALS_IPU12MM 6 +#define CLK_MM_GALS_IMG2MM 7 +#define CLK_MM_GALS_CAM2MM 8 +#define CLK_MM_GALS_IPU2MM 9 +#define CLK_MM_MDP_DL_TXCK 10 +#define CLK_MM_IPU_DL_TXCK 11 +#define CLK_MM_MDP_RDMA0 12 +#define CLK_MM_MDP_RDMA1 13 +#define CLK_MM_MDP_RSZ0 14 +#define CLK_MM_MDP_RSZ1 15 +#define CLK_MM_MDP_TDSHP 16 +#define CLK_MM_MDP_WROT0 17 +#define CLK_MM_FAKE_ENG 18 +#define CLK_MM_DISP_OVL0 19 +#define CLK_MM_DISP_OVL0_2L 20 +#define CLK_MM_DISP_OVL1_2L 21 +#define CLK_MM_DISP_RDMA0 22 +#define CLK_MM_DISP_RDMA1 23 +#define CLK_MM_DISP_WDMA0 24 +#define CLK_MM_DISP_COLOR0 25 +#define CLK_MM_DISP_CCORR0 26 +#define CLK_MM_DISP_AAL0 27 +#define CLK_MM_DISP_GAMMA0 28 +#define CLK_MM_DISP_DITHER0 29 +#define CLK_MM_DISP_SPLIT 30 +#define CLK_MM_DSI0_MM 31 +#define CLK_MM_DSI0_IF 32 +#define CLK_MM_DPI_MM 33 +#define CLK_MM_DPI_IF 34 +#define CLK_MM_FAKE_ENG2 35 +#define CLK_MM_MDP_DL_RX 36 +#define CLK_MM_IPU_DL_RX 37 +#define CLK_MM_26M 38 +#define CLK_MM_MMSYS_R2Y 39 +#define CLK_MM_DISP_RSZ 40 +#define CLK_MM_MDP_WDMA0 41 +#define CLK_MM_MDP_AAL 42 +#define CLK_MM_MDP_CCORR 43 +#define CLK_MM_DBI_MM 44 +#define CLK_MM_DBI_IF 45 +#define CLK_MM_NR_CLK 46 + +/* MCUCFG */ +#define CLK_MCU_MP0_SEL 0 +#define CLK_MCU_MP2_SEL 1 +#define CLK_MCU_BUS_SEL 2 +#define CLK_MCU_NR_CLK 3 + +#endif /* _DT_BINDINGS_CLK_MT8183_H */ -- cgit v1.3.1 From 34a5addb7b57cb5a0ad5940ff7ef1df7edb0ff55 Mon Sep 17 00:00:00 2001 From: Kate Liu Date: Fri, 11 Dec 2020 13:46:13 -0800 Subject: board: presidio: Add Parallel NAND support Set environment for Nand flash (U-boot 2020.04): - add nand flash in the device tree - add new default configuration file for G3 using parallel Nand - set nand parameters in presidio_asic.h Signed-off-by: Kate Liu Signed-off-by: Alex Nemirovsky CC: Tom Rini Reviewed-by: Tom Rini --- MAINTAINERS | 1 + arch/arm/dts/ca-presidio-engboard.dts | 14 ++++++++++++ configs/cortina_presidio-asic-pnand_defconfig | 33 +++++++++++++++++++++++++++ include/configs/presidio_asic.h | 9 ++++++++ 4 files changed, 57 insertions(+) create mode 100644 configs/cortina_presidio-asic-pnand_defconfig (limited to 'include') diff --git a/MAINTAINERS b/MAINTAINERS index f9a26ccf08b..a7a62dff814 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -200,6 +200,7 @@ F: drivers/i2c/i2c-cortina.c F: drivers/i2c/i2c-cortina.h F: drivers/mtd/nand/raw/cortina_nand.c F: drivers/mtd/nand/raw/cortina_nand.h +F: configs/cortina_presidio-asic-pnand_defconfig ARM/CZ.NIC TURRIS MOX SUPPORT M: Marek Behun diff --git a/arch/arm/dts/ca-presidio-engboard.dts b/arch/arm/dts/ca-presidio-engboard.dts index eef433e768e..0ab52fdfda8 100644 --- a/arch/arm/dts/ca-presidio-engboard.dts +++ b/arch/arm/dts/ca-presidio-engboard.dts @@ -52,6 +52,20 @@ clock-frequency = <400000>; }; + nand: nand-controller@f4324000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cortina,ca-nand"; + reg = <0 0xf4324000 0x3b0>, /* NAND controller */ + <0 0xf7001000 0xb4>, /* DMA_GLOBAL */ + <0 0xf7001a00 0x80>; /* DMA channel0 for FLASH */ + status = "okay"; + nand-ecc-mode = "hw"; + nand-ecc-strength = <16>; + nand-ecc-step-size = <1024>; /* Must be 1024 */ + nand_flash_base_addr = <0xe0000000>; + }; + sflash: sflash-controller@f4324000 { #address-cells = <2>; #size-cells = <1>; diff --git a/configs/cortina_presidio-asic-pnand_defconfig b/configs/cortina_presidio-asic-pnand_defconfig new file mode 100644 index 00000000000..e85cdc579ee --- /dev/null +++ b/configs/cortina_presidio-asic-pnand_defconfig @@ -0,0 +1,33 @@ +CONFIG_ARM=y +# CONFIG_SYS_ARCH_TIMER is not set +CONFIG_TARGET_PRESIDIO_ASIC=y +CONFIG_SYS_TEXT_BASE=0x04000000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x20000 +CONFIG_DM_GPIO=y +CONFIG_IDENT_STRING="Presidio-SoC" +CONFIG_DEFAULT_DEVICE_TREE="ca-presidio-engboard" +CONFIG_SHOW_BOOT_PROGRESS=y +CONFIG_BOOTDELAY=3 +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="earlycon=serial,0xf4329148 console=ttyS0,115200 root=/dev/ram0" +CONFIG_BOARD_EARLY_INIT_R=y +CONFIG_SYS_PROMPT="G3#" +CONFIG_CMD_MTD=y +CONFIG_CMD_WDT=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIMER=y +CONFIG_CMD_SMC=y +CONFIG_OF_CONTROL=y +CONFIG_OF_LIVE=y +# CONFIG_NET is not set +CONFIG_DM=y +CONFIG_CORTINA_GPIO=y +# CONFIG_MMC is not set +CONFIG_MTD=y +CONFIG_MTD_RAW_NAND=y +CONFIG_CORTINA_NAND=y +CONFIG_DM_SERIAL=y +CONFIG_CORTINA_UART=y +CONFIG_WDT=y +CONFIG_WDT_CORTINA=y diff --git a/include/configs/presidio_asic.h b/include/configs/presidio_asic.h index 34235b5a00c..710731efd56 100644 --- a/include/configs/presidio_asic.h +++ b/include/configs/presidio_asic.h @@ -67,4 +67,13 @@ #define CONFIG_SYS_MAXARGS 64 #define CONFIG_EXTRA_ENV_SETTINGS "silent=y\0" +/* nand driver parameters */ +#ifdef CONFIG_TARGET_PRESIDIO_ASIC + #define CONFIG_SYS_NAND_ONFI_DETECTION + #define CONFIG_SYS_MAX_NAND_DEVICE 1 + #define CONFIG_SYS_NAND_MAX_CHIPS 1 + #define CONFIG_SYS_NAND_BASE CONFIG_SYS_FLASH_BASE + #define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE } +#endif + #endif /* __PRESIDIO_ASIC_H */ -- cgit v1.3.1 From a3c85990c36508cf7a5e7be82a275b2033400118 Mon Sep 17 00:00:00 2001 From: Ryan Chen Date: Mon, 14 Dec 2020 13:54:23 +0800 Subject: clk: aspeed: Add AST2600 clock support This patch adds the clock control driver for the AST2600 SoC. Signed-off-by: Ryan Chen Signed-off-by: Chia-Wei, Wang --- arch/arm/include/asm/arch-aspeed/scu_ast2600.h | 338 +++++++ drivers/clk/aspeed/Makefile | 1 + drivers/clk/aspeed/clk_ast2600.c | 1173 ++++++++++++++++++++++++ include/dt-bindings/clock/ast2600-clock.h | 62 ++ 4 files changed, 1574 insertions(+) create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2600.h create mode 100644 drivers/clk/aspeed/clk_ast2600.c create mode 100644 include/dt-bindings/clock/ast2600-clock.h (limited to 'include') diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2600.h b/arch/arm/include/asm/arch-aspeed/scu_ast2600.h new file mode 100644 index 00000000000..a205fb1f762 --- /dev/null +++ b/arch/arm/include/asm/arch-aspeed/scu_ast2600.h @@ -0,0 +1,338 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) Aspeed Technology Inc. + */ +#ifndef _ASM_ARCH_SCU_AST2600_H +#define _ASM_ARCH_SCU_AST2600_H + +#define SCU_UNLOCK_KEY 0x1688a8a8 + +#define SCU_CLKGATE1_EMMC BIT(27) +#define SCU_CLKGATE1_MAC2 BIT(21) +#define SCU_CLKGATE1_MAC1 BIT(20) +#define SCU_CLKGATE1_USB_HUB BIT(14) +#define SCU_CLKGATE1_USB_HOST2 BIT(7) + +#define SCU_CLKGATE2_FSI BIT(30) +#define SCU_CLKGATE2_MAC4 BIT(21) +#define SCU_CLKGATE2_MAC3 BIT(20) +#define SCU_CLKGATE2_SDIO BIT(4) + +#define SCU_DRAM_HDSHK_SOC_INIT BIT(7) +#define SCU_DRAM_HDSHK_RDY BIT(6) + +#define SCU_CLKSRC1_ECC_RSA_DIV_MASK GENMASK(27, 26) +#define SCU_CLKSRC1_ECC_RSA_DIV_SHIFT 26 +#define SCU_CLKSRC1_PCLK_DIV_MASK GENMASK(25, 23) +#define SCU_CLKSRC1_PCLK_DIV_SHIFT 23 +#define SCU_CLKSRC1_BCLK_DIV_MASK GENMASK(22, 20) +#define SCU_CLKSRC1_BCLK_DIV_SHIFT 20 +#define SCU_CLKSRC1_ECC_RSA BIT(19) +#define SCU_CLKSRC1_MAC_DIV_MASK GENMASK(18, 16) +#define SCU_CLKSRC1_MAC_DIV_SHIFT 16 +#define SCU_CLKSRC1_EMMC_EN BIT(15) +#define SCU_CLKSRC1_EMMC_DIV_MASK GENMASK(14, 12) +#define SCU_CLKSRC1_EMMC_DIV_SHIFT 12 +#define SCU_CLKSRC1_EMMC BIT(11) + +#define SCU_CLKSRC2_RMII12 BIT(19) +#define SCU_CLKSRC2_RMII12_DIV_MASK GENMASK(18, 16) +#define SCU_CLKSRC2_RMII12_DIV_SHIFT 16 +#define SCU_CLKSRC2_UART5 BIT(14) + +#define SCU_CLKSRC4_SDIO_EN BIT(31) +#define SCU_CLKSRC4_SDIO_DIV_MASK GENMASK(30, 28) +#define SCU_CLKSRC4_SDIO_DIV_SHIFT 28 +#define SCU_CLKSRC4_MAC_DIV_MASK GENMASK(26, 24) +#define SCU_CLKSRC4_MAC_DIV_SHIFT 24 +#define SCU_CLKSRC4_RMII34_DIV_MASK GENMASK(18, 16) +#define SCU_CLKSRC4_RMII34_DIV_SHIFT 16 +#define SCU_CLKSRC4_PCLK_DIV_MASK GENMASK(11, 9) +#define SCU_CLKSRC4_PCLK_DIV_SHIFT 9 +#define SCU_CLKSRC4_SDIO BIT(8) +#define SCU_CLKSRC4_UART6 BIT(5) +#define SCU_CLKSRC4_UART4 BIT(3) +#define SCU_CLKSRC4_UART3 BIT(2) +#define SCU_CLKSRC4_UART2 BIT(1) +#define SCU_CLKSRC4_UART1 BIT(0) + +#define SCU_CLKSRC5_UART13 BIT(12) +#define SCU_CLKSRC5_UART12 BIT(11) +#define SCU_CLKSRC5_UART11 BIT(10) +#define SCU_CLKSRC5_UART10 BIT(9) +#define SCU_CLKSRC5_UART9 BIT(8) +#define SCU_CLKSRC5_UART8 BIT(7) +#define SCU_CLKSRC5_UART7 BIT(6) +#define SCU_CLKSRC5_HUXCLK_MASK GENMASK(5, 3) +#define SCU_CLKSRC5_HUXCLK_SHIFT 3 +#define SCU_CLKSRC5_UXCLK_MASK GENMASK(2, 0) +#define SCU_CLKSRC5_UXCLK_SHIFT 0 + +#define SCU_PINCTRL1_EMMC_MASK GENMASK(31, 24) +#define SCU_PINCTRL1_EMMC_SHIFT 24 + +#define SCU_PINCTRL16_MAC4_DRIVING_MASK GENMASK(3, 2) +#define SCU_PINCTRL16_MAC4_DRIVING_SHIFT 2 +#define SCU_PINCTRL16_MAC3_DRIVING_MASK GENMASK(1, 0) +#define SCU_PINCTRL16_MAC3_DRIVING_SHIFT 0 + +#define SCU_HWSTRAP1_CPU_AXI_CLK_RATIO BIT(16) +#define SCU_HWSTRAP1_VGA_MEM_MASK GENMASK(14, 13) +#define SCU_HWSTRAP1_VGA_MEM_SHIFT 13 +#define SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_MASK GENMASK(12, 11) +#define SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_SHIFT 11 +#define SCU_HWSTRAP1_CPU_FREQ_MASK GENMASK(10, 8) +#define SCU_HWSTRAP1_CPU_FREQ_SHIFT 8 +#define SCU_HWSTRAP1_MAC2_INTF BIT(7) +#define SCU_HWSTRAP1_MAC1_INTF BIT(6) + +#define SCU_EFUSE_DIS_DP BIT(17) +#define SCU_EFUSE_DIS_VGA BIT(14) +#define SCU_EFUSE_DIS_PCIE_EP BIT(13) +#define SCU_EFUSE_DIS_USB BIT(12) +#define SCU_EFUSE_DIS_RVAS BIT(10) +#define SCU_EFUSE_DIS_VIDEO_DEC BIT(9) +#define SCU_EFUSE_DIS_VIDEO BIT(8) +#define SCU_EFUSE_DIS_PCIE_RC BIT(7) +#define SCU_EFUSE_DIS_CM3 BIT(6) +#define SCU_EFUSE_DIS_CA7 BIT(5) + +#define SCU_PLL_RST BIT(25) +#define SCU_PLL_BYPASS BIT(24) +#define SCU_PLL_OFF BIT(23) +#define SCU_PLL_DIV_MASK GENMASK(22, 19) +#define SCU_PLL_DIV_SHIFT 19 +#define SCU_PLL_DENUM_MASK GENMASK(18, 13) +#define SCU_PLL_DENUM_SHIFT 13 +#define SCU_PLL_NUM_MASK GENMASK(12, 0) +#define SCU_PLL_NUM_SHIFT 0 + +#define SCU_UART_CLKGEN_N_MASK GENMASK(17, 8) +#define SCU_UART_CLKGEN_N_SHIFT 8 +#define SCU_UART_CLKGEN_R_MASK GENMASK(7, 0) +#define SCU_UART_CLKGEN_R_SHIFT 0 + +#define SCU_HUART_CLKGEN_N_MASK GENMASK(17, 8) +#define SCU_HUART_CLKGEN_N_SHIFT 8 +#define SCU_HUART_CLKGEN_R_MASK GENMASK(7, 0) +#define SCU_HUART_CLKGEN_R_SHIFT 0 + +#define SCU_MISC_CTRL1_UART5_DIV BIT(12) + +#ifndef __ASSEMBLY__ +struct ast2600_scu { + uint32_t prot_key1; /* 0x000 */ + uint32_t chip_id1; /* 0x004 */ + uint32_t rsv_0x08; /* 0x008 */ + uint32_t rsv_0x0c; /* 0x00C */ + uint32_t prot_key2; /* 0x010 */ + uint32_t chip_id2; /* 0x014 */ + uint32_t rsv_0x18[10]; /* 0x018 ~ 0x03C */ + uint32_t modrst_ctrl1; /* 0x040 */ + uint32_t modrst_clr1; /* 0x044 */ + uint32_t rsv_0x48; /* 0x048 */ + uint32_t rsv_0x4C; /* 0x04C */ + uint32_t modrst_ctrl2; /* 0x050 */ + uint32_t modrst_clr2; /* 0x054 */ + uint32_t rsv_0x58; /* 0x058 */ + uint32_t rsv_0x5C; /* 0x05C */ + uint32_t extrst_sel1; /* 0x060 */ + uint32_t sysrst_sts1_1; /* 0x064 */ + uint32_t sysrst_sts1_2; /* 0x068 */ + uint32_t sysrst_sts1_3; /* 0x06C */ + uint32_t extrst_sel2; /* 0x070 */ + uint32_t sysrst_sts2_1; /* 0x074 */ + uint32_t sysrst_sts2_2; /* 0x078 */ + uint32_t stsrst_sts3_2; /* 0x07C */ + uint32_t clkgate_ctrl1; /* 0x080 */ + uint32_t clkgate_clr1; /* 0x084 */ + uint32_t rsv_0x88; /* 0x088 */ + uint32_t rsv_0x8C; /* 0x08C */ + uint32_t clkgate_ctrl2; /* 0x090 */ + uint32_t clkgate_clr2; /* 0x094 */ + uint32_t rsv_0x98[10]; /* 0x098 ~ 0x0BC */ + uint32_t misc_ctrl1; /* 0x0C0 */ + uint32_t misc_ctrl2; /* 0x0C4 */ + uint32_t debug_ctrl1; /* 0x0C8 */ + uint32_t rsv_0xCC; /* 0x0CC */ + uint32_t misc_ctrl3; /* 0x0D0 */ + uint32_t misc_ctrl4; /* 0x0D4 */ + uint32_t debug_ctrl2; /* 0x0D8 */ + uint32_t rsv_0xdc[9]; /* 0x0DC ~ 0x0FC */ + uint32_t dram_hdshk; /* 0x100 */ + uint32_t soc_scratch[3]; /* 0x104 ~ 0x10C */ + uint32_t rsv_0x110[4]; /* 0x110 ~ 0x11C*/ + uint32_t cpu_scratch_wp; /* 0x120 */ + uint32_t rsv_0x124[23]; /* 0x124 */ + uint32_t smp_boot[12]; /* 0x180 */ + uint32_t cpu_scratch[20]; /* 0x1b0 */ + uint32_t hpll; /* 0x200 */ + uint32_t hpll_ext; /* 0x204 */ + uint32_t rsv_0x208[2]; /* 0x208 ~ 0x20C */ + uint32_t apll; /* 0x210 */ + uint32_t apll_ext; /* 0x214 */ + uint32_t rsv_0x218[2]; /* 0x218 ~ 0x21C */ + uint32_t mpll; /* 0x220 */ + uint32_t mpll_ext; /* 0x224 */ + uint32_t rsv_0x228[6]; /* 0x228 ~ 0x23C */ + uint32_t epll; /* 0x240 */ + uint32_t epll_ext; /* 0x244 */ + uint32_t rsv_0x248[6]; /* 0x248 ~ 0x25C */ + uint32_t dpll; /* 0x260 */ + uint32_t dpll_ext; /* 0x264 */ + uint32_t rsv_0x268[38]; /* 0x268 ~ 0x2FC */ + uint32_t clksrc1; /* 0x300 */ + uint32_t clksrc2; /* 0x304 */ + uint32_t clksrc3; /* 0x308 */ + uint32_t rsv_0x30c; /* 0x30C */ + uint32_t clksrc4; /* 0x310 */ + uint32_t clksrc5; /* 0x314 */ + uint32_t rsv_0x318[2]; /* 0x318 ~ 0x31C */ + uint32_t freq_counter_ctrl1; /* 0x320 */ + uint32_t freq_counter_cmp1; /* 0x324 */ + uint32_t rsv_0x328[2]; /* 0x328 ~ 0x32C */ + uint32_t freq_counter_ctrl2; /* 0x330 */ + uint32_t freq_counter_cmp2; /* 0x334 */ + uint32_t uart_clkgen; /* 0x338 */ + uint32_t huart_clkgen; /* 0x33C */ + uint32_t mac12_clk_delay; /* 0x340 */ + uint32_t rsv_0x344; /* 0x344 */ + uint32_t mac12_clk_delay_100M; /* 0x348 */ + uint32_t mac12_clk_delay_10M; /* 0x34C */ + uint32_t mac34_clk_delay; /* 0x350 */ + uint32_t rsv_0x354; /* 0x354 */ + uint32_t mac34_clk_delay_100M; /* 0x358 */ + uint32_t mac34_clk_delay_10M; /* 0x35C */ + uint32_t clkduty_meas_ctrl; /* 0x360 */ + uint32_t clkduty1; /* 0x364 */ + uint32_t clkduty2; /* 0x368 */ + uint32_t clkduty_meas_res; /* 0x36C */ + uint32_t clkduty_meas_ctrl2; /* 0x370 */ + uint32_t clkduty3; /* 0x374 */ + uint32_t rsv_0x378[34]; /* 0x378 ~ 0x3FC */ + uint32_t pinmux1; /* 0x400 */ + uint32_t pinmux2; /* 0x404 */ + uint32_t rsv_0x408; /* 0x408 */ + uint32_t pinmux3; /* 0x40C */ + uint32_t pinmux4; /* 0x410 */ + uint32_t pinmux5; /* 0x414 */ + uint32_t pinmux6; /* 0x418 */ + uint32_t pinmux7; /* 0x41C */ + uint32_t rsv_0x420[4]; /* 0x420 ~ 0x42C */ + uint32_t pinmux8; /* 0x430 */ + uint32_t pinmux9; /* 0x434 */ + uint32_t pinmux10; /* 0x438 */ + uint32_t rsv_0x43c; /* 0x43C */ + uint32_t pinmux12; /* 0x440 */ + uint32_t pinmux13; /* 0x444 */ + uint32_t rsv_0x448[2]; /* 0x448 ~ 0x44C */ + uint32_t pinmux14; /* 0x450 */ + uint32_t pinmux15; /* 0x454 */ + uint32_t pinmux16; /* 0x458 */ + uint32_t rsv_0x45c[21]; /* 0x45C ~ 0x4AC */ + uint32_t pinmux17; /* 0x4B0 */ + uint32_t pinmux18; /* 0x4B4 */ + uint32_t pinmux19; /* 0x4B8 */ + uint32_t pinmux20; /* 0x4BC */ + uint32_t rsv_0x4c0[5]; /* 0x4C0 ~ 0x4D0 */ + uint32_t pinmux22; /* 0x4D4 */ + uint32_t pinmux23; /* 0x4D8 */ + uint32_t rsv_0x4dc[9]; /* 0x4DC ~ 0x4FC */ + uint32_t hwstrap1; /* 0x500 */ + uint32_t hwstrap_clr1; /* 0x504 */ + uint32_t hwstrap_prot1; /* 0x508 */ + uint32_t rsv_0x50c; /* 0x50C */ + uint32_t hwstrap2; /* 0x510 */ + uint32_t hwstrap_clr2; /* 0x514 */ + uint32_t hwstrap_prot2; /* 0x518 */ + uint32_t rsv_0x51c; /* 0x51C */ + uint32_t rng_ctrl; /* 0x520 */ + uint32_t rng_data; /* 0x524 */ + uint32_t rsv_0x528[6]; /* 0x528 ~ 0x53C */ + uint32_t pwr_save_wakeup_en1; /* 0x540 */ + uint32_t pwr_save_wakeup_ctrl1; /* 0x544 */ + uint32_t rsv_0x548[2]; /* 0x548 */ + uint32_t pwr_save_wakeup_en2; /* 0x550 */ + uint32_t pwr_save_wakeup_ctrl2; /* 0x554 */ + uint32_t rsv_0x558[2]; /* 0x558 */ + uint32_t intr1_ctrl_sts; /* 0x560 */ + uint32_t rsv_0x564[3]; /* 0x564 */ + uint32_t intr2_ctrl_sts; /* 0x570 */ + uint32_t rsv_0x574[7]; /* 0x574 ~ 0x58C */ + uint32_t otp_ctrl; /* 0x590 */ + uint32_t efuse; /* 0x594 */ + uint32_t rsv_0x598[6]; /* 0x598 */ + uint32_t chip_unique_id[8]; /* 0x5B0 */ + uint32_t rsv_0x5e0[8]; /* 0x5E0 ~ 0x5FC */ + uint32_t disgpio_in_pull_down0; /* 0x610 */ + uint32_t disgpio_in_pull_down1; /* 0x614 */ + uint32_t disgpio_in_pull_down2; /* 0x618 */ + uint32_t disgpio_in_pull_down3; /* 0x61C */ + uint32_t rsv_0x620[4]; /* 0x620 ~ 0x62C */ + uint32_t disgpio_in_pull_down4; /* 0x630 */ + uint32_t disgpio_in_pull_down5; /* 0x634 */ + uint32_t disgpio_in_pull_down6; /* 0x638 */ + uint32_t rsv_0x63c[5]; /* 0x63C ~ 0x64C */ + uint32_t sli_driving_strength; /* 0x650 */ + uint32_t rsv_0x654[107]; /* 0x654 ~ 0x7FC */ + uint32_t ca7_ctrl1; /* 0x800 */ + uint32_t ca7_ctrl2; /* 0x804 */ + uint32_t ca7_ctrl3; /* 0x808 */ + uint32_t ca7_ctrl4; /* 0x80C */ + uint32_t rsv_0x810[4]; /* 0x810 ~ 0x81C */ + uint32_t ca7_parity_chk; /* 0x820 */ + uint32_t ca7_parity_clr; /* 0x824 */ + uint32_t rsv_0x828[118]; /* 0x828 ~ 0x9FC */ + uint32_t cm3_ctrl; /* 0xA00 */ + uint32_t cm3_base; /* 0xA04 */ + uint32_t cm3_imem_addr; /* 0xA08 */ + uint32_t cm3_dmem_addr; /* 0xA0C */ + uint32_t rsv_0xa10[12]; /* 0xA10 ~ 0xA3C */ + uint32_t cm3_cache_area; /* 0xA40 */ + uint32_t cm3_cache_invd_ctrl; /* 0xA44 */ + uint32_t cm3_cache_func_ctrl; /* 0xA48 */ + uint32_t rsv_0xa4c[108]; /* 0xA4C ~ 0xBFC */ + uint32_t pci_cfg[3]; /* 0xC00 */ + uint32_t rsv_0xc0c[5]; /* 0xC0C ~ 0xC1C */ + uint32_t pcie_cfg; /* 0xC20 */ + uint32_t mmio_decode; /* 0xC24 */ + uint32_t reloc_ctrl_decode[2]; /* 0xC28 */ + uint32_t rsv_0xc30[4]; /* 0xC30 ~ 0xC3C */ + uint32_t mbox_decode; /* 0xC40 */ + uint32_t shared_sram_decode[2]; /* 0xC44 */ + uint32_t bmc_rev_id; /* 0xC4C */ + uint32_t rsv_0xc50[5]; /* 0xC50 ~ 0xC60 */ + uint32_t bmc_device_id; /* 0xC64 */ + uint32_t rsv_0xc68[102]; /* 0xC68 ~ 0xDFC */ + uint32_t vga_scratch1; /* 0xE00 */ + uint32_t vga_scratch2; /* 0xE04 */ + uint32_t vga_scratch3; /* 0xE08 */ + uint32_t vga_scratch4; /* 0xE0C */ + uint32_t rsv_0xe10[4]; /* 0xE10 ~ 0xE1C */ + uint32_t vga_scratch5; /* 0xE20 */ + uint32_t vga_scratch6; /* 0xE24 */ + uint32_t vga_scratch7; /* 0xE28 */ + uint32_t vga_scratch8; /* 0xE2C */ + uint32_t rsv_0xe30[52]; /* 0xE30 ~ 0xEFC */ + uint32_t wr_prot1; /* 0xF00 */ + uint32_t wr_prot2; /* 0xF04 */ + uint32_t wr_prot3; /* 0xF08 */ + uint32_t wr_prot4; /* 0xF0C */ + uint32_t wr_prot5; /* 0xF10 */ + uint32_t wr_prot6; /* 0xF18 */ + uint32_t wr_prot7; /* 0xF1C */ + uint32_t wr_prot8; /* 0xF20 */ + uint32_t wr_prot9; /* 0xF24 */ + uint32_t rsv_0xf28[2]; /* 0xF28 ~ 0xF2C */ + uint32_t wr_prot10; /* 0xF30 */ + uint32_t wr_prot11; /* 0xF34 */ + uint32_t wr_prot12; /* 0xF38 */ + uint32_t wr_prot13; /* 0xF3C */ + uint32_t wr_prot14; /* 0xF40 */ + uint32_t rsv_0xf44; /* 0xF44 */ + uint32_t wr_prot15; /* 0xF48 */ + uint32_t rsv_0xf4c[5]; /* 0xF4C ~ 0xF5C */ + uint32_t wr_prot16; /* 0xF60 */ +}; +#endif +#endif diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile index 81764b43917..84776e5265e 100644 --- a/drivers/clk/aspeed/Makefile +++ b/drivers/clk/aspeed/Makefile @@ -4,3 +4,4 @@ # obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o +obj-$(CONFIG_ASPEED_AST2600) += clk_ast2600.o diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c new file mode 100644 index 00000000000..f72d384047f --- /dev/null +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -0,0 +1,1173 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) ASPEED Technology Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define CLKIN_25M 25000000UL + +/* MAC Clock Delay settings */ +#define MAC12_DEF_DELAY_1G 0x0041b75d +#define MAC12_DEF_DELAY_100M 0x00417410 +#define MAC12_DEF_DELAY_10M 0x00417410 +#define MAC34_DEF_DELAY_1G 0x0010438a +#define MAC34_DEF_DELAY_100M 0x00104208 +#define MAC34_DEF_DELAY_10M 0x00104208 + +/* + * 3-bit encode of CPU freqeucy + * Some code is duplicated + */ +enum ast2600_cpu_freq { + CPU_FREQ_1200M_1, + CPU_FREQ_1600M_1, + CPU_FREQ_1200M_2, + CPU_FREQ_1600M_2, + CPU_FREQ_800M_1, + CPU_FREQ_800M_2, + CPU_FREQ_800M_3, + CPU_FREQ_800M_4, +}; + +struct ast2600_clk_priv { + struct ast2600_scu *scu; +}; + +/* + * Clock divider/multiplier configuration struct. + * For H-PLL and M-PLL the formula is + * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1) + * M - Numerator + * N - Denumerator + * P - Post Divider + * They have the same layout in their control register. + * + * D-PLL and D2-PLL have extra divider (OD + 1), which is not + * yet needed and ignored by clock configurations. + */ +union ast2600_pll_reg { + uint32_t w; + struct { + unsigned int m : 13; + unsigned int n : 6; + unsigned int p : 4; + unsigned int off : 1; + unsigned int bypass : 1; + unsigned int reset : 1; + unsigned int reserved : 6; + } b; +}; + +struct ast2600_pll_cfg { + union ast2600_pll_reg reg; + unsigned int ext_reg; +}; + +struct ast2600_pll_desc { + uint32_t in; + uint32_t out; + struct ast2600_pll_cfg cfg; +}; + +static const struct ast2600_pll_desc ast2600_pll_lookup[] = { + { + .in = CLKIN_25M, + .out = 400000000, + .cfg.reg.b.m = 95, + .cfg.reg.b.n = 2, + .cfg.reg.b.p = 1, + .cfg.ext_reg = 0x31, + }, + { + .in = CLKIN_25M, + .out = 200000000, + .cfg.reg.b.m = 127, + .cfg.reg.b.n = 0, + .cfg.reg.b.p = 15, + .cfg.ext_reg = 0x3f, + }, + { + .in = CLKIN_25M, + .out = 334000000, + .cfg.reg.b.m = 667, + .cfg.reg.b.n = 4, + .cfg.reg.b.p = 9, + .cfg.ext_reg = 0x14d, + }, + { + .in = CLKIN_25M, + .out = 1000000000, + .cfg.reg.b.m = 119, + .cfg.reg.b.n = 2, + .cfg.reg.b.p = 0, + .cfg.ext_reg = 0x3d, + }, + { + .in = CLKIN_25M, + .out = 50000000, + .cfg.reg.b.m = 95, + .cfg.reg.b.n = 2, + .cfg.reg.b.p = 15, + .cfg.ext_reg = 0x31, + }, +}; + +/* divisor tables */ +static uint32_t axi_ahb_div0_table[] = { + 3, 2, 3, 4, +}; + +static uint32_t axi_ahb_div1_table[] = { + 3, 4, 6, 8, +}; + +static uint32_t axi_ahb_default_table[] = { + 3, 4, 3, 4, 2, 2, 2, 2, +}; + +extern uint32_t ast2600_get_pll_rate(struct ast2600_scu *scu, int pll_idx) +{ + union ast2600_pll_reg pll_reg; + uint32_t hwstrap1; + uint32_t cpu_freq; + uint32_t mul = 1, div = 1; + + switch (pll_idx) { + case ASPEED_CLK_APLL: + pll_reg.w = readl(&scu->apll); + break; + case ASPEED_CLK_DPLL: + pll_reg.w = readl(&scu->dpll); + break; + case ASPEED_CLK_EPLL: + pll_reg.w = readl(&scu->epll); + break; + case ASPEED_CLK_HPLL: + pll_reg.w = readl(&scu->hpll); + break; + case ASPEED_CLK_MPLL: + pll_reg.w = readl(&scu->mpll); + break; + } + + if (!pll_reg.b.bypass) { + /* F = 25Mhz * [(M + 2) / (n + 1)] / (p + 1) + * HPLL Numerator (M) = fix 0x5F when SCU500[10]=1 + * Fixed 0xBF when SCU500[10]=0 and SCU500[8]=1 + * SCU200[12:0] (default 0x8F) when SCU510[10]=0 and SCU510[8]=0 + * HPLL Denumerator (N) = SCU200[18:13] (default 0x2) + * HPLL Divider (P) = SCU200[22:19] (default 0x0) + * HPLL Bandwidth Adj (NB) = fix 0x2F when SCU500[10]=1 + * Fixed 0x5F when SCU500[10]=0 and SCU500[8]=1 + * SCU204[11:0] (default 0x31) when SCU500[10]=0 and SCU500[8]=0 + */ + if (pll_idx == ASPEED_CLK_HPLL) { + hwstrap1 = readl(&scu->hwstrap1); + cpu_freq = (hwstrap1 & SCU_HWSTRAP1_CPU_FREQ_MASK) >> + SCU_HWSTRAP1_CPU_FREQ_SHIFT; + + switch (cpu_freq) { + case CPU_FREQ_800M_1: + case CPU_FREQ_800M_2: + case CPU_FREQ_800M_3: + case CPU_FREQ_800M_4: + pll_reg.b.m = 0x5f; + break; + case CPU_FREQ_1600M_1: + case CPU_FREQ_1600M_2: + pll_reg.b.m = 0xbf; + break; + default: + pll_reg.b.m = 0x8f; + break; + } + } + + mul = (pll_reg.b.m + 1) / (pll_reg.b.n + 1); + div = (pll_reg.b.p + 1); + } + + return ((CLKIN_25M * mul) / div); +} + +static uint32_t ast2600_get_hclk_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL); + uint32_t axi_div, ahb_div; + uint32_t hwstrap1 = readl(&scu->hwstrap1); + uint32_t cpu_freq = (hwstrap1 & SCU_HWSTRAP1_CPU_FREQ_MASK) >> + SCU_HWSTRAP1_CPU_FREQ_SHIFT; + uint32_t axi_ahb_ratio = (hwstrap1 & SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_MASK) >> + SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_SHIFT; + + if (hwstrap1 & SCU_HWSTRAP1_CPU_AXI_CLK_RATIO) { + axi_ahb_div1_table[0] = axi_ahb_default_table[cpu_freq] * 2; + axi_div = 1; + ahb_div = axi_ahb_div1_table[axi_ahb_ratio]; + } else { + axi_ahb_div0_table[0] = axi_ahb_default_table[cpu_freq]; + axi_div = 2; + ahb_div = axi_ahb_div0_table[axi_ahb_ratio]; + } + + return (rate / axi_div / ahb_div); +} + +static uint32_t ast2600_get_bclk_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL); + uint32_t clksrc1 = readl(&scu->clksrc1); + uint32_t bclk_div = (clksrc1 & SCU_CLKSRC1_BCLK_DIV_MASK) >> + SCU_CLKSRC1_BCLK_DIV_SHIFT; + + return (rate / ((bclk_div + 1) * 4)); +} + +static uint32_t ast2600_get_pclk1_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL); + uint32_t clksrc1 = readl(&scu->clksrc1); + uint32_t pclk_div = (clksrc1 & SCU_CLKSRC1_PCLK_DIV_MASK) >> + SCU_CLKSRC1_PCLK_DIV_SHIFT; + + return (rate / ((pclk_div + 1) * 4)); +} + +static uint32_t ast2600_get_pclk2_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_hclk_rate(scu); + uint32_t clksrc4 = readl(&scu->clksrc4); + uint32_t pclk_div = (clksrc4 & SCU_CLKSRC4_PCLK_DIV_MASK) >> + SCU_CLKSRC4_PCLK_DIV_SHIFT; + + return (rate / ((pclk_div + 1) * 2)); +} + +static uint32_t ast2600_get_uxclk_in_rate(struct ast2600_scu *scu) +{ + uint32_t rate = 0; + uint32_t clksrc5 = readl(&scu->clksrc5); + uint32_t uxclk = (clksrc5 & SCU_CLKSRC5_UXCLK_MASK) >> + SCU_CLKSRC5_UXCLK_SHIFT; + + switch (uxclk) { + case 0: + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 4; + break; + case 1: + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 2; + break; + case 2: + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL); + break; + case 3: + rate = ast2600_get_hclk_rate(scu); + break; + } + + return rate; +} + +static uint32_t ast2600_get_huxclk_in_rate(struct ast2600_scu *scu) +{ + uint32_t rate = 0; + uint32_t clksrc5 = readl(&scu->clksrc5); + uint32_t huxclk = (clksrc5 & SCU_CLKSRC5_HUXCLK_MASK) >> + SCU_CLKSRC5_HUXCLK_SHIFT; + + switch (huxclk) { + case 0: + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 4; + break; + case 1: + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 2; + break; + case 2: + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL); + break; + case 3: + rate = ast2600_get_hclk_rate(scu); + break; + } + + return rate; +} + +static uint32_t ast2600_get_uart_uxclk_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_uxclk_in_rate(scu); + uint32_t uart_clkgen = readl(&scu->uart_clkgen); + uint32_t n = (uart_clkgen & SCU_UART_CLKGEN_N_MASK) >> + SCU_UART_CLKGEN_N_SHIFT; + uint32_t r = (uart_clkgen & SCU_UART_CLKGEN_R_MASK) >> + SCU_UART_CLKGEN_R_SHIFT; + + return ((rate * r) / (n * 2)); +} + +static uint32_t ast2600_get_uart_huxclk_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_huxclk_in_rate(scu); + uint32_t huart_clkgen = readl(&scu->huart_clkgen); + uint32_t n = (huart_clkgen & SCU_HUART_CLKGEN_N_MASK) >> + SCU_HUART_CLKGEN_N_SHIFT; + uint32_t r = (huart_clkgen & SCU_HUART_CLKGEN_R_MASK) >> + SCU_HUART_CLKGEN_R_SHIFT; + + return ((rate * r) / (n * 2)); +} + +static uint32_t ast2600_get_sdio_clk_rate(struct ast2600_scu *scu) +{ + uint32_t rate = 0; + uint32_t clksrc4 = readl(&scu->clksrc4); + uint32_t sdio_div = (clksrc4 & SCU_CLKSRC4_SDIO_DIV_MASK) >> + SCU_CLKSRC4_SDIO_DIV_SHIFT; + + if (clksrc4 & SCU_CLKSRC4_SDIO) + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL); + else + rate = ast2600_get_hclk_rate(scu); + + return (rate / ((sdio_div + 1) * 2)); +} + +static uint32_t ast2600_get_emmc_clk_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL); + uint32_t clksrc1 = readl(&scu->clksrc1); + uint32_t emmc_div = (clksrc1 & SCU_CLKSRC1_EMMC_DIV_MASK) >> + SCU_CLKSRC1_EMMC_DIV_SHIFT; + + return (rate / ((emmc_div + 1) * 4)); +} + +static uint32_t ast2600_get_uart_clk_rate(struct ast2600_scu *scu, int uart_idx) +{ + uint32_t rate = 0; + uint32_t uart5_clk = 0; + uint32_t clksrc2 = readl(&scu->clksrc2); + uint32_t clksrc4 = readl(&scu->clksrc4); + uint32_t clksrc5 = readl(&scu->clksrc5); + uint32_t misc_ctrl1 = readl(&scu->misc_ctrl1); + + switch (uart_idx) { + case 1: + case 2: + case 3: + case 4: + case 6: + if (clksrc4 & BIT(uart_idx - 1)) + rate = ast2600_get_uart_huxclk_rate(scu); + else + rate = ast2600_get_uart_uxclk_rate(scu); + break; + case 5: + /* + * SCU0C[12] and SCU304[14] together decide + * the UART5 clock generation + */ + if (misc_ctrl1 & SCU_MISC_CTRL1_UART5_DIV) + uart5_clk = 0x1 << 1; + + if (clksrc2 & SCU_CLKSRC2_UART5) + uart5_clk |= 0x1; + + switch (uart5_clk) { + case 0: + rate = 24000000; + break; + case 1: + rate = 192000000; + break; + case 2: + rate = 24000000 / 13; + break; + case 3: + rate = 192000000 / 13; + break; + } + + break; + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + if (clksrc5 & BIT(uart_idx - 1)) + rate = ast2600_get_uart_huxclk_rate(scu); + else + rate = ast2600_get_uart_uxclk_rate(scu); + break; + } + + return rate; +} + +static ulong ast2600_clk_get_rate(struct clk *clk) +{ + struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); + ulong rate = 0; + + switch (clk->id) { + case ASPEED_CLK_HPLL: + case ASPEED_CLK_EPLL: + case ASPEED_CLK_DPLL: + case ASPEED_CLK_MPLL: + case ASPEED_CLK_APLL: + rate = ast2600_get_pll_rate(priv->scu, clk->id); + break; + case ASPEED_CLK_AHB: + rate = ast2600_get_hclk_rate(priv->scu); + break; + case ASPEED_CLK_APB1: + rate = ast2600_get_pclk1_rate(priv->scu); + break; + case ASPEED_CLK_APB2: + rate = ast2600_get_pclk2_rate(priv->scu); + break; + case ASPEED_CLK_GATE_UART1CLK: + rate = ast2600_get_uart_clk_rate(priv->scu, 1); + break; + case ASPEED_CLK_GATE_UART2CLK: + rate = ast2600_get_uart_clk_rate(priv->scu, 2); + break; + case ASPEED_CLK_GATE_UART3CLK: + rate = ast2600_get_uart_clk_rate(priv->scu, 3); + break; + case ASPEED_CLK_GATE_UART4CLK: + rate = ast2600_get_uart_clk_rate(priv->scu, 4); + break; + case ASPEED_CLK_GATE_UART5CLK: + rate = ast2600_get_uart_clk_rate(priv->scu, 5); + break; + case ASPEED_CLK_BCLK: + rate = ast2600_get_bclk_rate(priv->scu); + break; + case ASPEED_CLK_SDIO: + rate = ast2600_get_sdio_clk_rate(priv->scu); + break; + case ASPEED_CLK_EMMC: + rate = ast2600_get_emmc_clk_rate(priv->scu); + break; + case ASPEED_CLK_UARTX: + rate = ast2600_get_uart_uxclk_rate(priv->scu); + break; + case ASPEED_CLK_HUARTX: + rate = ast2600_get_uart_huxclk_rate(priv->scu); + break; + default: + debug("can't get clk rate\n"); + return -ENOENT; + } + + return rate; +} + +/** + * @brief lookup PLL divider config by input/output rate + * @param[in] *pll - PLL descriptor + * @return true - if PLL divider config is found, false - else + * The function caller shall fill "pll->in" and "pll->out", + * then this function will search the lookup table + * to find a valid PLL divider configuration. + */ +static bool ast2600_search_clock_config(struct ast2600_pll_desc *pll) +{ + uint32_t i; + const struct ast2600_pll_desc *def_desc; + bool is_found = false; + + for (i = 0; i < ARRAY_SIZE(ast2600_pll_lookup); i++) { + def_desc = &ast2600_pll_lookup[i]; + + if (def_desc->in == pll->in && def_desc->out == pll->out) { + is_found = true; + pll->cfg.reg.w = def_desc->cfg.reg.w; + pll->cfg.ext_reg = def_desc->cfg.ext_reg; + break; + } + } + return is_found; +} + +static uint32_t ast2600_configure_pll(struct ast2600_scu *scu, + struct ast2600_pll_cfg *p_cfg, int pll_idx) +{ + uint32_t addr, addr_ext; + uint32_t reg; + + switch (pll_idx) { + case ASPEED_CLK_HPLL: + addr = (uint32_t)(&scu->hpll); + addr_ext = (uint32_t)(&scu->hpll_ext); + break; + case ASPEED_CLK_MPLL: + addr = (uint32_t)(&scu->mpll); + addr_ext = (uint32_t)(&scu->mpll_ext); + break; + case ASPEED_CLK_DPLL: + addr = (uint32_t)(&scu->dpll); + addr_ext = (uint32_t)(&scu->dpll_ext); + break; + case ASPEED_CLK_EPLL: + addr = (uint32_t)(&scu->epll); + addr_ext = (uint32_t)(&scu->epll_ext); + break; + case ASPEED_CLK_APLL: + addr = (uint32_t)(&scu->apll); + addr_ext = (uint32_t)(&scu->apll_ext); + break; + default: + debug("unknown PLL index\n"); + return 1; + } + + p_cfg->reg.b.bypass = 0; + p_cfg->reg.b.off = 1; + p_cfg->reg.b.reset = 1; + + reg = readl(addr); + reg &= ~GENMASK(25, 0); + reg |= p_cfg->reg.w; + writel(reg, addr); + + /* write extend parameter */ + writel(p_cfg->ext_reg, addr_ext); + udelay(100); + p_cfg->reg.b.off = 0; + p_cfg->reg.b.reset = 0; + reg &= ~GENMASK(25, 0); + reg |= p_cfg->reg.w; + writel(reg, addr); + while (!(readl(addr_ext) & BIT(31))) + ; + + return 0; +} + +static uint32_t ast2600_configure_ddr(struct ast2600_scu *scu, ulong rate) +{ + struct ast2600_pll_desc mpll; + + mpll.in = CLKIN_25M; + mpll.out = rate; + if (ast2600_search_clock_config(&mpll) == false) { + printf("error!! unable to find valid DDR clock setting\n"); + return 0; + } + ast2600_configure_pll(scu, &mpll.cfg, ASPEED_CLK_MPLL); + + return ast2600_get_pll_rate(scu, ASPEED_CLK_MPLL); +} + +static ulong ast2600_clk_set_rate(struct clk *clk, ulong rate) +{ + struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); + ulong new_rate; + + switch (clk->id) { + case ASPEED_CLK_MPLL: + new_rate = ast2600_configure_ddr(priv->scu, rate); + break; + default: + return -ENOENT; + } + + return new_rate; +} + +static uint32_t ast2600_configure_mac12_clk(struct ast2600_scu *scu) +{ + /* scu340[25:0]: 1G default delay */ + clrsetbits_le32(&scu->mac12_clk_delay, GENMASK(25, 0), + MAC12_DEF_DELAY_1G); + + /* set 100M/10M default delay */ + writel(MAC12_DEF_DELAY_100M, &scu->mac12_clk_delay_100M); + writel(MAC12_DEF_DELAY_10M, &scu->mac12_clk_delay_10M); + + /* MAC AHB = HPLL / 6 */ + clrsetbits_le32(&scu->clksrc1, SCU_CLKSRC1_MAC_DIV_MASK, + (0x2 << SCU_CLKSRC1_MAC_DIV_SHIFT)); + + return 0; +} + +static uint32_t ast2600_configure_mac34_clk(struct ast2600_scu *scu) +{ + /* + * scu350[31] RGMII 125M source: 0 = from IO pin + * scu350[25:0] MAC 1G delay + */ + clrsetbits_le32(&scu->mac34_clk_delay, (BIT(31) | GENMASK(25, 0)), + MAC34_DEF_DELAY_1G); + writel(MAC34_DEF_DELAY_100M, &scu->mac34_clk_delay_100M); + writel(MAC34_DEF_DELAY_10M, &scu->mac34_clk_delay_10M); + + /* + * clock source seletion and divider + * scu310[26:24] : MAC AHB bus clock = HCLK / 2 + * scu310[18:16] : RMII 50M = HCLK_200M / 4 + */ + clrsetbits_le32(&scu->clksrc4, + (SCU_CLKSRC4_MAC_DIV_MASK | SCU_CLKSRC4_RMII34_DIV_MASK), + ((0x0 << SCU_CLKSRC4_MAC_DIV_SHIFT) + | (0x3 << SCU_CLKSRC4_RMII34_DIV_SHIFT))); + + /* + * set driving strength + * scu458[3:2] : MAC4 driving strength + * scu458[1:0] : MAC3 driving strength + */ + clrsetbits_le32(&scu->pinmux16, + SCU_PINCTRL16_MAC4_DRIVING_MASK | SCU_PINCTRL16_MAC3_DRIVING_MASK, + (0x3 << SCU_PINCTRL16_MAC4_DRIVING_SHIFT) + | (0x3 << SCU_PINCTRL16_MAC3_DRIVING_SHIFT)); + + return 0; +} + +/** + * ast2600 RGMII clock source tree + * 125M from external PAD -------->|\ + * HPLL -->|\ | |---->RGMII 125M for MAC#1 & MAC#2 + * | |---->| divider |---->|/ + + * EPLL -->|/ | + * | + * +---------<-----------|RGMIICK PAD output enable|<-------------+ + * | + * +--------------------------->|\ + * | |----> RGMII 125M for MAC#3 & MAC#4 + * HCLK 200M ---->|divider|---->|/ + * To simplify the control flow: + * 1. RGMII 1/2 always use EPLL as the internal clock source + * 2. RGMII 3/4 always use RGMIICK pad as the RGMII 125M source + * 125M from external PAD -------->|\ + * | |---->RGMII 125M for MAC#1 & MAC#2 + * EPLL---->| divider |--->|/ + + * | + * +<--------------------|RGMIICK PAD output enable|<-------------+ + * | + * +--------------------------->RGMII 125M for MAC#3 & MAC#4 + */ +#define RGMIICK_SRC_PAD 0 +#define RGMIICK_SRC_EPLL 1 /* recommended */ +#define RGMIICK_SRC_HPLL 2 + +#define RGMIICK_DIV2 1 +#define RGMIICK_DIV3 2 +#define RGMIICK_DIV4 3 +#define RGMIICK_DIV5 4 +#define RGMIICK_DIV6 5 +#define RGMIICK_DIV7 6 +#define RGMIICK_DIV8 7 /* recommended */ + +#define RMIICK_DIV4 0 +#define RMIICK_DIV8 1 +#define RMIICK_DIV12 2 +#define RMIICK_DIV16 3 +#define RMIICK_DIV20 4 /* recommended */ +#define RMIICK_DIV24 5 +#define RMIICK_DIV28 6 +#define RMIICK_DIV32 7 + +struct ast2600_mac_clk_div { + uint32_t src; /* 0=external PAD, 1=internal PLL */ + uint32_t fin; /* divider input speed */ + uint32_t n; /* 0=div2, 1=div2, 2=div3, 3=div4,...,7=div8 */ + uint32_t fout; /* fout = fin / n */ +}; + +struct ast2600_mac_clk_div rgmii_clk_defconfig = { + .src = ASPEED_CLK_EPLL, + .fin = 1000000000, + .n = RGMIICK_DIV8, + .fout = 125000000, +}; + +struct ast2600_mac_clk_div rmii_clk_defconfig = { + .src = ASPEED_CLK_EPLL, + .fin = 1000000000, + .n = RMIICK_DIV20, + .fout = 50000000, +}; + +static void ast2600_init_mac_pll(struct ast2600_scu *p_scu, + struct ast2600_mac_clk_div *p_cfg) +{ + struct ast2600_pll_desc pll; + + pll.in = CLKIN_25M; + pll.out = p_cfg->fin; + if (ast2600_search_clock_config(&pll) == false) { + pr_err("unable to find valid ETHNET MAC clock setting\n"); + return; + } + ast2600_configure_pll(p_scu, &pll.cfg, p_cfg->src); +} + +static void ast2600_init_rgmii_clk(struct ast2600_scu *p_scu, + struct ast2600_mac_clk_div *p_cfg) +{ + uint32_t reg_304 = readl(&p_scu->clksrc2); + uint32_t reg_340 = readl(&p_scu->mac12_clk_delay); + uint32_t reg_350 = readl(&p_scu->mac34_clk_delay); + + reg_340 &= ~GENMASK(31, 29); + /* scu340[28]: RGMIICK PAD output enable (to MAC 3/4) */ + reg_340 |= BIT(28); + if (p_cfg->src == ASPEED_CLK_EPLL || p_cfg->src == ASPEED_CLK_HPLL) { + /* + * re-init PLL if the current PLL output frequency doesn't match + * the divider setting + */ + if (p_cfg->fin != ast2600_get_pll_rate(p_scu, p_cfg->src)) + ast2600_init_mac_pll(p_scu, p_cfg); + /* scu340[31]: select RGMII 125M from internal source */ + reg_340 |= BIT(31); + } + + reg_304 &= ~GENMASK(23, 20); + + /* set clock divider */ + reg_304 |= (p_cfg->n & 0x7) << 20; + + /* select internal clock source */ + if (p_cfg->src == ASPEED_CLK_HPLL) + reg_304 |= BIT(23); + + /* RGMII 3/4 clock source select */ + reg_350 &= ~BIT(31); + + writel(reg_304, &p_scu->clksrc2); + writel(reg_340, &p_scu->mac12_clk_delay); + writel(reg_350, &p_scu->mac34_clk_delay); +} + +/** + * ast2600 RMII/NCSI clock source tree + * HPLL -->|\ + * | |---->| divider |----> RMII 50M for MAC#1 & MAC#2 + * EPLL -->|/ + * HCLK(SCLICLK)---->| divider |----> RMII 50M for MAC#3 & MAC#4 + */ +static void ast2600_init_rmii_clk(struct ast2600_scu *p_scu, + struct ast2600_mac_clk_div *p_cfg) +{ + uint32_t clksrc2 = readl(&p_scu->clksrc2); + uint32_t clksrc4 = readl(&p_scu->clksrc4); + + if (p_cfg->src == ASPEED_CLK_EPLL || p_cfg->src == ASPEED_CLK_HPLL) { + /* + * re-init PLL if the current PLL output frequency doesn't match + * the divider setting + */ + if (p_cfg->fin != ast2600_get_pll_rate(p_scu, p_cfg->src)) + ast2600_init_mac_pll(p_scu, p_cfg); + } + + clksrc2 &= ~(SCU_CLKSRC2_RMII12 | SCU_CLKSRC2_RMII12_DIV_MASK); + + /* set RMII 1/2 clock divider */ + clksrc2 |= (p_cfg->n & 0x7) << 16; + + /* RMII clock source selection */ + if (p_cfg->src == ASPEED_CLK_HPLL) + clksrc2 |= SCU_CLKSRC2_RMII12; + + /* set RMII 3/4 clock divider */ + clksrc4 &= ~SCU_CLKSRC4_RMII34_DIV_MASK; + clksrc4 |= (0x3 << SCU_CLKSRC4_RMII34_DIV_SHIFT); + + writel(clksrc2, &p_scu->clksrc2); + writel(clksrc4, &p_scu->clksrc4); +} + +static uint32_t ast2600_configure_mac(struct ast2600_scu *scu, int index) +{ + uint32_t reset_bit; + uint32_t clkgate_bit; + + switch (index) { + case 1: + reset_bit = BIT(ASPEED_RESET_MAC1); + clkgate_bit = SCU_CLKGATE1_MAC1; + writel(reset_bit, &scu->modrst_ctrl1); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr1); + mdelay(10); + writel(reset_bit, &scu->modrst_clr1); + break; + case 2: + reset_bit = BIT(ASPEED_RESET_MAC2); + clkgate_bit = SCU_CLKGATE1_MAC2; + writel(reset_bit, &scu->modrst_ctrl1); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr1); + mdelay(10); + writel(reset_bit, &scu->modrst_clr1); + break; + case 3: + reset_bit = BIT(ASPEED_RESET_MAC3 - 32); + clkgate_bit = SCU_CLKGATE2_MAC3; + writel(reset_bit, &scu->modrst_ctrl2); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr2); + mdelay(10); + writel(reset_bit, &scu->modrst_clr2); + break; + case 4: + reset_bit = BIT(ASPEED_RESET_MAC4 - 32); + clkgate_bit = SCU_CLKGATE2_MAC4; + writel(reset_bit, &scu->modrst_ctrl2); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr2); + mdelay(10); + writel(reset_bit, &scu->modrst_clr2); + break; + default: + return -EINVAL; + } + + return 0; +} + +static void ast2600_configure_rsa_ecc_clk(struct ast2600_scu *scu) +{ + uint32_t clksrc1 = readl(&scu->clksrc1); + + /* Configure RSA clock = HPLL/3 */ + clksrc1 |= SCU_CLKSRC1_ECC_RSA; + clksrc1 &= ~SCU_CLKSRC1_ECC_RSA_DIV_MASK; + clksrc1 |= (2 << SCU_CLKSRC1_ECC_RSA_DIV_SHIFT); + + writel(clksrc1, &scu->clksrc1); +} + +static ulong ast2600_enable_sdclk(struct ast2600_scu *scu) +{ + uint32_t reset_bit; + uint32_t clkgate_bit; + + reset_bit = BIT(ASPEED_RESET_SD - 32); + clkgate_bit = SCU_CLKGATE2_SDIO; + + writel(reset_bit, &scu->modrst_ctrl2); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr2); + mdelay(10); + writel(reset_bit, &scu->modrst_clr2); + + return 0; +} + +static ulong ast2600_enable_extsdclk(struct ast2600_scu *scu) +{ + int i = 0; + uint32_t div = 0; + uint32_t rate = 0; + uint32_t clksrc4 = readl(&scu->clksrc4); + + /* + * ast2600 SD controller max clk is 200Mhz + * use apll for clock source 800/4 = 200 + * controller max is 200mhz + */ + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL); + for (i = 0; i < 8; i++) { + div = (i + 1) * 2; + if ((rate / div) <= 200000000) + break; + } + clksrc4 &= ~SCU_CLKSRC4_SDIO_DIV_MASK; + clksrc4 |= (i << SCU_CLKSRC4_SDIO_DIV_SHIFT); + clksrc4 |= SCU_CLKSRC4_SDIO; + writel(clksrc4, &scu->clksrc4); + + setbits_le32(&scu->clksrc4, SCU_CLKSRC4_SDIO_EN); + + return 0; +} + +static ulong ast2600_enable_emmcclk(struct ast2600_scu *scu) +{ + uint32_t reset_bit; + uint32_t clkgate_bit; + + reset_bit = BIT(ASPEED_RESET_EMMC); + clkgate_bit = SCU_CLKGATE1_EMMC; + + writel(reset_bit, &scu->modrst_ctrl1); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr1); + mdelay(10); + writel(reset_bit, &scu->modrst_clr1); + + return 0; +} + +static ulong ast2600_enable_extemmcclk(struct ast2600_scu *scu) +{ + int i = 0; + uint32_t div = 0; + uint32_t rate = 0; + uint32_t clksrc1 = readl(&scu->clksrc1); + + /* + * ast2600 eMMC controller max clk is 200Mhz + * HPll->1/2->|\ + * |->SCU300[11]->SCU300[14:12][1/N] + + * MPLL------>|/ | + * +----------------------------------------------+ + * | + * +---------> EMMC12C[15:8][1/N]-> eMMC clk + */ + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_MPLL); + for (i = 0; i < 8; i++) { + div = (i + 1) * 2; + if ((rate / div) <= 200000000) + break; + } + + clksrc1 &= ~SCU_CLKSRC1_EMMC_DIV_MASK; + clksrc1 |= (i << SCU_CLKSRC1_EMMC_DIV_SHIFT); + clksrc1 |= SCU_CLKSRC1_EMMC; + writel(clksrc1, &scu->clksrc1); + + setbits_le32(&scu->clksrc1, SCU_CLKSRC1_EMMC_EN); + + return 0; +} + +static ulong ast2600_enable_fsiclk(struct ast2600_scu *scu) +{ + uint32_t reset_bit; + uint32_t clkgate_bit; + + reset_bit = BIT(ASPEED_RESET_FSI % 32); + clkgate_bit = SCU_CLKGATE2_FSI; + + /* The FSI clock is shared between masters. If it's already on + * don't touch it, as that will reset the existing master. + */ + if (!(readl(&scu->clkgate_ctrl2) & clkgate_bit)) { + debug("%s: already running, not touching it\n", __func__); + return 0; + } + + writel(reset_bit, &scu->modrst_ctrl2); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr2); + mdelay(10); + writel(reset_bit, &scu->modrst_clr2); + + return 0; +} + +static ulong ast2600_enable_usbahclk(struct ast2600_scu *scu) +{ + uint32_t reset_bit; + uint32_t clkgate_bit; + + reset_bit = BIT(ASPEED_RESET_EHCI_P1); + clkgate_bit = SCU_CLKGATE1_USB_HUB; + + writel(reset_bit, &scu->modrst_ctrl1); + udelay(100); + writel(clkgate_bit, &scu->clkgate_ctrl1); + mdelay(20); + writel(reset_bit, &scu->modrst_clr1); + + return 0; +} + +static ulong ast2600_enable_usbbhclk(struct ast2600_scu *scu) +{ + uint32_t reset_bit; + uint32_t clkgate_bit; + + reset_bit = BIT(ASPEED_RESET_EHCI_P2); + clkgate_bit = SCU_CLKGATE1_USB_HOST2; + + writel(reset_bit, &scu->modrst_ctrl1); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr1); + mdelay(20); + writel(reset_bit, &scu->modrst_clr1); + + return 0; +} + +static int ast2600_clk_enable(struct clk *clk) +{ + struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); + + switch (clk->id) { + case ASPEED_CLK_GATE_MAC1CLK: + ast2600_configure_mac(priv->scu, 1); + break; + case ASPEED_CLK_GATE_MAC2CLK: + ast2600_configure_mac(priv->scu, 2); + break; + case ASPEED_CLK_GATE_MAC3CLK: + ast2600_configure_mac(priv->scu, 3); + break; + case ASPEED_CLK_GATE_MAC4CLK: + ast2600_configure_mac(priv->scu, 4); + break; + case ASPEED_CLK_GATE_SDCLK: + ast2600_enable_sdclk(priv->scu); + break; + case ASPEED_CLK_GATE_SDEXTCLK: + ast2600_enable_extsdclk(priv->scu); + break; + case ASPEED_CLK_GATE_EMMCCLK: + ast2600_enable_emmcclk(priv->scu); + break; + case ASPEED_CLK_GATE_EMMCEXTCLK: + ast2600_enable_extemmcclk(priv->scu); + break; + case ASPEED_CLK_GATE_FSICLK: + ast2600_enable_fsiclk(priv->scu); + break; + case ASPEED_CLK_GATE_USBPORT1CLK: + ast2600_enable_usbahclk(priv->scu); + break; + case ASPEED_CLK_GATE_USBPORT2CLK: + ast2600_enable_usbbhclk(priv->scu); + break; + default: + pr_err("can't enable clk\n"); + return -ENOENT; + } + + return 0; +} + +struct clk_ops ast2600_clk_ops = { + .get_rate = ast2600_clk_get_rate, + .set_rate = ast2600_clk_set_rate, + .enable = ast2600_clk_enable, +}; + +static int ast2600_clk_probe(struct udevice *dev) +{ + struct ast2600_clk_priv *priv = dev_get_priv(dev); + + priv->scu = devfdt_get_addr_ptr(dev); + if (IS_ERR(priv->scu)) + return PTR_ERR(priv->scu); + + ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); + ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); + ast2600_configure_mac12_clk(priv->scu); + ast2600_configure_mac34_clk(priv->scu); + ast2600_configure_rsa_ecc_clk(priv->scu); + + return 0; +} + +static int ast2600_clk_bind(struct udevice *dev) +{ + int ret; + + /* The reset driver does not have a device node, so bind it here */ + ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); + if (ret) + debug("Warning: No reset driver: ret=%d\n", ret); + + return 0; +} + +struct aspeed_clks { + ulong id; + const char *name; +}; + +static struct aspeed_clks aspeed_clk_names[] = { + { ASPEED_CLK_HPLL, "hpll" }, + { ASPEED_CLK_MPLL, "mpll" }, + { ASPEED_CLK_APLL, "apll" }, + { ASPEED_CLK_EPLL, "epll" }, + { ASPEED_CLK_DPLL, "dpll" }, + { ASPEED_CLK_AHB, "hclk" }, + { ASPEED_CLK_APB1, "pclk1" }, + { ASPEED_CLK_APB2, "pclk2" }, + { ASPEED_CLK_BCLK, "bclk" }, + { ASPEED_CLK_UARTX, "uxclk" }, + { ASPEED_CLK_HUARTX, "huxclk" }, +}; + +int soc_clk_dump(void) +{ + struct udevice *dev; + struct clk clk; + unsigned long rate; + int i, ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu), + &dev); + if (ret) + return ret; + + printf("Clk\t\tHz\n"); + + for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) { + clk.id = aspeed_clk_names[i].id; + ret = clk_request(dev, &clk); + if (ret < 0) { + debug("%s clk_request() failed: %d\n", __func__, ret); + continue; + } + + ret = clk_get_rate(&clk); + rate = ret; + + clk_free(&clk); + + if (ret == -ENOTSUPP) { + printf("clk ID %lu not supported yet\n", + aspeed_clk_names[i].id); + continue; + } + if (ret < 0) { + printf("%s %lu: get_rate err: %d\n", __func__, + aspeed_clk_names[i].id, ret); + continue; + } + + printf("%s(%3lu):\t%lu\n", aspeed_clk_names[i].name, + aspeed_clk_names[i].id, rate); + } + + return 0; +} + +static const struct udevice_id ast2600_clk_ids[] = { + { .compatible = "aspeed,ast2600-scu", }, + { }, +}; + +U_BOOT_DRIVER(aspeed_ast2600_scu) = { + .name = "aspeed_ast2600_scu", + .id = UCLASS_CLK, + .of_match = ast2600_clk_ids, + .priv_auto = sizeof(struct ast2600_clk_priv), + .ops = &ast2600_clk_ops, + .bind = ast2600_clk_bind, + .probe = ast2600_clk_probe, +}; diff --git a/include/dt-bindings/clock/ast2600-clock.h b/include/dt-bindings/clock/ast2600-clock.h new file mode 100644 index 00000000000..36294a5140b --- /dev/null +++ b/include/dt-bindings/clock/ast2600-clock.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) ASPEED Technology Inc. + */ + +#define ASPEED_CLK_GATE_ECLK 0 +#define ASPEED_CLK_GATE_GCLK 1 +#define ASPEED_CLK_GATE_MCLK 2 +#define ASPEED_CLK_GATE_VCLK 3 +#define ASPEED_CLK_GATE_BCLK 4 +#define ASPEED_CLK_GATE_DCLK 5 +#define ASPEED_CLK_GATE_LCLK 6 +#define ASPEED_CLK_GATE_YCLK 7 +#define ASPEED_CLK_GATE_LHCCLK 8 +#define ASPEED_CLK_GATE_REFCLK 9 +#define ASPEED_CLK_GATE_ESPICLK 10 +#define ASPEED_CLK_GATE_UART1CLK 11 +#define ASPEED_CLK_GATE_UART2CLK 12 +#define ASPEED_CLK_GATE_UART3CLK 13 +#define ASPEED_CLK_GATE_UART4CLK 14 +#define ASPEED_CLK_GATE_UART5CLK 15 +#define ASPEED_CLK_GATE_UART6CLK 16 +#define ASPEED_CLK_GATE_UART7CLK 17 +#define ASPEED_CLK_GATE_UART8CLK 18 +#define ASPEED_CLK_GATE_UART9CLK 19 +#define ASPEED_CLK_GATE_UART10CLK 20 +#define ASPEED_CLK_GATE_UART11CLK 21 +#define ASPEED_CLK_GATE_UART12CLK 22 +#define ASPEED_CLK_GATE_UART13CLK 23 +#define ASPEED_CLK_GATE_MAC1CLK 24 +#define ASPEED_CLK_GATE_MAC2CLK 25 +#define ASPEED_CLK_GATE_MAC3CLK 26 +#define ASPEED_CLK_GATE_MAC4CLK 27 +#define ASPEED_CLK_GATE_RSACLK 28 +#define ASPEED_CLK_GATE_SDCLK 29 +#define ASPEED_CLK_GATE_SDEXTCLK 30 +#define ASPEED_CLK_GATE_EMMCCLK 31 +#define ASPEED_CLK_GATE_EMMCEXTCLK 32 +#define ASPEED_CLK_GATE_USBUHCICLK 33 +#define ASPEED_CLK_GATE_USBPORT1CLK 34 +#define ASPEED_CLK_GATE_USBPORT2CLK 35 +#define ASPEED_CLK_GATE_FSICLK 36 + +#define ASPEED_CLK_APLL 37 +#define ASPEED_CLK_EPLL 38 +#define ASPEED_CLK_DPLL 39 +#define ASPEED_CLK_HPLL 40 +#define ASPEED_CLK_AHB 41 +#define ASPEED_CLK_APB1 42 +#define ASPEED_CLK_APB2 43 +#define ASPEED_CLK_UART 44 +#define ASPEED_CLK_SDIO 45 +#define ASPEED_CLK_ECLK 46 +#define ASPEED_CLK_ECLK_MUX 47 +#define ASPEED_CLK_LHCLK 48 +#define ASPEED_CLK_MAC 49 +#define ASPEED_CLK_BCLK 50 +#define ASPEED_CLK_MPLL 51 +#define ASPEED_CLK_24M 52 +#define ASPEED_CLK_EMMC 53 +#define ASPEED_CLK_UARTX 54 +#define ASPEED_CLK_HUARTX 55 -- cgit v1.3.1 From 9fc21086b7fe7aa5ca328bb290c4cd78aeab6eaf Mon Sep 17 00:00:00 2001 From: "Chia-Wei, Wang" Date: Mon, 14 Dec 2020 13:54:26 +0800 Subject: reset: aspeed: Add AST2600 reset support Add controller reset support through the System Control Unit (SCU) of AST2600 SoC. Signed-off-by: Chia-Wei, Wang Reviewed-by: Ryan Chen --- drivers/reset/Kconfig | 9 +++ drivers/reset/Makefile | 1 + drivers/reset/reset-ast2600.c | 108 ++++++++++++++++++++++++++++++ include/dt-bindings/reset/ast2600-reset.h | 70 +++++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 drivers/reset/reset-ast2600.c create mode 100644 include/dt-bindings/reset/ast2600-reset.h (limited to 'include') diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 33c2736554e..f5b3f8826fb 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -81,6 +81,15 @@ config RESET_AST2500 Say Y if you want to control reset signals of different peripherals through System Control Unit (SCU). +config RESET_AST2600 + bool "Reset controller driver for AST2600 SoCs" + depends on DM_RESET + default y if ASPEED_AST2600 + help + Support for reset controller on AST2600 SoC. + Say Y if you want to control reset signals of different peripherals + through System Control Unit (SCU). + config RESET_ROCKCHIP bool "Reset controller driver for Rockchip SoCs" depends on DM_RESET && ARCH_ROCKCHIP && CLK diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index fa52aa33291..8a0f5280761 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o obj-$(CONFIG_RESET_AST2500) += reset-ast2500.o +obj-$(CONFIG_RESET_AST2600) += reset-ast2600.o obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o obj-$(CONFIG_RESET_MESON) += reset-meson.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o diff --git a/drivers/reset/reset-ast2600.c b/drivers/reset/reset-ast2600.c new file mode 100644 index 00000000000..f64adaf74e8 --- /dev/null +++ b/drivers/reset/reset-ast2600.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2020 ASPEED Technology Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ast2600_reset_priv { + struct ast2600_scu *scu; +}; + +static int ast2600_reset_request(struct reset_ctl *reset_ctl) +{ + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, + reset_ctl->dev, reset_ctl->id); + + return 0; +} + +static int ast2600_reset_free(struct reset_ctl *reset_ctl) +{ + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, + reset_ctl->dev, reset_ctl->id); + + return 0; +} + +static int ast2600_reset_assert(struct reset_ctl *reset_ctl) +{ + struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev); + struct ast2600_scu *scu = priv->scu; + + debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); + + if (reset_ctl->id < 32) + writel(BIT(reset_ctl->id), scu->modrst_ctrl1); + else + writel(BIT(reset_ctl->id - 32), scu->modrst_ctrl2); + + return 0; +} + +static int ast2600_reset_deassert(struct reset_ctl *reset_ctl) +{ + struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev); + struct ast2600_scu *scu = priv->scu; + + debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); + + if (reset_ctl->id < 32) + writel(BIT(reset_ctl->id), scu->modrst_clr1); + else + writel(BIT(reset_ctl->id - 32), scu->modrst_clr2); + + return 0; +} + +static int ast2600_reset_probe(struct udevice *dev) +{ + int rc; + struct ast2600_reset_priv *priv = dev_get_priv(dev); + struct udevice *scu_dev; + + /* get SCU base from clock device */ + rc = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(aspeed_ast2600_scu), &scu_dev); + if (rc) { + debug("%s: clock device not found, rc=%d\n", __func__, rc); + return rc; + } + + priv->scu = devfdt_get_addr_ptr(scu_dev); + if (IS_ERR_OR_NULL(priv->scu)) { + debug("%s: invalid SCU base pointer\n", __func__); + return PTR_ERR(priv->scu); + } + + return 0; +} + +static const struct udevice_id ast2600_reset_ids[] = { + { .compatible = "aspeed,ast2600-reset" }, + { } +}; + +struct reset_ops ast2600_reset_ops = { + .request = ast2600_reset_request, + .rfree = ast2600_reset_free, + .rst_assert = ast2600_reset_assert, + .rst_deassert = ast2600_reset_deassert, +}; + +U_BOOT_DRIVER(ast2600_reset) = { + .name = "ast2600_reset", + .id = UCLASS_RESET, + .of_match = ast2600_reset_ids, + .probe = ast2600_reset_probe, + .ops = &ast2600_reset_ops, + .priv_auto = sizeof(struct ast2600_reset_priv), +}; diff --git a/include/dt-bindings/reset/ast2600-reset.h b/include/dt-bindings/reset/ast2600-reset.h new file mode 100644 index 00000000000..b6d0f79917a --- /dev/null +++ b/include/dt-bindings/reset/ast2600-reset.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) ASPEED Technology Inc. + */ + +#ifndef _ABI_MACH_ASPEED_AST2600_RESET_H_ +#define _ABI_MACH_ASPEED_AST2600_RESET_H_ + +#define ASPEED_RESET_FSI (59) +#define ASPEED_RESET_RESERVED58 (58) +#define ASPEED_RESET_RESERVED57 (57) +#define ASPEED_RESET_SD (56) +#define ASPEED_RESET_ADC (55) +#define ASPEED_RESET_JTAG_MASTER2 (54) +#define ASPEED_RESET_MAC4 (53) +#define ASPEED_RESET_MAC3 (52) +#define ASPEED_RESET_RESERVE51 (51) +#define ASPEED_RESET_RESERVE50 (50) +#define ASPEED_RESET_RESERVE49 (49) +#define ASPEED_RESET_RESERVE48 (48) +#define ASPEED_RESET_RESERVE47 (47) +#define ASPEED_RESET_RESERVE46 (46) +#define ASPEED_RESET_I3C5 (45) +#define ASPEED_RESET_I3C4 (44) +#define ASPEED_RESET_I3C3 (43) +#define ASPEED_RESET_I3C2 (42) +#define ASPEED_RESET_I3C1 (41) +#define ASPEED_RESET_I3C0 (40) +#define ASPEED_RESET_I3C_DMA (39) +#define ASPEED_RESET_RESERVED38 (38) +#define ASPEED_RESET_PWM (37) +#define ASPEED_RESET_PECI (36) +#define ASPEED_RESET_MII (35) +#define ASPEED_RESET_I2C (34) +#define ASPEED_RESET_RESERVED33 (33) +#define ASPEED_RESET_LPC_ESPI (32) +#define ASPEED_RESET_H2X (31) +#define ASPEED_RESET_GP_MCU (30) +#define ASPEED_RESET_DP_MCU (29) +#define ASPEED_RESET_DP (28) +#define ASPEED_RESET_RC_XDMA (27) +#define ASPEED_RESET_GRAPHICS (26) +#define ASPEED_RESET_DEV_XDMA (25) +#define ASPEED_RESET_DEV_MCTP (24) +#define ASPEED_RESET_RC_MCTP (23) +#define ASPEED_RESET_JTAG_MASTER (22) +#define ASPEED_RESET_PCIE_DEV_OE (21) +#define ASPEED_RESET_PCIE_DEV_O (20) +#define ASPEED_RESET_PCIE_RC_OE (19) +#define ASPEED_RESET_PCIE_RC_O (18) +#define ASPEED_RESET_RESERVED17 (17) +#define ASPEED_RESET_EMMC (16) +#define ASPEED_RESET_UHCI (15) +#define ASPEED_RESET_EHCI_P1 (14) +#define ASPEED_RESET_CRT (13) +#define ASPEED_RESET_MAC2 (12) +#define ASPEED_RESET_MAC1 (11) +#define ASPEED_RESET_RESERVED10 (10) +#define ASPEED_RESET_RVAS (9) +#define ASPEED_RESET_PCI_VGA (8) +#define ASPEED_RESET_2D (7) +#define ASPEED_RESET_VIDEO (6) +#define ASPEED_RESET_PCI_DP (5) +#define ASPEED_RESET_HACE (4) +#define ASPEED_RESET_EHCI_P2 (3) +#define ASPEED_RESET_RESERVED2 (2) +#define ASPEED_RESET_AHB (1) +#define ASPEED_RESET_SDRAM (0) + +#endif /* _ABI_MACH_ASPEED_AST2600_RESET_H_ */ -- cgit v1.3.1 From 4a84cf06aa05b10b31b876e6d6f43168945213af Mon Sep 17 00:00:00 2001 From: "Chia-Wei, Wang" Date: Mon, 14 Dec 2020 13:54:28 +0800 Subject: aspeed: Add AST2600 platform support Add low level platform initialization for the AST2600 SoC. The 2-stage booting with U-Boot SPL are leveraged to support different booting mode. However, currently the patch supports only the booting from memory-mapped SPI flash. Signed-off-by: Chia-Wei, Wang Reviewed-by: Ryan Chen --- arch/arm/include/asm/arch-aspeed/boot0.h | 23 +++ arch/arm/include/asm/arch-aspeed/platform.h | 5 + arch/arm/mach-aspeed/Kconfig | 20 +++ arch/arm/mach-aspeed/Makefile | 1 + arch/arm/mach-aspeed/ast2600/Kconfig | 17 ++ arch/arm/mach-aspeed/ast2600/Makefile | 2 + arch/arm/mach-aspeed/ast2600/board_common.c | 105 ++++++++++++ arch/arm/mach-aspeed/ast2600/lowlevel_init.S | 233 +++++++++++++++++++++++++++ arch/arm/mach-aspeed/ast2600/spl.c | 55 +++++++ board/aspeed/evb_ast2600/Kconfig | 12 ++ board/aspeed/evb_ast2600/Makefile | 1 + board/aspeed/evb_ast2600/evb_ast2600.c | 5 + drivers/sysreset/sysreset_ast.c | 5 + include/configs/evb_ast2600.h | 16 ++ 14 files changed, 500 insertions(+) create mode 100644 arch/arm/include/asm/arch-aspeed/boot0.h create mode 100644 arch/arm/mach-aspeed/ast2600/Kconfig create mode 100644 arch/arm/mach-aspeed/ast2600/Makefile create mode 100644 arch/arm/mach-aspeed/ast2600/board_common.c create mode 100644 arch/arm/mach-aspeed/ast2600/lowlevel_init.S create mode 100644 arch/arm/mach-aspeed/ast2600/spl.c create mode 100644 board/aspeed/evb_ast2600/Kconfig create mode 100644 board/aspeed/evb_ast2600/Makefile create mode 100644 board/aspeed/evb_ast2600/evb_ast2600.c create mode 100644 include/configs/evb_ast2600.h (limited to 'include') diff --git a/arch/arm/include/asm/arch-aspeed/boot0.h b/arch/arm/include/asm/arch-aspeed/boot0.h new file mode 100644 index 00000000000..368becc87ab --- /dev/null +++ b/arch/arm/include/asm/arch-aspeed/boot0.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) Aspeed Technology Inc. + */ + +#ifndef _ASM_ARCH_BOOT0_H +#define _ASM_ARCH_BOOT0_H + +_start: + ARM_VECTORS + + .word 0x0 /* key location */ + .word 0x0 /* start address of image */ + .word 0xfc00 /* maximum image size: 63KB */ + .word 0x0 /* signature address */ + .word 0x0 /* header revision ID low */ + .word 0x0 /* header revision ID high */ + .word 0x0 /* reserved */ + .word 0x0 /* checksum */ + .word 0x0 /* BL2 secure header */ + .word 0x0 /* public key or digest offset for BL2 */ + +#endif diff --git a/arch/arm/include/asm/arch-aspeed/platform.h b/arch/arm/include/asm/arch-aspeed/platform.h index 6cee036f54c..d50ec5f8a9f 100644 --- a/arch/arm/include/asm/arch-aspeed/platform.h +++ b/arch/arm/include/asm/arch-aspeed/platform.h @@ -13,6 +13,11 @@ #define ASPEED_DRAM_BASE 0x80000000 #define ASPEED_SRAM_BASE 0x1e720000 #define ASPEED_SRAM_SIZE 0x9000 +#elif defined(CONFIG_ASPEED_AST2600) +#define ASPEED_MAC_COUNT 4 +#define ASPEED_DRAM_BASE 0x80000000 +#define ASPEED_SRAM_BASE 0x10000000 +#define ASPEED_SRAM_SIZE 0x10000 #else #err "Unrecognized Aspeed platform." #endif diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig index 4f021baa062..9a725f195a3 100644 --- a/arch/arm/mach-aspeed/Kconfig +++ b/arch/arm/mach-aspeed/Kconfig @@ -9,6 +9,11 @@ config SYS_SOC config SYS_TEXT_BASE default 0x00000000 +choice + prompt "Aspeed SoC select" + depends on ARCH_ASPEED + default ASPEED_AST2500 + config ASPEED_AST2500 bool "Support Aspeed AST2500 SoC" depends on DM_RESET @@ -18,6 +23,21 @@ config ASPEED_AST2500 It is used as Board Management Controller on many server boards, which is enabled by support of LPC and eSPI peripherals. +config ASPEED_AST2600 + bool "Support Aspeed AST2600 SoC" + select CPU_V7A + select CPU_V7_HAS_NONSEC + select SYS_ARCH_TIMER + select SUPPORT_SPL + select ENABLE_ARM_SOC_BOOT0_HOOK + help + The Aspeed AST2600 is a ARM-based SoC with Cortex-A7 CPU. + It is used as Board Management Controller on many server boards, + which is enabled by support of LPC and eSPI peripherals. + +endchoice + source "arch/arm/mach-aspeed/ast2500/Kconfig" +source "arch/arm/mach-aspeed/ast2600/Kconfig" endif diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile index 33f65b50b28..42599c125b8 100644 --- a/arch/arm/mach-aspeed/Makefile +++ b/arch/arm/mach-aspeed/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o obj-$(CONFIG_ASPEED_AST2500) += ast2500/ +obj-$(CONFIG_ASPEED_AST2600) += ast2600/ diff --git a/arch/arm/mach-aspeed/ast2600/Kconfig b/arch/arm/mach-aspeed/ast2600/Kconfig new file mode 100644 index 00000000000..f3a53387a16 --- /dev/null +++ b/arch/arm/mach-aspeed/ast2600/Kconfig @@ -0,0 +1,17 @@ +if ASPEED_AST2600 + +config SYS_CPU + default "armv7" + +config TARGET_EVB_AST2600 + bool "EVB-AST2600" + depends on ASPEED_AST2600 + help + EVB-AST2600 is Aspeed evaluation board for AST2600A0 chip. + It has 512M of RAM, 32M of SPI flash, two Ethernet ports, + 4 Serial ports, 4 USB ports, VGA port, PCIe, SD card slot, + 20 pin JTAG, pinouts for 14 I2Cs, 3 SPIs and eSPI, 8 PWMs. + +source "board/aspeed/evb_ast2600/Kconfig" + +endif diff --git a/arch/arm/mach-aspeed/ast2600/Makefile b/arch/arm/mach-aspeed/ast2600/Makefile new file mode 100644 index 00000000000..448d3201aff --- /dev/null +++ b/arch/arm/mach-aspeed/ast2600/Makefile @@ -0,0 +1,2 @@ +obj-y += lowlevel_init.o board_common.o +obj-$(CONFIG_SPL_BUILD) += spl.o diff --git a/arch/arm/mach-aspeed/ast2600/board_common.c b/arch/arm/mach-aspeed/ast2600/board_common.c new file mode 100644 index 00000000000..a53e1632f6c --- /dev/null +++ b/arch/arm/mach-aspeed/ast2600/board_common.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) Aspeed Technology Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* Memory Control registers */ +#define MCR_BASE 0x1e6e0000 +#define MCR_CONF (MCR_BASE + 0x004) + +/* bit fields of MCR_CONF */ +#define MCR_CONF_ECC_EN BIT(7) +#define MCR_CONF_VGA_MEMSZ_MASK GENMASK(3, 2) +#define MCR_CONF_VGA_MEMSZ_SHIFT 2 +#define MCR_CONF_MEMSZ_MASK GENMASK(1, 0) +#define MCR_CONF_MEMSZ_SHIFT 0 + +int dram_init(void) +{ + int ret; + struct udevice *dev; + struct ram_info ram; + + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) { + debug("cannot get DRAM driver\n"); + return ret; + } + + ret = ram_get_info(dev, &ram); + if (ret) { + debug("cannot get DRAM information\n"); + return ret; + } + + gd->ram_size = ram.size; + return 0; +} + +int board_init(void) +{ + int i = 0, rc; + struct udevice *dev; + + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + + while (1) { + rc = uclass_get_device(UCLASS_MISC, i++, &dev); + if (rc) + break; + } + + return 0; +} + +void board_add_ram_info(int use_default) +{ + int rc; + uint32_t conf; + uint32_t ecc, act_size, vga_rsvd; + struct udevice *scu_dev; + struct ast2600_scu *scu; + + rc = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(aspeed_ast2600_scu), &scu_dev); + if (rc) { + debug("%s: cannot find SCU device, rc=%d\n", __func__, rc); + return; + } + + scu = devfdt_get_addr_ptr(scu_dev); + if (IS_ERR_OR_NULL(scu)) { + debug("%s: cannot get SCU address pointer\n", __func__); + return; + } + + conf = readl(MCR_CONF); + + ecc = conf & MCR_CONF_ECC_EN; + act_size = 0x100 << ((conf & MCR_CONF_MEMSZ_MASK) >> MCR_CONF_MEMSZ_SHIFT); + vga_rsvd = 0x8 << ((conf & MCR_CONF_VGA_MEMSZ_MASK) >> MCR_CONF_VGA_MEMSZ_SHIFT); + + /* no VGA reservation if efuse VGA disable bit is set */ + if (readl(scu->efuse) & SCU_EFUSE_DIS_VGA) + vga_rsvd = 0; + + printf(" (capacity:%d MiB, VGA:%d MiB), ECC %s", act_size, + vga_rsvd, (ecc) ? "on" : "off"); +} + +void enable_caches(void) +{ + /* get rid of the warning message */ +} diff --git a/arch/arm/mach-aspeed/ast2600/lowlevel_init.S b/arch/arm/mach-aspeed/ast2600/lowlevel_init.S new file mode 100644 index 00000000000..594963d039d --- /dev/null +++ b/arch/arm/mach-aspeed/ast2600/lowlevel_init.S @@ -0,0 +1,233 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) ASPEED Technology Inc. + */ +#include +#include +#include +#include + +/* SCU register offsets */ +#define SCU_BASE 0x1e6e2000 +#define SCU_PROT_KEY1 (SCU_BASE + 0x000) +#define SCU_PROT_KEY2 (SCU_BASE + 0x010) +#define SCU_SMP_BOOT (SCU_BASE + 0x180) +#define SCU_HWSTRAP1 (SCU_BASE + 0x510) +#define SCU_CA7_PARITY_CHK (SCU_BASE + 0x820) +#define SCU_CA7_PARITY_CLR (SCU_BASE + 0x824) +#define SCU_MMIO_DEC (SCU_BASE + 0xc24) + +/* FMC SPI register offsets */ +#define FMC_BASE 0x1e620000 +#define FMC_CE0_CTRL (FMC_BASE + 0x010) +#define FMC_SW_RST_CTRL (FMC_BASE + 0x050) +#define FMC_WDT1_CTRL_MODE (FMC_BASE + 0x060) +#define FMC_WDT2_CTRL_MODE (FMC_BASE + 0x064) + +/* + * The SMP mailbox provides a space with few instructions in it + * for secondary cores to execute on and wait for the signal of + * SMP core bring up. + * + * SMP mailbox + * +----------------------+ + * | | + * | mailbox insn. for | + * | cpuN polling SMP go | + * | | + * +----------------------+ 0xC + * | mailbox ready signal | + * +----------------------+ 0x8 + * | cpuN GO signal | + * +----------------------+ 0x4 + * | cpuN entrypoint | + * +----------------------+ SMP_MAILBOX_BASE + */ +#define SMP_MBOX_BASE (SCU_SMP_BOOT) +#define SMP_MBOX_FIELD_ENTRY (SMP_MBOX_BASE + 0x0) +#define SMP_MBOX_FIELD_GOSIGN (SMP_MBOX_BASE + 0x4) +#define SMP_MBOX_FIELD_READY (SMP_MBOX_BASE + 0x8) +#define SMP_MBOX_FIELD_POLLINSN (SMP_MBOX_BASE + 0xc) + +.macro scu_unlock + movw r0, #(SCU_UNLOCK_KEY & 0xffff) + movt r0, #(SCU_UNLOCK_KEY >> 16) + + ldr r1, =SCU_PROT_KEY1 + str r0, [r1] + ldr r1, =SCU_PROT_KEY2 + str r0, [r1] +.endm + +.macro timer_init + ldr r1, =SCU_HWSTRAP1 + ldr r1, [r1] + and r1, #0x700 + lsr r1, #0x8 + + /* 1.2GHz */ + cmp r1, #0x0 + movweq r0, #0x8c00 + movteq r0, #0x4786 + + /* 1.6GHz */ + cmp r1, #0x1 + movweq r0, #0x1000 + movteq r0, #0x5f5e + + /* 1.2GHz */ + cmp r1, #0x2 + movweq r0, #0x8c00 + movteq r0, #0x4786 + + /* 1.6GHz */ + cmp r1, #0x3 + movweq r0, #0x1000 + movteq r0, #0x5f5e + + /* 800MHz */ + cmp r1, #0x4 + movwge r0, #0x0800 + movtge r0, #0x2faf + + mcr p15, 0, r0, c14, c0, 0 @; update CNTFRQ +.endm + + +.globl lowlevel_init + +lowlevel_init: +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) + mov pc, lr +#else + /* setup ARM arch timer frequency */ + timer_init + + /* reset SMP mailbox as early as possible */ + mov r0, #0x0 + ldr r1, =SMP_MBOX_FIELD_READY + str r0, [r1] + + /* set ACTLR.SMP to enable cache use */ + mrc p15, 0, r0, c1, c0, 1 + orr r0, #0x40 + mcr p15, 0, r0, c1, c0, 1 + + /* + * we treat cpu0 as the primary core and + * put secondary core (cpuN) to sleep + */ + mrc p15, 0, r0, c0, c0, 5 @; Read CPU ID register + ands r0, #0xff @; Mask off, leaving the CPU ID field + movw r2, #0xab00 + movt r2, #0xabba + orr r2, r0 + + beq do_primary_core_setup + + /* hold cpuN until mailbox is ready */ +poll_mailbox_ready: + wfe + ldr r0, =SMP_MBOX_FIELD_READY + ldr r0, [r0] + movw r1, #0xcafe + movt r1, #0xbabe + cmp r1, r0 + bne poll_mailbox_ready + + /* parameters for relocated SMP go polling insn. */ + ldr r0, =SMP_MBOX_FIELD_GOSIGN + ldr r1, =SMP_MBOX_FIELD_ENTRY + + /* no return */ + ldr pc, =SMP_MBOX_FIELD_POLLINSN + +do_primary_core_setup: + scu_unlock + + /* MMIO decode setting */ + ldr r0, =SCU_MMIO_DEC + mov r1, #0x2000 + str r1, [r0] + + /* enable CA7 cache parity check */ + mov r0, #0 + ldr r1, =SCU_CA7_PARITY_CLR + str r0, [r1] + + mov r0, #0x1 + ldr r1, =SCU_CA7_PARITY_CHK + str r0, [r1] + + /* do not fill FMC50[1] if boot from eMMC */ + ldr r0, =SCU_HWSTRAP1 + ldr r1, [r0] + ands r1, #0x04 + bne skip_fill_wip_bit + + /* fill FMC50[1] for waiting WIP idle */ + mov r0, #0x02 + ldr r1, =FMC_SW_RST_CTRL + str r0, [r1] + +skip_fill_wip_bit: + /* disable FMC WDT for SPI address mode detection */ + mov r0, #0 + ldr r1, =FMC_WDT1_CTRL_MODE + str r0, [r1] + + /* relocate mailbox insn. for cpuN polling SMP go signal */ + adrl r0, mailbox_insn + adrl r1, mailbox_insn_end + + ldr r2, =#SMP_MBOX_FIELD_POLLINSN + +relocate_mailbox_insn: + ldr r3, [r0], #0x4 + str r3, [r2], #0x4 + cmp r0, r1 + bne relocate_mailbox_insn + + /* reset SMP go sign */ + mov r0, #0 + ldr r1, =SMP_MBOX_FIELD_GOSIGN + str r0, [r1] + + /* notify cpuN mailbox is ready */ + movw r0, #0xCAFE + movt r0, #0xBABE + ldr r1, =SMP_MBOX_FIELD_READY + str r0, [r1] + sev + + /* back to arch calling code */ + mov pc, lr + +/* + * insn. inside mailbox to poll SMP go signal. + * + * Note that as this code will be relocated, any + * pc-relative assembly should NOT be used. + */ +mailbox_insn: + /* + * r0 ~ r3 are parameters: + * r0 = SMP_MBOX_FIELD_GOSIGN + * r1 = SMP_MBOX_FIELD_ENTRY + * r2 = per-cpu go sign value + * r3 = no used now + */ +poll_mailbox_smp_go: + wfe + ldr r4, [r0] + cmp r2, r4 + bne poll_mailbox_smp_go + + /* SMP GO signal confirmed, release cpuN */ + ldr pc, [r1] + +mailbox_insn_end: + /* should never reach */ + b . + +#endif diff --git a/arch/arm/mach-aspeed/ast2600/spl.c b/arch/arm/mach-aspeed/ast2600/spl.c new file mode 100644 index 00000000000..9201d4a4d44 --- /dev/null +++ b/arch/arm/mach-aspeed/ast2600/spl.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) Aspeed Technology Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +void board_init_f(ulong dummy) +{ + spl_early_init(); + preloader_console_init(); + timer_init(); + dram_init(); +} + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_RAM; +} + +struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +{ + /* + * When boot from SPI, AST2600 already remap 0x00000000 ~ 0x0fffffff + * to BMC SPI memory space 0x20000000 ~ 0x2fffffff. The next stage BL + * has been located in SPI for XIP. In this case, the load buffer for + * SPL image loading will be set to the remapped address of the next + * BL instead of the DRAM space CONFIG_SYS_LOAD_ADDR + */ + return (struct image_header *)(CONFIG_SYS_TEXT_BASE); +} + +#ifdef CONFIG_SPL_OS_BOOT +int spl_start_uboot(void) +{ + /* boot linux */ + return 0; +} +#endif + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* just empty function now - can't decide what to choose */ + debug("%s: %s\n", __func__, name); + return 0; +} +#endif diff --git a/board/aspeed/evb_ast2600/Kconfig b/board/aspeed/evb_ast2600/Kconfig new file mode 100644 index 00000000000..42008cd0335 --- /dev/null +++ b/board/aspeed/evb_ast2600/Kconfig @@ -0,0 +1,12 @@ +if TARGET_EVB_AST2600 + +config SYS_BOARD + default "evb_ast2600" + +config SYS_VENDOR + default "aspeed" + +config SYS_CONFIG_NAME + default "evb_ast2600" + +endif diff --git a/board/aspeed/evb_ast2600/Makefile b/board/aspeed/evb_ast2600/Makefile new file mode 100644 index 00000000000..9291db6ee10 --- /dev/null +++ b/board/aspeed/evb_ast2600/Makefile @@ -0,0 +1 @@ +obj-y += evb_ast2600.o diff --git a/board/aspeed/evb_ast2600/evb_ast2600.c b/board/aspeed/evb_ast2600/evb_ast2600.c new file mode 100644 index 00000000000..e6dc8c79525 --- /dev/null +++ b/board/aspeed/evb_ast2600/evb_ast2600.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) Aspeed Technology Inc. + */ +#include diff --git a/drivers/sysreset/sysreset_ast.c b/drivers/sysreset/sysreset_ast.c index ee941c77706..d747ed00a7f 100644 --- a/drivers/sysreset/sysreset_ast.c +++ b/drivers/sysreset/sysreset_ast.c @@ -12,6 +12,7 @@ #include #include #include +#include static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type) { @@ -33,11 +34,15 @@ static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type) return -EPROTONOSUPPORT; } +#if !defined(CONFIG_SPL_BUILD) ret = wdt_expire_now(wdt, reset_mode); if (ret) { debug("Sysreset failed: %d", ret); return ret; } +#else + hang(); +#endif return -EINPROGRESS; } diff --git a/include/configs/evb_ast2600.h b/include/configs/evb_ast2600.h new file mode 100644 index 00000000000..e7975bf66d2 --- /dev/null +++ b/include/configs/evb_ast2600.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) Aspeed Technology Inc. + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE + +/* Memory Info */ +#define CONFIG_SYS_LOAD_ADDR 0x83000000 + +#endif /* __CONFIG_H */ -- cgit v1.3.1 From 2767d881f031124b2193ab33b32e48b29c6e18e1 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Mon, 21 Dec 2020 08:19:39 -0800 Subject: power: pmic: add driver for Monolithic Power mp5416 This adds basic register access and child regulator binding for the Monolithic MP5416 Power Management IC which integrates four DC/DC switching converters and five LDO regulators. Signed-off-by: Tim Harvey --- drivers/power/pmic/Kconfig | 15 +++++++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/mp5416.c | 98 +++++++++++++++++++++++++++++++++++++++++++++ include/power/mp5416.h | 41 +++++++++++++++++++ 4 files changed, 155 insertions(+) create mode 100644 drivers/power/pmic/mp5416.c create mode 100644 include/power/mp5416.h (limited to 'include') diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 7d51510d1b8..583fd3ddcde 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -91,6 +91,21 @@ config DM_PMIC_FAN53555 The driver implements read/write operations for use with the FAN53555 regulator driver and binds the regulator driver to its node. +config DM_PMIC_MP5416 + bool "Enable Driver Model for PMIC MP5416" + depends on DM_PMIC + help + This config enables implementation of driver-model pmic uclass features + for PMIC MP5416. The driver implements read/write operations. + +config SPL_DM_PMIC_MP5416 + bool "Enable Driver Model for PMIC MP5416 in SPL stage" + depends on DM_PMIC + help + This config enables implementation of driver-model pmic uclass + features for PMIC MP5416. The driver implements read/write + operations. + config DM_PMIC_PCA9450 bool "Enable Driver Model for PMIC PCA9450" depends on DM_PMIC diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 9cd6c375c06..2b2a6ddb565 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o obj-$(CONFIG_DM_PMIC_MAX8998) += max8998.o obj-$(CONFIG_DM_PMIC_MC34708) += mc34708.o obj-$(CONFIG_$(SPL_)DM_PMIC_BD71837) += bd71837.o +obj-$(CONFIG_$(SPL_)DM_PMIC_MP5416) += mp5416.o obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze100.o obj-$(CONFIG_$(SPL_)DM_PMIC_PCA9450) += pca9450.o obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o diff --git a/drivers/power/pmic/mp5416.c b/drivers/power/pmic/mp5416.c new file mode 100644 index 00000000000..458c4df688c --- /dev/null +++ b/drivers/power/pmic/mp5416.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 Gateworks Corporation + */ +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static const struct pmic_child_info pmic_children_info[] = { + /* buck */ + { .prefix = "b", .driver = MP6416_REGULATOR_DRIVER }, + /* ldo */ + { .prefix = "l", .driver = MP6416_REGULATOR_DRIVER }, + { }, +}; + +static int mp5416_reg_count(struct udevice *dev) +{ + return MP5416_NUM_OF_REGS - 1; +} + +static int mp5416_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) +{ + if (dm_i2c_write(dev, reg, buff, len)) { + pr_err("write error to device: %p register: %#x!", dev, reg); + return -EIO; + } + + return 0; +} + +static int mp5416_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + if (dm_i2c_read(dev, reg, buff, len)) { + pr_err("read error from device: %p register: %#x!", dev, reg); + return -EIO; + } + + return 0; +} + +static int mp5416_bind(struct udevice *dev) +{ + int children; + ofnode regulators_node; + + debug("%s %s\n", __func__, dev->name); + regulators_node = dev_read_subnode(dev, "regulators"); + if (!ofnode_valid(regulators_node)) { + debug("%s: %s regulators subnode not found!\n", __func__, + dev->name); + return -ENXIO; + } + + debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); + + children = pmic_bind_children(dev, regulators_node, pmic_children_info); + if (!children) + debug("%s: %s - no child found\n", __func__, dev->name); + + /* Always return success for this device */ + return 0; +} + +static int mp5416_probe(struct udevice *dev) +{ + debug("%s %s\n", __func__, dev->name); + + return 0; +} + +static struct dm_pmic_ops mp5416_ops = { + .reg_count = mp5416_reg_count, + .read = mp5416_read, + .write = mp5416_write, +}; + +static const struct udevice_id mp5416_ids[] = { + { .compatible = "mps,mp5416", }, + { } +}; + +U_BOOT_DRIVER(pmic_mp5416) = { + .name = "mp5416 pmic", + .id = UCLASS_PMIC, + .of_match = mp5416_ids, + .bind = mp5416_bind, + .probe = mp5416_probe, + .ops = &mp5416_ops, +}; diff --git a/include/power/mp5416.h b/include/power/mp5416.h new file mode 100644 index 00000000000..dc096fed3f2 --- /dev/null +++ b/include/power/mp5416.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (C) 2020 Gateworks Corporation */ + +#ifndef MP5416_H_ +#define MP5416_H_ + +#define MP6416_REGULATOR_DRIVER "mp5416_regulator" + +enum { + MP5416_CTL0 = 0x00, + MP5416_CTL1 = 0x01, + MP5416_CTL2 = 0x02, + MP5416_ILIMIT = 0x03, + MP5416_VSET_SW1 = 0x04, + MP5416_VSET_SW2 = 0x05, + MP5416_VSET_SW3 = 0x06, + MP5416_VSET_SW4 = 0x07, + MP5416_VSET_LDO2 = 0x08, + MP5416_VSET_LDO3 = 0x09, + MP5416_VSET_LDO4 = 0x0a, + MP5416_VSET_LDO5 = 0x0b, + MP5416_STATUS1 = 0x0d, + MP5416_STATUS2 = 0x0e, + MP5416_STATUS3 = 0x0f, + MP5416_ID2 = 0x11, + MP5416_NUM_OF_REGS = 0x12, +}; + +#define MP5416_VSET_EN BIT(7) +#define MP5416_VSET_SW1_GVAL(x) ((((x) & 0x7f) * 12500) + 600000) +#define MP5416_VSET_SW2_GVAL(x) ((((x) & 0x7f) * 25000) + 800000) +#define MP5416_VSET_SW3_GVAL(x) ((((x) & 0x7f) * 12500) + 600000) +#define MP5416_VSET_SW4_GVAL(x) ((((x) & 0x7f) * 25000) + 800000) +#define MP5416_VSET_LDO_GVAL(x) ((((x) & 0x7f) * 25000) + 800000) +#define MP5416_VSET_LDO_SVAL(x) ((((x) & 0x7f) * 25000) + 800000) +#define MP5416_VSET_SW1_SVAL(x) (((x) - 600000) / 12500) +#define MP5416_VSET_SW2_SVAL(x) (((x) - 800000) / 25000) +#define MP5416_VSET_SW3_SVAL(x) (((x) - 600000) / 12500) +#define MP5416_VSET_SW4_SVAL(x) (((x) - 800000) / 25000) + +#endif -- cgit v1.3.1