diff options
113 files changed, 13496 insertions, 138 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index b3baaf4..44256d9 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -153,6 +153,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \ rk3399-nanopi-r4s.dtb \ rk3399-orangepi.dtb \ rk3399-pinebook-pro.dtb \ + rk3399-pinephone-pro.dtb \ rk3399-puma-haikou.dtb \ rk3399-roc-pc.dtb \ rk3399-roc-pc-mezzanine.dtb \ @@ -170,6 +171,9 @@ dtb-$(CONFIG_ROCKCHIP_RV1108) += \ rv1108-elgin-r1.dtb \ rv1108-evb.dtb +dtb-$(CONFIG_ROCKCHIP_RV1126) += \ + rv1126-edgeble-neu2-io.dtb + dtb-$(CONFIG_ARCH_S5P4418) += \ s5p4418-nanopi2.dtb diff --git a/arch/arm/dts/px30-ringneck-haikou-u-boot.dtsi b/arch/arm/dts/px30-ringneck-haikou-u-boot.dtsi new file mode 100644 index 0000000..e8a34c7 --- /dev/null +++ b/arch/arm/dts/px30-ringneck-haikou-u-boot.dtsi @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include "px30-u-boot.dtsi" + +/ { + config { + u-boot,mmc-env-offset = <0x5000>; /* @ 20KB */ + u-boot,efi-partition-entries-offset = <0x200000>; /* 2MB */ + u-boot,boot-led = "module_led"; + }; + + chosen { + stdout-path = "serial0:115200n8"; + u-boot,spl-boot-order = "same-as-spl", &emmc, &sdmmc; + }; +}; + +&binman { + simple-bin { + blob { + offset = <((CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR - 64) * 512)>; + }; + }; +}; + +&emmc_clk { + u-boot,dm-pre-reloc; +}; + +&emmc_cmd { + u-boot,dm-pre-reloc; +}; + +&emmc_bus8 { + u-boot,dm-pre-reloc; +}; + +&gpio0 { + u-boot,dm-pre-reloc; +}; + +&gpio1 { + u-boot,dm-pre-reloc; +}; + +&gpio2 { + u-boot,dm-pre-reloc; + + /* + * The Qseven BIOS_DISABLE signal on the PX30-µQ7 keeps the on-module + * eMMC powered-down initially (in fact it keeps the reset signal + * asserted). BIOS_DISABLE_OVERRIDE pin allows to re-enable eMMC after + * the SPL has been booted from SD Card. + */ + bios-disable-override-hog { + u-boot,dm-pre-reloc; + }; +}; + +&pinctrl { + u-boot,dm-pre-reloc; +}; + +&pcfg_pull_none_8ma { + u-boot,dm-pre-reloc; +}; + +&pcfg_pull_up_8ma { + u-boot,dm-pre-reloc; +}; + +&sdmmc_bus4 { + u-boot,dm-pre-reloc; +}; + +&sdmmc_clk { + u-boot,dm-pre-reloc; +}; + +&sdmmc_cmd { + u-boot,dm-pre-reloc; +}; + +&sdmmc_det { + u-boot,dm-pre-reloc; +}; + +&uart0 { + clock-frequency = <24000000>; + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/px30-ringneck-haikou.dts b/arch/arm/dts/px30-ringneck-haikou.dts new file mode 100644 index 0000000..08a3ad3 --- /dev/null +++ b/arch/arm/dts/px30-ringneck-haikou.dts @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2022 Theobroma Systems Design und Consulting GmbH + */ + +/dts-v1/; +#include "px30-ringneck.dtsi" +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> + +/ { + model = "Theobroma Systems PX30-uQ7 SoM on Haikou devkit"; + compatible = "tsd,px30-ringneck-haikou", "rockchip,px30"; + + aliases { + mmc2 = &sdmmc; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-0 = <&haikou_keys_pin>; + pinctrl-names = "default"; + + button-batlow-n { + label = "BATLOW#"; + linux,code = <KEY_BATTERY>; + gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>; + }; + + button-slp-btn-n { + label = "SLP_BTN#"; + linux,code = <KEY_SLEEP>; + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + }; + + button-wake-n { + label = "WAKE#"; + linux,code = <KEY_WAKEUP>; + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + wakeup-source; + }; + + switch-lid-btn-n { + label = "LID_BTN#"; + linux,code = <SW_LID>; + linux,input-type = <EV_SW>; + gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + pinctrl-0 = <&module_led_pin>, <&sd_card_led_pin>; + + sd_card_led: led-1 { + gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc2"; + function = LED_FUNCTION_SD; + color = <LED_COLOR_ID_BLUE>; + }; + }; + + i2s0-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "Haikou,I2S-codec"; + simple-audio-card,mclk-fs = <512>; + + simple-audio-card,codec { + clocks = <&sgtl5000_clk>; + sound-dai = <&sgtl5000>; + }; + + simple-audio-card,cpu { + bitclock-master; + frame-master; + sound-dai = <&i2s0_8ch>; + }; + }; + + sgtl5000_clk: sgtl5000-oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; + }; + + dc_12v: dc-12v-regulator { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc3v3_baseboard: vcc3v3-baseboard-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_baseboard"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_baseboard: vcc5v0-baseboard-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_baseboard"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vdda_codec: vdda-codec-regulator { + compatible = "regulator-fixed"; + regulator-name = "vdda_codec"; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_baseboard>; + }; + + vddd_codec: vddd-codec-regulator { + compatible = "regulator-fixed"; + regulator-name = "vddd_codec"; + regulator-boot-on; + regulator-min-microvolt = <1600000>; + regulator-max-microvolt = <1600000>; + vin-supply = <&vcc5v0_baseboard>; + }; +}; + +&i2c2 { + status = "okay"; + clock-frequency = <400000>; + + sgtl5000: codec@a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&sgtl5000_clk>; + #sound-dai-cells = <0>; + VDDA-supply = <&vdda_codec>; + VDDIO-supply = <&vcc3v3_baseboard>; + VDDD-supply = <&vddd_codec>; + }; +}; + +&i2c3 { + eeprom@50 { + reg = <0x50>; + compatible = "atmel,24c01"; + pagesize = <8>; + size = <128>; + vcc-supply = <&vcc3v3_baseboard>; + }; +}; + +&i2s0_8ch { + status = "okay"; +}; + +&gmac { + status = "okay"; +}; + +&pinctrl { + haikou { + haikou_keys_pin: haikou-keys-pin { + rockchip,pins = + /* WAKE# */ + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + /* SLP_BTN# */ + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + /* LID_BTN */ + <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + /* BATLOW# */ + <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + /* BIOS_DISABLE# */ + <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + leds { + sd_card_led_pin: sd-card-led-pin { + rockchip,pins = + <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&sdmmc { + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; + disable-wp; + vmmc-supply = <&vcc3v3_baseboard>; + status = "okay"; +}; + +&spi1 { + status = "okay"; +}; + +&u2phy_otg { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&uart5 { + pinctrl-0 = <&uart5_xfer>; + status = "okay"; +}; + +&usb20_otg { + status = "okay"; +}; diff --git a/arch/arm/dts/px30-ringneck.dtsi b/arch/arm/dts/px30-ringneck.dtsi new file mode 100644 index 0000000..1239775 --- /dev/null +++ b/arch/arm/dts/px30-ringneck.dtsi @@ -0,0 +1,382 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2022 Theobroma Systems Design und Consulting GmbH + */ + +/dts-v1/; +#include "px30.dtsi" +#include <dt-bindings/leds/common.h> + +/ { + aliases { + mmc0 = &emmc; + mmc1 = &sdio; + rtc0 = &rtc_twi; + rtc1 = &rk809; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + pinctrl-0 = <&emmc_reset>; + pinctrl-names = "default"; + reset-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&module_led_pin>; + status = "okay"; + + module_led: led-0 { + gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_HIGH>; + function = LED_FUNCTION_HEARTBEAT; + linux,default-trigger = "heartbeat"; + color = <LED_COLOR_ID_AMBER>; + }; + }; + + vcc5v0_sys: vccsys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + supports-emmc; + mmc-pwrseq = <&emmc_pwrseq>; + non-removable; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_emmc>; + + status = "okay"; +}; + +/* On-module TI DP83825I PHY but no connector, enable in carrierboard */ +&gmac { + snps,reset-gpio = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 50000 50000>; + phy-supply = <&vcc_3v3>; + clock_in_out = "output"; +}; + +&gpio2 { + /* + * The Qseven BIOS_DISABLE signal on the PX30-µQ7 keeps the on-module + * eMMC powered-down initially (in fact it keeps the reset signal + * asserted). BIOS_DISABLE_OVERRIDE pin allows to re-enable eMMC after + * the SPL has been booted from SD Card. + */ + bios-disable-override-hog { + gpios = <RK_PB5 GPIO_ACTIVE_LOW>; + output-high; + line-name = "bios_disable_override"; + gpio-hog; + }; + + /* + * The BIOS_DISABLE hog is a feedback pin for the actual status of the + * signal, ignoring the BIOS_DISABLE_OVERRIDE logic. This usually + * represents the state of a switch on the baseboard. + */ + bios-disable-n-hog { + gpios = <RK_PC2 GPIO_ACTIVE_LOW>; + line-name = "bios_disable"; + input; + gpio-hog; + }; +}; + +&gpu { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&pmic_int>; + pinctrl-names = "default"; + #clock-cells = <0>; + clock-output-names = "xin32k"; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc5v0_sys>; + vcc2-supply = <&vcc5v0_sys>; + vcc3-supply = <&vcc5v0_sys>; + vcc4-supply = <&vcc5v0_sys>; + vcc5-supply = <&vcc_3v3>; + vcc6-supply = <&vcc_3v3>; + vcc7-supply = <&vcc_3v3>; + vcc9-supply = <&vcc5v0_sys>; + + regulators { + vdd_log: DCDC_REG1 { + regulator-name = "vdd_log"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v0_1v8: vcc_emmc: DCDC_REG4 { + regulator-name = "vcc_3v0_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_3v3: DCDC_REG5 { + regulator-name = "vcc_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_1v0: LDO_REG3 { + regulator-name = "vcc_1v0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_lcd: LDO_REG7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-name = "vcc_lcd"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_1v8_lcd: LDO_REG8 { + regulator-name = "vcc_1v8_lcd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca_1v8: LDO_REG9 { + regulator-name = "vcca_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + }; + }; +}; + +&i2c1 { + status = "okay"; + + /* SE05x is limited to Fast Mode */ + clock-frequency = <400000>; + + fan: fan@18 { + compatible = "ti,amc6821"; + reg = <0x18>; + #cooling-cells = <2>; + }; + + rtc_twi: rtc@6f { + compatible = "isil,isl1208"; + reg = <0x6f>; + }; +}; + +&i2c3 { + status = "okay"; +}; + +&i2s0_8ch { + rockchip,trcm-sync-tx-only; + + pinctrl-0 = <&i2s0_8ch_sclktx &i2s0_8ch_lrcktx + &i2s0_8ch_sdo0 &i2s0_8ch_sdi0>; +}; + +&io_domains { + vccio1-supply = <&vcc_3v3>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_3v3>; + vccio4-supply = <&vcc_3v3>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_emmc>; + vccio-oscgpi-supply = <&vcc_3v3>; + + status = "okay"; +}; + +&pinctrl { + emmc { + emmc_reset: emmc-reset { + rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + leds { + module_led_pin: module-led-pin { + rockchip,pins = <1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic-int { + rockchip,pins = + <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdmmc { + vqmmc-supply = <&vccio_sd>; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; +}; + +&u2phy_host { + status = "okay"; +}; + +/* Mule UCAN */ +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&wdt { + status = "okay"; +}; diff --git a/arch/arm/dts/px30.dtsi b/arch/arm/dts/px30.dtsi index 00f50b0..bfa3580 100644 --- a/arch/arm/dts/px30.dtsi +++ b/arch/arm/dts/px30.dtsi @@ -365,6 +365,28 @@ status = "disabled"; }; + i2s0_8ch: i2s@ff060000 { + compatible = "rockchip,px30-i2s-tdm"; + reg = <0x0 0xff060000 0x0 0x1000>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru SCLK_I2S0_TX>, <&cru SCLK_I2S0_RX>, <&cru HCLK_I2S0>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + dmas = <&dmac 16>, <&dmac 17>; + dma-names = "tx", "rx"; + rockchip,grf = <&grf>; + resets = <&cru SRST_I2S0_TX>, <&cru SRST_I2S0_RX>; + reset-names = "tx-m", "rx-m"; + pinctrl-names = "default"; + pinctrl-0 = <&i2s0_8ch_sclktx &i2s0_8ch_sclkrx + &i2s0_8ch_lrcktx &i2s0_8ch_lrckrx + &i2s0_8ch_sdo0 &i2s0_8ch_sdi0 + &i2s0_8ch_sdo1 &i2s0_8ch_sdi1 + &i2s0_8ch_sdo2 &i2s0_8ch_sdi2 + &i2s0_8ch_sdo3 &i2s0_8ch_sdi3>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + i2s1_2ch: i2s@ff070000 { compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s"; reg = <0x0 0xff070000 0x0 0x1000>; @@ -528,7 +550,7 @@ i2c0: i2c@ff180000 { compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c"; reg = <0x0 0xff180000 0x0 0x1000>; - clocks = <&cru SCLK_I2C0>, <&cru PCLK_I2C0>; + clocks = <&cru SCLK_I2C0>, <&cru PCLK_I2C0>; clock-names = "i2c", "pclk"; interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; pinctrl-names = "default"; @@ -711,7 +733,7 @@ clock-names = "pclk", "timer"; }; - dmac: dmac@ff240000 { + dmac: dma-controller@ff240000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x0 0xff240000 0x0 0x4000>; interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>, @@ -1072,7 +1094,7 @@ }; dsi: dsi@ff450000 { - compatible = "rockchip,px30-mipi-dsi"; + compatible = "rockchip,px30-mipi-dsi", "snps,dw-mipi-dsi"; reg = <0x0 0xff450000 0x0 0x10000>; interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru PCLK_MIPI_DSI>; diff --git a/arch/arm/dts/rk3399-pinephone-pro-u-boot.dtsi b/arch/arm/dts/rk3399-pinephone-pro-u-boot.dtsi new file mode 100644 index 0000000..1dad283 --- /dev/null +++ b/arch/arm/dts/rk3399-pinephone-pro-u-boot.dtsi @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Peter Robinson <pbrobinson at gmail.com> + */ + +#include "rk3399-u-boot.dtsi" +#include "rk3399-sdram-lpddr4-100.dtsi" + +/ { + chosen { + u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc; + }; + + config { + u-boot,spl-payload-offset = <0x60000>; /* @ 384KB */ + }; +}; + +&rng { + status = "okay"; +}; + +&sdhci { + max-frequency = <25000000>; + u-boot,dm-pre-reloc; +}; + +&sdmmc { + max-frequency = <20000000>; + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/rk3399-pinephone-pro.dts b/arch/arm/dts/rk3399-pinephone-pro.dts new file mode 100644 index 0000000..04403a7 --- /dev/null +++ b/arch/arm/dts/rk3399-pinephone-pro.dts @@ -0,0 +1,474 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Martijn Braam <martijn@brixit.nl> + * Copyright (c) 2021 Kamil TrzciÅ„ski <ayufan@ayufan.eu> + */ + +/* + * PinePhone Pro datasheet: + * https://files.pine64.org/doc/PinePhonePro/PinephonePro-Schematic-V1.0-20211127.pdf + */ + +/dts-v1/; +#include <dt-bindings/input/linux-event-codes.h> +#include "rk3399.dtsi" +#include "rk3399-opp.dtsi" + +/ { + model = "Pine64 PinePhonePro"; + compatible = "pine64,pinephone-pro", "rockchip,rk3399"; + chassis-type = "handset"; + + aliases { + mmc0 = &sdio0; + mmc1 = &sdmmc; + mmc2 = &sdhci; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pwrbtn_pin>; + + key-power { + debounce-interval = <20>; + gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; + label = "Power"; + linux,code = <KEY_POWER>; + wakeup-source; + }; + }; + + vcc_sys: vcc-sys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + }; + + vcc3v3_sys: vcc3v3-sys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_sys>; + }; + + vcca1v8_s3: vcc1v8-s3-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcca1v8_s3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + regulator-always-on; + regulator-boot-on; + }; + + vcc1v8_codec: vcc1v8-codec-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc1v8_codec_en>; + regulator-name = "vcc1v8_codec"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + }; + + wifi_pwrseq: sdio-wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk818 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h_pin>; + /* + * Wait between power-on and SDIO access for CYP43455 + * POR circuit. + */ + post-power-on-delay-ms = <110>; + /* + * Wait between consecutive toggles for CYP43455 CBUCK + * regulator discharge. + */ + power-off-delay-us = <10000>; + + /* WL_REG_ON on module */ + reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + }; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_b>; +}; + +&emmc_phy { + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <168>; + i2c-scl-falling-time-ns = <4>; + status = "okay"; + + rk818: pmic@1c { + compatible = "rockchip,rk818"; + reg = <0x1c>; + interrupt-parent = <&gpio1>; + interrupts = <RK_PC5 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc6-supply = <&vcc_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc_sys>; + vcc9-supply = <&vcc3v3_sys>; + + regulators { + vdd_cpu_l: DCDC_REG1 { + regulator-name = "vdd_cpu_l"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <875000>; + regulator-max-microvolt = <975000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_center: DCDC_REG2 { + regulator-name = "vdd_center"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1000000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG4 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcca3v0_codec: LDO_REG1 { + regulator-name = "vcca3v0_codec"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + + vcc3v0_touch: LDO_REG2 { + regulator-name = "vcc3v0_touch"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + + vcca1v8_codec: LDO_REG3 { + regulator-name = "vcca1v8_codec"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + rk818_pwr_on: LDO_REG4 { + regulator-name = "rk818_pwr_on"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v0: LDO_REG5 { + regulator-name = "vcc_3v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v5: LDO_REG6 { + regulator-name = "vcc_1v5"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc1v8_dvp: LDO_REG7 { + regulator-name = "vcc1v8_dvp"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + vcc3v3_s3: LDO_REG8 { + regulator-name = "vcc3v3_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG9 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + }; + + vcc3v3_s0: SWITCH_REG { + regulator-name = "vcc3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + }; + }; + + vdd_cpu_b: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; + fcs,suspend-voltage-selector = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&vsel1_pin>; + regulator-name = "vdd_cpu_b"; + regulator-min-microvolt = <875000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: regulator@41 { + compatible = "silergy,syr828"; + reg = <0x41>; + fcs,suspend-voltage-selector = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&vsel2_pin>; + regulator-name = "vdd_gpu"; + regulator-min-microvolt = <875000>; + regulator-max-microvolt = <975000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&cluster0_opp { + opp04 { + status = "disabled"; + }; + + opp05 { + status = "disabled"; + }; +}; + +&cluster1_opp { + opp06 { + opp-hz = /bits/ 64 <1500000000>; + opp-microvolt = <1100000 1100000 1150000>; + }; + + opp07 { + status = "disabled"; + }; +}; + +&io_domains { + bt656-supply = <&vcc1v8_dvp>; + audio-supply = <&vcca1v8_codec>; + sdmmc-supply = <&vccio_sd>; + gpio1830-supply = <&vcc_3v0>; + status = "okay"; +}; + +&pmu_io_domains { + pmu1830-supply = <&vcc_1v8>; + status = "okay"; +}; + +&pinctrl { + buttons { + pwrbtn_pin: pwrbtn-pin { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + vsel1_pin: vsel1-pin { + rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + vsel2_pin: vsel2-pin { + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + sdio-pwrseq { + wifi_enable_h_pin: wifi-enable-h-pin { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sound { + vcc1v8_codec_en: vcc1v8-codec-en { + rockchip,pins = <3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + wireless-bluetooth { + bt_wake_pin: bt-wake-pin { + rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bt_host_wake_pin: bt-host-wake-pin { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bt_reset_pin: bt-reset-pin { + rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&sdio0 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + disable-wp; + keep-power-in-suspend; + mmc-pwrseq = <&wifi_pwrseq>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; + sd-uhs-sdr104; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; + disable-wp; + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + vmmc-supply = <&vcc3v3_sys>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + mmc-hs200-1_8v; + non-removable; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <1>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "brcm,bcm4345c5"; + clocks = <&rk818 1>; + clock-names = "lpo"; + device-wakeup-gpios = <&gpio2 RK_PD2 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; + max-speed = <1500000>; + pinctrl-names = "default"; + pinctrl-0 = <&bt_host_wake_pin &bt_wake_pin &bt_reset_pin>; + shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; + vbat-supply = <&vcc3v3_sys>; + vddio-supply = <&vcc_1v8>; + }; +}; + +&uart2 { + status = "okay"; +}; diff --git a/arch/arm/dts/rk3399-puma-haikou.dts b/arch/arm/dts/rk3399-puma-haikou.dts index 292bb7e..115c14c 100644 --- a/arch/arm/dts/rk3399-puma-haikou.dts +++ b/arch/arm/dts/rk3399-puma-haikou.dts @@ -49,7 +49,7 @@ sgtl5000_clk: sgtl5000-oscillator { compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <24576000>; + clock-frequency = <24576000>; }; dc_12v: dc-12v { @@ -207,7 +207,7 @@ cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; disable-wp; - max-frequency = <150000000>; + max-frequency = <40000000>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vcc3v3_baseboard>; @@ -232,6 +232,7 @@ &usbdrd_dwc3_0 { dr_mode = "otg"; + extcon = <&extcon_usb3>; status = "okay"; }; diff --git a/arch/arm/dts/rk3399-puma.dtsi b/arch/arm/dts/rk3399-puma.dtsi index fb67db4..aa3e21b 100644 --- a/arch/arm/dts/rk3399-puma.dtsi +++ b/arch/arm/dts/rk3399-puma.dtsi @@ -25,6 +25,13 @@ }; }; + extcon_usb3: extcon-usb3 { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb3_id>; + }; + clkin_gmac: external-gmac-clock { compatible = "fixed-clock"; clock-frequency = <125000000>; @@ -55,7 +62,6 @@ vcc5v0_host: vcc5v0-host-regulator { compatible = "regulator-fixed"; gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_LOW>; - enable-active-low; pinctrl-names = "default"; pinctrl-0 = <&vcc5v0_host_en>; regulator-name = "vcc5v0_host"; @@ -71,6 +77,17 @@ regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; }; + + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 1>; + pwm-supply = <&vcc5v0_sys>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + regulator-boot-on; + }; }; &cpu_b0 { @@ -422,9 +439,22 @@ <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; }; }; + + usb3 { + usb3_id: usb3-id { + rockchip,pins = + <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; }; &sdhci { + /* + * Signal integrity isn't great at 200MHz but 100MHz has proven stable + * enough. + */ + max-frequency = <100000000>; + bus-width = <8>; mmc-hs400-1_8v; mmc-hs400-enhanced-strobe; diff --git a/arch/arm/dts/rv1126-edgeble-neu2-io-u-boot.dtsi b/arch/arm/dts/rv1126-edgeble-neu2-io-u-boot.dtsi new file mode 100644 index 0000000..51a1617 --- /dev/null +++ b/arch/arm/dts/rv1126-edgeble-neu2-io-u-boot.dtsi @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. + */ + +#include "rv1126-u-boot.dtsi" + +&sdio { + status = "disabled"; +}; diff --git a/arch/arm/dts/rv1126-edgeble-neu2-io.dts b/arch/arm/dts/rv1126-edgeble-neu2-io.dts new file mode 100644 index 0000000..dded0a1 --- /dev/null +++ b/arch/arm/dts/rv1126-edgeble-neu2-io.dts @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Rockchip Electronics Co., Ltd. + * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. + */ + +/dts-v1/; +#include "rv1126.dtsi" +#include "rv1126-edgeble-neu2.dtsi" + +/ { + model = "Edgeble Neu2 IO Board"; + compatible = "edgeble,neural-compute-module-2-io", + "edgeble,neural-compute-module-2", "rockchip,rv1126"; + + aliases { + serial2 = &uart2; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + card-detect-delay = <200>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_bus4 &sdmmc0_det>; + rockchip,default-sample-phase = <90>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr104; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; diff --git a/arch/arm/dts/rv1126-edgeble-neu2.dtsi b/arch/arm/dts/rv1126-edgeble-neu2.dtsi new file mode 100644 index 0000000..cc64ba4 --- /dev/null +++ b/arch/arm/dts/rv1126-edgeble-neu2.dtsi @@ -0,0 +1,338 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Rockchip Electronics Co., Ltd. + * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. + */ + +/ { + compatible = "edgeble,neural-compute-module-2", "rockchip,rv1126"; + + aliases { + mmc0 = &emmc; + }; + + vcc5v0_sys: vcc5v0-sys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vccio_flash: vccio-flash-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&flash_vol_sel>; + regulator-name = "vccio_flash"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + }; + + sdio_pwrseq: pwrseq-sdio { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk809 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + reset-gpios = <&gpio1 RK_PD0 GPIO_ACTIVE_LOW>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&emmc { + bus-width = <8>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk &emmc_rstnout>; + rockchip,default-sample-phase = <90>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vccio_flash>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + status = "okay"; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PB1 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "rk808-clkout1", "rk808-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc5v0_sys>; + vcc2-supply = <&vcc5v0_sys>; + vcc3-supply = <&vcc5v0_sys>; + vcc4-supply = <&vcc5v0_sys>; + vcc5-supply = <&vcc_buck5>; + vcc6-supply = <&vcc_buck5>; + vcc7-supply = <&vcc5v0_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc5v0_sys>; + + regulators { + vdd_npu_vepu: DCDC_REG1 { + regulator-name = "vdd_npu_vepu"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <650000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc3v3_sys: DCDC_REG4 { + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_buck5: DCDC_REG5 { + regulator-name = "vcc_buck5"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <2200000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <2200000>; + }; + }; + + vcc_0v8: LDO_REG1 { + regulator-name = "vcc_0v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_pmu: LDO_REG2 { + regulator-name = "vcc1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd0v8_pmu: LDO_REG3 { + regulator-name = "vcc0v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <800000>; + }; + }; + + vcc_1v8: LDO_REG4 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_dovdd: LDO_REG5 { + regulator-name = "vcc_dovdd"; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_dvdd: LDO_REG6 { + regulator-name = "vcc_dvdd"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_avdd: LDO_REG7 { + regulator-name = "vcc_avdd"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG8 { + regulator-name = "vccio_sd"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_sd: LDO_REG9 { + regulator-name = "vcc3v3_sd"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_5v0: SWITCH_REG1 { + regulator-name = "vcc_5v0"; + }; + + vcc_3v3: SWITCH_REG2 { + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + }; + }; + }; +}; + +&pinctrl { + bt { + bt_enable: bt-enable { + rockchip,pins = <3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + flash { + flash_vol_sel: flash-vol-sel { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + wifi { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + pmuio0-supply = <&vcc1v8_pmu>; + pmuio1-supply = <&vcc3v3_sys>; + vccio1-supply = <&vccio_flash>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_1v8>; + vccio4-supply = <&vcc_dovdd>; + vccio5-supply = <&vcc_1v8>; + vccio6-supply = <&vcc_1v8>; + vccio7-supply = <&vcc_dovdd>; + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + max-frequency = <100000000>; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc1_clk &sdmmc1_cmd &sdmmc1_bus4>; + rockchip,default-sample-phase = <90>; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sys>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_ctsn &uart0_rtsn>; + status = "okay"; + + bluetooth { + compatible = "qcom,qca9377-bt"; + clocks = <&rk809 1>; + enable-gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_HIGH>; /* BT_RST */ + max-speed = <2000000>; + pinctrl-names = "default"; + pinctrl-0 = <&bt_enable>; + vddxo-supply = <&vcc3v3_sys>; + vddio-supply = <&vcc_1v8>; + }; +}; diff --git a/arch/arm/dts/rv1126-pinctrl.dtsi b/arch/arm/dts/rv1126-pinctrl.dtsi new file mode 100644 index 0000000..28d8d29 --- /dev/null +++ b/arch/arm/dts/rv1126-pinctrl.dtsi @@ -0,0 +1,211 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd + */ + +#include <dt-bindings/pinctrl/rockchip.h> +#include "rockchip-pinconf.dtsi" + +/* + * This file is auto generated by pin2dts tool, please keep these code + * by adding changes at end of this file. + */ +&pinctrl { + emmc { + /omit-if-no-ref/ + emmc_rstnout: emmc-rstnout { + rockchip,pins = + /* emmc_rstn */ + <1 RK_PA3 2 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + emmc_bus8: emmc-bus8 { + rockchip,pins = + /* emmc_d0 */ + <0 RK_PC4 2 &pcfg_pull_up_drv_level_2>, + /* emmc_d1 */ + <0 RK_PC5 2 &pcfg_pull_up_drv_level_2>, + /* emmc_d2 */ + <0 RK_PC6 2 &pcfg_pull_up_drv_level_2>, + /* emmc_d3 */ + <0 RK_PC7 2 &pcfg_pull_up_drv_level_2>, + /* emmc_d4 */ + <0 RK_PD0 2 &pcfg_pull_up_drv_level_2>, + /* emmc_d5 */ + <0 RK_PD1 2 &pcfg_pull_up_drv_level_2>, + /* emmc_d6 */ + <0 RK_PD2 2 &pcfg_pull_up_drv_level_2>, + /* emmc_d7 */ + <0 RK_PD3 2 &pcfg_pull_up_drv_level_2>; + }; + /omit-if-no-ref/ + emmc_clk: emmc-clk { + rockchip,pins = + /* emmc_clko */ + <0 RK_PD7 2 &pcfg_pull_up_drv_level_2>; + }; + /omit-if-no-ref/ + emmc_cmd: emmc-cmd { + rockchip,pins = + /* emmc_cmd */ + <0 RK_PD5 2 &pcfg_pull_up_drv_level_2>; + }; + }; + i2c0 { + /omit-if-no-ref/ + i2c0_xfer: i2c0-xfer { + rockchip,pins = + /* i2c0_scl */ + <0 RK_PB4 1 &pcfg_pull_none_drv_level_0_smt>, + /* i2c0_sda */ + <0 RK_PB5 1 &pcfg_pull_none_drv_level_0_smt>; + }; + }; + sdmmc0 { + /omit-if-no-ref/ + sdmmc0_bus4: sdmmc0-bus4 { + rockchip,pins = + /* sdmmc0_d0 */ + <1 RK_PA4 1 &pcfg_pull_up_drv_level_2>, + /* sdmmc0_d1 */ + <1 RK_PA5 1 &pcfg_pull_up_drv_level_2>, + /* sdmmc0_d2 */ + <1 RK_PA6 1 &pcfg_pull_up_drv_level_2>, + /* sdmmc0_d3 */ + <1 RK_PA7 1 &pcfg_pull_up_drv_level_2>; + }; + /omit-if-no-ref/ + sdmmc0_clk: sdmmc0-clk { + rockchip,pins = + /* sdmmc0_clk */ + <1 RK_PB0 1 &pcfg_pull_up_drv_level_2>; + }; + /omit-if-no-ref/ + sdmmc0_cmd: sdmmc0-cmd { + rockchip,pins = + /* sdmmc0_cmd */ + <1 RK_PB1 1 &pcfg_pull_up_drv_level_2>; + }; + /omit-if-no-ref/ + sdmmc0_det: sdmmc0-det { + rockchip,pins = + <0 RK_PA3 1 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + sdmmc0_pwr: sdmmc0-pwr { + rockchip,pins = + <0 RK_PC0 1 &pcfg_pull_none>; + }; + }; + sdmmc1 { + /omit-if-no-ref/ + sdmmc1_bus4: sdmmc1-bus4 { + rockchip,pins = + /* sdmmc1_d0 */ + <1 RK_PB4 1 &pcfg_pull_up_drv_level_2>, + /* sdmmc1_d1 */ + <1 RK_PB5 1 &pcfg_pull_up_drv_level_2>, + /* sdmmc1_d2 */ + <1 RK_PB6 1 &pcfg_pull_up_drv_level_2>, + /* sdmmc1_d3 */ + <1 RK_PB7 1 &pcfg_pull_up_drv_level_2>; + }; + /omit-if-no-ref/ + sdmmc1_clk: sdmmc1-clk { + rockchip,pins = + /* sdmmc1_clk */ + <1 RK_PB2 1 &pcfg_pull_up_drv_level_2>; + }; + /omit-if-no-ref/ + sdmmc1_cmd: sdmmc1-cmd { + rockchip,pins = + /* sdmmc1_cmd */ + <1 RK_PB3 1 &pcfg_pull_up_drv_level_2>; + }; + /omit-if-no-ref/ + sdmmc1_det: sdmmc1-det { + rockchip,pins = + <1 RK_PD0 2 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + sdmmc1_pwr: sdmmc1-pwr { + rockchip,pins = + <1 RK_PD1 2 &pcfg_pull_none>; + }; + }; + uart0 { + /omit-if-no-ref/ + uart0_xfer: uart0-xfer { + rockchip,pins = + /* uart0_rx */ + <1 RK_PC2 1 &pcfg_pull_up>, + /* uart0_tx */ + <1 RK_PC3 1 &pcfg_pull_up>; + }; + /omit-if-no-ref/ + uart0_ctsn: uart0-ctsn { + rockchip,pins = + <1 RK_PC1 1 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + uart0_rtsn: uart0-rtsn { + rockchip,pins = + <1 RK_PC0 1 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + uart0_rtsn_gpio: uart0-rts-pin { + rockchip,pins = + <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + uart1 { + /omit-if-no-ref/ + uart1m0_xfer: uart1m0-xfer { + rockchip,pins = + /* uart1_rx_m0 */ + <0 RK_PB7 2 &pcfg_pull_up>, + /* uart1_tx_m0 */ + <0 RK_PB6 2 &pcfg_pull_up>; + }; + }; + uart2 { + /omit-if-no-ref/ + uart2m1_xfer: uart2m1-xfer { + rockchip,pins = + /* uart2_rx_m1 */ + <3 RK_PA3 1 &pcfg_pull_up>, + /* uart2_tx_m1 */ + <3 RK_PA2 1 &pcfg_pull_up>; + }; + }; + uart3 { + /omit-if-no-ref/ + uart3m0_xfer: uart3m0-xfer { + rockchip,pins = + /* uart3_rx_m0 */ + <3 RK_PC7 4 &pcfg_pull_up>, + /* uart3_tx_m0 */ + <3 RK_PC6 4 &pcfg_pull_up>; + }; + }; + uart4 { + /omit-if-no-ref/ + uart4m0_xfer: uart4m0-xfer { + rockchip,pins = + /* uart4_rx_m0 */ + <3 RK_PA5 4 &pcfg_pull_up>, + /* uart4_tx_m0 */ + <3 RK_PA4 4 &pcfg_pull_up>; + }; + }; + uart5 { + /omit-if-no-ref/ + uart5m0_xfer: uart5m0-xfer { + rockchip,pins = + /* uart5_rx_m0 */ + <3 RK_PA7 4 &pcfg_pull_up>, + /* uart5_tx_m0 */ + <3 RK_PA6 4 &pcfg_pull_up>; + }; + }; +}; diff --git a/arch/arm/dts/rv1126-u-boot.dtsi b/arch/arm/dts/rv1126-u-boot.dtsi new file mode 100644 index 0000000..bc77037 --- /dev/null +++ b/arch/arm/dts/rv1126-u-boot.dtsi @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. + */ + +#include "rockchip-u-boot.dtsi" + +/ { + chosen { + u-boot,spl-boot-order = \ + "same-as-spl", &emmc, &sdmmc; + }; + + dmc { + compatible = "rockchip,rv1126-dmc"; + u-boot,dm-pre-reloc; + }; +}; + +&gpio0 { + u-boot,dm-spl; +}; + +&gpio1 { + u-boot,dm-spl; +}; + +&grf { + u-boot,dm-spl; +}; + +&pmu { + u-boot,dm-spl; +}; + +&pmugrf { + u-boot,dm-spl; +}; + +&xin24m { + u-boot,dm-spl; +}; + +&cru { + u-boot,dm-spl; +}; + +&pmucru { + u-boot,dm-spl; +}; + +&sdmmc { + u-boot,dm-spl; +}; + +&emmc { + u-boot,dm-spl; +}; + +&uart2 { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/rv1126.dtsi b/arch/arm/dts/rv1126.dtsi new file mode 100644 index 0000000..1cb4314 --- /dev/null +++ b/arch/arm/dts/rv1126.dtsi @@ -0,0 +1,438 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd. + */ + +#include <dt-bindings/clock/rockchip,rv1126-cru.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/pinctrl/rockchip.h> +#include <dt-bindings/power/rockchip,rv1126-power.h> +#include <dt-bindings/soc/rockchip,boot-mode.h> + +/ { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "rockchip,rv1126"; + + interrupt-parent = <&gic>; + + aliases { + i2c0 = &i2c0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@f00 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0xf00>; + enable-method = "psci"; + clocks = <&cru ARMCLK>; + }; + + cpu1: cpu@f01 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0xf01>; + enable-method = "psci"; + clocks = <&cru ARMCLK>; + }; + + cpu2: cpu@f02 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0xf02>; + enable-method = "psci"; + clocks = <&cru ARMCLK>; + }; + + cpu3: cpu@f03 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0xf03>; + enable-method = "psci"; + clocks = <&cru ARMCLK>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a7-pmu"; + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + clock-frequency = <24000000>; + }; + + xin24m: oscillator { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "xin24m"; + #clock-cells = <0>; + }; + + grf: syscon@fe000000 { + compatible = "rockchip,rv1126-grf", "syscon", "simple-mfd"; + reg = <0xfe000000 0x20000>; + }; + + pmugrf: syscon@fe020000 { + compatible = "rockchip,rv1126-pmugrf", "syscon", "simple-mfd"; + reg = <0xfe020000 0x1000>; + + pmu_io_domains: io-domains { + compatible = "rockchip,rv1126-pmu-io-voltage-domain"; + status = "disabled"; + }; + }; + + qos_emmc: qos@fe860000 { + compatible = "rockchip,rv1126-qos", "syscon"; + reg = <0xfe860000 0x20>; + }; + + qos_nandc: qos@fe860080 { + compatible = "rockchip,rv1126-qos", "syscon"; + reg = <0xfe860080 0x20>; + }; + + qos_sfc: qos@fe860200 { + compatible = "rockchip,rv1126-qos", "syscon"; + reg = <0xfe860200 0x20>; + }; + + qos_sdio: qos@fe86c000 { + compatible = "rockchip,rv1126-qos", "syscon"; + reg = <0xfe86c000 0x20>; + }; + + gic: interrupt-controller@feff0000 { + compatible = "arm,gic-400"; + interrupt-controller; + #interrupt-cells = <3>; + #address-cells = <0>; + + reg = <0xfeff1000 0x1000>, + <0xfeff2000 0x2000>, + <0xfeff4000 0x2000>, + <0xfeff6000 0x2000>; + interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + }; + + pmu: power-management@ff3e0000 { + compatible = "rockchip,rv1126-pmu", "syscon", "simple-mfd"; + reg = <0xff3e0000 0x1000>; + + power: power-controller { + compatible = "rockchip,rv1126-power-controller"; + #power-domain-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + + power-domain@RV1126_PD_NVM { + reg = <RV1126_PD_NVM>; + clocks = <&cru HCLK_EMMC>, + <&cru CLK_EMMC>, + <&cru HCLK_NANDC>, + <&cru CLK_NANDC>, + <&cru HCLK_SFC>, + <&cru HCLK_SFCXIP>, + <&cru SCLK_SFC>; + pm_qos = <&qos_emmc>, + <&qos_nandc>, + <&qos_sfc>; + #power-domain-cells = <0>; + }; + + power-domain@RV1126_PD_SDIO { + reg = <RV1126_PD_SDIO>; + clocks = <&cru HCLK_SDIO>, + <&cru CLK_SDIO>; + pm_qos = <&qos_sdio>; + #power-domain-cells = <0>; + }; + }; + }; + + i2c0: i2c@ff3f0000 { + compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c"; + reg = <0xff3f0000 0x1000>; + interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + rockchip,grf = <&pmugrf>; + clocks = <&pmucru CLK_I2C0>, <&pmucru PCLK_I2C0>; + clock-names = "i2c", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_xfer>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + uart1: serial@ff410000 { + compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart"; + reg = <0xff410000 0x100>; + interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <24000000>; + clocks = <&pmucru SCLK_UART1>, <&pmucru PCLK_UART1>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac 7>, <&dmac 6>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&uart1m0_xfer>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + pmucru: clock-controller@ff480000 { + compatible = "rockchip,rv1126-pmucru"; + reg = <0xff480000 0x1000>; + rockchip,grf = <&grf>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + cru: clock-controller@ff490000 { + compatible = "rockchip,rv1126-cru"; + reg = <0xff490000 0x1000>; + clocks = <&xin24m>; + clock-names = "xin24m"; + rockchip,grf = <&grf>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + dmac: dma-controller@ff4e0000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0xff4e0000 0x4000>; + interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + arm,pl330-periph-burst; + clocks = <&cru ACLK_DMAC>; + clock-names = "apb_pclk"; + }; + + uart0: serial@ff560000 { + compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart"; + reg = <0xff560000 0x100>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <24000000>; + clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac 5>, <&dmac 4>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart2: serial@ff570000 { + compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart"; + reg = <0xff570000 0x100>; + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <24000000>; + clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac 9>, <&dmac 8>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2m1_xfer>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart3: serial@ff580000 { + compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart"; + reg = <0xff580000 0x100>; + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <24000000>; + clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac 11>, <&dmac 10>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&uart3m0_xfer>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart4: serial@ff590000 { + compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart"; + reg = <0xff590000 0x100>; + interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <24000000>; + clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac 13>, <&dmac 12>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&uart4m0_xfer>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart5: serial@ff5a0000 { + compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart"; + reg = <0xff5a0000 0x100>; + interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <24000000>; + clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>; + clock-names = "baudclk", "apb_pclk"; + dmas = <&dmac 15>, <&dmac 14>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&uart5m0_xfer>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + saradc: adc@ff5e0000 { + compatible = "rockchip,rv1126-saradc", "rockchip,rk3399-saradc"; + reg = <0xff5e0000 0x100>; + interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; + #io-channel-cells = <1>; + clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>; + clock-names = "saradc", "apb_pclk"; + resets = <&cru SRST_SARADC_P>; + reset-names = "saradc-apb"; + status = "disabled"; + }; + + timer0: timer@ff660000 { + compatible = "rockchip,rv1126-timer", "rockchip,rk3288-timer"; + reg = <0xff660000 0x20>; + interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_TIMER>, <&cru CLK_TIMER0>; + clock-names = "pclk", "timer"; + }; + + emmc: mmc@ffc50000 { + compatible = "rockchip,rv1126-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0xffc50000 0x4000>; + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru HCLK_EMMC>, <&cru CLK_EMMC>, + <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <200000000>; + power-domains = <&power RV1126_PD_NVM>; + status = "disabled"; + }; + + sdmmc: mmc@ffc60000 { + compatible = "rockchip,rv1126-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0xffc60000 0x4000>; + interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru HCLK_SDMMC>, <&cru CLK_SDMMC>, + <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <200000000>; + status = "disabled"; + }; + + sdio: mmc@ffc70000 { + compatible = "rockchip,rv1126-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0xffc70000 0x4000>; + interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru HCLK_SDIO>, <&cru CLK_SDIO>, + <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <200000000>; + power-domains = <&power RV1126_PD_SDIO>; + status = "disabled"; + }; + + pinctrl: pinctrl { + compatible = "rockchip,rv1126-pinctrl"; + rockchip,grf = <&grf>; + rockchip,pmu = <&pmugrf>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio0: gpio@ff460000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff460000 0x100>; + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&pmucru PCLK_GPIO0>, <&pmucru DBCLK_GPIO0>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio@ff620000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff620000 0x100>; + interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio@ff630000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff630000 0x100>; + interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio3: gpio@ff640000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff640000 0x100>; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio4: gpio@ff650000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff650000 0x100>; + interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +}; + +#include "rv1126-pinctrl.dtsi" diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1126.h b/arch/arm/include/asm/arch-rockchip/cru_rv1126.h new file mode 100644 index 0000000..49a1f76 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/cru_rv1126.h @@ -0,0 +1,459 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 Rockchip Electronics Co. Ltd. + * Author: Finley Xiao <finley.xiao@rock-chips.com> + */ + +#ifndef _ASM_ARCH_CRU_RV1126_H +#define _ASM_ARCH_CRU_RV1126_H + +#define MHz 1000000 +#define KHz 1000 +#define OSC_HZ (24 * MHz) + +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT) +#define APLL_HZ (1008 * MHz) +#else +#define APLL_HZ (816 * MHz) +#endif +#define GPLL_HZ (1188 * MHz) +#define CPLL_HZ (500 * MHz) +#define HPLL_HZ (1400 * MHz) +#define PCLK_PDPMU_HZ (100 * MHz) +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT) +#define ACLK_PDBUS_HZ (396 * MHz) +#else +#define ACLK_PDBUS_HZ (500 * MHz) +#endif +#define HCLK_PDBUS_HZ (200 * MHz) +#define PCLK_PDBUS_HZ (100 * MHz) +#define ACLK_PDPHP_HZ (300 * MHz) +#define HCLK_PDPHP_HZ (200 * MHz) +#define HCLK_PDCORE_HZ (200 * MHz) +#define HCLK_PDAUDIO_HZ (150 * MHz) +#define CLK_OSC0_DIV_HZ (32768) +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT) +#define ACLK_PDVI_HZ (297 * MHz) +#define CLK_ISP_HZ (297 * MHz) +#define ACLK_PDISPP_HZ (297 * MHz) +#define CLK_ISPP_HZ (237 * MHz) +#define ACLK_VOP_HZ (300 * MHz) +#define DCLK_VOP_HZ (65 * MHz) +#endif + +/* RV1126 pll id */ +enum rv1126_pll_id { + APLL, + DPLL, + CPLL, + HPLL, + GPLL, + PLL_COUNT, +}; + +struct rv1126_clk_info { + unsigned long id; + char *name; + bool is_cru; +}; + +/* Private data for the clock driver - used by rockchip_get_cru() */ +struct rv1126_pmuclk_priv { + struct rv1126_pmucru *pmucru; + ulong gpll_hz; +}; + +struct rv1126_clk_priv { + struct rv1126_cru *cru; + struct rv1126_grf *grf; + ulong gpll_hz; + ulong cpll_hz; + ulong hpll_hz; + ulong armclk_hz; + ulong armclk_enter_hz; + ulong armclk_init_hz; + bool sync_kernel; + bool set_armclk_rate; +}; + +struct rv1126_pll { + unsigned int con0; + unsigned int con1; + unsigned int con2; + unsigned int con3; + unsigned int con4; + unsigned int con5; + unsigned int con6; + unsigned int reserved0[1]; +}; + +struct rv1126_pmucru { + unsigned int pmu_mode; + unsigned int reserved1[3]; + struct rv1126_pll pll; + unsigned int offsetcal_status; + unsigned int reserved2[51]; + unsigned int pmu_clksel_con[14]; + unsigned int reserved3[18]; + unsigned int pmu_clkgate_con[3]; + unsigned int reserved4[29]; + unsigned int pmu_softrst_con[2]; + unsigned int reserved5[14]; + unsigned int pmu_autocs_con[2]; +}; + +check_member(rv1126_pmucru, pmu_autocs_con[1], 0x244); + +struct rv1126_cru { + struct rv1126_pll pll[4]; + unsigned int offsetcal_status[4]; + unsigned int mode; + unsigned int reserved1[27]; + unsigned int clksel_con[78]; + unsigned int reserved2[18]; + unsigned int clkgate_con[25]; + unsigned int reserved3[7]; + unsigned int softrst_con[15]; + unsigned int reserved4[17]; + unsigned int ssgtbl[32]; + unsigned int glb_cnt_th; + unsigned int glb_rst_st; + unsigned int glb_srst_fst; + unsigned int glb_srst_snd; + unsigned int glb_rst_con; + unsigned int reserved5[11]; + unsigned int sdmmc_con[2]; + unsigned int sdio_con[2]; + unsigned int emmc_con[2]; + unsigned int reserved6[2]; + unsigned int gmac_con; + unsigned int misc[2]; + unsigned int reserved7[45]; + unsigned int autocs_con[26]; +}; + +check_member(rv1126_cru, autocs_con[25], 0x584); + +struct pll_rate_table { + unsigned long rate; + unsigned int fbdiv; + unsigned int postdiv1; + unsigned int refdiv; + unsigned int postdiv2; + unsigned int dsmpd; + unsigned int frac; +}; + +struct cpu_rate_table { + unsigned long rate; + unsigned int aclk_div; + unsigned int pclk_div; +}; + +#define RV1126_PMU_MODE 0x0 +#define RV1126_PMU_PLL_CON(x) ((x) * 0x4 + 0x10) +#define RV1126_PLL_CON(x) ((x) * 0x4) +#define RV1126_MODE_CON 0x90 + +enum { + /* CRU_PMU_CLK_SEL0_CON */ + RTC32K_SEL_SHIFT = 7, + RTC32K_SEL_MASK = 0x3 << RTC32K_SEL_SHIFT, + RTC32K_SEL_PMUPVTM = 0, + RTC32K_SEL_OSC1_32K, + RTC32K_SEL_OSC0_DIV32K, + + /* CRU_PMU_CLK_SEL1_CON */ + PCLK_PDPMU_DIV_SHIFT = 0, + PCLK_PDPMU_DIV_MASK = 0x1f, + + /* CRU_PMU_CLK_SEL2_CON */ + CLK_I2C0_DIV_SHIFT = 0, + CLK_I2C0_DIV_MASK = 0x7f, + + /* CRU_PMU_CLK_SEL3_CON */ + CLK_I2C2_DIV_SHIFT = 0, + CLK_I2C2_DIV_MASK = 0x7f, + + /* CRU_PMU_CLK_SEL6_CON */ + CLK_PWM1_SEL_SHIFT = 15, + CLK_PWM1_SEL_MASK = 1 << CLK_PWM1_SEL_SHIFT, + CLK_PWM1_SEL_XIN24M = 0, + CLK_PWM1_SEL_GPLL, + CLK_PWM1_DIV_SHIFT = 8, + CLK_PWM1_DIV_MASK = 0x7f << CLK_PWM1_DIV_SHIFT, + CLK_PWM0_SEL_SHIFT = 7, + CLK_PWM0_SEL_MASK = 1 << CLK_PWM0_SEL_SHIFT, + CLK_PWM0_SEL_XIN24M = 0, + CLK_PWM0_SEL_GPLL, + CLK_PWM0_DIV_SHIFT = 0, + CLK_PWM0_DIV_MASK = 0x7f, + + /* CRU_PMU_CLK_SEL9_CON */ + CLK_SPI0_SEL_SHIFT = 7, + CLK_SPI0_SEL_MASK = 1 << CLK_SPI0_SEL_SHIFT, + CLK_SPI0_SEL_GPLL = 0, + CLK_SPI0_SEL_XIN24M, + CLK_SPI0_DIV_SHIFT = 0, + CLK_SPI0_DIV_MASK = 0x7f, + + /* CRU_PMU_CLK_SEL13_CON */ + CLK_RTC32K_FRAC_NUMERATOR_SHIFT = 16, + CLK_RTC32K_FRAC_NUMERATOR_MASK = 0xffff << 16, + CLK_RTC32K_FRAC_DENOMINATOR_SHIFT = 0, + CLK_RTC32K_FRAC_DENOMINATOR_MASK = 0xffff, + + /* CRU_CLK_SEL0_CON */ + CORE_HCLK_DIV_SHIFT = 8, + CORE_HCLK_DIV_MASK = 0x1f << CORE_HCLK_DIV_SHIFT, + + /* CRU_CLK_SEL1_CON */ + CORE_ACLK_DIV_SHIFT = 4, + CORE_ACLK_DIV_MASK = 0xf << CORE_ACLK_DIV_SHIFT, + CORE_DBG_DIV_SHIFT = 0, + CORE_DBG_DIV_MASK = 0x7, + + /* CRU_CLK_SEL2_CON */ + HCLK_PDBUS_SEL_SHIFT = 15, + HCLK_PDBUS_SEL_MASK = 1 << HCLK_PDBUS_SEL_SHIFT, + HCLK_PDBUS_SEL_GPLL = 0, + HCLK_PDBUS_SEL_CPLL, + HCLK_PDBUS_DIV_SHIFT = 8, + HCLK_PDBUS_DIV_MASK = 0x1f << HCLK_PDBUS_DIV_SHIFT, + ACLK_PDBUS_SEL_SHIFT = 6, + ACLK_PDBUS_SEL_MASK = 0x3 << ACLK_PDBUS_SEL_SHIFT, + ACLK_PDBUS_SEL_GPLL = 0, + ACLK_PDBUS_SEL_CPLL, + ACLK_PDBUS_SEL_DPLL, + ACLK_PDBUS_DIV_SHIFT = 0, + ACLK_PDBUS_DIV_MASK = 0x1f, + + /* CRU_CLK_SEL3_CON */ + CLK_SCR1_SEL_SHIFT = 15, + CLK_SCR1_SEL_MASK = 1 << CLK_SCR1_SEL_SHIFT, + CLK_SCR1_SEL_GPLL = 0, + CLK_SCR1_SEL_CPLL, + CLK_SCR1_DIV_SHIFT = 8, + CLK_SCR1_DIV_MASK = 0x1f << CLK_SCR1_DIV_SHIFT, + PCLK_PDBUS_SEL_SHIFT = 7, + PCLK_PDBUS_SEL_MASK = 1 << PCLK_PDBUS_SEL_SHIFT, + PCLK_PDBUS_SEL_GPLL = 0, + PCLK_PDBUS_SEL_CPLL, + PCLK_PDBUS_DIV_SHIFT = 0, + PCLK_PDBUS_DIV_MASK = 0x1f, + + /* CRU_CLK_SEL4_CON */ + ACLK_CRYPTO_SEL_SHIFT = 7, + ACLK_CRYPTO_SEL_MASK = 1 << ACLK_CRYPTO_SEL_SHIFT, + ACLK_CRYPTO_SEL_GPLL = 0, + ACLK_CRYPTO_SEL_CPLL, + ACLK_CRYPTO_DIV_SHIFT = 0, + ACLK_CRYPTO_DIV_MASK = 0x1f, + + /* CRU_CLK_SEL5_CON */ + CLK_I2C3_DIV_SHIFT = 8, + CLK_I2C3_DIV_MASK = 0x7f << CLK_I2C3_DIV_SHIFT, + CLK_I2C1_DIV_SHIFT = 0, + CLK_I2C1_DIV_MASK = 0x7f, + + /* CRU_CLK_SEL6_CON */ + CLK_I2C5_DIV_SHIFT = 8, + CLK_I2C5_DIV_MASK = 0x7f << CLK_I2C5_DIV_SHIFT, + CLK_I2C4_DIV_SHIFT = 0, + CLK_I2C4_DIV_MASK = 0x7f, + + /* CRU_CLK_SEL7_CON */ + CLK_CRYPTO_PKA_SEL_SHIFT = 15, + CLK_CRYPTO_PKA_SEL_MASK = 1 << CLK_CRYPTO_PKA_SEL_SHIFT, + CLK_CRYPTO_PKA_SEL_GPLL = 0, + CLK_CRYPTO_PKA_SEL_CPLL, + CLK_CRYPTO_PKA_DIV_SHIFT = 8, + CLK_CRYPTO_PKA_DIV_MASK = 0x1f << CLK_CRYPTO_PKA_DIV_SHIFT, + CLK_CRYPTO_CORE_SEL_SHIFT = 7, + CLK_CRYPTO_CORE_SEL_MASK = 1 << CLK_CRYPTO_CORE_SEL_SHIFT, + CLK_CRYPTO_CORE_SEL_GPLL = 0, + CLK_CRYPTO_CORE_SEL_CPLL, + CLK_CRYPTO_CORE_DIV_SHIFT = 0, + CLK_CRYPTO_CORE_DIV_MASK = 0x1f, + + /* CRU_CLK_SEL8_CON */ + CLK_SPI1_SEL_SHIFT = 8, + CLK_SPI1_SEL_MASK = 1 << CLK_SPI1_SEL_SHIFT, + CLK_SPI1_SEL_GPLL = 0, + CLK_SPI1_SEL_XIN24M, + CLK_SPI1_DIV_SHIFT = 0, + CLK_SPI1_DIV_MASK = 0x7f, + + /* CRU_CLK_SEL9_CON */ + CLK_PWM2_SEL_SHIFT = 15, + CLK_PWM2_SEL_MASK = 1 << CLK_PWM2_SEL_SHIFT, + CLK_PWM2_SEL_XIN24M = 0, + CLK_PWM2_SEL_GPLL, + CLK_PWM2_DIV_SHIFT = 8, + CLK_PWM2_DIV_MASK = 0x7f << CLK_PWM2_DIV_SHIFT, + + /* CRU_CLK_SEL20_CON */ + CLK_SARADC_DIV_SHIFT = 0, + CLK_SARADC_DIV_MASK = 0x7ff, + + /* CRU_CLK_SEL25_CON */ + DCLK_DECOM_SEL_SHIFT = 15, + DCLK_DECOM_SEL_MASK = 1 << DCLK_DECOM_SEL_SHIFT, + DCLK_DECOM_SEL_GPLL = 0, + DCLK_DECOM_SEL_CPLL, + DCLK_DECOM_DIV_SHIFT = 8, + DCLK_DECOM_DIV_MASK = 0x7f << DCLK_DECOM_DIV_SHIFT, + + /* CRU_CLK_SEL26_CON */ + HCLK_PDAUDIO_DIV_SHIFT = 0, + HCLK_PDAUDIO_DIV_MASK = 0x1f, + + /* CRU_CLK_SEL45_CON */ + ACLK_PDVO_SEL_SHIFT = 7, + ACLK_PDVO_SEL_MASK = 1 << ACLK_PDVO_SEL_SHIFT, + ACLK_PDVO_SEL_GPLL = 0, + ACLK_PDVO_SEL_CPLL, + ACLK_PDVO_DIV_SHIFT = 0, + ACLK_PDVO_DIV_MASK = 0x1f, + + /* CRU_CLK_SEL47_CON */ + DCLK_VOP_SEL_SHIFT = 8, + DCLK_VOP_SEL_MASK = 1 << DCLK_VOP_SEL_SHIFT, + DCLK_VOP_SEL_GPLL = 0, + DCLK_VOP_SEL_CPLL, + DCLK_VOP_DIV_SHIFT = 0, + DCLK_VOP_DIV_MASK = 0xff, + +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT) + /* CRU_CLK_SEL49_CON */ + ACLK_PDVI_SEL_SHIFT = 6, + ACLK_PDVI_SEL_MASK = 0x3 << ACLK_PDVI_SEL_SHIFT, + ACLK_PDVI_SEL_CPLL = 0, + ACLK_PDVI_SEL_GPLL, + ACLK_PDVI_SEL_HPLL, + ACLK_PDVI_DIV_SHIFT = 0, + ACLK_PDVI_DIV_MASK = 0x1f, + + /* CRU_CLK_SEL50_CON */ + CLK_ISP_SEL_SHIFT = 6, + CLK_ISP_SEL_MASK = 0x3 << CLK_ISP_SEL_SHIFT, + CLK_ISP_SEL_GPLL = 0, + CLK_ISP_SEL_CPLL, + CLK_ISP_SEL_HPLL, + CLK_ISP_DIV_SHIFT = 0, + CLK_ISP_DIV_MASK = 0x1f, +#endif + + /* CRU_CLK_SEL53_CON */ + HCLK_PDPHP_DIV_SHIFT = 8, + HCLK_PDPHP_DIV_MASK = 0x1f << HCLK_PDPHP_DIV_SHIFT, + ACLK_PDPHP_SEL_SHIFT = 7, + ACLK_PDPHP_SEL_MASK = 1 << ACLK_PDPHP_SEL_SHIFT, + ACLK_PDPHP_SEL_GPLL = 0, + ACLK_PDPHP_SEL_CPLL, + ACLK_PDPHP_DIV_SHIFT = 0, + ACLK_PDPHP_DIV_MASK = 0x1f, + + /* CRU_CLK_SEL57_CON */ + EMMC_SEL_SHIFT = 14, + EMMC_SEL_MASK = 0x3 << EMMC_SEL_SHIFT, + EMMC_SEL_GPLL = 0, + EMMC_SEL_CPLL, + EMMC_SEL_XIN24M, + EMMC_DIV_SHIFT = 0, + EMMC_DIV_MASK = 0xff, + + /* CRU_CLK_SEL58_CON */ + SCLK_SFC_SEL_SHIFT = 15, + SCLK_SFC_SEL_MASK = 0x1 << SCLK_SFC_SEL_SHIFT, + SCLK_SFC_SEL_CPLL = 0, + SCLK_SFC_SEL_GPLL, + SCLK_SFC_DIV_SHIFT = 0, + SCLK_SFC_DIV_MASK = 0xff, + + /* CRU_CLK_SEL59_CON */ + CLK_NANDC_SEL_SHIFT = 15, + CLK_NANDC_SEL_MASK = 0x1 << CLK_NANDC_SEL_SHIFT, + CLK_NANDC_SEL_GPLL = 0, + CLK_NANDC_SEL_CPLL, + CLK_NANDC_DIV_SHIFT = 0, + CLK_NANDC_DIV_MASK = 0xff, + + /* CRU_CLK_SEL61_CON */ + CLK_GMAC_OUT_SEL_SHIFT = 15, + CLK_GMAC_OUT_SEL_MASK = 0x1 << CLK_GMAC_OUT_SEL_SHIFT, + CLK_GMAC_OUT_SEL_CPLL = 0, + CLK_GMAC_OUT_SEL_GPLL, + CLK_GMAC_OUT_DIV_SHIFT = 8, + CLK_GMAC_OUT_DIV_MASK = 0x1f << CLK_GMAC_OUT_DIV_SHIFT, + + /* CRU_CLK_SEL63_CON */ + PCLK_GMAC_DIV_SHIFT = 8, + PCLK_GMAC_DIV_MASK = 0x1f << PCLK_GMAC_DIV_SHIFT, + CLK_GMAC_SRC_SEL_SHIFT = 7, + CLK_GMAC_SRC_SEL_MASK = 0x1 << CLK_GMAC_SRC_SEL_SHIFT, + CLK_GMAC_SRC_SEL_CPLL = 0, + CLK_GMAC_SRC_SEL_GPLL, + CLK_GMAC_SRC_DIV_SHIFT = 0, + CLK_GMAC_SRC_DIV_MASK = 0x1f << CLK_GMAC_SRC_DIV_SHIFT, + +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT) + /* CRU_CLK_SEL68_CON */ + ACLK_PDISPP_SEL_SHIFT = 6, + ACLK_PDISPP_SEL_MASK = 0x3 << ACLK_PDISPP_SEL_SHIFT, + ACLK_PDISPP_SEL_CPLL = 0, + ACLK_PDISPP_SEL_GPLL, + ACLK_PDISPP_SEL_HPLL, + ACLK_PDISPP_DIV_SHIFT = 0, + ACLK_PDISPP_DIV_MASK = 0x1f, + + /* CRU_CLK_SEL69_CON */ + CLK_ISPP_SEL_SHIFT = 6, + CLK_ISPP_SEL_MASK = 0x3 << CLK_ISPP_SEL_SHIFT, + CLK_ISPP_SEL_CPLL = 0, + CLK_ISPP_SEL_GPLL, + CLK_ISPP_SEL_HPLL, + CLK_ISPP_DIV_SHIFT = 0, + CLK_ISPP_DIV_MASK = 0x1f, + + /* CRU_CLK_SEL73_CON */ + MIPICSI_OUT_SEL_SHIFT = 10, + MIPICSI_OUT_SEL_MASK = 0x3 << MIPICSI_OUT_SEL_SHIFT, + MIPICSI_OUT_SEL_XIN24M = 0, + MIPICSI_OUT_SEL_DIV, + MIPICSI_OUT_SEL_FRACDIV, + MIPICSI_OUT_DIV_SHIFT = 0, + MIPICSI_OUT_DIV_MASK = 0x1f, +#endif + + /* CRU_GMAC_CON */ + GMAC_SRC_M1_SEL_SHIFT = 5, + GMAC_SRC_M1_SEL_MASK = 0x1 << GMAC_SRC_M1_SEL_SHIFT, + GMAC_SRC_M1_SEL_INT = 0, + GMAC_SRC_M1_SEL_EXT, + GMAC_MODE_SEL_SHIFT = 4, + GMAC_MODE_SEL_MASK = 0x1 << GMAC_MODE_SEL_SHIFT, + GMAC_RGMII_MODE = 0, + GMAC_RMII_MODE, + RGMII_CLK_SEL_SHIFT = 2, + RGMII_CLK_SEL_MASK = 0x3 << RGMII_CLK_SEL_SHIFT, + RGMII_CLK_DIV0 = 0, + RGMII_CLK_DIV1, + RGMII_CLK_DIV50, + RGMII_CLK_DIV5, + RMII_CLK_SEL_SHIFT = 1, + RMII_CLK_SEL_MASK = 0x1 << RMII_CLK_SEL_SHIFT, + RMII_CLK_DIV20 = 0, + RMII_CLK_DIV2, + GMAC_SRC_M0_SEL_SHIFT = 0, + GMAC_SRC_M0_SEL_MASK = 0x1, + GMAC_SRC_M0_SEL_INT = 0, + GMAC_SRC_M0_SEL_EXT, + + /* GRF_IOFUNC_CON1 */ + GMAC_SRC_SEL_SHIFT = 12, + GMAC_SRC_SEL_MASK = 1 << GMAC_SRC_SEL_SHIFT, + GMAC_SRC_SEL_M0 = 0, + GMAC_SRC_SEL_M1, +}; +#endif diff --git a/arch/arm/include/asm/arch-rockchip/dram_spec_timing.h b/arch/arm/include/asm/arch-rockchip/dram_spec_timing.h new file mode 100644 index 0000000..a691e97 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/dram_spec_timing.h @@ -0,0 +1,452 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Rockchip Electronics Co., Ltd + */ + +#ifndef __ROCKCHIP_DRAM_SPEC_TIMING_H__ +#define __ROCKCHIP_DRAM_SPEC_TIMING_H__ + +enum ddr3_speed_rate { + /* 5-5-5 */ + DDR3_800D = 0, + /* 6-6-6 */ + DDR3_800E = 1, + /* 6-6-6 */ + DDR3_1066E = 2, + /* 7-7-7 */ + DDR3_1066F = 3, + /* 8-8-8 */ + DDR3_1066G = 4, + /* 7-7-7 */ + DDR3_1333F = 5, + /* 8-8-8 */ + DDR3_1333G = 6, + /* 9-9-9 */ + DDR3_1333H = 7, + /* 10-10-10 */ + DDR3_1333J = 8, + /* 8-8-8 */ + DDR3_1600G = 9, + /* 9-9-9 */ + DDR3_1600H = 10, + /* 10-10-10 */ + DDR3_1600J = 11, + /* 11-11-11 */ + DDR3_1600K = 12, + /* 10-10-10 */ + DDR3_1866J = 13, + /* 11-11-11 */ + DDR3_1866K = 14, + /* 12-12-12 */ + DDR3_1866L = 15, + /* 13-13-13 */ + DDR3_1866M = 16, + /* 11-11-11 */ + DDR3_2133K = 17, + /* 12-12-12 */ + DDR3_2133L = 18, + /* 13-13-13 */ + DDR3_2133M = 19, + /* 14-14-14 */ + DDR3_2133N = 20, + DDR3_DEFAULT = 21, +}; + +enum ddr4_speed_rate { + /* DDR4_1600J (10-10-10) */ + DDR4_1600J = 0, + /* DDR4_1600K (11-11-11) */ + DDR4_1600K = 1, + /* DDR4_1600L (12-12-12) */ + DDR4_1600L = 2, + /* DDR4_1800L (12-12-12) */ + DDR4_1866L = 3, + /* DDR4_1800M (13-13-13) */ + DDR4_1866M = 4, + /* DDR4_1800N (14-14-14) */ + DDR4_1866N = 5, + /* DDR4_2133N (14-14-14) */ + DDR4_2133N = 6, + /* DDR4_2133P (15-15-15) */ + DDR4_2133P = 7, + /* DDR4_2133R (16-16-16) */ + DDR4_2133R = 8, + /* DDR4_2400P (15-15-15) */ + DDR4_2400P = 9, + /* DDR4_2400R (16-16-16) */ + DDR4_2400R = 10, + /* DDR4_2400U (18-18-18) */ + DDR4_2400U = 11, + /* DEFAULT */ + DDR4_DEFAULT = 12, +}; + +/* mr0 for ddr3 */ +#define DDR3_BL8 (0) +#define DDR3_BC4_8 (1) +#define DDR3_BC4 (2) +#define DDR3_CL(n) (((((n) - 4) & 0x7) << 4)\ + | ((((n) - 4) & 0x8) >> 1)) +#define DDR3_WR(n) (((n) & 0x7) << 9) +#define DDR3_DLL_RESET (1 << 8) +#define DDR3_DLL_DERESET (0 << 8) + +/* mr1 for ddr3 */ +#define DDR3_DLL_ENABLE (0) +#define DDR3_DLL_DISABLE (1) +#define DDR3_MR1_AL(n) (((n) & 0x3) << 3) + +#define DDR3_DS_40 (0) +#define DDR3_DS_34 BIT(1) +#define DDR3_DS_MASK ((1 << 1) | (1 << 5)) +#define DDR3_RTT_NOM_MASK ((1 << 2) | (1 << 6) | (1 << 9)) +#define DDR3_RTT_NOM_DIS (0) +#define DDR3_RTT_NOM_60 BIT(2) +#define DDR3_RTT_NOM_120 BIT(6) +#define DDR3_RTT_NOM_40 ((1 << 2) | (1 << 6)) +#define DDR3_TDQS BIT(11) + +/* mr2 for ddr3 */ +#define DDR3_MR2_CWL(n) ((((n) - 5) & 0x7) << 3) +#define DDR3_RTT_WR_DIS (0) +#define DDR3_RTT_WR_60 (1 << 9) +#define DDR3_RTT_WR_120 (2 << 9) + +/* + * MR0 (Device Information) + * 0:DAI complete, 1:DAI still in progress + */ +#define LPDDR2_DAI (0x1) +/* 0:S2 or S4 SDRAM, 1:NVM */ +#define LPDDR2_DI (0x1 << 1) +/* 0:DNV not supported, 1:DNV supported */ +#define LPDDR2_DNVI (0x1 << 2) +#define LPDDR2_RZQI (0x3 << 3) + +/* + * 00:RZQ self test not supported, + * 01:ZQ-pin may connect to VDDCA or float + * 10:ZQ-pin may short to GND. + * 11:ZQ-pin self test completed, no error condition detected. + */ + +/* MR1 (Device Feature) */ +#define LPDDR2_BL4 (0x2) +#define LPDDR2_BL8 (0x3) +#define LPDDR2_BL16 (0x4) +#define LPDDR2_N_WR(n) (((n) - 2) << 5) + +/* MR2 (Device Feature 2) */ +#define LPDDR2_RL3_WL1 (0x1) +#define LPDDR2_RL4_WL2 (0x2) +#define LPDDR2_RL5_WL2 (0x3) +#define LPDDR2_RL6_WL3 (0x4) +#define LPDDR2_RL7_WL4 (0x5) +#define LPDDR2_RL8_WL4 (0x6) + +/* MR3 (IO Configuration 1) */ +#define LPDDR2_DS_34 (0x1) +#define LPDDR2_DS_40 (0x2) +#define LPDDR2_DS_48 (0x3) +#define LPDDR2_DS_60 (0x4) +#define LPDDR2_DS_80 (0x6) +/* optional */ +#define LPDDR2_DS_120 (0x7) + +/* MR4 (Device Temperature) */ +#define LPDDR2_TREF_MASK (0x7) +#define LPDDR2_4_TREF (0x1) +#define LPDDR2_2_TREF (0x2) +#define LPDDR2_1_TREF (0x3) +#define LPDDR2_025_TREF (0x5) +#define LPDDR2_025_TREF_DERATE (0x6) + +#define LPDDR2_TUF (0x1 << 7) + +/* MR8 (Basic configuration 4) */ +#define LPDDR2_S4 (0x0) +#define LPDDR2_S2 (0x1) +#define LPDDR2_N (0x2) +/* Unit:MB */ +#define LPDDR2_DENSITY(mr8) (8 << (((mr8) >> 2) & 0xf)) +#define LPDDR2_IO_WIDTH(mr8) (32 >> (((mr8) >> 6) & 0x3)) + +/* MR10 (Calibration) */ +#define LPDDR2_ZQINIT (0xff) +#define LPDDR2_ZQCL (0xab) +#define LPDDR2_ZQCS (0x56) +#define LPDDR2_ZQRESET (0xc3) + +/* MR16 (PASR Bank Mask), S2 SDRAM Only */ +#define LPDDR2_PASR_FULL (0x0) +#define LPDDR2_PASR_1_2 (0x1) +#define LPDDR2_PASR_1_4 (0x2) +#define LPDDR2_PASR_1_8 (0x3) + +/* + * MR0 (Device Information) + * 0:DAI complete, + * 1:DAI still in progress + */ +#define LPDDR3_DAI (0x1) +/* + * 00:RZQ self test not supported, + * 01:ZQ-pin may connect to VDDCA or float + * 10:ZQ-pin may short to GND. + * 11:ZQ-pin self test completed, no error condition detected. + */ +#define LPDDR3_RZQI (0x3 << 3) +/* + * 0:DRAM does not support WL(Set B), + * 1:DRAM support WL(Set B) + */ +#define LPDDR3_WL_SUPOT BIT(6) +/* + * 0:DRAM does not support RL=3,nWR=3,WL=1; + * 1:DRAM supports RL=3,nWR=3,WL=1 for frequencies <=166 + */ +#define LPDDR3_RL3_SUPOT BIT(7) + +/* MR1 (Device Feature) */ +#define LPDDR3_BL8 (0x3) +#define LPDDR3_N_WR(n) ((n) << 5) + +/* MR2 (Device Feature 2), WL Set A,default */ +/* <=166MHz,optional*/ +#define LPDDR3_RL3_WL1 (0x1) +/* <=400MHz*/ +#define LPDDR3_RL6_WL3 (0x4) +/* <=533MHz*/ +#define LPDDR3_RL8_WL4 (0x6) +/* <=600MHz*/ +#define LPDDR3_RL9_WL5 (0x7) +/* <=667MHz,default*/ +#define LPDDR3_RL10_WL6 (0x8) +/* <=733MHz*/ +#define LPDDR3_RL11_WL6 (0x9) +/* <=800MHz*/ +#define LPDDR3_RL12_WL6 (0xa) +/* <=933MHz*/ +#define LPDDR3_RL14_WL8 (0xc) +/* <=1066MHz*/ +#define LPDDR3_RL16_WL8 (0xe) + +/* WL Set B, optional */ +/* <=667MHz,default*/ +#define LPDDR3_RL10_WL8 (0x8) +/* <=733MHz*/ +#define LPDDR3_RL11_WL9 (0x9) +/* <=800MHz*/ +#define LPDDR3_RL12_WL9 (0xa) +/* <=933MHz*/ +#define LPDDR3_RL14_WL11 (0xc) +/* <=1066MHz*/ +#define LPDDR3_RL16_WL13 (0xe) + +/* 1:enable nWR programming > 9(default)*/ +#define LPDDR3_N_WRE BIT(4) +/* 1:Select WL Set B*/ +#define LPDDR3_WL_S BIT(6) +/* 1:enable*/ +#define LPDDR3_WR_LEVEL BIT(7) + +/* MR3 (IO Configuration 1) */ +#define LPDDR3_DS_34 (0x1) +#define LPDDR3_DS_40 (0x2) +#define LPDDR3_DS_48 (0x3) +#define LPDDR3_DS_60 (0x4) +#define LPDDR3_DS_80 (0x6) +#define LPDDR3_DS_34D_40U (0x9) +#define LPDDR3_DS_40D_48U (0xa) +#define LPDDR3_DS_34D_48U (0xb) + +/* MR4 (Device Temperature) */ +#define LPDDR3_TREF_MASK (0x7) +/* SDRAM Low temperature operating limit exceeded */ +#define LPDDR3_LT_EXED (0x0) +#define LPDDR3_4_TREF (0x1) +#define LPDDR3_2_TREF (0x2) +#define LPDDR3_1_TREF (0x3) +#define LPDDR3_05_TREF (0x4) +#define LPDDR3_025_TREF (0x5) +#define LPDDR3_025_TREF_DERATE (0x6) +/* SDRAM High temperature operating limit exceeded */ +#define LPDDR3_HT_EXED (0x7) + +/* 1:value has changed since last read of MR4 */ +#define LPDDR3_TUF (0x1 << 7) + +/* MR8 (Basic configuration 4) */ +#define LPDDR3_S8 (0x3) +#define LPDDR3_DENSITY(mr8) (8 << (((mr8) >> 2) & 0xf)) +#define LPDDR3_IO_WIDTH(mr8) (32 >> (((mr8) >> 6) & 0x3)) + +/* MR10 (Calibration) */ +#define LPDDR3_ZQINIT (0xff) +#define LPDDR3_ZQCL (0xab) +#define LPDDR3_ZQCS (0x56) +#define LPDDR3_ZQRESET (0xc3) + +/* MR11 (ODT Control) */ +#define LPDDR3_ODT_60 (1) +#define LPDDR3_ODT_120 (2) +#define LPDDR3_ODT_240 (3) +#define LPDDR3_ODT_DIS (0) + +/* MR2 (Device Feature 2) */ +/* RL & nRTP for DBI-RD Disabled */ +#define LPDDR4_RL6_NRTP8 (0x0) +#define LPDDR4_RL10_NRTP8 (0x1) +#define LPDDR4_RL14_NRTP8 (0x2) +#define LPDDR4_RL20_NRTP8 (0x3) +#define LPDDR4_RL24_NRTP10 (0x4) +#define LPDDR4_RL28_NRTP12 (0x5) +#define LPDDR4_RL32_NRTP14 (0x6) +#define LPDDR4_RL36_NRTP16 (0x7) +/* RL & nRTP for DBI-RD Disabled */ +#define LPDDR4_RL12_NRTP8 (0x1) +#define LPDDR4_RL16_NRTP8 (0x2) +#define LPDDR4_RL22_NRTP8 (0x3) +#define LPDDR4_RL28_NRTP10 (0x4) +#define LPDDR4_RL32_NRTP12 (0x5) +#define LPDDR4_RL36_NRTP14 (0x6) +#define LPDDR4_RL40_NRTP16 (0x7) +/* WL Set A,default */ +#define LPDDR4_A_WL4 (0x0 << 3) +#define LPDDR4_A_WL6 (0x1 << 3) +#define LPDDR4_A_WL8 (0x2 << 3) +#define LPDDR4_A_WL10 (0x3 << 3) +#define LPDDR4_A_WL12 (0x4 << 3) +#define LPDDR4_A_WL14 (0x5 << 3) +#define LPDDR4_A_WL16 (0x6 << 3) +#define LPDDR4_A_WL18 (0x7 << 3) +/* WL Set B, optional */ +#define LPDDR4_B_WL4 (0x0 << 3) +#define LPDDR4_B_WL8 (0x1 << 3) +#define LPDDR4_B_WL12 (0x2 << 3) +#define LPDDR4_B_WL18 (0x3 << 3) +#define LPDDR4_B_WL22 (0x4 << 3) +#define LPDDR4_B_WL26 (0x5 << 3) +#define LPDDR4_B_WL30 (0x6 << 3) +#define LPDDR4_B_WL34 (0x7 << 3) +/* 1:Select WL Set B*/ +#define LPDDR4_WL_B BIT(6) +/* 1:enable*/ +#define LPDDR4_WR_LEVEL BIT(7) + +/* MR3 */ +#define LPDDR4_VDDQ_2_5 (0) +#define LPDDR4_VDDQ_3 (1) +#define LPDDR4_PU_CAL_MASK (1) +#define LPDDR4_WRPST_0_5_TCK (0 << 1) +#define LPDDR4_WRPST_1_5_TCK (1 << 1) +#define LPDDR4_PPR_EN (1 << 2) +/* PDDS */ +#define LPDDR4_PDDS_MASK (0x7 << 3) +#define LPDDR4_PDDS_SHIFT (3) +#define LPDDR4_PDDS_240 (0x1 << 3) +#define LPDDR4_PDDS_120 (0x2 << 3) +#define LPDDR4_PDDS_80 (0x3 << 3) +#define LPDDR4_PDDS_60 (0x4 << 3) +#define LPDDR4_PDDS_48 (0x5 << 3) +#define LPDDR4_PDDS_40 (0x6 << 3) +#define LPDDR4_DBI_RD_EN BIT(6) +#define LPDDR4_DBI_WR_EN BIT(7) + +/* MR11 (ODT Control) */ +#define LPDDR4_DQODT_MASK (0x7) +#define LPDDR4_DQODT_SHIFT (0x0) +#define LPDDR4_DQODT_240 (1) +#define LPDDR4_DQODT_120 (2) +#define LPDDR4_DQODT_80 (3) +#define LPDDR4_DQODT_60 (4) +#define LPDDR4_DQODT_48 (5) +#define LPDDR4_DQODT_40 (6) +#define LPDDR4_DQODT_DIS (0) +#define LPDDR4_CAODT_MASK (0x7 << 4) +#define LPDDR4_CAODT_SHIFT (4) +#define LPDDR4_CAODT_240 (1 << 4) +#define LPDDR4_CAODT_120 (2 << 4) +#define LPDDR4_CAODT_80 (3 << 4) +#define LPDDR4_CAODT_60 (4 << 4) +#define LPDDR4_CAODT_48 (5 << 4) +#define LPDDR4_CAODT_40 (6 << 4) +#define LPDDR4_CAODT_DIS (0 << 4) + +/* MR22 */ +#define LPDDR4_ODTE_CK_SHIFT (3) +#define LPDDR4_ODTE_CS_SHIFT (4) +#define LPDDR4_ODTD_CA_SHIFT (5) +#define LPDDR4_SOC_ODT_MASK (0x7) +#define LPDDR4_SOC_ODT_SHIFT (0) +#define LPDDR4_SOC_ODT_240 (1) +#define LPDDR4_SOC_ODT_120 (2) +#define LPDDR4_SOC_ODT_80 (3) +#define LPDDR4_SOC_ODT_60 (4) +#define LPDDR4_SOC_ODT_48 (5) +#define LPDDR4_SOC_ODT_40 (6) +#define LPDDR4_SOC_ODT_DIS (0) + +/* LPDDR4x */ +/* MR3 */ +#define LPDDR4X_VDDQ_0_6 (0) +#define LPDDR4X_VDDQ_0_5 (1) + +/* mr0 for ddr4 */ +#define DDR4_BL8 (0) +#define DDR4_BC4_8 (1) +#define DDR4_BC4 (2) +#define DDR4_WR_RTP(n) ((n) << 9) +#define DDR4_CL(n) ((((n) & 0xe) << 3) | ((n) & 1) << 2) +#define DDR4_DLL_RESET(n) ((n) << 8) +#define DDR4_DLL_ON BIT(0) +#define DDR4_DLL_OFF (0 << 0) + +/* mr1 for ddr4 */ +#define DDR4_AL ((n) << 3) +#define DDR4_DS_34 (0) +#define DDR4_DS_48 BIT(1) +#define DDR4_DS_MASK (0x3 << 1) +#define DDR4_RTT_NOM_MASK (0x7 << 8) +#define DDR4_RTT_NOM_DIS (0) +#define DDR4_RTT_NOM_60 BIT(8) +#define DDR4_RTT_NOM_120 (2 << 8) +#define DDR4_RTT_NOM_40 (0x3 << 8) +#define DDR4_RTT_NOM_240 (0x4 << 8) +#define DDR4_RTT_NOM_48 (0x5 << 8) +#define DDR4_RTT_NOM_80 (0x6 << 8) +#define DDR4_RTT_NOM_34 (0x7 << 8) + +/* mr2 for ddr4 */ +#define DDR4_MR2_CWL(n) ((n) << 3) +#define DDR4_RTT_WR_DIS (0) +#define DDR4_RTT_WR_120 BIT(9) +#define DDR4_RTT_WR_240 (2 << 9) + +/* mr4 for ddr4 */ +#define DDR4_READ_PREAMBLE(n) ((n) << 11) +#define DDR4_WRITE_PREAMBLE(n) ((n) << 12) +#define DDR4_READ_PREAMBLE_TRAIN(n) ((n) << 10) + +/* mr5 for ddr4 */ +#define DDR4_RD_DBI(n) ((n) << 12) +#define DDR4_WR_DBI(n) ((n) << 11) +#define DDR4_DM(n) ((n) << 10) +#define DDR4_RTT_PARK_DIS (0 << 6) +#define DDR4_RTT_PARK_60 (1 << 6) +#define DDR4_RTT_PARK_120 (2 << 6) +#define DDR4_RTT_PARK_40 (3 << 6) +#define DDR4_RTT_PARK_240 (4 << 6) +#define DDR4_RTT_PARK_48 (5 << 6) +#define DDR4_RTT_PARK_80 (6 << 6) +#define DDR4_RTT_PARK_34 (7 << 6) +#define DIS_ODT_PD (1 << 5) +#define EN_ODT_PD (0 << 5) + +/* mr6 for ddr4 */ +#define DDR4_TCCD_L(n) (((n) - 4) << 10) + +#define PS_2_CLK(freq, ps) (((uint64_t)(ps) / 100 * (uint64_t)(freq) +\ + 9999) / 10000) + +#endif /* __ROCKCHIP_DRAM_SPEC_TIMING_H__ */ diff --git a/arch/arm/include/asm/arch-rockchip/grf_rv1126.h b/arch/arm/include/asm/arch-rockchip/grf_rv1126.h new file mode 100644 index 0000000..4e0488b --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/grf_rv1126.h @@ -0,0 +1,251 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2019 Rockchip Electronics Co., Ltd. + */ + +#ifndef _ASM_ARCH_GRF_RV1126_H +#define _ASM_ARCH_GRF_RV1126_H + +struct rv1126_grf { + unsigned int soc_con0; + unsigned int soc_con1; + unsigned int soc_con2; + unsigned int reserved0[1]; + unsigned int soc_status0; + unsigned int soc_status1; + unsigned int reserved1[2]; + unsigned int cpu_con0; + unsigned int cpu_con1; + unsigned int reserved2[2]; + unsigned int cpu_status0; + unsigned int reserved3[3]; + unsigned int noc_con0; + unsigned int noc_con1; + unsigned int noc_con2; + unsigned int noc_con3; + unsigned int usbhost_con0; + unsigned int usbhost_con1; + unsigned int usbhost_status0; + unsigned int usbotg_con0; + unsigned int usbotg_con1; + unsigned int usbotg_status0; + unsigned int usbotg_status1; + unsigned int usbotg_status2; + unsigned int mac_con0; + unsigned int mac_con1; + unsigned int mac_con2; + unsigned int reserved4[2]; + unsigned int mac_status0; + unsigned int mac_status1; + unsigned int mac_status2; + unsigned int mem_con0; + unsigned int mem_con1; + unsigned int mem_con2; + unsigned int mem_con3; + unsigned int reserved5[(0x100 - 0x09c) / 4 - 1]; + unsigned int tsadc_con0; + unsigned int reserved6[3]; + unsigned int chip_id; + unsigned int reserved7[(0x10000 - 0x110) / 4 - 1]; + unsigned int gpio0c_iomux_h; + unsigned int gpio0d_iomux_l; + unsigned int gpio0d_iomux_h; + unsigned int reserved8[1]; + unsigned int gpio1a_iomux_l; + unsigned int gpio1a_iomux_h; + unsigned int gpio1b_iomux_l; + unsigned int gpio1b_iomux_h; + unsigned int gpio1c_iomux_l; + unsigned int gpio1c_iomux_h; + unsigned int gpio1d_iomux_l; + unsigned int gpio1d_iomux_h; + unsigned int gpio2a_iomux_l; + unsigned int gpio2a_iomux_h; + unsigned int gpio2b_iomux_l; + unsigned int gpio2b_iomux_h; + unsigned int gpio2c_iomux_l; + unsigned int gpio2c_iomux_h; + unsigned int gpio2d_iomux_l; + unsigned int gpio2d_iomux_h; + unsigned int gpio3a_iomux_l; + unsigned int gpio3a_iomux_h; + unsigned int gpio3b_iomux_l; + unsigned int gpio3b_iomux_h; + unsigned int gpio3c_iomux_l; + unsigned int gpio3c_iomux_h; + unsigned int gpio3d_iomux_l; + unsigned int gpio3d_iomux_h; + unsigned int gpio4a_iomux_l; + unsigned int reserved9[3]; + unsigned int gpio0c_ds_h; + unsigned int gpio0d_ds_l; + unsigned int gpio0d_ds_h; + unsigned int reserved10[1]; + unsigned int gpio1a_ds_l; + unsigned int gpio1a_ds_h; + unsigned int gpio1b_ds_l; + unsigned int gpio1b_ds_h; + unsigned int gpio1c_ds_l; + unsigned int gpio1c_ds_h; + unsigned int gpio1d_ds_l; + unsigned int gpio1d_ds_h; + unsigned int gpio2a_ds_l; + unsigned int gpio2a_ds_h; + unsigned int gpio2b_ds_l; + unsigned int gpio2b_ds_h; + unsigned int gpio2c_ds_l; + unsigned int gpio2c_ds_h; + unsigned int gpio2d_ds_l; + unsigned int gpio2d_ds_h; + unsigned int gpio3a_ds_l; + unsigned int gpio3a_ds_h; + unsigned int gpio3b_ds_l; + unsigned int gpio3b_ds_h; + unsigned int gpio3c_ds_l; + unsigned int gpio3c_ds_h; + unsigned int gpio3d_ds_l; + unsigned int gpio3d_ds_h; + unsigned int gpio4a_ds_l; + unsigned int reserved12[3]; + unsigned int gpio0c_p_h; + unsigned int gpio0d_p; + unsigned int gpio1a_p; + unsigned int gpio1b_p; + unsigned int gpio1c_p; + unsigned int gpio1d_p; + unsigned int gpio2a_p; + unsigned int gpio2b_p; + unsigned int gpio2c_p; + unsigned int gpio2d_p; + unsigned int gpio3a_p; + unsigned int gpio3b_p; + unsigned int gpio3c_p; + unsigned int gpio3d_p; + unsigned int gpio4a_p; + unsigned int reserved13[1]; + unsigned int gpio0c_ie_h; + unsigned int gpio0d_ie; + unsigned int gpio1a_ie; + unsigned int gpio1b_ie; + unsigned int gpio1c_ie; + unsigned int gpio1d_ie; + unsigned int gpio2a_ie; + unsigned int gpio2b_ie; + unsigned int gpio2c_ie; + unsigned int gpio2d_ie; + unsigned int gpio3a_ie; + unsigned int gpio3b_ie; + unsigned int gpio3c_ie; + unsigned int gpio3d_ie; + unsigned int gpio4a_ie; + unsigned int reserved14[1]; + unsigned int gpio0c_smt_h; + unsigned int gpio0d_smt; + unsigned int gpio1a_smt; + unsigned int gpio1b_smt; + unsigned int gpio1c_smt; + unsigned int gpio1d_smt; + unsigned int gpio2a_smt; + unsigned int gpio2b_smt; + unsigned int gpio2c_smt; + unsigned int gpio2d_smt; + unsigned int gpio3a_smt; + unsigned int gpio3b_smt; + unsigned int gpio3c_smt; + unsigned int gpio3d_smt; + unsigned int gpio4a_smt; + unsigned int reserved15[(0x10200 - 0x101b8) / 4 - 1]; + unsigned int csiphy0_con; + unsigned int reserved16[1]; + unsigned int csiphy0_status; + unsigned int reserved17[1]; + unsigned int csiphy1_con; + unsigned int reserved18[1]; + unsigned int csiphy1_status; + unsigned int reserved19[1]; + unsigned int dsiphy_con; + unsigned int reserved20[3]; + unsigned int usbphy_con0; + unsigned int usbphy_con1; + unsigned int usbphy_con2; + unsigned int reserved21[3]; + unsigned int usbphy_status; + unsigned int reserved22[1]; + unsigned int cifio_con; + unsigned int sddetflt_con; + unsigned int uart2rx_low_con; + unsigned int reserved23[1]; + unsigned int iofunc_con0; + unsigned int iofunc_con1; + unsigned int iofunc_con2; + unsigned int iofunc_con3; + unsigned int usbphy0_cfg_con; + unsigned int usbphy0_cfg_addrin; + unsigned int usbphy0_cfg_addrout; + unsigned int usbphy0_cfg_dly_con; + unsigned int usbphy1_cfg_con; + unsigned int usbphy1_cfg_addrin; + unsigned int usbphy1_cfg_addrout; + unsigned int usbphy1_cfg_dly_con; + unsigned int reserved24[(0x10300 - 0x1028c) / 4 - 1]; + unsigned int usb_sig_detect_con; + unsigned int usb_sig_detect_status; + unsigned int usb_sig_detect_clr; + unsigned int reserved25[1]; + unsigned int usb_linestate_con; + unsigned int usb_disconnect_con; + unsigned int usb_bvalid_con; + unsigned int usb_id_con; +}; + +check_member(rv1126_grf, usb_id_con, 0x1031c); + +struct rv1126_pmugrf { + unsigned int gpio0a_iomux_l; + unsigned int gpio0a_iomux_h; + unsigned int gpio0b_iomux_l; + unsigned int gpio0b_iomux_h; + unsigned int gpio0c_iomux_l; + unsigned int reserved0[3]; + unsigned int gpio0a_ds_l; + unsigned int gpio0a_ds_h; + unsigned int gpio0b_ds_l; + unsigned int gpio0b_ds_h; + unsigned int gpio0c_ds_l; + unsigned int osc_ds; + unsigned int reserved1[2]; + unsigned int gpio0a_p; + unsigned int gpio0b_p; + unsigned int gpio0c_p_l; + unsigned int reserved2[1]; + unsigned int gpio0a_ie; + unsigned int gpio0b_ie; + unsigned int gpio0c_ie_l; + unsigned int reserved3[1]; + unsigned int gpio0a_smt; + unsigned int gpio0b_smt; + unsigned int gpio0c_smt_l; + unsigned int reserved4[(0x100 - 0x68) / 4 - 1]; + unsigned int soc_con[7]; + unsigned int reserved5[(0x140 - 0x118) / 4 - 1]; + unsigned int io_vsel; + unsigned int io_vret; + unsigned int reserved6[(0x180 - 0x144) / 4 - 1]; + unsigned int pmupvtm_clkdiv; + unsigned int reserved7[(0x200 - 0x180) / 4 - 1]; + unsigned int os_reg[12]; + unsigned int rstfunc_status; + unsigned int rstfunc_clr; + unsigned int reserved8[(0x380 - 0x234) / 4 - 1]; + unsigned int sd_detect_con; + unsigned int reserved9[3]; + unsigned int sd_detect_status; + unsigned int reserved10[3]; + unsigned int sd_detect_clr; + unsigned int reserved11[3]; + unsigned int sd_det_count; +}; + +check_member(rv1126_pmugrf, sd_det_count, 0x3b0); + +#endif diff --git a/arch/arm/include/asm/arch-rockchip/sdram_common.h b/arch/arm/include/asm/arch-rockchip/sdram_common.h index 5efa6e9..e53e5a9 100644 --- a/arch/arm/include/asm/arch-rockchip/sdram_common.h +++ b/arch/arm/include/asm/arch-rockchip/sdram_common.h @@ -15,6 +15,210 @@ #define MIN(a, b) (((a) > (b)) ? (b) : (a)) #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +/* get head info for initial */ +#define DDR_FREQ_F0_SHIFT (0) +#define DDR_FREQ_F1_SHIFT (12) +#define DDR_FREQ_F2_SHIFT (0) +#define DDR_FREQ_F3_SHIFT (12) +#define DDR_FREQ_F4_SHIFT (0) +#define DDR_FREQ_F5_SHIFT (12) +#define DDR_FREQ_MASK (0xfff) + +#define UART_INFO_ID_SHIFT (28) +#define UART_INFO_IOMUX_SHIFT (24) +#define UART_INFO_BAUD_SHIFT (0) +#define UART_INFO_ID(n) (((n) >> 28) & 0xf) +#define UART_INFO_IOMUX(n) (((n) >> 24) & 0xf) +#define UART_INFO_BAUD(n) ((n) & 0xffffff) + +/* g_ch_info[15:0]: g_stdby_idle */ +#define STANDBY_IDLE(n) ((n) & 0xffff) + +#define SR_INFO(n) (((n) >> 16) & 0xffff) +#define PD_INFO(n) ((n) & 0xffff) + +#define FIRST_SCAN_CH(n) (((n) >> 28) & 0xf) +#define CHANNEL_MASK(n) (((n) >> 24) & 0xf) +#define STRIDE_TYPE(n) (((n) >> 16) & 0xff) + +#define DDR_2T_INFO(n) ((n) & 1) +#define PLL_SSMOD_SPREAD(n) (((n) >> 1) & 0xff) +#define PLL_SSMOD_DIV(n) (((n) >> 9) & 0xff) +#define PLL_SSMOD_DOWNSPREAD(n) (((n) >> 17) & 0x3) + +/* sdram_head_info_v2 define */ +/* for *_drv_odten and *_drv_odtoff */ +#define PHY_DQ_DRV_SHIFT 0 +#define PHY_CA_DRV_SHIFT 8 +#define PHY_CLK_DRV_SHIFT 16 +#define DRAM_DQ_DRV_SHIFT 24 +#define DRV_INFO_PHY_DQ_DRV(n) ((n) & 0xff) +#define DRV_INFO_PHY_CA_DRV(n) (((n) >> PHY_CA_DRV_SHIFT) & 0xff) +#define DRV_INFO_PHY_CLK_DRV(n) (((n) >> PHY_CLK_DRV_SHIFT) & 0xff) +#define DRV_INFO_DRAM_DQ_DRV(n) (((n) >> DRAM_DQ_DRV_SHIFT) & 0xff) + +/* for *_odt_info */ +#define DRAM_ODT_SHIFT 0 +#define PHY_ODT_SHIFT 8 +#define PHY_ODT_PUUP_EN_SHIFT 18 +#define PHY_ODT_PUDN_EN_SHIFT 19 +#define ODT_INFO_DRAM_ODT(n) (((n) >> DRAM_ODT_SHIFT) & 0xff) +#define ODT_INFO_PHY_ODT(n) (((n) >> PHY_ODT_SHIFT) & 0x3ff) +#define ODT_INFO_PULLUP_EN(n) (((n) >> PHY_ODT_PUUP_EN_SHIFT) & 1) +#define ODT_INFO_PULLDOWN_EN(n) (((n) >> PHY_ODT_PUDN_EN_SHIFT) & 1) + +/* for *odt_en_freq; */ +#define DRAM_ODT_EN_FREQ_SHIFT 0 +#define PHY_ODT_EN_FREQ_SHIFT 12 +#define DRAMODT_EN_FREQ(n) (((n) >> DRAM_ODT_EN_FREQ_SHIFT) & \ + 0xfff) +#define PHYODT_EN_FREQ(n) (((n) >> PHY_ODT_EN_FREQ_SHIFT) & 0xfff) + +#define PHY_DQ_SR_SHIFT 0 +#define PHY_CA_SR_SHIFT 8 +#define PHY_CLK_SR_SHIFT 16 +#define DQ_SR_INFO(n) (((n) >> PHY_DQ_SR_SHIFT) & 0xff) +#define CA_SR_INFO(n) (((n) >> PHY_CA_SR_SHIFT) & 0xff) +#define CLK_SR_INFO(n) (((n) >> PHY_CLK_SR_SHIFT) & 0xff) + +/* LP4 */ +#define LP4_CA_ODT_SHIFT (18) +#define LP4_DRV_PU_CAL_ODTEN_SHIFT (26) +#define LP4_DRV_PU_CAL_ODTOFF_SHIFT (27) +#define PHY_LP4_DRV_PULLDOWN_EN_ODTEN_SHIFT (28) +#define PHY_LP4_DRV_PULLDOWN_EN_ODTOFF_SHIFT (29) +#define ODT_INFO_LP4_CA_ODT(n) (((n) >> LP4_CA_ODT_SHIFT) & \ + 0xff) +#define LP4_DRV_PU_CAL_ODTEN(n) \ + (((n) >> LP4_DRV_PU_CAL_ODTEN_SHIFT) & 1) +#define LP4_DRV_PU_CAL_ODTOFF(n) \ + (((n) >> LP4_DRV_PU_CAL_ODTOFF_SHIFT) & 1) +#define PHY_LP4_DRV_PULLDOWN_EN_ODTEN(n) \ + (((n) >> PHY_LP4_DRV_PULLDOWN_EN_ODTEN_SHIFT) & 1) +#define PHY_LP4_DRV_PULLDOWN_EN_ODTOFF(n) \ + (((n) >> PHY_LP4_DRV_PULLDOWN_EN_ODTOFF_SHIFT) & 1) + +#define PHY_LP4_CS_DRV_ODTEN_SHIFT (0) +#define PHY_LP4_CS_DRV_ODTOFF_SHIFT (8) +#define LP4_ODTE_CK_SHIFT (16) +#define LP4_ODTE_CS_EN_SHIFT (17) +#define LP4_ODTD_CA_EN_SHIFT (18) +#define PHY_LP4_CS_DRV_ODTEN(n) \ + (((n) >> PHY_LP4_CS_DRV_ODTEN_SHIFT) & 0xff) +#define PHY_LP4_CS_DRV_ODTOFF(n) \ + (((n) >> PHY_LP4_CS_DRV_ODTOFF_SHIFT) & 0xff) +#define LP4_ODTE_CK_EN(n) (((n) >> LP4_ODTE_CK_SHIFT) & 1) +#define LP4_ODTE_CS_EN(n) (((n) >> LP4_ODTE_CS_EN_SHIFT) & 1) +#define LP4_ODTD_CA_EN(n) (((n) >> LP4_ODTD_CA_EN_SHIFT) & 1) + +#define PHY_LP4_DQ_VREF_SHIFT (0) +#define LP4_DQ_VREF_SHIFT (10) +#define LP4_CA_VREF_SHIFT (20) + +#define PHY_LP4_DQ_VREF(n) \ + (((n) >> PHY_LP4_DQ_VREF_SHIFT) & 0x3ff) +#define LP4_DQ_VREF(n) (((n) >> LP4_DQ_VREF_SHIFT) & 0x3ff) +#define LP4_CA_VREF(n) (((n) >> LP4_CA_VREF_SHIFT) & 0x3ff) + +#define LP4_DQ_ODT_EN_FREQ_SHIFT (0) +#define PHY_LP4_ODT_EN_FREQ_SHIFT (12) +#define LP4_CA_ODT_EN_FREQ_SHIFT (0) +#define PHY_LP4_ODT_EN_FREQ(n) \ + (((n) >> PHY_LP4_ODT_EN_FREQ_SHIFT) & 0xfff) +#define LP4_DQ_ODT_EN_FREQ(n) \ + (((n) >> LP4_DQ_ODT_EN_FREQ_SHIFT) & 0xfff) +#define LP4_CA_ODT_EN_FREQ(n) \ + (((n) >> LP4_CA_ODT_EN_FREQ_SHIFT) & 0xfff) + +struct sdram_head_info_v0 { + u32 start_tag; + u32 version_info; + u32 gcpu_gen_freq; + u32 g_d2_lp2_freq; + u32 g_d3_lp3_freq; + u32 g_d4_lp4_freq; + u32 g_uart_info; + u32 g_sr_pd_idle; + u32 g_ch_info; + u32 g_2t_info; + u32 reserved11; + u32 reserved12; + u32 reserved13; +}; + +struct index_info { + u8 offset; + u8 size; +}; + +struct sdram_head_info_index_v2 { + u32 start_tag; + u32 version_info; + struct index_info cpu_gen_index; + struct index_info global_index; + + struct index_info ddr2_index; + struct index_info ddr3_index; + + struct index_info ddr4_index; + struct index_info ddr5_index; + + struct index_info lp2_index; + struct index_info lp3_index; + + struct index_info lp4_index; + struct index_info lp5_index; + + struct index_info skew_index; + struct index_info dq_map_index; + + struct index_info lp4x_index; + struct index_info reserved; +}; + +struct global_info { + u32 uart_info; + u32 sr_pd_info; + u32 ch_info; + u32 info_2t; + u32 reserved[4]; +}; + +struct ddr2_3_4_lp2_3_info { + u32 ddr_freq0_1; + u32 ddr_freq2_3; + u32 ddr_freq4_5; + u32 drv_when_odten; + u32 drv_when_odtoff; + u32 odt_info; + u32 odten_freq; + u32 sr_when_odten; + u32 sr_when_odtoff; +}; + +struct lp4_info { + u32 ddr_freq0_1; + u32 ddr_freq2_3; + u32 ddr_freq4_5; + u32 drv_when_odten; + u32 drv_when_odtoff; + u32 odt_info; + u32 dq_odten_freq; + u32 sr_when_odten; + u32 sr_when_odtoff; + u32 ca_odten_freq; + u32 cs_drv_ca_odt_info; + u32 vref_when_odten; + u32 vref_when_odtoff; +}; + +struct dq_map_info { + u32 byte_map[2]; + u32 lp3_dq0_7_map; + u32 lp2_dq0_7_map; + u32 ddr4_dq_map[4]; +}; + struct sdram_cap_info { unsigned int rank; /* dram column number, 0 means this channel is invalid */ @@ -46,6 +250,14 @@ struct sdram_base_params { }; #define DDR_SYS_REG_VERSION (0x2) +/* for modify tRFC and related timing */ +#define DIE_CAP_512MBIT 64 +#define DIE_CAP_1GBIT 128 +#define DIE_CAP_2GBIT 256 +#define DIE_CAP_4GBIT 512 +#define DIE_CAP_8GBIT 1024 +#define DIE_CAP_16GBIT 2048 +#define DIE_CAP_32GBIT 4096 /* * sys_reg2 bitfield struct * [31] row_3_4_ch1 @@ -116,7 +328,7 @@ struct sdram_base_params { void sdram_print_dram_type(unsigned char dramtype); void sdram_print_ddr_info(struct sdram_cap_info *cap_info, - struct sdram_base_params *base); + struct sdram_base_params *base, u32 split); void sdram_print_stride(unsigned int stride); void sdram_org_config(struct sdram_cap_info *cap_info, diff --git a/arch/arm/include/asm/arch-rockchip/sdram_msch.h b/arch/arm/include/asm/arch-rockchip/sdram_msch.h index cfb3d9c..d1926f4 100644 --- a/arch/arm/include/asm/arch-rockchip/sdram_msch.h +++ b/arch/arm/include/asm/arch-rockchip/sdram_msch.h @@ -57,6 +57,18 @@ union noc_devtodev0 { } b; }; +union noc_devtodev_rv1126 { + u32 d32; + struct { + unsigned busrdtord : 3; + unsigned reserved0 : 1; + unsigned busrdtowr : 4; + unsigned buswrtord : 4; + unsigned buswrtowr : 3; + unsigned reserved2 : 17; + } b; +}; + union noc_ddrmode { u32 d32; struct { diff --git a/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h index 3a36577..3780dc6 100644 --- a/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h +++ b/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h @@ -12,7 +12,7 @@ #endif struct ddr_pctl_regs { - u32 pctl[30][2]; + u32 pctl[35][2]; }; /* ddr pctl registers define */ @@ -25,6 +25,7 @@ struct ddr_pctl_regs { #define DDR_PCTL2_MRCTRL2 0x1c #define DDR_PCTL2_DERATEEN 0x20 #define DDR_PCTL2_DERATEINT 0x24 +#define DDR_PCTL2_MSTR2 0x28 #define DDR_PCTL2_PWRCTL 0x30 #define DDR_PCTL2_PWRTMG 0x34 #define DDR_PCTL2_HWLPCTL 0x38 @@ -122,8 +123,103 @@ struct ddr_pctl_regs { #define DDR_PCTL2_PCFGW_n 0x408 #define DDR_PCTL2_PCTRL_n 0x490 +#define UMCTL2_REGS_FREQ(n) \ + ((0x1000 * (n) + (((n) > 0) ? 0x1000 : 0))) + +/* PCTL2_MSTR */ +#define PCTL2_FREQUENCY_MODE_MASK (1) +#define PCTL2_FREQUENCY_MODE_SHIFT (29) +#define PCTL2_DLL_OFF_MODE BIT(15) +/* PCTL2_STAT */ +#define PCTL2_SELFREF_TYPE_MASK (3 << 4) +#define PCTL2_SELFREF_TYPE_SR_NOT_AUTO (2 << 4) +#define PCTL2_OPERATING_MODE_MASK (7) +#define PCTL2_OPERATING_MODE_INIT (0) +#define PCTL2_OPERATING_MODE_NORMAL (1) +#define PCTL2_OPERATING_MODE_PD (2) +#define PCTL2_OPERATING_MODE_SR (3) +/* PCTL2_MRCTRL0 */ +#define PCTL2_MR_WR BIT(31) +#define PCTL2_MR_ADDR_SHIFT (12) +#define PCTL2_MR_RANK_SHIFT (4) +#define PCTL2_MR_TYPE_WR (0) +#define PCTL2_MR_TYPE_RD (1) +/* PCTL2_MRCTRL1 */ +#define PCTL2_MR_ADDRESS_SHIFT (8) +#define PCTL2_MR_DATA_MASK (0xff) /* PCTL2_MRSTAT */ -#define MR_WR_BUSY BIT(0) +#define PCTL2_MR_WR_BUSY BIT(0) +/* PCTL2_DERATEEN */ +#define PCTL2_DERATE_ENABLE (1) +/* PCTL2_PWRCTL */ +#define PCTL2_SELFREF_SW BIT(5) +#define PCTL2_POWERDOWN_EN BIT(1) +#define PCTL2_SELFREF_EN (1) +/* PCTL2_PWRTMG */ +#define PCTL2_SELFREF_TO_X32_MASK (0xFF) +#define PCTL2_SELFREF_TO_X32_SHIFT (16) +#define PCTL2_POWERDOWN_TO_X32_MASK (0x1F) +/* PCTL2_INIT3 */ +#define PCTL2_DDR34_MR0_SHIFT (16) +#define PCTL2_LPDDR234_MR1_SHIFT (16) +#define PCTL2_DDR34_MR1_SHIFT (0) +#define PCTL2_LPDDR234_MR2_SHIFT (0) +/* PCTL2_INIT4 */ +#define PCTL2_DDR34_MR2_SHIFT (16) +#define PCTL2_LPDDR234_MR3_SHIFT (16) +#define PCTL2_DDR34_MR3_SHIFT (0) +#define PCTL2_LPDDR4_MR13_SHIFT (0) + +/* PCTL2_INIT6 */ +#define PCTL2_DDR4_MR4_SHIFT (16) +#define PCTL2_LPDDR4_MR11_SHIFT (16) +#define PCTL2_DDR4_MR5_SHIFT (0) +#define PCTL2_LPDDR4_MR12_SHIFT (0) + +/* PCTL2_INIT7 */ +#define PCTL2_LPDDR4_MR22_SHIFT (16) +#define PCTL2_DDR4_MR6_SHIFT (0) +#define PCTL2_LPDDR4_MR14_SHIFT (0) + +#define PCTL2_MR_MASK (0xffff) + +/* PCTL2_RFSHCTL3 */ +#define PCTL2_DIS_AUTO_REFRESH (1) +/* PCTL2_ZQCTL0 */ +#define PCTL2_DIS_AUTO_ZQ BIT(31) +#define PCTL2_DIS_SRX_ZQCL BIT(30) +/* PCTL2_DFILPCFG0 */ +#define PCTL2_DFI_LP_EN_SR BIT(8) +#define PCTL2_DFI_LP_EN_SR_MASK BIT(8) +#define PCTL2_DFI_LP_EN_SR_SHIFT (8) +/* PCTL2_DFIMISC */ +#define PCTL2_DFI_INIT_COMPLETE_EN (1) +/* PCTL2_DFISTAT */ +#define PCTL2_DFI_LP_ACK BIT(1) +#define PCTL2_DFI_INIT_COMPLETE (1) +/* PCTL2_DBG1 */ +#define PCTL2_DIS_HIF BIT(1) +/* PCTL2_DBGCAM */ +#define PCTL2_DBG_WR_Q_EMPTY BIT(26) +#define PCTL2_DBG_RD_Q_EMPTY BIT(25) +#define PCTL2_DBG_LPR_Q_DEPTH_MASK (0xffff << 8) +#define PCTL2_DBG_LPR_Q_DEPTH_EMPTY (0x0 << 8) +/* PCTL2_DBGCMD */ +#define PCTL2_RANK1_REFRESH BIT(1) +#define PCTL2_RANK0_REFRESH (1) +/* PCTL2_DBGSTAT */ +#define PCTL2_RANK1_REFRESH_BUSY BIT(1) +#define PCTL2_RANK0_REFRESH_BUSY (1) +/* PCTL2_SWCTL */ +#define PCTL2_SW_DONE (1) +#define PCTL2_SW_DONE_CLEAR (0) +/* PCTL2_SWSTAT */ +#define PCTL2_SW_DONE_ACK (1) +/* PCTL2_PSTAT */ +#define PCTL2_WR_PORT_BUSY_0 BIT(16) +#define PCTL2_RD_PORT_BUSY_0 (1) +/* PCTL2_PCTRLn */ +#define PCTL2_PORT_EN (1) void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num); int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg, diff --git a/arch/arm/include/asm/arch-rockchip/sdram_phy_rv1126.h b/arch/arm/include/asm/arch-rockchip/sdram_phy_rv1126.h new file mode 100644 index 0000000..5b64ec3 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/sdram_phy_rv1126.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Rockchip Electronics Co., Ltd + */ + +#ifndef _ASM_ARCH_SDRAM_RK1126_PHY_H +#define _ASM_ARCH_SDRAM_RK1126_PHY_H + +/* PHY_REG0 */ +#define DIGITAL_DERESET BIT(3) +#define ANALOG_DERESET BIT(2) +#define DIGITAL_RESET (0 << 3) +#define ANALOG_RESET (0 << 2) + +/* PHY_REG1 */ +#define PHY_DDR2 (0) +#define PHY_LPDDR2 (1) +#define PHY_DDR3 (2) +#define PHY_LPDDR3 (3) +#define PHY_DDR4 (4) +#define PHY_DDR5 (5) +#define PHY_BL_4 (0 << 3) +#define PHY_BL_8_OR_16 BIT(3) + +/* PHY_REG2 */ +#define PHY_DTT_EN BIT(0) +#define PHY_DTT_DISB (0 << 0) +#define PHY_WRITE_LEVELING_EN BIT(2) +#define PHY_WRITE_LEVELING_DISB (0 << 2) +#define PHY_SELECT_CS0 (2) +#define PHY_SELECT_CS1 (1) +#define PHY_SELECT_CS0_1 (0) +#define PHY_WRITE_LEVELING_SELECTCS(n) ((n) << 6) +#define PHY_DATA_TRAINING_SELECTCS(n) ((n) << 4) + +/* PHY_REGf */ +#define PHY_DQ_WIDTH_MASK (0xf) + +/* PHY_REG51 */ +#define PHY_PBDIV_BIT9_MASK BIT(0) +#define PHY_PBDIV_BIT9_SHIFT (0) +#define PHY_POSTDIV_EN_MASK BIT(7) +#define PHY_POSTDIV_EN_SHIFT (7) + +/* PHY_REG52 */ +#define PHY_PREDIV_MASK (0x1F) +#define PHY_PREDIV_SHIFT (0) + +/* PHY_REG53*/ +#define PHY_POSTDIV_MASK (0x7) +#define PHY_POSTDIV_SHIFT (5) +#define PHY_PD_DISB BIT(3) + +/* PHY_REG90 */ +#define PHY_PLL_LOCK BIT(2) + +struct ca_skew { + u32 a0_a3_a3_cke1_a_de_skew; + u32 a1_ba1_null_cke0_b_de_skew; + u32 a2_a9_a9_a4_a_de_skew; + u32 a3_a15_null_a5_b_de_skew; + u32 a4_a6_a6_ck_a_de_skew; + u32 a5_a12_null_odt0_b_de_skew; + u32 a6_ba2_null_a0_a_de_skew; + u32 a7_a4_a4_odt0_a_de_skew; + u32 a8_a1_a1_cke0_a_de_skew; + u32 a9_a5_a5_a5_a_de_skew; + u32 a10_a8_a8_clkb_a_de_skew; + u32 a11_a7_a7_ca2_a_de_skew; + u32 a12_rasn_null_ca1_a_de_skew; + u32 a13_a13_null_ca3_a_de_skew; + u32 a14_a14_null_csb1_b_de_skew; + u32 a15_a10_null_ca0_b_de_skew; + u32 a16_a11_null_csb0_b_de_skew; + u32 a17_null_null_null_de_skew; + u32 ba0_csb1_csb1_csb0_a_de_skew; + u32 ba1_wen_null_cke1_b_de_skew; + u32 bg0_odt1_odt1_csb1_a_de_skew; + u32 bg1_a2_a2_odt1_a_de_skew; + u32 cke0_casb_null_ca1_b_de_skew; + u32 ck_ck_ck_ck_b_de_skew; + u32 ckb_ckb_ckb_ckb_b_de_skew; + u32 csb0_odt0_odt0_ca2_b_de_skew; + u32 odt0_csb0_csb0_ca4_b_de_skew; + u32 resetn_resetn_null_resetn_de_skew; + u32 actn_cke_cke_ca3_b_de_skew; + u32 null_null_null_null_de_skew; + u32 csb1_ba0_null_null_de_skew; + u32 odt1_a0_a0_odt1_b_de_skew; +}; + +#define PHY_REG(base, n) ((base) + 4 * (n)) +#endif /* _ASM_ARCH_SDRAM_RK1126_PHY_H */ diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rv1126.h b/arch/arm/include/asm/arch-rockchip/sdram_rv1126.h new file mode 100644 index 0000000..6a07436 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/sdram_rv1126.h @@ -0,0 +1,420 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Rockchip Electronics Co., Ltd + */ + +#ifndef _ASM_ARCH_SDRAM_RK1126_H +#define _ASM_ARCH_SDRAM_RK1126_H + +#include <asm/arch-rockchip/dram_spec_timing.h> +#include <asm/arch-rockchip/sdram.h> +#include <asm/arch-rockchip/sdram_common.h> +#include <asm/arch-rockchip/sdram_msch.h> +#include <asm/arch-rockchip/sdram_pctl_px30.h> +#include <asm/arch-rockchip/sdram_phy_rv1126.h> + +#define AGINGX0_VAL (4) +#define AGING_CPU_VAL (0xff) +#define AGING_NPU_VAL (0xff) +#define AGING_OTHER_VAL (0x33) + +#define PATTERN (0x5aa5f00f) + +#define PHY_DDR3_RON_DISABLE (0) +#define PHY_DDR3_RON_455ohm (1) +#define PHY_DDR3_RON_230ohm (2) +#define PHY_DDR3_RON_153ohm (3) +#define PHY_DDR3_RON_115ohm (4) +#define PHY_DDR3_RON_91ohm (5) +#define PHY_DDR3_RON_76ohm (6) +#define PHY_DDR3_RON_65ohm (7) +#define PHY_DDR3_RON_57ohm (16) +#define PHY_DDR3_RON_51ohm (17) +#define PHY_DDR3_RON_46ohm (18) +#define PHY_DDR3_RON_41ohm (19) +#define PHY_DDR3_RON_38ohm (20) +#define PHY_DDR3_RON_35ohm (21) +#define PHY_DDR3_RON_32ohm (22) +#define PHY_DDR3_RON_30ohm (23) +#define PHY_DDR3_RON_28ohm (24) +#define PHY_DDR3_RON_27ohm (25) +#define PHY_DDR3_RON_25ohm (26) +#define PHY_DDR3_RON_24ohm (27) +#define PHY_DDR3_RON_23ohm (28) +#define PHY_DDR3_RON_22ohm (29) +#define PHY_DDR3_RON_21ohm (30) +#define PHY_DDR3_RON_20ohm (31) + +#define PHY_DDR3_RTT_DISABLE (0) +#define PHY_DDR3_RTT_561ohm (1) +#define PHY_DDR3_RTT_282ohm (2) +#define PHY_DDR3_RTT_188ohm (3) +#define PHY_DDR3_RTT_141ohm (4) +#define PHY_DDR3_RTT_113ohm (5) +#define PHY_DDR3_RTT_94ohm (6) +#define PHY_DDR3_RTT_81ohm (7) +#define PHY_DDR3_RTT_72ohm (16) +#define PHY_DDR3_RTT_64ohm (17) +#define PHY_DDR3_RTT_58ohm (18) +#define PHY_DDR3_RTT_52ohm (19) +#define PHY_DDR3_RTT_48ohm (20) +#define PHY_DDR3_RTT_44ohm (21) +#define PHY_DDR3_RTT_41ohm (22) +#define PHY_DDR3_RTT_38ohm (23) +#define PHY_DDR3_RTT_37ohm (24) +#define PHY_DDR3_RTT_34ohm (25) +#define PHY_DDR3_RTT_32ohm (26) +#define PHY_DDR3_RTT_31ohm (27) +#define PHY_DDR3_RTT_29ohm (28) +#define PHY_DDR3_RTT_28ohm (29) +#define PHY_DDR3_RTT_27ohm (30) +#define PHY_DDR3_RTT_25ohm (31) + +#define PHY_DDR4_LPDDR3_RON_DISABLE (0) +#define PHY_DDR4_LPDDR3_RON_482ohm (1) +#define PHY_DDR4_LPDDR3_RON_244ohm (2) +#define PHY_DDR4_LPDDR3_RON_162ohm (3) +#define PHY_DDR4_LPDDR3_RON_122ohm (4) +#define PHY_DDR4_LPDDR3_RON_97ohm (5) +#define PHY_DDR4_LPDDR3_RON_81ohm (6) +#define PHY_DDR4_LPDDR3_RON_69ohm (7) +#define PHY_DDR4_LPDDR3_RON_61ohm (16) +#define PHY_DDR4_LPDDR3_RON_54ohm (17) +#define PHY_DDR4_LPDDR3_RON_48ohm (18) +#define PHY_DDR4_LPDDR3_RON_44ohm (19) +#define PHY_DDR4_LPDDR3_RON_40ohm (20) +#define PHY_DDR4_LPDDR3_RON_37ohm (21) +#define PHY_DDR4_LPDDR3_RON_34ohm (22) +#define PHY_DDR4_LPDDR3_RON_32ohm (23) +#define PHY_DDR4_LPDDR3_RON_30ohm (24) +#define PHY_DDR4_LPDDR3_RON_28ohm (25) +#define PHY_DDR4_LPDDR3_RON_27ohm (26) +#define PHY_DDR4_LPDDR3_RON_25ohm (27) +#define PHY_DDR4_LPDDR3_RON_24ohm (28) +#define PHY_DDR4_LPDDR3_RON_23ohm (29) +#define PHY_DDR4_LPDDR3_RON_22ohm (30) +#define PHY_DDR4_LPDDR3_RON_21ohm (31) + +#define PHY_DDR4_LPDDR3_RTT_DISABLE (0) +#define PHY_DDR4_LPDDR3_RTT_586ohm (1) +#define PHY_DDR4_LPDDR3_RTT_294ohm (2) +#define PHY_DDR4_LPDDR3_RTT_196ohm (3) +#define PHY_DDR4_LPDDR3_RTT_148ohm (4) +#define PHY_DDR4_LPDDR3_RTT_118ohm (5) +#define PHY_DDR4_LPDDR3_RTT_99ohm (6) +#define PHY_DDR4_LPDDR3_RTT_85ohm (7) +#define PHY_DDR4_LPDDR3_RTT_76ohm (16) +#define PHY_DDR4_LPDDR3_RTT_67ohm (17) +#define PHY_DDR4_LPDDR3_RTT_60ohm (18) +#define PHY_DDR4_LPDDR3_RTT_55ohm (19) +#define PHY_DDR4_LPDDR3_RTT_50ohm (20) +#define PHY_DDR4_LPDDR3_RTT_46ohm (21) +#define PHY_DDR4_LPDDR3_RTT_43ohm (22) +#define PHY_DDR4_LPDDR3_RTT_40ohm (23) +#define PHY_DDR4_LPDDR3_RTT_38ohm (24) +#define PHY_DDR4_LPDDR3_RTT_36ohm (25) +#define PHY_DDR4_LPDDR3_RTT_34ohm (26) +#define PHY_DDR4_LPDDR3_RTT_32ohm (27) +#define PHY_DDR4_LPDDR3_RTT_31ohm (28) +#define PHY_DDR4_LPDDR3_RTT_29ohm (29) +#define PHY_DDR4_LPDDR3_RTT_28ohm (30) +#define PHY_DDR4_LPDDR3_RTT_27ohm (31) + +#define PHY_LPDDR4_RON_DISABLE (0) +#define PHY_LPDDR4_RON_501ohm (1) +#define PHY_LPDDR4_RON_253ohm (2) +#define PHY_LPDDR4_RON_168ohm (3) +#define PHY_LPDDR4_RON_126ohm (4) +#define PHY_LPDDR4_RON_101ohm (5) +#define PHY_LPDDR4_RON_84ohm (6) +#define PHY_LPDDR4_RON_72ohm (7) +#define PHY_LPDDR4_RON_63ohm (16) +#define PHY_LPDDR4_RON_56ohm (17) +#define PHY_LPDDR4_RON_50ohm (18) +#define PHY_LPDDR4_RON_46ohm (19) +#define PHY_LPDDR4_RON_42ohm (20) +#define PHY_LPDDR4_RON_38ohm (21) +#define PHY_LPDDR4_RON_36ohm (22) +#define PHY_LPDDR4_RON_33ohm (23) +#define PHY_LPDDR4_RON_31ohm (24) +#define PHY_LPDDR4_RON_29ohm (25) +#define PHY_LPDDR4_RON_28ohm (26) +#define PHY_LPDDR4_RON_26ohm (27) +#define PHY_LPDDR4_RON_25ohm (28) +#define PHY_LPDDR4_RON_24ohm (29) +#define PHY_LPDDR4_RON_23ohm (30) +#define PHY_LPDDR4_RON_22ohm (31) + +#define PHY_LPDDR4_RTT_DISABLE (0) +#define PHY_LPDDR4_RTT_604ohm (1) +#define PHY_LPDDR4_RTT_303ohm (2) +#define PHY_LPDDR4_RTT_202ohm (3) +#define PHY_LPDDR4_RTT_152ohm (4) +#define PHY_LPDDR4_RTT_122ohm (5) +#define PHY_LPDDR4_RTT_101ohm (6) +#define PHY_LPDDR4_RTT_87ohm (7) +#define PHY_LPDDR4_RTT_78ohm (16) +#define PHY_LPDDR4_RTT_69ohm (17) +#define PHY_LPDDR4_RTT_62ohm (18) +#define PHY_LPDDR4_RTT_56ohm (19) +#define PHY_LPDDR4_RTT_52ohm (20) +#define PHY_LPDDR4_RTT_48ohm (21) +#define PHY_LPDDR4_RTT_44ohm (22) +#define PHY_LPDDR4_RTT_41ohm (23) +#define PHY_LPDDR4_RTT_39ohm (24) +#define PHY_LPDDR4_RTT_37ohm (25) +#define PHY_LPDDR4_RTT_35ohm (26) +#define PHY_LPDDR4_RTT_33ohm (27) +#define PHY_LPDDR4_RTT_32ohm (28) +#define PHY_LPDDR4_RTT_30ohm (29) +#define PHY_LPDDR4_RTT_29ohm (30) +#define PHY_LPDDR4_RTT_27ohm (31) + +#define ADD_CMD_CA (0x150) +#define ADD_GROUP_CS0_A (0x170) +#define ADD_GROUP_CS0_B (0x1d0) +#define ADD_GROUP_CS1_A (0x1a0) +#define ADD_GROUP_CS1_B (0x200) + +/* PMUGRF */ +#define PMUGRF_OS_REG0 (0x200) +#define PMUGRF_OS_REG(n) (PMUGRF_OS_REG0 + (n) * 4) +#define PMUGRF_CON_DDRPHY_BUFFEREN_MASK (0x3 << (12 + 16)) +#define PMUGRF_CON_DDRPHY_BUFFEREN_EN (0x1 << 12) +#define PMUGRF_CON_DDRPHY_BUFFEREN_DIS (0x2 << 12) + +/* DDR GRF */ +#define DDR_GRF_CON(n) (0 + (n) * 4) +#define DDR_GRF_STATUS_BASE (0X100) +#define DDR_GRF_STATUS(n) (DDR_GRF_STATUS_BASE + (n) * 4) +#define DDR_GRF_LP_CON (0x20) + +#define SPLIT_MODE_32_L16_VALID (0) +#define SPLIT_MODE_32_H16_VALID (1) +#define SPLIT_MODE_16_L8_VALID (2) +#define SPLIT_MODE_16_H8_VALID (3) + +#define DDR_GRF_SPLIT_CON (0x10) +#define SPLIT_MODE_MASK (0x3) +#define SPLIT_MODE_OFFSET (9) +#define SPLIT_BYPASS_MASK (1) +#define SPLIT_BYPASS_OFFSET (8) +#define SPLIT_SIZE_MASK (0xff) +#define SPLIT_SIZE_OFFSET (0) + +/* SGRF SOC_CON13 */ +#define UPCTL2_ASRSTN_REQ(n) (((0x1 << 0) << 16) | ((n) << 0)) +#define UPCTL2_PSRSTN_REQ(n) (((0x1 << 1) << 16) | ((n) << 1)) +#define UPCTL2_SRSTN_REQ(n) (((0x1 << 2) << 16) | ((n) << 2)) + +/* CRU define */ +/* CRU_PLL_CON0 */ +#define PB(n) ((0x1 << (15 + 16)) | ((n) << 15)) +#define POSTDIV1(n) ((0x7 << (12 + 16)) | ((n) << 12)) +#define FBDIV(n) ((0xFFF << 16) | (n)) + +/* CRU_PLL_CON1 */ +#define RSTMODE(n) ((0x1 << (15 + 16)) | ((n) << 15)) +#define RST(n) ((0x1 << (14 + 16)) | ((n) << 14)) +#define PD(n) ((0x1 << (13 + 16)) | ((n) << 13)) +#define DSMPD(n) ((0x1 << (12 + 16)) | ((n) << 12)) +#define LOCK(n) (((n) >> 10) & 0x1) +#define POSTDIV2(n) ((0x7 << (6 + 16)) | ((n) << 6)) +#define REFDIV(n) ((0x3F << 16) | (n)) + +/* CRU_PLL_CON3 */ +#define SSMOD_SPREAD(n) ((0x1f << (8 + 16)) | ((n) << 8)) +#define SSMOD_DIVVAL(n) ((0xf << (4 + 16)) | ((n) << 4)) +#define SSMOD_DOWNSPREAD(n) ((0x1 << (3 + 16)) | ((n) << 3)) +#define SSMOD_RESET(n) ((0x1 << (2 + 16)) | ((n) << 2)) +#define SSMOD_DIS_SSCG(n) ((0x1 << (1 + 16)) | ((n) << 1)) +#define SSMOD_BP(n) ((0x1 << (0 + 16)) | ((n) << 0)) + +/* CRU_MODE */ +#define CLOCK_FROM_XIN_OSC (0) +#define CLOCK_FROM_PLL (1) +#define CLOCK_FROM_RTC_32K (2) +#define DPLL_MODE(n) ((0x3 << (2 + 16)) | ((n) << 2)) + +/* CRU_SOFTRESET_CON1 */ +#define DDRPHY_PSRSTN_REQ(n) (((0x1 << 14) << 16) | ((n) << 14)) +#define DDRPHY_SRSTN_REQ(n) (((0x1 << 15) << 16) | ((n) << 15)) +/* CRU_CLKGATE_CON2 */ +#define DDR_MSCH_EN_MASK ((0x1 << 10) << 16) +#define DDR_MSCH_EN_SHIFT (10) + +/* CRU register */ +#define CRU_PLL_CON(pll_id, n) ((pll_id) * 0x20 + (n) * 4) +#define CRU_MODE (0xa0) +#define CRU_GLB_CNT_TH (0xb0) +#define CRU_CLKSEL_CON_BASE 0x100 +#define CRU_CLKSELS_CON(i) (CRU_CLKSEL_CON_BASE + ((i) * 4)) +#define CRU_CLKGATE_CON_BASE 0x230 +#define CRU_CLKGATE_CON(i) (CRU_CLKGATE_CON_BASE + ((i) * 4)) +#define CRU_CLKSFTRST_CON_BASE 0x300 +#define CRU_CLKSFTRST_CON(i) (CRU_CLKSFTRST_CON_BASE + ((i) * 4)) + +/* SGRF_SOC_CON2 */ +#define MSCH_AXI_BYPASS_ALL_MASK (1) +#define MSCH_AXI_BYPASS_ALL_SHIFT (15) + +/* SGRF_SOC_CON12 */ +#define CLK_DDR_UPCTL_EN_MASK ((0x1 << 2) << 16) +#define CLK_DDR_UPCTL_EN_SHIFT (2) +#define ACLK_DDR_UPCTL_EN_MASK ((0x1 << 0) << 16) +#define ACLK_DDR_UPCTL_EN_SHIFT (0) + +/* DDRGRF DDR CON2 */ +#define DFI_FREQ_CHANGE_ACK BIT(10) +/* DDRGRF status8 */ +#define DFI_FREQ_CHANGE_REQ BIT(19) + +struct rv1126_ddrgrf { + u32 ddr_grf_con[4]; + u32 grf_ddrsplit_con; + u32 reserved1[(0x20 - 0x10) / 4 - 1]; + u32 ddr_grf_lp_con; + u32 reserved2[(0x40 - 0x20) / 4 - 1]; + u32 grf_ddrphy_con[6]; + u32 reserved3[(0x100 - 0x54) / 4 - 1]; + u32 ddr_grf_status[18]; + u32 reserved4[(0x150 - 0x144) / 4 - 1]; + u32 grf_ddrhold_status; + u32 reserved5[(0x160 - 0x150) / 4 - 1]; + u32 grf_ddrphy_status[2]; +}; + +struct rv1126_ddr_phy_regs { + u32 phy[8][2]; +}; + +struct msch_regs { + u32 coreid; + u32 revisionid; + u32 deviceconf; + u32 devicesize; + u32 ddrtiminga0; + u32 ddrtimingb0; + u32 ddrtimingc0; + u32 devtodev0; + u32 reserved1[(0x110 - 0x20) / 4]; + u32 ddrmode; + u32 ddr4timing; + u32 reserved2[(0x1000 - 0x118) / 4]; + u32 agingx0; + u32 reserved3[(0x1040 - 0x1004) / 4]; + u32 aging0; + u32 aging1; + u32 aging2; + u32 aging3; +}; + +struct sdram_msch_timings { + union noc_ddrtiminga0 ddrtiminga0; + union noc_ddrtimingb0 ddrtimingb0; + union noc_ddrtimingc0 ddrtimingc0; + union noc_devtodev_rv1126 devtodev0; + union noc_ddrmode ddrmode; + union noc_ddr4timing ddr4timing; + u32 agingx0; + u32 aging0; + u32 aging1; + u32 aging2; + u32 aging3; +}; + +struct rv1126_sdram_channel { + struct sdram_cap_info cap_info; + struct sdram_msch_timings noc_timings; +}; + +struct rv1126_sdram_params { + struct rv1126_sdram_channel ch; + struct sdram_base_params base; + struct ddr_pctl_regs pctl_regs; + struct rv1126_ddr_phy_regs phy_regs; +}; + +struct rv1126_fsp_param { + u32 flag; + u32 freq_mhz; + + /* dram size */ + u32 dq_odt; + u32 ca_odt; + u32 ds_pdds; + u32 vref_ca[2]; + u32 vref_dq[2]; + + /* phy side */ + u32 wr_dq_drv; + u32 wr_ca_drv; + u32 wr_ckcs_drv; + u32 rd_odt; + u32 rd_odt_up_en; + u32 rd_odt_down_en; + u32 vref_inner; + u32 vref_out; + u32 lp4_drv_pd_en; + + struct sdram_msch_timings noc_timings; +}; + +#define MAX_IDX (4) +#define FSP_FLAG (0xfead0001) +#define SHARE_MEM_BASE (0x100000) +/* + * Borrow share memory space to temporarily store FSP parame. + * In the stage of DDR init write FSP parame to this space. + * In the stage of trust init move FSP parame to SRAM space + * from share memory space. + */ +#define FSP_PARAM_STORE_ADDR (SHARE_MEM_BASE) + +/* store result of read and write training, for ddr_dq_eye tool in u-boot */ +#define RW_TRN_RESULT_ADDR (0x2000000 + 0x8000) /* 32M + 32k */ +#define PRINT_STEP 1 + +#undef FSP_NUM +#undef CS_NUM +#undef BYTE_NUM + +#define FSP_NUM 4 +#define CS_NUM 2 +#define BYTE_NUM 4 +#define RD_DESKEW_NUM 64 +#define WR_DESKEW_NUM 64 + +#define LP4_WIDTH_REF_MHZ_H 1056 +#define LP4_RD_WIDTH_REF_H 12 +#define LP4_WR_WIDTH_REF_H 13 + +#define LP4_WIDTH_REF_MHZ_L 924 +#define LP4_RD_WIDTH_REF_L 15 +#define LP4_WR_WIDTH_REF_L 15 + +#define DDR4_WIDTH_REF_MHZ_H 1056 +#define DDR4_RD_WIDTH_REF_H 13 +#define DDR4_WR_WIDTH_REF_H 9 + +#define DDR4_WIDTH_REF_MHZ_L 924 +#define DDR4_RD_WIDTH_REF_L 15 +#define DDR4_WR_WIDTH_REF_L 11 + +#define LP3_WIDTH_REF_MHZ_H 1056 +#define LP3_RD_WIDTH_REF_H 15 +#define LP3_WR_WIDTH_REF_H 13 + +#define LP3_WIDTH_REF_MHZ_L 924 +#define LP3_RD_WIDTH_REF_L 16 +#define LP3_WR_WIDTH_REF_L 15 + +#define DDR3_WIDTH_REF_MHZ_H 1056 +#define DDR3_RD_WIDTH_REF_H 14 +#define DDR3_WR_WIDTH_REF_H 14 + +#define DDR3_WIDTH_REF_MHZ_L 924 +#define DDR3_RD_WIDTH_REF_L 17 +#define DDR3_WR_WIDTH_REF_L 17 + +#endif /* _ASM_ARCH_SDRAM_RK1126_H */ diff --git a/arch/arm/include/asm/arch-rv1126/boot0.h b/arch/arm/include/asm/arch-rv1126/boot0.h new file mode 100644 index 0000000..2e78b07 --- /dev/null +++ b/arch/arm/include/asm/arch-rv1126/boot0.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2019 Rockchip Electronics Co., Ltd + */ + +#ifndef __ASM_ARCH_BOOT0_H__ +#define __ASM_ARCH_BOOT0_H__ + +#include <asm/arch-rockchip/boot0.h> + +#endif diff --git a/arch/arm/include/asm/arch-rv1126/gpio.h b/arch/arm/include/asm/arch-rv1126/gpio.h new file mode 100644 index 0000000..eca79d5 --- /dev/null +++ b/arch/arm/include/asm/arch-rv1126/gpio.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2019 Rockchip Electronics Co., Ltd + */ + +#ifndef __ASM_ARCH_GPIO_H__ +#define __ASM_ARCH_GPIO_H__ + +#include <asm/arch-rockchip/gpio.h> + +#endif diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 4898260..b678ec4 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -302,6 +302,51 @@ config ROCKCHIP_RV1108 The Rockchip RV1108 is a ARM-based SoC with a single-core Cortex-A7 and a DSP. +config ROCKCHIP_RV1126 + bool "Support Rockchip RV1126" + select CPU_V7A + select SKIP_LOWLEVEL_INIT_ONLY + select TPL + select SUPPORT_TPL + select TPL_NEEDS_SEPARATE_STACK + select TPL_ROCKCHIP_BACK_TO_BROM + select SPL + select SUPPORT_SPL + select SPL_STACK_R + select CLK + select FIT + select PINCTRL + select RAM + select ROCKCHIP_SDRAM_COMMON + select REGMAP + select SYSCON + select DM_PMIC + select DM_REGULATOR_FIXED + select DM_RESET + select REGULATOR_RK8XX + select PMIC_RK8XX + select BOARD_LATE_INIT + imply ROCKCHIP_COMMON_BOARD + imply TPL_DM + imply TPL_LIBCOMMON_SUPPORT + imply TPL_LIBGENERIC_SUPPORT + imply TPL_OF_CONTROL + imply TPL_OF_PLATDATA + imply TPL_RAM + imply TPL_ROCKCHIP_COMMON_BOARD + imply TPL_SERIAL + imply SPL_CLK + imply SPL_DM + imply SPL_DRIVERS_MISC + imply SPL_LIBCOMMON_SUPPORT + imply SPL_LIBGENERIC_SUPPORT + imply SPL_OF_CONTROL + imply SPL_RAM + imply SPL_REGMAP + imply SPL_ROCKCHIP_COMMON_BOARD + imply SPL_SERIAL + imply SPL_SYSCON + config ROCKCHIP_USB_UART bool "Route uart output to usb pins" help @@ -447,4 +492,5 @@ source "arch/arm/mach-rockchip/rk3368/Kconfig" source "arch/arm/mach-rockchip/rk3399/Kconfig" source "arch/arm/mach-rockchip/rk3568/Kconfig" source "arch/arm/mach-rockchip/rv1108/Kconfig" +source "arch/arm/mach-rockchip/rv1126/Kconfig" endif diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 6c1c7b8..32138fa 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_ROCKCHIP_RK3368) += rk3368/ obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399/ obj-$(CONFIG_ROCKCHIP_RK3568) += rk3568/ obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108/ +obj-$(CONFIG_ROCKCHIP_RV1126) += rv1126/ # Clear out SPL objects, in case this is a TPL build obj-spl-$(CONFIG_TPL_BUILD) = diff --git a/arch/arm/mach-rockchip/px30/Kconfig b/arch/arm/mach-rockchip/px30/Kconfig index 28639c0..4189392 100644 --- a/arch/arm/mach-rockchip/px30/Kconfig +++ b/arch/arm/mach-rockchip/px30/Kconfig @@ -35,6 +35,30 @@ config TARGET_PX30_CORE * PX30.Core needs to mount on top of C.TOUCH 2.0 carrier with pluged 10.1" OF for creating complete PX30.Core C.TOUCH 2.0 10.1" Open Frame. +config TARGET_RINGNECK_PX30 + bool "Theobroma Systems PX30-µQ7 (Ringneck)" + help + The PX30-uQ7 (Ringneck) SoM is a µQseven-compatible (40mmx70mm, + MXM-230 connector) system-on-module from Theobroma Systems[1], + featuring the Rockchip PX30. + + It provides the following feature set: + * up to 4GB DDR4 + * up to 128GB on-module eMMC (with 8-bit 1.8V interface) + * SD card (on a baseboard) via edge connector + * Fast Ethernet with on-module TI DP83825I PHY + * MIPI-DSI/LVDS + * MIPI-CSI + * USB + - 1x USB 2.0 dual-role + - 3x USB 2.0 host + * on-module companion controller (STM32 Cortex-M0 or ATtiny), implementing: + - low-power RTC functionality (ISL1208 emulation) + - fan controller (AMC6821 emulation) + - USB<->CAN bridge controller (STM32 only) + * on-module Espressif ESP32 for Bluetooth + 2.4GHz WiFi + * on-module NXP SE05x Secure Element + config ROCKCHIP_BOOT_MODE_REG default 0xff010200 @@ -71,5 +95,6 @@ config DEBUG_UART_CHANNEL source "board/engicam/px30_core/Kconfig" source "board/hardkernel/odroid_go2/Kconfig" source "board/rockchip/evb_px30/Kconfig" +source "board/theobroma-systems/ringneck_px30/Kconfig" endif diff --git a/arch/arm/mach-rockchip/px30/px30.c b/arch/arm/mach-rockchip/px30/px30.c index 0641e6a..3bca25c 100644 --- a/arch/arm/mach-rockchip/px30/px30.c +++ b/arch/arm/mach-rockchip/px30/px30.c @@ -5,9 +5,12 @@ #include <common.h> #include <clk.h> #include <dm.h> +#include <fdt_support.h> #include <init.h> +#include <spl.h> #include <asm/armv8/mmu.h> #include <asm/io.h> +#include <asm/arch-rockchip/bootrom.h> #include <asm/arch-rockchip/grf_px30.h> #include <asm/arch-rockchip/hardware.h> #include <asm/arch-rockchip/uart.h> @@ -15,6 +18,11 @@ #include <asm/arch-rockchip/cru_px30.h> #include <dt-bindings/clock/px30-cru.h> +const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = { + [BROM_BOOTSOURCE_EMMC] = "/mmc@ff390000", + [BROM_BOOTSOURCE_SD] = "/mmc@ff370000", +}; + static struct mm_region px30_mem_map[] = { { .virt = 0x0UL, @@ -234,6 +242,7 @@ enum { int arch_cpu_init(void) { static struct px30_grf * const grf = (void *)GRF_BASE; + static struct px30_cru * const cru = (void *)CRU_BASE; u32 __maybe_unused val; #ifdef CONFIG_SPL_BUILD @@ -285,6 +294,9 @@ int arch_cpu_init(void) /* Clear the force_jtag */ rk_clrreg(&grf->cpu_con[1], 1 << 7); + /* Make TSADC and WDT trigger a first global reset */ + clrsetbits_le32(&cru->glb_rst_con, 0x3, 0x3); + return 0; } @@ -297,8 +309,18 @@ void board_debug_uart_init(void) CONFIG_DEBUG_UART_BASE == 0xff030000) static struct px30_pmugrf * const pmugrf = (void *)PMUGRF_BASE; #endif +#if !defined(CONFIG_DEBUG_UART_BASE) || \ + (CONFIG_DEBUG_UART_BASE != 0xff158000 && \ + CONFIG_DEBUG_UART_BASE != 0xff168000 && \ + CONFIG_DEBUG_UART_BASE != 0xff178000 && \ + CONFIG_DEBUG_UART_BASE != 0xff030000) || \ + (defined(CONFIG_DEBUG_UART_BASE) && \ + (CONFIG_DEBUG_UART_BASE == 0xff158000 || \ + CONFIG_DEBUG_UART_BASE == 0xff168000 || \ + CONFIG_DEBUG_UART_BASE == 0xff178000)) static struct px30_grf * const grf = (void *)GRF_BASE; static struct px30_cru * const cru = (void *)CRU_BASE; +#endif #if defined(CONFIG_DEBUG_UART_BASE) && CONFIG_DEBUG_UART_BASE == 0xff030000 static struct px30_pmucru * const pmucru = (void *)PMUCRU_BASE; #endif @@ -421,3 +443,52 @@ void board_debug_uart_init(void) #endif /* CONFIG_DEBUG_UART_BASE && CONFIG_DEBUG_UART_BASE == ... */ } #endif /* CONFIG_DEBUG_UART_BOARD_INIT */ + +#if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD) +const char *spl_decode_boot_device(u32 boot_device) +{ + int i; + static const struct { + u32 boot_device; + const char *ofpath; + } spl_boot_devices_tbl[] = { + { BOOT_DEVICE_MMC2, "/mmc@ff370000" }, + { BOOT_DEVICE_MMC1, "/mmc@ff390000" }, + }; + + for (i = 0; i < ARRAY_SIZE(spl_boot_devices_tbl); ++i) + if (spl_boot_devices_tbl[i].boot_device == boot_device) + return spl_boot_devices_tbl[i].ofpath; + + return NULL; +} + +void spl_perform_fixups(struct spl_image_info *spl_image) +{ + void *blob = spl_image->fdt_addr; + const char *boot_ofpath; + int chosen; + + /* + * Inject the ofpath of the device the full U-Boot (or Linux in + * Falcon-mode) was booted from into the FDT, if a FDT has been + * loaded at the same time. + */ + if (!blob) + return; + + boot_ofpath = spl_decode_boot_device(spl_image->boot_device); + if (!boot_ofpath) { + pr_err("%s: could not map boot_device to ofpath\n", __func__); + return; + } + + chosen = fdt_find_or_add_subnode(blob, 0, "chosen"); + if (chosen < 0) { + pr_err("%s: could not find/create '/chosen'\n", __func__); + return; + } + fdt_setprop_string(blob, chosen, + "u-boot,spl-boot-device", boot_ofpath); +} +#endif diff --git a/arch/arm/mach-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig index b48feeb..d01063a 100644 --- a/arch/arm/mach-rockchip/rk3399/Kconfig +++ b/arch/arm/mach-rockchip/rk3399/Kconfig @@ -39,6 +39,13 @@ config TARGET_PINEBOOK_PRO_RK3399 with 4Gb RAM, onboard eMMC, USB-C, a USB3 and USB2 port, 1920*1080 screen and all the usual laptop features. +config TARGET_PINEPHONE_PRO_RK3399 + bool "PinePhone Pro" + help + PinePhone Pro is a phone based on a variant of the Rockchip + rk3399 SoC with 4Gb RAM, onboard eMMC, USB-C, headphone jack, + 720x1440 screen and a Quectel 4G/LTE modem. + config TARGET_PUMA_RK3399 bool "Theobroma Systems RK3399-Q7 (Puma)" help @@ -165,6 +172,7 @@ endif # BOOTCOUNT_LIMIT source "board/firefly/roc-pc-rk3399/Kconfig" source "board/google/gru/Kconfig" source "board/pine64/pinebook-pro-rk3399/Kconfig" +source "board/pine64/pinephone-pro-rk3399/Kconfig" source "board/pine64/rockpro64_rk3399/Kconfig" source "board/rockchip/evb_rk3399/Kconfig" source "board/theobroma-systems/puma_rk3399/Kconfig" diff --git a/arch/arm/mach-rockchip/rv1126/Kconfig b/arch/arm/mach-rockchip/rv1126/Kconfig new file mode 100644 index 0000000..7382c55 --- /dev/null +++ b/arch/arm/mach-rockchip/rv1126/Kconfig @@ -0,0 +1,59 @@ +if ROCKCHIP_RV1126 + +config TARGET_RV1126_NEU2 + bool "Edgeble Neural Compute Module 2(Neu2) SoM" + help + Neu2: + Neural Compute Module 2(Neu2) is a 96boards SoM-CB compute module + based on Rockchip RV1126 from Edgeble AI. + Neu2 powered with Consumer grade (0 to +80 °C) RV1126 SoC. + Neu2k powered with Industrial grade (-40 °C to +85 °C) RV1126K SoC. + + Neu2-IO: + Neural Compute Module 2(Neu2) IO board is an industrial form factor + IO board and Neu2 needs to mount on top of this IO board in order to + create complete Edgeble Neural Compute Module 2(Neu2) IO platform. + +config SOC_SPECIFIC_OPTIONS # dummy + def_bool y + select HAS_CUSTOM_SYS_INIT_SP_ADDR + +config ROCKCHIP_BOOT_MODE_REG + default 0xfe020200 + +config ROCKCHIP_STIMER_BASE + default 0xff670020 + +config SYS_SOC + default "rv1126" + +config CUSTOM_SYS_INIT_SP_ADDR + default 0x800000 + +config SPL_STACK + default 0x600000 + +config SPL_STACK_R_ADDR + default 0x800000 + +config TPL_LDSCRIPT + default "arch/arm/mach-rockchip/u-boot-tpl.lds" + +config TPL_STACK + default 0xff718000 + +config TPL_SYS_MALLOC_F_LEN + default 0x2000 + +config TPL_TEXT_BASE + default 0xff701000 + +config SYS_MALLOC_F_LEN + default 0x2000 + +config TEXT_BASE + default 0x600000 + +source board/edgeble/neural-compute-module-2/Kconfig + +endif diff --git a/arch/arm/mach-rockchip/rv1126/Makefile b/arch/arm/mach-rockchip/rv1126/Makefile new file mode 100644 index 0000000..b287563 --- /dev/null +++ b/arch/arm/mach-rockchip/rv1126/Makefile @@ -0,0 +1,13 @@ +# +# (C) Copyright 2019 Rockchip Electronics Co., Ltd +# Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += rv1126.o + +ifndef CONFIG_TPL_BUILD +obj-y += clk_rv1126.o +obj-y += syscon_rv1126.o +endif diff --git a/arch/arm/mach-rockchip/rv1126/clk_rv1126.c b/arch/arm/mach-rockchip/rv1126/clk_rv1126.c new file mode 100644 index 0000000..bd89027 --- /dev/null +++ b/arch/arm/mach-rockchip/rv1126/clk_rv1126.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd + * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. + */ + +#include <common.h> +#include <dm.h> +#include <syscon.h> +#include <asm/arch-rockchip/clock.h> +#include <asm/arch-rockchip/cru_rv1126.h> +#include <linux/err.h> + +int rockchip_get_clk(struct udevice **devp) +{ + return uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(rockchip_rv1126_cru), devp); +} + +void *rockchip_get_cru(void) +{ + struct rv1126_clk_priv *priv; + struct udevice *dev; + int ret; + + ret = rockchip_get_clk(&dev); + if (ret) + return ERR_PTR(ret); + + priv = dev_get_priv(dev); + + return priv->cru; +} diff --git a/arch/arm/mach-rockchip/rv1126/rv1126.c b/arch/arm/mach-rockchip/rv1126/rv1126.c new file mode 100644 index 0000000..b9b8987 --- /dev/null +++ b/arch/arm/mach-rockchip/rv1126/rv1126.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 Rockchip Electronics Co., Ltd + * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch-rockchip/bootrom.h> +#include <asm/arch-rockchip/hardware.h> +#include <asm/arch-rockchip/grf_rv1126.h> + +#define FIREWALL_APB_BASE 0xffa60000 +#define FW_DDR_CON_REG 0x80 +#define GRF_BASE 0xFE000000 + +const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = { + [BROM_BOOTSOURCE_EMMC] = "/mmc@ffc50000", + [BROM_BOOTSOURCE_SD] = "/mmc@ffc60000", +}; + +/* GRF_GPIO3A_IOMUX_L */ +enum { + GPIO3A3_SHIFT = 12, + GPIO3A3_MASK = GENMASK(14, 12), + GPIO3A3_GPIO = 0, + GPIO3A3_UART2_RX_M1, + GPIO3A3_A7_JTAG_TMS_M1, + + GPIO3A2_SHIFT = 8, + GPIO3A2_MASK = GENMASK(10, 8), + GPIO3A2_GPIO = 0, + GPIO3A2_UART2_TX_M1, + GPIO3A2_A7_JTAG_TCK_M1, +}; + +/* GRF_IOFUNC_CON2 */ +enum { + UART2_IO_SEL_SHIFT = 8, + UART2_IO_SEL_MASK = GENMASK(8, 8), + UART2_IO_SEL_M0 = 0, + UART2_IO_SEL_M1, +}; + +void board_debug_uart_init(void) +{ + static struct rv1126_grf * const grf = (void *)GRF_BASE; + + /* Enable early UART2 channel m1 on the rv1126 */ + rk_clrsetreg(&grf->iofunc_con2, UART2_IO_SEL_MASK, + UART2_IO_SEL_M1 << UART2_IO_SEL_SHIFT); + + /* Switch iomux */ + rk_clrsetreg(&grf->gpio3a_iomux_l, + GPIO3A3_MASK | GPIO3A2_MASK, + GPIO3A3_UART2_RX_M1 << GPIO3A3_SHIFT | + GPIO3A2_UART2_TX_M1 << GPIO3A2_SHIFT); +} + +#ifndef CONFIG_TPL_BUILD +int arch_cpu_init(void) +{ + /** + * Set dram area unsecure in spl + * + * usb & mmc & sfc controllers can read data to dram + * since they are unsecure. + * (Note: only secure-world can access this register) + */ + if (IS_ENABLED(CONFIG_SPL_BUILD)) + writel(0, FIREWALL_APB_BASE + FW_DDR_CON_REG); + + return 0; +} +#endif diff --git a/arch/arm/mach-rockchip/rv1126/syscon_rv1126.c b/arch/arm/mach-rockchip/rv1126/syscon_rv1126.c new file mode 100644 index 0000000..599ea66 --- /dev/null +++ b/arch/arm/mach-rockchip/rv1126/syscon_rv1126.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2019 Rockchip Electronics Co., Ltd + * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. + */ + +#include <common.h> +#include <dm.h> +#include <log.h> +#include <syscon.h> +#include <asm/arch-rockchip/clock.h> + +static const struct udevice_id rv1126_syscon_ids[] = { + { .compatible = "rockchip,rv1126-grf", .data = ROCKCHIP_SYSCON_GRF }, + { .compatible = "rockchip,rv1126-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF }, + { } +}; + +U_BOOT_DRIVER(syscon_rv1126) = { + .name = "rv1126_syscon", + .id = UCLASS_SYSCON, + .of_match = rv1126_syscon_ids, +}; + +#if CONFIG_IS_ENABLED(OF_PLATDATA) +static int rv1126_syscon_bind_of_plat(struct udevice *dev) +{ + dev->driver_data = dev->driver->of_match->data; + debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data); + + return 0; +} + +U_BOOT_DRIVER(rockchip_rv1126_pmu) = { + .name = "rockchip_rv1126_pmu", + .id = UCLASS_SYSCON, + .of_match = rv1126_syscon_ids, + .bind = rv1126_syscon_bind_of_plat, +}; + +U_BOOT_DRIVER(rockchip_rv1126_pmugrf) = { + .name = "rockchip_rv1126_pmugrf", + .id = UCLASS_SYSCON, + .of_match = rv1126_syscon_ids + 1, + .bind = rv1126_syscon_bind_of_plat, +}; +#endif diff --git a/board/edgeble/neural-compute-module-2/Kconfig b/board/edgeble/neural-compute-module-2/Kconfig new file mode 100644 index 0000000..21faf4a --- /dev/null +++ b/board/edgeble/neural-compute-module-2/Kconfig @@ -0,0 +1,16 @@ +if TARGET_RV1126_NEU2 + +config SYS_BOARD + default "neural-compute-module-2" + +config SYS_VENDOR + default "edgeble" + +config SYS_CONFIG_NAME + default "neural-compute-module-2" + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select RAM_ROCKCHIP_LPDDR4 + +endif diff --git a/board/edgeble/neural-compute-module-2/MAINTAINERS b/board/edgeble/neural-compute-module-2/MAINTAINERS new file mode 100644 index 0000000..38edb3a --- /dev/null +++ b/board/edgeble/neural-compute-module-2/MAINTAINERS @@ -0,0 +1,6 @@ +RV1126-ECM0 +M: Jagan Teki <jagan@edgeble.ai> +S: Maintained +F: board/edgeble/neural-compute-module-2 +F: include/configs/neural-compute-module-2.h +F: configs/neu2-io-rv1126_defconfig diff --git a/board/edgeble/neural-compute-module-2/Makefile b/board/edgeble/neural-compute-module-2/Makefile new file mode 100644 index 0000000..3bfc89f --- /dev/null +++ b/board/edgeble/neural-compute-module-2/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += neu2.o diff --git a/board/edgeble/neural-compute-module-2/neu2.c b/board/edgeble/neural-compute-module-2/neu2.c new file mode 100644 index 0000000..3d2262c --- /dev/null +++ b/board/edgeble/neural-compute-module-2/neu2.c @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. + */ diff --git a/board/engicam/px30_core/Kconfig b/board/engicam/px30_core/Kconfig index a03be78..924c30f 100644 --- a/board/engicam/px30_core/Kconfig +++ b/board/engicam/px30_core/Kconfig @@ -11,6 +11,6 @@ config SYS_CONFIG_NAME config BOARD_SPECIFIC_OPTIONS # dummy def_bool y - select RAM_PX30_DDR4 + select RAM_ROCKCHIP_DDR4 endif diff --git a/board/pine64/pinephone-pro-rk3399/Kconfig b/board/pine64/pinephone-pro-rk3399/Kconfig new file mode 100644 index 0000000..13d6465 --- /dev/null +++ b/board/pine64/pinephone-pro-rk3399/Kconfig @@ -0,0 +1,15 @@ +if TARGET_PINEPHONE_PRO_RK3399 + +config SYS_BOARD + default "pinephone-pro-rk3399" + +config SYS_VENDOR + default "pine64" + +config SYS_CONFIG_NAME + default "pinephone-pro-rk3399" + +config BOARD_SPECIFIC_OPTIONS + def_bool y + +endif diff --git a/board/pine64/pinephone-pro-rk3399/MAINTAINERS b/board/pine64/pinephone-pro-rk3399/MAINTAINERS new file mode 100644 index 0000000..c923ff1 --- /dev/null +++ b/board/pine64/pinephone-pro-rk3399/MAINTAINERS @@ -0,0 +1,8 @@ +PINEPHONE_PRO +M: Peter Robinson <pbrobinson@gmail.com> +S: Maintained +F: board/pine64/rk3399-pinephone-pro/ +F: include/configs/rk3399-pinephone-pro.h +F: arch/arm/dts/rk3399-pinephone-pro.dts +F: arch/arm/dts/rk3399-pinephone-pro-u-boot.dtsi +F: configs/pinephone-pro-rk3399_defconfig diff --git a/board/pine64/pinephone-pro-rk3399/Makefile b/board/pine64/pinephone-pro-rk3399/Makefile new file mode 100644 index 0000000..8d92030 --- /dev/null +++ b/board/pine64/pinephone-pro-rk3399/Makefile @@ -0,0 +1 @@ +obj-y += pinephone-pro-rk3399.o diff --git a/board/pine64/pinephone-pro-rk3399/pinephone-pro-rk3399.c b/board/pine64/pinephone-pro-rk3399/pinephone-pro-rk3399.c new file mode 100644 index 0000000..eb639cd --- /dev/null +++ b/board/pine64/pinephone-pro-rk3399/pinephone-pro-rk3399.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2016 Rockchip Electronics Co., Ltd + * (C) Copyright 2022 Peter Robinson <pbrobinson at gmail.com> + */ + +#include <common.h> +#include <dm.h> +#include <init.h> +#include <syscon.h> +#include <asm/io.h> +#include <asm/arch-rockchip/clock.h> +#include <asm/arch-rockchip/grf_rk3399.h> +#include <asm/arch-rockchip/hardware.h> +#include <asm/arch-rockchip/misc.h> +#include <power/regulator.h> + +#define GRF_IO_VSEL_BT565_SHIFT 0 +#define PMUGRF_CON0_VSEL_SHIFT 8 + +#ifndef CONFIG_SPL_BUILD +int board_early_init_f(void) +{ + struct udevice *regulator; + int ret; + + ret = regulator_get_by_platname("vcc5v0_usb", ®ulator); + if (ret) { + pr_debug("%s vcc5v0_usb init fail! ret %d\n", __func__, ret); + goto out; + } + + ret = regulator_set_enable(regulator, true); + if (ret) + pr_debug("%s vcc5v0-host-en-gpio set fail! ret %d\n", __func__, ret); + +out: + return 0; +} +#endif + +#ifdef CONFIG_MISC_INIT_R +static void setup_iodomain(void) +{ + struct rk3399_grf_regs *grf = + syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + struct rk3399_pmugrf_regs *pmugrf = + syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF); + + /* BT565 is in 1.8v domain */ + rk_setreg(&grf->io_vsel, 1 << GRF_IO_VSEL_BT565_SHIFT); + + /* Set GPIO1 1.8v/3.0v source select to PMU1830_VOL */ + rk_setreg(&pmugrf->soc_con0, 1 << PMUGRF_CON0_VSEL_SHIFT); +} + +int misc_init_r(void) +{ + const u32 cpuid_offset = 0x7; + const u32 cpuid_length = 0x10; + u8 cpuid[cpuid_length]; + int ret; + + setup_iodomain(); + + ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid); + if (ret) + return ret; + + ret = rockchip_cpuid_set(cpuid, cpuid_length); + if (ret) + return ret; + + return ret; +} +#endif diff --git a/board/theobroma-systems/ringneck_px30/Kconfig b/board/theobroma-systems/ringneck_px30/Kconfig new file mode 100644 index 0000000..24d9480 --- /dev/null +++ b/board/theobroma-systems/ringneck_px30/Kconfig @@ -0,0 +1,18 @@ +if TARGET_RINGNECK_PX30 + +config SYS_BOARD + default "ringneck_px30" + +config SYS_VENDOR + default "theobroma-systems" + +config SYS_CONFIG_NAME + default "ringneck_px30" + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + +config ENV_SIZE + default 0x3000 + +endif diff --git a/board/theobroma-systems/ringneck_px30/MAINTAINERS b/board/theobroma-systems/ringneck_px30/MAINTAINERS new file mode 100644 index 0000000..d764e26 --- /dev/null +++ b/board/theobroma-systems/ringneck_px30/MAINTAINERS @@ -0,0 +1,9 @@ +RINGNECK-PX30 +M: Quentin Schulz <quentin.schulz@theobroma-systems.com> +M: Klaus Goger <klaus.goger@theobroma-systems.com> +S: Maintained +F: board/theobroma-systems/ringneck_px30 +F: include/configs/ringneck_px30.h +F: arch/arm/dts/px30-ringneck* +F: configs/ringneck-px30_defconfig +W: https://www.theobroma-systems.com/px30-uq7#tech-spec diff --git a/board/theobroma-systems/ringneck_px30/Makefile b/board/theobroma-systems/ringneck_px30/Makefile new file mode 100644 index 0000000..31ada1a --- /dev/null +++ b/board/theobroma-systems/ringneck_px30/Makefile @@ -0,0 +1,7 @@ +# +# (C) Copyright 2022 Theobroma Systems Design und Consulting GmbH +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ringneck-px30.o diff --git a/board/theobroma-systems/ringneck_px30/README b/board/theobroma-systems/ringneck_px30/README new file mode 100644 index 0000000..e756b3a --- /dev/null +++ b/board/theobroma-systems/ringneck_px30/README @@ -0,0 +1,69 @@ +Introduction +============ + +The PX30-uQ7 (Ringneck) SoM is a µQseven-compatible (40mmx70mm, MXM-230 +connector) system-on-module from Theobroma Systems[1], featuring the +Rockchip PX30. + +It provides the following feature set: + * up to 4GB DDR4 + * up to 128GB on-module eMMC (with 8-bit 1.8V interface) + * SD card (on a baseboard) via edge connector + * Fast Ethernet with on-module TI DP83825I PHY + * MIPI-DSI/LVDS + * MIPI-CSI + * USB + - 1x USB 2.0 dual-role + - 3x USB 2.0 host + * on-module companion controller (STM32 Cortex-M0 or ATtiny), implementing: + - low-power RTC functionality (ISL1208 emulation) + - fan controller (AMC6821 emulation) + - USB<->CAN bridge controller (STM32 only) + * on-module Espressif ESP32 for Bluetooth + 2.4GHz WiFi + * on-module NXP SE05x Secure Element + +Here is the step-by-step to boot to U-Boot on px30. + +Get the Source and build ATF binary +=================================== + + > git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git + +Compile the ATF +=============== + + > cd trusted-firmware-a + > make CROSS_COMPILE=aarch64-linux-gnu- PLAT=px30 bl31 + > cp build/px30/release/bl31/bl31.elf ../u-boot/bl31.elf + +Compile the U-Boot +================== + + > cd ../u-boot + > make CROSS_COMPILE=aarch64-linux-gnu- ringneck-px30_defconfig all + +Flash the image +=============== + +Copy u-boot-rockchip.bin to offset 32k for SD/eMMC. + +SD-Card +------- + + > dd if=u-boot-rockchip.bin of=/dev/sdb seek=64 + +eMMC +---- + +rkdeveloptool allows to flash the on-board eMMC via the USB OTG interface with +help of the Rockchip loader binary. + + > git clone https://github.com/rockchip-linux/rkdeveloptool + > cd rkdeveloptool + > autoreconf -i && ./configure && make + > git clone https://github.com/rockchip-linux/rkbin.git + > cd rkbin + > ./tools/boot_merger RKBOOT/PX30MINIALL.ini + > cd .. + > ./rkdeveloptool db rkbin/px30_loader_v1.16.131.bin + > ./rkdeveloptool wl 64 ../u-boot-rockchip.bin diff --git a/board/theobroma-systems/ringneck_px30/ringneck-px30.c b/board/theobroma-systems/ringneck_px30/ringneck-px30.c new file mode 100644 index 0000000..47d1a40 --- /dev/null +++ b/board/theobroma-systems/ringneck_px30/ringneck-px30.c @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2022 Theobroma Systems Design und Consulting GmbH + */ + +#include <common.h> +#include <dm.h> +#include <env.h> +#include <env_internal.h> +#include <init.h> +#include <log.h> +#include <misc.h> +#include <spl.h> +#include <syscon.h> +#include <u-boot/crc.h> +#include <usb.h> +#include <dm/pinctrl.h> +#include <dm/uclass-internal.h> +#include <asm/io.h> +#include <asm/setup.h> +#include <asm/arch-rockchip/clock.h> +#include <asm/arch-rockchip/hardware.h> +#include <asm/arch-rockchip/periph.h> +#include <asm/arch-rockchip/misc.h> +#include <power/regulator.h> +#include <u-boot/sha256.h> + +/* + * Swap mmc0 and mmc1 in boot_targets if booted from SD-Card. + * + * If bootsource is uSD-card we can assume that we want to use the + * SD-Card instead of the eMMC as first boot_target for distroboot. + * We only want to swap the defaults and not any custom environment a + * user has set. We exit early if a changed boot_targets environment + * is detected. + */ +static int setup_boottargets(void) +{ + const char *boot_device = + ofnode_read_chosen_string("u-boot,spl-boot-device"); + char *env_default, *env; + + if (!boot_device) { + debug("%s: /chosen/u-boot,spl-boot-device not set\n", + __func__); + return -1; + } + debug("%s: booted from %s\n", __func__, boot_device); + + env_default = env_get_default("boot_targets"); + env = env_get("boot_targets"); + if (!env) { + debug("%s: boot_targets does not exist\n", __func__); + return -1; + } + debug("%s: boot_targets current: %s - default: %s\n", + __func__, env, env_default); + + if (strcmp(env_default, env) != 0) { + debug("%s: boot_targets not default, don't change it\n", + __func__); + return 0; + } + + /* + * Make the default boot medium between SD Card and eMMC, the one that + * was used to load U-Boot proper. + */ + bool sd_booted = !strcmp(boot_device, "/mmc@ff370000"); + char *mmc0, *mmc1; + + debug("%s: booted from %s\n", __func__, + sd_booted ? "SD-Card" : "eMMC"); + mmc0 = strstr(env, "mmc0"); + mmc1 = strstr(env, "mmc1"); + + if (!mmc0 || !mmc1) { + debug("%s: only one mmc boot_target found\n", __func__); + return -1; + } + + /* + * If mmc0 comes first in the boot order and U-Boot proper was + * loaded from mmc1, swap mmc0 and mmc1 in the list. + * If mmc1 comes first in the boot order and U-Boot proper was + * loaded from mmc0, swap mmc0 and mmc1 in the list. + */ + if ((mmc0 < mmc1 && sd_booted) || + (mmc0 > mmc1 && !sd_booted)) { + mmc0[3] = '1'; + mmc1[3] = '0'; + debug("%s: set boot_targets to: %s\n", __func__, env); + env_set("boot_targets", env); + } + + return 0; +} + +int mmc_get_env_dev(void) +{ + const char *boot_device = + ofnode_read_chosen_string("u-boot,spl-boot-device"); + + if (!boot_device) { + debug("%s: /chosen/u-boot,spl-boot-device not set\n", + __func__); + return CONFIG_SYS_MMC_ENV_DEV; + } + + debug("%s: booted from %s\n", __func__, boot_device); + + if (!strcmp(boot_device, "/mmc@ff370000")) + return 1; + + if (!strcmp(boot_device, "/mmc@ff390000")) + return 0; + + return CONFIG_SYS_MMC_ENV_DEV; +} + +#if !IS_ENABLED(CONFIG_ENV_IS_NOWHERE) +#error Please enable CONFIG_ENV_IS_NOWHERE +#endif + +enum env_location arch_env_get_location(enum env_operation op, int prio) +{ + const char *boot_device = + ofnode_read_chosen_string("u-boot,spl-boot-device"); + + if (prio > 0) + return ENVL_UNKNOWN; + + if (!boot_device) { + debug("%s: /chosen/u-boot,spl-boot-device not set\n", + __func__); + return ENVL_NOWHERE; + } + + debug("%s: booted from %s\n", __func__, boot_device); + + if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC) && + (!strcmp(boot_device, "/mmc@ff370000") || + !strcmp(boot_device, "/mmc@ff390000"))) + return ENVL_MMC; + + printf("%s: No environment available: booted from %s but U-Boot " + "config does not allow loading environment from it.", + __func__, boot_device); + + return ENVL_NOWHERE; +} + +int misc_init_r(void) +{ + const u32 cpuid_offset = 0x7; + const u32 cpuid_length = 0x10; + u8 cpuid[cpuid_length]; + int ret; + + ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid); + if (ret) + return ret; + + ret = rockchip_cpuid_set(cpuid, cpuid_length); + if (ret) + return ret; + + ret = rockchip_setup_macaddr(); + if (ret) + return ret; + + setup_boottargets(); + + return 0; +} diff --git a/common/spl/Kconfig.tpl b/common/spl/Kconfig.tpl index e314b79..1874f9d 100644 --- a/common/spl/Kconfig.tpl +++ b/common/spl/Kconfig.tpl @@ -132,7 +132,7 @@ config TPL_TEXT_BASE config TPL_MAX_SIZE hex "Maximum size (in bytes) for the TPL stage" default 0x2e000 if ROCKCHIP_RK3399 - default 0x8000 if ROCKCHIP_RK3288 + default 0x8000 if ROCKCHIP_RK3288 || ROCKCHIP_RV1126 default 0x7000 if ROCKCHIP_RK322X || ROCKCHIP_RK3328 || ROCKCHIP_RK3368 default 0x2800 if ROCKCHIP_PX30 default 0x0 diff --git a/configs/khadas-edge-captain-rk3399_defconfig b/configs/khadas-edge-captain-rk3399_defconfig index 754fd4e..f6e90bf 100644 --- a/configs/khadas-edge-captain-rk3399_defconfig +++ b/configs/khadas-edge-captain-rk3399_defconfig @@ -53,7 +53,7 @@ CONFIG_PMIC_RK8XX=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y -CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_RAM_ROCKCHIP_LPDDR4=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYS_NS16550_MEM32=y diff --git a/configs/khadas-edge-rk3399_defconfig b/configs/khadas-edge-rk3399_defconfig index 7518f7f..f74963c 100644 --- a/configs/khadas-edge-rk3399_defconfig +++ b/configs/khadas-edge-rk3399_defconfig @@ -52,7 +52,7 @@ CONFIG_PMIC_RK8XX=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y -CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_RAM_ROCKCHIP_LPDDR4=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYS_NS16550_MEM32=y diff --git a/configs/khadas-edge-v-rk3399_defconfig b/configs/khadas-edge-v-rk3399_defconfig index 4c4301a..3abfef1 100644 --- a/configs/khadas-edge-v-rk3399_defconfig +++ b/configs/khadas-edge-v-rk3399_defconfig @@ -53,7 +53,7 @@ CONFIG_PMIC_RK8XX=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y -CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_RAM_ROCKCHIP_LPDDR4=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYS_NS16550_MEM32=y diff --git a/configs/leez-rk3399_defconfig b/configs/leez-rk3399_defconfig index 5a958ee..bee55f8 100644 --- a/configs/leez-rk3399_defconfig +++ b/configs/leez-rk3399_defconfig @@ -48,7 +48,7 @@ CONFIG_PMIC_RK8XX=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y -CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_RAM_ROCKCHIP_LPDDR4=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYS_NS16550_MEM32=y diff --git a/configs/nanopi-r4s-rk3399_defconfig b/configs/nanopi-r4s-rk3399_defconfig index 40a45a0..0ef5486 100644 --- a/configs/nanopi-r4s-rk3399_defconfig +++ b/configs/nanopi-r4s-rk3399_defconfig @@ -49,7 +49,7 @@ CONFIG_PMIC_RK8XX=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y -CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_RAM_ROCKCHIP_LPDDR4=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYS_NS16550_MEM32=y diff --git a/configs/neu2-io-rv1126_defconfig b/configs/neu2-io-rv1126_defconfig new file mode 100644 index 0000000..e0816f8 --- /dev/null +++ b/configs/neu2-io-rv1126_defconfig @@ -0,0 +1,57 @@ +CONFIG_ARM=y +CONFIG_SPL_SKIP_LOWLEVEL_INIT_ONLY=y +CONFIG_TPL_SKIP_LOWLEVEL_INIT_ONLY=y +CONFIG_COUNTER_FREQUENCY=24000000 +CONFIG_SYS_ARCH_TIMER=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_DEFAULT_DEVICE_TREE="rv1126-edgeble-neu2-io" +CONFIG_ROCKCHIP_RV1126=y +CONFIG_TARGET_RV1126_NEU2=y +CONFIG_DEBUG_UART_BASE=0xff570000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SYS_LOAD_ADDR=0xe00800 +CONFIG_DEBUG_UART=y +CONFIG_SYS_MONITOR_LEN=614400 +CONFIG_FIT_VERBOSE=y +CONFIG_DEFAULT_FDT_FILE="rv1126-edgeble-neu2-io.dtb" +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_MISC_INIT_R=y +CONFIG_SPL_PAD_TO=0x7f8000 +CONFIG_SPL_NO_BSS_LIMIT=y +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +# CONFIG_CMD_BOOTD is not set +CONFIG_SYS_BOOTM_LEN=0x4000000 +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +CONFIG_CMD_GPT=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MMC=y +# CONFIG_CMD_ITEST is not set +# CONFIG_CMD_SETEXPR is not set +# CONFIG_SPL_DOS_PARTITION is not set +# CONFIG_ISO_PARTITION is not set +CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 +CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_MISC=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_REGULATOR_PWM=y +CONFIG_PWM_ROCKCHIP=y +# CONFIG_RAM_ROCKCHIP_DEBUG is not set +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYSRESET=y +# CONFIG_TPL_SYSRESET is not set +CONFIG_DM_THERMAL=y +CONFIG_SPL_TINY_MEMSET=y +CONFIG_LZO=y +CONFIG_ERRNO_STR=y diff --git a/configs/pinebook-pro-rk3399_defconfig b/configs/pinebook-pro-rk3399_defconfig index dfbf5e7..c885cba 100644 --- a/configs/pinebook-pro-rk3399_defconfig +++ b/configs/pinebook-pro-rk3399_defconfig @@ -74,7 +74,7 @@ CONFIG_PMIC_RK8XX=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y -CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_RAM_ROCKCHIP_LPDDR4=y CONFIG_DM_RESET=y CONFIG_DM_RNG=y CONFIG_RNG_ROCKCHIP=y diff --git a/configs/pinephone-pro-rk3399_defconfig b/configs/pinephone-pro-rk3399_defconfig new file mode 100644 index 0000000..eb979f6 --- /dev/null +++ b/configs/pinephone-pro-rk3399_defconfig @@ -0,0 +1,104 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=24000000 +CONFIG_ARCH_ROCKCHIP=y +CONFIG_TEXT_BASE=0x00200000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x8000 +CONFIG_ENV_OFFSET=0x3F8000 +CONFIG_DEFAULT_DEVICE_TREE="rk3399-pinephone-pro" +CONFIG_ROCKCHIP_RK3399=y +CONFIG_TARGET_PINEPHONE_PRO_RK3399=y +CONFIG_DEBUG_UART_BASE=0xFF1A0000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +CONFIG_SYS_LOAD_ADDR=0x800800 +CONFIG_DEBUG_UART=y +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x300000 +CONFIG_BOOTDELAY=3 +CONFIG_USE_PREBOOT=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-pinephone-pro.dtb" +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_MISC_INIT_R=y +CONFIG_SPL_MAX_SIZE=0x2e000 +CONFIG_SPL_PAD_TO=0x7f8000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x400000 +CONFIG_SPL_BSS_MAX_SIZE=0x2000 +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_STACK=0x400000 +CONFIG_SPL_STACK_R=y +CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000 +CONFIG_SPL_SPI_LOAD=y +CONFIG_TPL=y +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_DM_KEYBOARD=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_MISC=y +CONFIG_ROCKCHIP_EFUSE=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_SDMA=y +CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_SF_DEFAULT_BUS=1 +CONFIG_SF_DEFAULT_SPEED=20000000 +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_TYPEC=y +CONFIG_DM_PMIC_FAN53555=y +CONFIG_DM_REGULATOR_FAN53555=y +CONFIG_PMIC_RK8XX=y +CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_RK8XX=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_DM_RESET=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_ROCKCHIP_SPI=y +CONFIG_SYSRESET=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_GENERIC=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_KEYBOARD=y +CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y +CONFIG_USB_ETHER_RTL8152=y +CONFIG_DISPLAY=y +CONFIG_VIDEO=y +CONFIG_VIDEO_ROCKCHIP=y +CONFIG_DISPLAY_ROCKCHIP_EDP=y +CONFIG_SPL_TINY_MEMSET=y +CONFIG_ERRNO_STR=y diff --git a/configs/ringneck-px30_defconfig b/configs/ringneck-px30_defconfig new file mode 100644 index 0000000..dd332ec --- /dev/null +++ b/configs/ringneck-px30_defconfig @@ -0,0 +1,129 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=24000000 +CONFIG_ARCH_ROCKCHIP=y +CONFIG_TEXT_BASE=0x00200000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 +CONFIG_DEFAULT_DEVICE_TREE="px30-ringneck-haikou" +CONFIG_SPL_TEXT_BASE=0x00000000 +CONFIG_ROCKCHIP_PX30=y +CONFIG_TARGET_RINGNECK_PX30=y +CONFIG_TPL_LIBGENERIC_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_STACK_R_ADDR=0x600000 +CONFIG_DEBUG_UART_BASE=0xFF030000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SYS_LOAD_ADDR=0x800800 +CONFIG_TPL_MAX_SIZE=0x20000 +CONFIG_DEBUG_UART=y +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x400000 +CONFIG_TPL_SYS_MALLOC_F_LEN=0x600 +# CONFIG_ANDROID_BOOT_IMAGE is not set +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_DEFAULT_FDT_FILE="rockchip/px30-ringneck-haikou.dtb" +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_MISC_INIT_R=y +CONFIG_SPL_MAX_SIZE=0x20000 +CONFIG_SPL_PAD_TO=0x0 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x4000000 +CONFIG_SPL_BSS_MAX_SIZE=0x4000 +CONFIG_SPL_BOOTROM_SUPPORT=y +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_STACK=0x400000 +CONFIG_SPL_STACK_R=y +CONFIG_SYS_SPL_MALLOC=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200 +CONFIG_SPL_ATF=y +# CONFIG_TPL_FRAMEWORK is not set +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_LZMADEC is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPT=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_ITEST is not set +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_SLEEP is not set +# CONFIG_SPL_DOS_PARTITION is not set +# CONFIG_ISO_PARTITION is not set +CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_LIVE=y +CONFIG_OF_SPL_REMOVE_PROPS="interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_NOWHERE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_BUTTON=y +CONFIG_BUTTON_GPIO=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_FASTBOOT_BUF_ADDR=0x800800 +CONFIG_FASTBOOT_BUF_SIZE=0x04000000 +CONFIG_GPIO_HOG=y +CONFIG_SPL_GPIO_HOG=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_MISC=y +CONFIG_ROCKCHIP_OTP=y +CONFIG_SUPPORT_EMMC_RPMB=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_PHY_TI_GENERIC=y +CONFIG_PHY_GIGE=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_GMAC_ROCKCHIP=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_RK8XX=y +CONFIG_REGULATOR_PWM=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_REGULATOR_RK8XX=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_TPL_RAM=y +CONFIG_ROCKCHIP_SDRAM_COMMON=y +CONFIG_RAM_PX30_DDR4=y +CONFIG_DM_RESET=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y +# CONFIG_SPECIFY_CONSOLE_INDEX is not set +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_DEBUG_UART_SKIP_INIT=y +CONFIG_SYS_NS16550_MEM32=y +CONFIG_SOUND=y +CONFIG_SYSRESET=y +CONFIG_DM_THERMAL=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_SPL_TINY_MEMSET=y +CONFIG_TPL_TINY_MEMSET=y +CONFIG_LZO=y +CONFIG_ERRNO_STR=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/roc-pc-mezzanine-rk3399_defconfig b/configs/roc-pc-mezzanine-rk3399_defconfig index 6827c98..00239c2 100644 --- a/configs/roc-pc-mezzanine-rk3399_defconfig +++ b/configs/roc-pc-mezzanine-rk3399_defconfig @@ -22,6 +22,7 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x300000 # CONFIG_ANDROID_BOOT_IMAGE is not set CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-roc-pc-mezzanine.dtb" CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_MISC_INIT_R=y CONFIG_SPL_MAX_SIZE=0x2e000 CONFIG_SPL_PAD_TO=0x7f8000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y @@ -50,6 +51,7 @@ CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_ROCKCHIP_GPIO=y CONFIG_SYS_I2C_ROCKCHIP=y CONFIG_MISC=y +CONFIG_ROCKCHIP_EFUSE=y CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y @@ -67,7 +69,7 @@ CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y # CONFIG_RAM_ROCKCHIP_DEBUG is not set -CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_RAM_ROCKCHIP_LPDDR4=y CONFIG_DM_RESET=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_SHIFT=2 diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig index 3e58db0..ed70ce0 100644 --- a/configs/roc-pc-rk3399_defconfig +++ b/configs/roc-pc-rk3399_defconfig @@ -23,6 +23,7 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x300000 CONFIG_USE_PREBOOT=y CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-roc-pc.dtb" CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_MISC_INIT_R=y CONFIG_SPL_MAX_SIZE=0x2e000 CONFIG_SPL_PAD_TO=0x7f8000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y @@ -50,6 +51,7 @@ CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_ROCKCHIP_GPIO=y CONFIG_SYS_I2C_ROCKCHIP=y CONFIG_MISC=y +CONFIG_ROCKCHIP_EFUSE=y CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y @@ -66,7 +68,7 @@ CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y # CONFIG_RAM_ROCKCHIP_DEBUG is not set -CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_RAM_ROCKCHIP_LPDDR4=y CONFIG_DM_RESET=y CONFIG_DM_RNG=y CONFIG_RNG_ROCKCHIP=y diff --git a/configs/rock-pi-4-rk3399_defconfig b/configs/rock-pi-4-rk3399_defconfig index 7c49ccd..ac182ee 100644 --- a/configs/rock-pi-4-rk3399_defconfig +++ b/configs/rock-pi-4-rk3399_defconfig @@ -64,7 +64,7 @@ CONFIG_PMIC_RK8XX=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y -CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_RAM_ROCKCHIP_LPDDR4=y CONFIG_DM_RESET=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_SHIFT=2 diff --git a/configs/rock-pi-4c-rk3399_defconfig b/configs/rock-pi-4c-rk3399_defconfig index 4f61a0f..292436b 100644 --- a/configs/rock-pi-4c-rk3399_defconfig +++ b/configs/rock-pi-4c-rk3399_defconfig @@ -64,7 +64,7 @@ CONFIG_PMIC_RK8XX=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y -CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_RAM_ROCKCHIP_LPDDR4=y CONFIG_DM_RESET=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_SHIFT=2 diff --git a/configs/rockpro64-rk3399_defconfig b/configs/rockpro64-rk3399_defconfig index 5b8d678..6422b9f 100644 --- a/configs/rockpro64-rk3399_defconfig +++ b/configs/rockpro64-rk3399_defconfig @@ -71,7 +71,7 @@ CONFIG_PMIC_RK8XX=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y -CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_RAM_ROCKCHIP_LPDDR4=y CONFIG_DM_RESET=y CONFIG_DM_RNG=y CONFIG_RNG_ROCKCHIP=y diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst index 4ca7b00..28c837a 100644 --- a/doc/board/rockchip/rockchip.rst +++ b/doc/board/rockchip/rockchip.rst @@ -27,6 +27,7 @@ List of mainline supported Rockchip boards: - Engicam PX30.Core C.TOUCH 2.0 10.1 (px30-core-ctouch2-of10-px30) - Engicam PX30.Core EDIMM2.2 Starter Kit (px30-core-edimm2.2-px30) - Firefly Core-PX30-JD4 (firefly-px30) + - Theobroma Systems PX30-µQ7 SoM - Ringneck (ringneck-px30) * rk3036 - Rockchip Evb-RK3036 (evb-rk3036) - Kylin (kylin_rk3036) @@ -89,6 +90,9 @@ List of mainline supported Rockchip boards: - Rockchip Evb-rv1108 (evb-rv1108) - Elgin-R1 (elgin-rv1108) +* rv1126 + - Edgeble Neural Compute Module 2 SoM - Neu2/Neu2k (neu2-io-r1126) + Building -------- diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index a72d8fe..f719f4e 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_ROCKCHIP_RK3368) += clk_rk3368.o obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o obj-$(CONFIG_ROCKCHIP_RK3568) += clk_rk3568.o obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o +obj-$(CONFIG_ROCKCHIP_RV1126) += clk_rv1126.o diff --git a/drivers/clk/rockchip/clk_px30.c b/drivers/clk/rockchip/clk_px30.c index 5d46744..33a7348 100644 --- a/drivers/clk/rockchip/clk_px30.c +++ b/drivers/clk/rockchip/clk_px30.c @@ -1415,6 +1415,9 @@ static int px30_clk_enable(struct clk *clk) case SCLK_GMAC_RMII: /* Required to successfully probe the Designware GMAC driver */ return 0; + case PCLK_WDT_NS: + /* Required to successfully probe the Designware watchdog driver */ + return 0; } debug("%s: unsupported clk %ld\n", __func__, clk->id); diff --git a/drivers/clk/rockchip/clk_rv1126.c b/drivers/clk/rockchip/clk_rv1126.c new file mode 100644 index 0000000..3ed2936 --- /dev/null +++ b/drivers/clk/rockchip/clk_rv1126.c @@ -0,0 +1,1889 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd + * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. + * Author: Finley Xiao <finley.xiao@rock-chips.com> + */ + +#include <common.h> +#include <bitfield.h> +#include <clk-uclass.h> +#include <dm.h> +#include <errno.h> +#include <syscon.h> +#include <asm/arch-rockchip/clock.h> +#include <asm/arch-rockchip/cru_rv1126.h> +#include <asm/arch-rockchip/grf_rv1126.h> +#include <asm/arch-rockchip/hardware.h> +#include <dm/device-internal.h> +#include <asm/io.h> +#include <dm/lists.h> +#include <dt-bindings/clock/rockchip,rv1126-cru.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define RV1126_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \ +{ \ + .rate = _rate##U, \ + .aclk_div = _aclk_div, \ + .pclk_div = _pclk_div, \ +} + +#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) + +static struct rockchip_cpu_rate_table rv1126_cpu_rates[] = { + RV1126_CPUCLK_RATE(1200000000, 1, 5), + RV1126_CPUCLK_RATE(1008000000, 1, 5), + RV1126_CPUCLK_RATE(816000000, 1, 3), + RV1126_CPUCLK_RATE(600000000, 1, 3), + RV1126_CPUCLK_RATE(408000000, 1, 1), +}; + +static struct rockchip_pll_rate_table rv1126_pll_rates[] = { + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0), + RK3036_PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0), + RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0), + RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(1100000000, 3, 275, 2, 1, 1, 0), + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), + RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0), + RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), + RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0), + RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0), + RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0), + RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0), + RK3036_PLL_RATE(200000000, 1, 100, 6, 2, 1, 0), + RK3036_PLL_RATE(100000000, 1, 100, 6, 4, 1, 0), + { /* sentinel */ }, +}; + +static struct rockchip_pll_clock rv1126_pll_clks[] = { + [APLL] = PLL(pll_rk3328, PLL_APLL, RV1126_PLL_CON(0), + RV1126_MODE_CON, 0, 10, 0, rv1126_pll_rates), + [DPLL] = PLL(pll_rk3328, PLL_DPLL, RV1126_PLL_CON(8), + RV1126_MODE_CON, 2, 10, 0, NULL), + [CPLL] = PLL(pll_rk3328, PLL_CPLL, RV1126_PLL_CON(16), + RV1126_MODE_CON, 4, 10, 0, rv1126_pll_rates), + [HPLL] = PLL(pll_rk3328, PLL_HPLL, RV1126_PLL_CON(24), + RV1126_MODE_CON, 6, 10, 0, rv1126_pll_rates), + [GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1126_PMU_PLL_CON(0), + RV1126_PMU_MODE, 0, 10, 0, rv1126_pll_rates), +}; + +static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv, + struct rv1126_pmuclk_priv *pmu_priv, + ulong rate); +/* + * + * rational_best_approximation(31415, 10000, + * (1 << 8) - 1, (1 << 5) - 1, &n, &d); + * + * you may look at given_numerator as a fixed point number, + * with the fractional part size described in given_denominator. + * + * for theoretical background, see: + * http://en.wikipedia.org/wiki/Continued_fraction + */ +static void rational_best_approximation(unsigned long given_numerator, + unsigned long given_denominator, + unsigned long max_numerator, + unsigned long max_denominator, + unsigned long *best_numerator, + unsigned long *best_denominator) +{ + unsigned long n, d, n0, d0, n1, d1; + + n = given_numerator; + d = given_denominator; + n0 = 0; + d1 = 0; + n1 = 1; + d0 = 1; + for (;;) { + unsigned long t, a; + + if (n1 > max_numerator || d1 > max_denominator) { + n1 = n0; + d1 = d0; + break; + } + if (d == 0) + break; + t = d; + a = n / d; + d = n % d; + n = t; + t = n0 + a * n1; + n0 = n1; + n1 = t; + t = d0 + a * d1; + d0 = d1; + d1 = t; + } + *best_numerator = n1; + *best_denominator = d1; +} + +static ulong rv1126_gpll_get_pmuclk(struct rv1126_pmuclk_priv *priv) +{ + return rockchip_pll_get_rate(&rv1126_pll_clks[GPLL], + priv->pmucru, GPLL); +} + +static ulong rv1126_gpll_set_pmuclk(struct rv1126_pmuclk_priv *pmu_priv, ulong rate) +{ + struct udevice *cru_dev; + struct rv1126_clk_priv *priv; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(rockchip_rv1126_cru), + &cru_dev); + if (ret) { + printf("%s: could not find cru device\n", __func__); + return ret; + } + priv = dev_get_priv(cru_dev); + + if (rv1126_gpll_set_rate(priv, pmu_priv, rate)) { + printf("%s: failed to set gpll rate %lu\n", __func__, rate); + return -EINVAL; + } + return 0; +} + +static ulong rv1126_rtc32k_get_pmuclk(struct rv1126_pmuclk_priv *priv) +{ + struct rv1126_pmucru *pmucru = priv->pmucru; + unsigned long m, n; + u32 fracdiv; + + fracdiv = readl(&pmucru->pmu_clksel_con[13]); + m = fracdiv & CLK_RTC32K_FRAC_NUMERATOR_MASK; + m >>= CLK_RTC32K_FRAC_NUMERATOR_SHIFT; + n = fracdiv & CLK_RTC32K_FRAC_DENOMINATOR_MASK; + n >>= CLK_RTC32K_FRAC_DENOMINATOR_SHIFT; + + return OSC_HZ * m / n; +} + +static ulong rv1126_rtc32k_set_pmuclk(struct rv1126_pmuclk_priv *priv, + ulong rate) +{ + struct rv1126_pmucru *pmucru = priv->pmucru; + unsigned long m, n, val; + + rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, + RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT); + + rational_best_approximation(rate, OSC_HZ, + GENMASK(16 - 1, 0), + GENMASK(16 - 1, 0), + &m, &n); + val = m << CLK_RTC32K_FRAC_NUMERATOR_SHIFT | n; + writel(val, &pmucru->pmu_clksel_con[13]); + + return rv1126_rtc32k_get_pmuclk(priv); +} + +static ulong rv1126_i2c_get_pmuclk(struct rv1126_pmuclk_priv *priv, + ulong clk_id) +{ + struct rv1126_pmucru *pmucru = priv->pmucru; + u32 div, con; + + switch (clk_id) { + case CLK_I2C0: + con = readl(&pmucru->pmu_clksel_con[2]); + div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT; + break; + case CLK_I2C2: + con = readl(&pmucru->pmu_clksel_con[3]); + div = (con & CLK_I2C1_DIV_MASK) >> CLK_I2C1_DIV_SHIFT; + break; + default: + return -ENOENT; + } + + return DIV_TO_RATE(priv->gpll_hz, div); +} + +static ulong rv1126_i2c_set_pmuclk(struct rv1126_pmuclk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rv1126_pmucru *pmucru = priv->pmucru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 127); + + switch (clk_id) { + case CLK_I2C0: + rk_clrsetreg(&pmucru->pmu_clksel_con[2], CLK_I2C0_DIV_MASK, + (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT); + break; + case CLK_I2C2: + rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C2_DIV_MASK, + (src_clk_div - 1) << CLK_I2C2_DIV_SHIFT); + break; + default: + return -ENOENT; + } + + return rv1126_i2c_get_pmuclk(priv, clk_id); +} + +static ulong rv1126_pwm_get_pmuclk(struct rv1126_pmuclk_priv *priv, + ulong clk_id) +{ + struct rv1126_pmucru *pmucru = priv->pmucru; + u32 div, sel, con; + + switch (clk_id) { + case CLK_PWM0: + con = readl(&pmucru->pmu_clksel_con[6]); + sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT; + div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT; + if (sel == CLK_PWM0_SEL_XIN24M) + return OSC_HZ; + break; + case CLK_PWM1: + con = readl(&pmucru->pmu_clksel_con[6]); + sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT; + div = (con & CLK_PWM1_DIV_MASK) >> CLK_PWM1_DIV_SHIFT; + if (sel == CLK_PWM1_SEL_XIN24M) + return OSC_HZ; + break; + default: + return -ENOENT; + } + + return DIV_TO_RATE(priv->gpll_hz, div); +} + +static ulong rv1126_pwm_set_pmuclk(struct rv1126_pmuclk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rv1126_pmucru *pmucru = priv->pmucru; + int src_clk_div; + + switch (clk_id) { + case CLK_PWM0: + if (rate == OSC_HZ) { + rk_clrsetreg(&pmucru->pmu_clksel_con[6], + CLK_PWM0_SEL_MASK, + CLK_PWM0_SEL_XIN24M << CLK_PWM0_SEL_SHIFT); + rk_clrsetreg(&pmucru->pmu_clksel_con[6], + CLK_PWM0_DIV_MASK, 0); + } else { + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 127); + rk_clrsetreg(&pmucru->pmu_clksel_con[6], + CLK_PWM0_DIV_MASK, + (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT); + rk_clrsetreg(&pmucru->pmu_clksel_con[6], + CLK_PWM0_SEL_MASK, + CLK_PWM0_SEL_GPLL << CLK_PWM0_SEL_SHIFT); + } + break; + case CLK_PWM1: + if (rate == OSC_HZ) { + rk_clrsetreg(&pmucru->pmu_clksel_con[6], + CLK_PWM1_SEL_MASK, + CLK_PWM1_SEL_XIN24M << CLK_PWM1_SEL_SHIFT); + rk_clrsetreg(&pmucru->pmu_clksel_con[6], + CLK_PWM1_DIV_MASK, 0); + } else { + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 127); + rk_clrsetreg(&pmucru->pmu_clksel_con[6], + CLK_PWM1_DIV_MASK, + (src_clk_div - 1) << CLK_PWM1_DIV_SHIFT); + rk_clrsetreg(&pmucru->pmu_clksel_con[6], + CLK_PWM1_SEL_MASK, + CLK_PWM1_SEL_GPLL << CLK_PWM1_SEL_SHIFT); + } + break; + default: + return -ENOENT; + } + + return rv1126_pwm_get_pmuclk(priv, clk_id); +} + +static ulong rv1126_spi_get_pmuclk(struct rv1126_pmuclk_priv *priv) +{ + struct rv1126_pmucru *pmucru = priv->pmucru; + u32 div, con; + + con = readl(&pmucru->pmu_clksel_con[9]); + div = (con & CLK_SPI0_DIV_MASK) >> CLK_SPI0_DIV_SHIFT; + + return DIV_TO_RATE(priv->gpll_hz, div); +} + +static ulong rv1126_spi_set_pmuclk(struct rv1126_pmuclk_priv *priv, + ulong rate) +{ + struct rv1126_pmucru *pmucru = priv->pmucru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 127); + + rk_clrsetreg(&pmucru->pmu_clksel_con[9], + CLK_SPI0_SEL_MASK | CLK_SPI0_DIV_MASK, + CLK_SPI0_SEL_GPLL << CLK_SPI0_SEL_SHIFT | + (src_clk_div - 1) << CLK_SPI0_DIV_SHIFT); + + return rv1126_spi_get_pmuclk(priv); +} + +static ulong rv1126_pdpmu_get_pmuclk(struct rv1126_pmuclk_priv *priv) +{ + struct rv1126_pmucru *pmucru = priv->pmucru; + u32 div, con; + + con = readl(&pmucru->pmu_clksel_con[1]); + div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT; + + return DIV_TO_RATE(priv->gpll_hz, div); +} + +static ulong rv1126_pdpmu_set_pmuclk(struct rv1126_pmuclk_priv *priv, + ulong rate) +{ + struct rv1126_pmucru *pmucru = priv->pmucru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 31); + + rk_clrsetreg(&pmucru->pmu_clksel_con[1], + PCLK_PDPMU_DIV_MASK, + (src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT); + + return rv1126_pdpmu_get_pmuclk(priv); +} + +static ulong rv1126_pmuclk_get_rate(struct clk *clk) +{ + struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev); + ulong rate = 0; + + if (!priv->gpll_hz) { + printf("%s gpll=%lu\n", __func__, priv->gpll_hz); + return -ENOENT; + } + + debug("%s %ld\n", __func__, clk->id); + switch (clk->id) { + case PLL_GPLL: + rate = rv1126_gpll_get_pmuclk(priv); + break; + case CLK_RTC32K: + rate = rv1126_rtc32k_get_pmuclk(priv); + break; + case CLK_I2C0: + case CLK_I2C2: + rate = rv1126_i2c_get_pmuclk(priv, clk->id); + break; + case CLK_PWM0: + case CLK_PWM1: + rate = rv1126_pwm_get_pmuclk(priv, clk->id); + break; + case CLK_SPI0: + rate = rv1126_spi_get_pmuclk(priv); + break; + case PCLK_PDPMU: + rate = rv1126_pdpmu_get_pmuclk(priv); + break; + default: + debug("%s: Unsupported CLK#%ld\n", __func__, clk->id); + return -ENOENT; + } + + return rate; +} + +static ulong rv1126_pmuclk_set_rate(struct clk *clk, ulong rate) +{ + struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev); + ulong ret = 0; + + if (!priv->gpll_hz) { + printf("%s gpll=%lu\n", __func__, priv->gpll_hz); + return -ENOENT; + } + + debug("%s %ld %ld\n", __func__, clk->id, rate); + switch (clk->id) { + case PLL_GPLL: + ret = rv1126_gpll_set_pmuclk(priv, rate); + break; + case CLK_RTC32K: + ret = rv1126_rtc32k_set_pmuclk(priv, rate); + break; + case CLK_I2C0: + case CLK_I2C2: + ret = rv1126_i2c_set_pmuclk(priv, clk->id, rate); + break; + case CLK_PWM0: + case CLK_PWM1: + ret = rv1126_pwm_set_pmuclk(priv, clk->id, rate); + break; + case CLK_SPI0: + ret = rv1126_spi_set_pmuclk(priv, rate); + break; + case PCLK_PDPMU: + ret = rv1126_pdpmu_set_pmuclk(priv, rate); + break; + default: + debug("%s: Unsupported CLK#%ld\n", __func__, clk->id); + return -ENOENT; + } + + return ret; +} + +static int rv1126_rtc32k_set_parent(struct clk *clk, struct clk *parent) +{ + struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev); + struct rv1126_pmucru *pmucru = priv->pmucru; + + if (parent->id == CLK_OSC0_DIV32K) + rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, + RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT); + else + rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, + RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT); + + return 0; +} + +static int rv1126_pmuclk_set_parent(struct clk *clk, struct clk *parent) +{ + switch (clk->id) { + case CLK_RTC32K: + return rv1126_rtc32k_set_parent(clk, parent); + default: + debug("%s: Unsupported CLK#%ld\n", __func__, clk->id); + return -ENOENT; + } +} + +static struct clk_ops rv1126_pmuclk_ops = { + .get_rate = rv1126_pmuclk_get_rate, + .set_rate = rv1126_pmuclk_set_rate, + .set_parent = rv1126_pmuclk_set_parent, +}; + +static int rv1126_pmuclk_probe(struct udevice *dev) +{ + struct rv1126_pmuclk_priv *priv = dev_get_priv(dev); + + priv->gpll_hz = rv1126_gpll_get_pmuclk(priv); + + return 0; +} + +static int rv1126_pmuclk_of_to_plat(struct udevice *dev) +{ + struct rv1126_pmuclk_priv *priv = dev_get_priv(dev); + + priv->pmucru = dev_read_addr_ptr(dev); + + return 0; +} + +static int rv1126_pmuclk_bind(struct udevice *dev) +{ +#if CONFIG_IS_ENABLED(RESET_ROCKCHIP) + int ret; + + ret = offsetof(struct rv1126_pmucru, pmu_softrst_con[0]); + ret = rockchip_reset_bind(dev, ret, 2); + if (ret) + debug("Warning: software reset driver bind faile\n"); +#endif + return 0; +} + +static const struct udevice_id rv1126_pmuclk_ids[] = { + { .compatible = "rockchip,rv1126-pmucru" }, + { } +}; + +U_BOOT_DRIVER(rockchip_rv1126_pmucru) = { + .name = "rockchip_rv1126_pmucru", + .id = UCLASS_CLK, + .of_match = rv1126_pmuclk_ids, + .priv_auto = sizeof(struct rv1126_pmuclk_priv), + .of_to_plat = rv1126_pmuclk_of_to_plat, + .ops = &rv1126_pmuclk_ops, + .bind = rv1126_pmuclk_bind, + .probe = rv1126_pmuclk_probe, +}; + +static int rv1126_armclk_set_clk(struct rv1126_clk_priv *priv, ulong hz) +{ + struct rv1126_cru *cru = priv->cru; + const struct rockchip_cpu_rate_table *rate; + ulong old_rate; + + rate = rockchip_get_cpu_settings(rv1126_cpu_rates, hz); + if (!rate) { + printf("%s unsupported rate\n", __func__); + return -EINVAL; + } + + /* + * set up dependent divisors for DBG and ACLK clocks. + */ + old_rate = rockchip_pll_get_rate(&rv1126_pll_clks[APLL], + priv->cru, APLL); + if (old_rate > hz) { + if (rockchip_pll_set_rate(&rv1126_pll_clks[APLL], + priv->cru, APLL, hz)) + return -EINVAL; + rk_clrsetreg(&cru->clksel_con[1], + CORE_DBG_DIV_MASK | CORE_ACLK_DIV_MASK, + rate->pclk_div << CORE_DBG_DIV_SHIFT | + rate->aclk_div << CORE_ACLK_DIV_SHIFT); + } else if (old_rate < hz) { + rk_clrsetreg(&cru->clksel_con[1], + CORE_DBG_DIV_MASK | CORE_ACLK_DIV_MASK, + rate->pclk_div << CORE_DBG_DIV_SHIFT | + rate->aclk_div << CORE_ACLK_DIV_SHIFT); + if (rockchip_pll_set_rate(&rv1126_pll_clks[APLL], + priv->cru, APLL, hz)) + return -EINVAL; + } + + return 0; +} + +static ulong rv1126_pdcore_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 con, div; + + con = readl(&cru->clksel_con[0]); + div = (con & CORE_HCLK_DIV_MASK) >> CORE_HCLK_DIV_SHIFT; + + return DIV_TO_RATE(priv->gpll_hz, div); +} + +static ulong rv1126_pdcore_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 31); + + rk_clrsetreg(&cru->clksel_con[0], CORE_HCLK_DIV_MASK, + (src_clk_div - 1) << CORE_HCLK_DIV_SHIFT); + + return rv1126_pdcore_get_clk(priv); +} + +static ulong rv1126_pdbus_get_clk(struct rv1126_clk_priv *priv, ulong clk_id) +{ + struct rv1126_cru *cru = priv->cru; + u32 con, div, sel, parent; + + switch (clk_id) { + case ACLK_PDBUS: + con = readl(&cru->clksel_con[2]); + div = (con & ACLK_PDBUS_DIV_MASK) >> ACLK_PDBUS_DIV_SHIFT; + sel = (con & ACLK_PDBUS_SEL_MASK) >> ACLK_PDBUS_SEL_SHIFT; + if (sel == ACLK_PDBUS_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == ACLK_PDBUS_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + break; + case HCLK_PDBUS: + con = readl(&cru->clksel_con[2]); + div = (con & HCLK_PDBUS_DIV_MASK) >> HCLK_PDBUS_DIV_SHIFT; + sel = (con & HCLK_PDBUS_SEL_MASK) >> HCLK_PDBUS_SEL_SHIFT; + if (sel == HCLK_PDBUS_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == HCLK_PDBUS_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + break; + case PCLK_PDBUS: + case PCLK_WDT: + con = readl(&cru->clksel_con[3]); + div = (con & PCLK_PDBUS_DIV_MASK) >> PCLK_PDBUS_DIV_SHIFT; + sel = (con & PCLK_PDBUS_SEL_MASK) >> PCLK_PDBUS_SEL_SHIFT; + if (sel == PCLK_PDBUS_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == PCLK_PDBUS_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + break; + default: + return -ENOENT; + } + + return DIV_TO_RATE(parent, div); +} + +static ulong rv1126_pdbus_set_clk(struct rv1126_clk_priv *priv, ulong clk_id, + ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div, clk_sel; + + switch (clk_id) { + case ACLK_PDBUS: + if (CPLL_HZ % rate) { + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + clk_sel = ACLK_PDBUS_SEL_GPLL; + } else { + src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); + clk_sel = ACLK_PDBUS_SEL_CPLL; + } + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[2], + ACLK_PDBUS_SEL_MASK | ACLK_PDBUS_DIV_MASK, + clk_sel << ACLK_PDBUS_SEL_SHIFT | + (src_clk_div - 1) << ACLK_PDBUS_DIV_SHIFT); + break; + case HCLK_PDBUS: + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[2], + HCLK_PDBUS_SEL_MASK | HCLK_PDBUS_DIV_MASK, + HCLK_PDBUS_SEL_GPLL << HCLK_PDBUS_SEL_SHIFT | + (src_clk_div - 1) << HCLK_PDBUS_DIV_SHIFT); + break; + case PCLK_PDBUS: + case PCLK_WDT: + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[3], + PCLK_PDBUS_SEL_MASK | PCLK_PDBUS_DIV_MASK, + PCLK_PDBUS_SEL_GPLL << PCLK_PDBUS_SEL_SHIFT | + (src_clk_div - 1) << PCLK_PDBUS_DIV_SHIFT); + break; + + default: + printf("do not support this pdbus freq\n"); + return -EINVAL; + } + + return rv1126_pdbus_get_clk(priv, clk_id); +} + +static ulong rv1126_pdphp_get_clk(struct rv1126_clk_priv *priv, ulong clk_id) +{ + struct rv1126_cru *cru = priv->cru; + u32 con, div, parent; + + switch (clk_id) { + case ACLK_PDPHP: + con = readl(&cru->clksel_con[53]); + div = (con & ACLK_PDPHP_DIV_MASK) >> ACLK_PDPHP_DIV_SHIFT; + parent = priv->gpll_hz; + break; + case HCLK_PDPHP: + con = readl(&cru->clksel_con[53]); + div = (con & HCLK_PDPHP_DIV_MASK) >> HCLK_PDPHP_DIV_SHIFT; + parent = priv->gpll_hz; + break; + default: + return -ENOENT; + } + + return DIV_TO_RATE(parent, div); +} + +static ulong rv1126_pdphp_set_clk(struct rv1126_clk_priv *priv, ulong clk_id, + ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 31); + + switch (clk_id) { + case ACLK_PDPHP: + rk_clrsetreg(&cru->clksel_con[53], + ACLK_PDPHP_SEL_MASK | ACLK_PDPHP_DIV_MASK, + ACLK_PDPHP_SEL_GPLL << ACLK_PDPHP_SEL_SHIFT | + (src_clk_div - 1) << ACLK_PDPHP_DIV_SHIFT); + break; + case HCLK_PDPHP: + rk_clrsetreg(&cru->clksel_con[53], + HCLK_PDPHP_DIV_MASK, + (src_clk_div - 1) << HCLK_PDPHP_DIV_SHIFT); + break; + default: + printf("do not support this pdphp freq\n"); + return -EINVAL; + } + + return rv1126_pdphp_get_clk(priv, clk_id); +} + +static ulong rv1126_pdaudio_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 con, div; + + con = readl(&cru->clksel_con[26]); + div = (con & HCLK_PDAUDIO_DIV_MASK) >> HCLK_PDAUDIO_DIV_SHIFT; + + return DIV_TO_RATE(priv->gpll_hz, div); +} + +static ulong rv1126_pdaudio_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 31); + + rk_clrsetreg(&cru->clksel_con[26], HCLK_PDAUDIO_DIV_MASK, + (src_clk_div - 1) << HCLK_PDAUDIO_DIV_SHIFT); + + return rv1126_pdaudio_get_clk(priv); +} + +static ulong rv1126_i2c_get_clk(struct rv1126_clk_priv *priv, ulong clk_id) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, con; + + switch (clk_id) { + case CLK_I2C1: + con = readl(&cru->clksel_con[5]); + div = (con & CLK_I2C1_DIV_MASK) >> CLK_I2C1_DIV_SHIFT; + break; + case CLK_I2C3: + con = readl(&cru->clksel_con[5]); + div = (con & CLK_I2C3_DIV_MASK) >> CLK_I2C3_DIV_SHIFT; + break; + case CLK_I2C4: + con = readl(&cru->clksel_con[6]); + div = (con & CLK_I2C4_DIV_MASK) >> CLK_I2C4_DIV_SHIFT; + break; + case CLK_I2C5: + con = readl(&cru->clksel_con[6]); + div = (con & CLK_I2C5_DIV_MASK) >> CLK_I2C5_DIV_SHIFT; + break; + default: + return -ENOENT; + } + + return DIV_TO_RATE(priv->gpll_hz, div); +} + +static ulong rv1126_i2c_set_clk(struct rv1126_clk_priv *priv, ulong clk_id, + ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 127); + + switch (clk_id) { + case CLK_I2C1: + rk_clrsetreg(&cru->clksel_con[5], CLK_I2C1_DIV_MASK, + (src_clk_div - 1) << CLK_I2C1_DIV_SHIFT); + break; + case CLK_I2C3: + rk_clrsetreg(&cru->clksel_con[5], CLK_I2C3_DIV_MASK, + (src_clk_div - 1) << CLK_I2C3_DIV_SHIFT); + break; + case CLK_I2C4: + rk_clrsetreg(&cru->clksel_con[6], CLK_I2C4_DIV_MASK, + (src_clk_div - 1) << CLK_I2C4_DIV_SHIFT); + break; + case CLK_I2C5: + rk_clrsetreg(&cru->clksel_con[6], CLK_I2C5_DIV_MASK, + (src_clk_div - 1) << CLK_I2C5_DIV_SHIFT); + break; + default: + return -ENOENT; + } + + return rv1126_i2c_get_clk(priv, clk_id); +} + +static ulong rv1126_spi_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, con; + + con = readl(&cru->clksel_con[8]); + div = (con & CLK_SPI1_DIV_MASK) >> CLK_SPI1_DIV_SHIFT; + + return DIV_TO_RATE(priv->gpll_hz, div); +} + +static ulong rv1126_spi_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 127); + + rk_clrsetreg(&cru->clksel_con[8], + CLK_SPI1_SEL_MASK | CLK_SPI1_DIV_MASK, + CLK_SPI1_SEL_GPLL << CLK_SPI1_SEL_SHIFT | + (src_clk_div - 1) << CLK_SPI1_DIV_SHIFT); + + return rv1126_spi_get_clk(priv); +} + +static ulong rv1126_pwm_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, sel, con; + + con = readl(&cru->clksel_con[9]); + sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT; + div = (con & CLK_PWM2_DIV_MASK) >> CLK_PWM2_DIV_SHIFT; + if (sel == CLK_PWM2_SEL_XIN24M) + return OSC_HZ; + + return DIV_TO_RATE(priv->gpll_hz, div); +} + +static ulong rv1126_pwm_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + if (rate == OSC_HZ) { + rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_SEL_MASK, + CLK_PWM2_SEL_XIN24M << CLK_PWM2_SEL_SHIFT); + rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_DIV_MASK, 0); + } else { + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 127); + rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_DIV_MASK, + (src_clk_div - 1) << CLK_PWM2_DIV_SHIFT); + rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_SEL_MASK, + CLK_PWM2_SEL_GPLL << CLK_PWM2_SEL_SHIFT); + } + + return rv1126_pwm_get_clk(priv); +} + +static ulong rv1126_saradc_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, con; + + con = readl(&cru->clksel_con[20]); + div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT; + + return DIV_TO_RATE(OSC_HZ, div); +} + +static ulong rv1126_saradc_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(OSC_HZ, rate); + assert(src_clk_div - 1 <= 2047); + rk_clrsetreg(&cru->clksel_con[20], CLK_SARADC_DIV_MASK, + (src_clk_div - 1) << CLK_SARADC_DIV_SHIFT); + + return rv1126_saradc_get_clk(priv); +} + +static ulong rv1126_crypto_get_clk(struct rv1126_clk_priv *priv, ulong clk_id) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, sel, con, parent; + + switch (clk_id) { + case CLK_CRYPTO_CORE: + con = readl(&cru->clksel_con[7]); + div = (con & CLK_CRYPTO_CORE_DIV_MASK) >> CLK_CRYPTO_CORE_DIV_SHIFT; + sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >> CLK_CRYPTO_CORE_SEL_SHIFT; + if (sel == CLK_CRYPTO_CORE_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == CLK_CRYPTO_CORE_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + break; + case CLK_CRYPTO_PKA: + con = readl(&cru->clksel_con[7]); + div = (con & CLK_CRYPTO_PKA_DIV_MASK) >> CLK_CRYPTO_PKA_DIV_SHIFT; + sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >> CLK_CRYPTO_PKA_SEL_SHIFT; + if (sel == CLK_CRYPTO_PKA_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == CLK_CRYPTO_PKA_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + break; + case ACLK_CRYPTO: + con = readl(&cru->clksel_con[4]); + div = (con & ACLK_CRYPTO_DIV_MASK) >> ACLK_CRYPTO_DIV_SHIFT; + sel = (con & ACLK_CRYPTO_SEL_MASK) >> ACLK_CRYPTO_SEL_SHIFT; + if (sel == ACLK_CRYPTO_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == ACLK_CRYPTO_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + break; + default: + return -ENOENT; + } + + return DIV_TO_RATE(parent, div); +} + +static ulong rv1126_crypto_set_clk(struct rv1126_clk_priv *priv, ulong clk_id, + ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 31); + + switch (clk_id) { + case CLK_CRYPTO_CORE: + rk_clrsetreg(&cru->clksel_con[7], + CLK_CRYPTO_CORE_SEL_MASK | + CLK_CRYPTO_CORE_DIV_MASK, + CLK_CRYPTO_CORE_SEL_GPLL << + CLK_CRYPTO_CORE_SEL_SHIFT | + (src_clk_div - 1) << CLK_CRYPTO_CORE_DIV_SHIFT); + break; + case CLK_CRYPTO_PKA: + rk_clrsetreg(&cru->clksel_con[7], + CLK_CRYPTO_PKA_SEL_MASK | + CLK_CRYPTO_PKA_DIV_MASK, + CLK_CRYPTO_PKA_SEL_GPLL << + CLK_CRYPTO_PKA_SEL_SHIFT | + (src_clk_div - 1) << CLK_CRYPTO_PKA_DIV_SHIFT); + break; + case ACLK_CRYPTO: + rk_clrsetreg(&cru->clksel_con[4], + ACLK_CRYPTO_SEL_MASK | ACLK_CRYPTO_DIV_MASK, + ACLK_CRYPTO_SEL_GPLL << ACLK_CRYPTO_SEL_SHIFT | + (src_clk_div - 1) << ACLK_CRYPTO_DIV_SHIFT); + break; + default: + return -ENOENT; + } + + return rv1126_crypto_get_clk(priv, clk_id); +} + +static ulong rv1126_mmc_get_clk(struct rv1126_clk_priv *priv, ulong clk_id) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, sel, con, con_id; + + switch (clk_id) { + case HCLK_SDMMC: + case CLK_SDMMC: + con_id = 55; + break; + case HCLK_SDIO: + case CLK_SDIO: + con_id = 56; + break; + case HCLK_EMMC: + case CLK_EMMC: + case SCLK_EMMC_SAMPLE: + con_id = 57; + break; + default: + return -ENOENT; + } + + con = readl(&cru->clksel_con[con_id]); + div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT; + sel = (con & EMMC_SEL_MASK) >> EMMC_SEL_SHIFT; + if (sel == EMMC_SEL_GPLL) + return DIV_TO_RATE(priv->gpll_hz, div) / 2; + else if (sel == EMMC_SEL_CPLL) + return DIV_TO_RATE(priv->cpll_hz, div) / 2; + else if (sel == EMMC_SEL_XIN24M) + return DIV_TO_RATE(OSC_HZ, div) / 2; + + return -ENOENT; +} + +static ulong rv1126_mmc_set_clk(struct rv1126_clk_priv *priv, ulong clk_id, + ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + u32 con_id; + + switch (clk_id) { + case HCLK_SDMMC: + case CLK_SDMMC: + con_id = 55; + break; + case HCLK_SDIO: + case CLK_SDIO: + con_id = 56; + break; + case HCLK_EMMC: + case CLK_EMMC: + con_id = 57; + break; + default: + return -ENOENT; + } + + /* Select clk_sdmmc/emmc source from GPLL by default */ + /* mmc clock defaulg div 2 internal, need provide double in cru */ + src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, rate); + + if (src_clk_div > 127) { + /* use 24MHz source for 400KHz clock */ + src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, rate); + rk_clrsetreg(&cru->clksel_con[con_id], + EMMC_SEL_MASK | EMMC_DIV_MASK, + EMMC_SEL_XIN24M << EMMC_SEL_SHIFT | + (src_clk_div - 1) << EMMC_DIV_SHIFT); + } else { + rk_clrsetreg(&cru->clksel_con[con_id], + EMMC_SEL_MASK | EMMC_DIV_MASK, + EMMC_SEL_GPLL << EMMC_SEL_SHIFT | + (src_clk_div - 1) << EMMC_DIV_SHIFT); + } + + return rv1126_mmc_get_clk(priv, clk_id); +} + +static ulong rv1126_sfc_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, sel, con, parent; + + con = readl(&cru->clksel_con[58]); + div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT; + sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT; + if (sel == SCLK_SFC_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == SCLK_SFC_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + + return DIV_TO_RATE(parent, div); +} + +static ulong rv1126_sfc_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + rk_clrsetreg(&cru->clksel_con[58], + SCLK_SFC_SEL_MASK | SCLK_SFC_DIV_MASK, + SCLK_SFC_SEL_GPLL << SCLK_SFC_SEL_SHIFT | + (src_clk_div - 1) << SCLK_SFC_DIV_SHIFT); + + return rv1126_sfc_get_clk(priv); +} + +static ulong rv1126_nand_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, sel, con, parent; + + con = readl(&cru->clksel_con[59]); + div = (con & CLK_NANDC_DIV_MASK) >> CLK_NANDC_DIV_SHIFT; + sel = (con & CLK_NANDC_SEL_MASK) >> CLK_NANDC_SEL_SHIFT; + if (sel == CLK_NANDC_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == CLK_NANDC_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + + return DIV_TO_RATE(parent, div); +} + +static ulong rv1126_nand_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + rk_clrsetreg(&cru->clksel_con[59], + CLK_NANDC_SEL_MASK | CLK_NANDC_DIV_MASK, + CLK_NANDC_SEL_GPLL << CLK_NANDC_SEL_SHIFT | + (src_clk_div - 1) << CLK_NANDC_DIV_SHIFT); + + return rv1126_nand_get_clk(priv); +} + +static ulong rv1126_aclk_vop_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, sel, con, parent; + + con = readl(&cru->clksel_con[45]); + div = (con & ACLK_PDVO_DIV_MASK) >> ACLK_PDVO_DIV_SHIFT; + sel = (con & ACLK_PDVO_SEL_MASK) >> ACLK_PDVO_SEL_SHIFT; + if (sel == ACLK_PDVO_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == ACLK_PDVO_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + + return DIV_TO_RATE(parent, div); +} + +static ulong rv1126_aclk_vop_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[45], + ACLK_PDVO_SEL_MASK | ACLK_PDVO_DIV_MASK, + ACLK_PDVO_SEL_GPLL << ACLK_PDVO_SEL_SHIFT | + (src_clk_div - 1) << ACLK_PDVO_DIV_SHIFT); + + return rv1126_aclk_vop_get_clk(priv); +} + +static ulong rv1126_dclk_vop_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, sel, con, parent; + + con = readl(&cru->clksel_con[47]); + div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT; + sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT; + if (sel == DCLK_VOP_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == DCLK_VOP_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + + return DIV_TO_RATE(parent, div); +} + +static ulong rv1126_dclk_vop_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + ulong pll_rate, now, best_rate = 0; + u32 i, div, best_div = 0, best_sel = 0; + + for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) { + switch (i) { + case DCLK_VOP_SEL_GPLL: + pll_rate = priv->gpll_hz; + break; + case DCLK_VOP_SEL_CPLL: + pll_rate = priv->cpll_hz; + break; + default: + printf("do not support this vop pll sel\n"); + return -EINVAL; + } + + div = DIV_ROUND_UP(pll_rate, rate); + if (div > 255) + continue; + now = pll_rate / div; + if (abs(rate - now) < abs(rate - best_rate)) { + best_rate = now; + best_div = div; + best_sel = i; + } + debug("pll_rate=%lu, best_rate=%lu, best_div=%u, best_sel=%u\n", + pll_rate, best_rate, best_div, best_sel); + } + + if (best_rate) { + rk_clrsetreg(&cru->clksel_con[47], + DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_MASK, + best_sel << DCLK_VOP_SEL_SHIFT | + (best_div - 1) << DCLK_VOP_DIV_SHIFT); + } else { + printf("do not support this vop freq %lu\n", rate); + return -EINVAL; + } + + return rv1126_dclk_vop_get_clk(priv); +} + +static ulong rv1126_scr1_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, sel, con, parent; + + con = readl(&cru->clksel_con[3]); + div = (con & CLK_SCR1_DIV_MASK) >> CLK_SCR1_DIV_SHIFT; + sel = (con & CLK_SCR1_SEL_MASK) >> CLK_SCR1_SEL_SHIFT; + if (sel == CLK_SCR1_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == CLK_SCR1_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + + return DIV_TO_RATE(parent, div); +} + +static ulong rv1126_scr1_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[3], + CLK_SCR1_SEL_MASK | CLK_SCR1_DIV_MASK, + CLK_SCR1_SEL_GPLL << CLK_SCR1_SEL_SHIFT | + (src_clk_div - 1) << CLK_SCR1_DIV_SHIFT); + + return rv1126_scr1_get_clk(priv); +} + +static ulong rv1126_gmac_src_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, sel, con, parent; + + con = readl(&cru->clksel_con[63]); + div = (con & CLK_GMAC_SRC_DIV_MASK) >> CLK_GMAC_SRC_DIV_SHIFT; + sel = (con & CLK_GMAC_SRC_SEL_MASK) >> CLK_GMAC_SRC_SEL_SHIFT; + if (sel == CLK_GMAC_SRC_SEL_CPLL) + parent = priv->cpll_hz; + else if (sel == CLK_GMAC_SRC_SEL_GPLL) + parent = priv->gpll_hz; + else + return -ENOENT; + + return DIV_TO_RATE(parent, div); +} + +static ulong rv1126_gmac_src_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[63], + CLK_GMAC_SRC_SEL_MASK | CLK_GMAC_SRC_DIV_MASK, + CLK_GMAC_SRC_SEL_CPLL << CLK_GMAC_SRC_SEL_SHIFT | + (src_clk_div - 1) << CLK_GMAC_SRC_DIV_SHIFT); + + return rv1126_gmac_src_get_clk(priv); +} + +static ulong rv1126_gmac_out_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, sel, con, parent; + + con = readl(&cru->clksel_con[61]); + div = (con & CLK_GMAC_OUT_DIV_MASK) >> CLK_GMAC_OUT_DIV_SHIFT; + sel = (con & CLK_GMAC_OUT_SEL_MASK) >> CLK_GMAC_OUT_SEL_SHIFT; + if (sel == CLK_GMAC_OUT_SEL_CPLL) + parent = priv->cpll_hz; + else if (sel == CLK_GMAC_OUT_SEL_GPLL) + parent = priv->gpll_hz; + else + return -ENOENT; + + return DIV_TO_RATE(parent, div); +} + +static ulong rv1126_gmac_out_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[61], + CLK_GMAC_OUT_SEL_MASK | CLK_GMAC_OUT_DIV_MASK, + CLK_GMAC_OUT_SEL_CPLL << CLK_GMAC_OUT_SEL_SHIFT | + (src_clk_div - 1) << CLK_GMAC_OUT_DIV_SHIFT); + + return rv1126_gmac_out_get_clk(priv); +} + +static ulong rv1126_gmac_tx_rx_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + u32 con, sel, div_sel; + + con = readl(&cru->gmac_con); + sel = (con & GMAC_MODE_SEL_MASK) >> GMAC_MODE_SEL_SHIFT; + + if (sel == GMAC_RGMII_MODE) { + if (rate == 2500000) + div_sel = RGMII_CLK_DIV50; + else if (rate == 25000000) + div_sel = RGMII_CLK_DIV5; + else + div_sel = RGMII_CLK_DIV0; + rk_clrsetreg(&cru->gmac_con, RGMII_CLK_SEL_MASK, + div_sel << RGMII_CLK_SEL_SHIFT); + } else if (sel == GMAC_RMII_MODE) { + if (rate == 2500000) + div_sel = RMII_CLK_DIV20; + else + div_sel = RMII_CLK_DIV2; + rk_clrsetreg(&cru->gmac_con, RMII_CLK_SEL_MASK, + div_sel << RMII_CLK_SEL_SHIFT); + } + + return 0; +} + +static ulong rv1126_pclk_gmac_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, con, parent; + + parent = rv1126_pdphp_get_clk(priv, ACLK_PDPHP); + + con = readl(&cru->clksel_con[63]); + div = (con & PCLK_GMAC_DIV_MASK) >> PCLK_GMAC_DIV_SHIFT; + + return DIV_TO_RATE(parent, div); +} + +static ulong rv1126_dclk_decom_get_clk(struct rv1126_clk_priv *priv) +{ + struct rv1126_cru *cru = priv->cru; + u32 div, sel, con, parent; + + con = readl(&cru->clksel_con[25]); + div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT; + sel = (con & DCLK_DECOM_SEL_MASK) >> DCLK_DECOM_SEL_SHIFT; + if (sel == DCLK_DECOM_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == DCLK_DECOM_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + + return DIV_TO_RATE(parent, div); +} + +static ulong rv1126_dclk_decom_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct rv1126_cru *cru = priv->cru; + u32 src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 127); + rk_clrsetreg(&cru->clksel_con[25], + DCLK_DECOM_SEL_MASK | DCLK_DECOM_DIV_MASK, + DCLK_DECOM_SEL_GPLL << DCLK_DECOM_SEL_SHIFT | + (src_clk_div - 1) << DCLK_DECOM_DIV_SHIFT); + + return rv1126_dclk_decom_get_clk(priv); +} + +static ulong rv1126_clk_get_rate(struct clk *clk) +{ + struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); + ulong rate = 0; + + if (!priv->gpll_hz) { + printf("%s gpll=%lu\n", __func__, priv->gpll_hz); + return -ENOENT; + } + + switch (clk->id) { + case PLL_APLL: + case ARMCLK: + rate = rockchip_pll_get_rate(&rv1126_pll_clks[APLL], priv->cru, + APLL); + break; + case PLL_CPLL: + rate = rockchip_pll_get_rate(&rv1126_pll_clks[CPLL], priv->cru, + CPLL); + break; + case PLL_HPLL: + rate = rockchip_pll_get_rate(&rv1126_pll_clks[HPLL], priv->cru, + HPLL); + break; + case PLL_DPLL: + rate = rockchip_pll_get_rate(&rv1126_pll_clks[DPLL], priv->cru, + DPLL); + break; + case HCLK_PDCORE_NIU: + rate = rv1126_pdcore_get_clk(priv); + break; + case ACLK_PDBUS: + case HCLK_PDBUS: + case PCLK_PDBUS: + case PCLK_WDT: + rate = rv1126_pdbus_get_clk(priv, clk->id); + break; + case ACLK_PDPHP: + case HCLK_PDPHP: + rate = rv1126_pdphp_get_clk(priv, clk->id); + break; + case HCLK_PDAUDIO: + rate = rv1126_pdaudio_get_clk(priv); + break; + case CLK_I2C1: + case CLK_I2C3: + case CLK_I2C4: + case CLK_I2C5: + rate = rv1126_i2c_get_clk(priv, clk->id); + break; + case CLK_SPI1: + rate = rv1126_spi_get_clk(priv); + break; + case CLK_PWM2: + rate = rv1126_pwm_get_clk(priv); + break; + case CLK_SARADC: + rate = rv1126_saradc_get_clk(priv); + break; + case CLK_CRYPTO_CORE: + case CLK_CRYPTO_PKA: + case ACLK_CRYPTO: + rate = rv1126_crypto_get_clk(priv, clk->id); + break; + case CLK_SDMMC: + case HCLK_SDMMC: + case CLK_SDIO: + case HCLK_SDIO: + case CLK_EMMC: + case HCLK_EMMC: + case SCLK_EMMC_SAMPLE: + rate = rv1126_mmc_get_clk(priv, clk->id); + break; + case SCLK_SFC: + rate = rv1126_sfc_get_clk(priv); + break; + case CLK_NANDC: + rate = rv1126_nand_get_clk(priv); + break; + case ACLK_PDVO: + case ACLK_VOP: + rate = rv1126_aclk_vop_get_clk(priv); + break; + case DCLK_VOP: + rate = rv1126_dclk_vop_get_clk(priv); + break; + case CLK_SCR1_CORE: + rate = rv1126_scr1_get_clk(priv); + break; + case CLK_GMAC_SRC: + rate = rv1126_gmac_src_get_clk(priv); + break; + case CLK_GMAC_ETHERNET_OUT: + rate = rv1126_gmac_out_get_clk(priv); + break; + case PCLK_GMAC: + rate = rv1126_pclk_gmac_get_clk(priv); + break; + case DCLK_DECOM: + rate = rv1126_dclk_decom_get_clk(priv); + break; + default: + debug("%s: Unsupported CLK#%ld\n", __func__, clk->id); + return -ENOENT; + } + + return rate; +}; + +static ulong rv1126_clk_set_rate(struct clk *clk, ulong rate) +{ + struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); + ulong ret = 0; + + if (!priv->gpll_hz) { + printf("%s gpll=%lu\n", __func__, priv->gpll_hz); + return -ENOENT; + } + + switch (clk->id) { + case PLL_APLL: + case ARMCLK: + if (priv->armclk_hz) + rv1126_armclk_set_clk(priv, rate); + priv->armclk_hz = rate; + break; + case PLL_CPLL: + ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru, + CPLL, rate); + break; + case PLL_HPLL: + ret = rockchip_pll_set_rate(&rv1126_pll_clks[HPLL], priv->cru, + HPLL, rate); + break; + case ACLK_PDBUS: + case HCLK_PDBUS: + case PCLK_PDBUS: + case PCLK_WDT: + ret = rv1126_pdbus_set_clk(priv, clk->id, rate); + break; + case ACLK_PDPHP: + case HCLK_PDPHP: + ret = rv1126_pdphp_set_clk(priv, clk->id, rate); + break; + case HCLK_PDCORE_NIU: + ret = rv1126_pdcore_set_clk(priv, rate); + break; + case HCLK_PDAUDIO: + ret = rv1126_pdaudio_set_clk(priv, rate); + break; + case CLK_I2C1: + case CLK_I2C3: + case CLK_I2C4: + case CLK_I2C5: + ret = rv1126_i2c_set_clk(priv, clk->id, rate); + break; + case CLK_SPI1: + ret = rv1126_spi_set_clk(priv, rate); + break; + case CLK_PWM2: + ret = rv1126_pwm_set_clk(priv, rate); + break; + case CLK_SARADC: + ret = rv1126_saradc_set_clk(priv, rate); + break; + case CLK_CRYPTO_CORE: + case CLK_CRYPTO_PKA: + case ACLK_CRYPTO: + ret = rv1126_crypto_set_clk(priv, clk->id, rate); + break; + case CLK_SDMMC: + case HCLK_SDMMC: + case CLK_SDIO: + case HCLK_SDIO: + case CLK_EMMC: + case HCLK_EMMC: + ret = rv1126_mmc_set_clk(priv, clk->id, rate); + break; + case SCLK_SFC: + ret = rv1126_sfc_set_clk(priv, rate); + break; + case CLK_NANDC: + ret = rv1126_nand_set_clk(priv, rate); + break; + case ACLK_PDVO: + case ACLK_VOP: + ret = rv1126_aclk_vop_set_clk(priv, rate); + break; + case DCLK_VOP: + ret = rv1126_dclk_vop_set_clk(priv, rate); + break; + case CLK_SCR1_CORE: + ret = rv1126_scr1_set_clk(priv, rate); + break; + case CLK_GMAC_SRC: + ret = rv1126_gmac_src_set_clk(priv, rate); + break; + case CLK_GMAC_ETHERNET_OUT: + ret = rv1126_gmac_out_set_clk(priv, rate); + break; + case CLK_GMAC_TX_RX: + ret = rv1126_gmac_tx_rx_set_clk(priv, rate); + break; + case DCLK_DECOM: + ret = rv1126_dclk_decom_set_clk(priv, rate); + break; + default: + debug("%s: Unsupported CLK#%ld\n", __func__, clk->id); + return -ENOENT; + } + + return ret; +}; + +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) +static int rv1126_gmac_src_set_parent(struct clk *clk, struct clk *parent) +{ + struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); + struct rv1126_grf *grf = priv->grf; + + if (parent->id == CLK_GMAC_SRC_M0) + rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK, + GMAC_SRC_SEL_M0 << GMAC_SRC_SEL_SHIFT); + else if (parent->id == CLK_GMAC_SRC_M1) + rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK, + GMAC_SRC_SEL_M1 << GMAC_SRC_SEL_SHIFT); + + return 0; +} + +static int rv1126_gmac_src_m0_set_parent(struct clk *clk, struct clk *parent) +{ + struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); + struct rv1126_cru *cru = priv->cru; + + if (parent->id == CLK_GMAC_DIV) + rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK, + GMAC_SRC_M0_SEL_INT << GMAC_SRC_M0_SEL_SHIFT); + else + rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK, + GMAC_SRC_M0_SEL_EXT << GMAC_SRC_M0_SEL_SHIFT); + + return 0; +} + +static int rv1126_gmac_src_m1_set_parent(struct clk *clk, struct clk *parent) +{ + struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); + struct rv1126_cru *cru = priv->cru; + + if (parent->id == CLK_GMAC_DIV) + rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M1_SEL_MASK, + GMAC_SRC_M1_SEL_INT << GMAC_SRC_M1_SEL_SHIFT); + else + rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M1_SEL_MASK, + GMAC_SRC_M1_SEL_EXT << GMAC_SRC_M1_SEL_SHIFT); + + return 0; +} + +static int rv1126_gmac_tx_rx_set_parent(struct clk *clk, struct clk *parent) +{ + struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); + struct rv1126_cru *cru = priv->cru; + + if (parent->id == RGMII_MODE_CLK) + rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK, + GMAC_RGMII_MODE << GMAC_MODE_SEL_SHIFT); + else + rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK, + GMAC_RMII_MODE << GMAC_MODE_SEL_SHIFT); + + return 0; +} + +static int rv1126_clk_set_parent(struct clk *clk, struct clk *parent) +{ + switch (clk->id) { + case CLK_GMAC_SRC: + return rv1126_gmac_src_set_parent(clk, parent); + case CLK_GMAC_SRC_M0: + return rv1126_gmac_src_m0_set_parent(clk, parent); + case CLK_GMAC_SRC_M1: + return rv1126_gmac_src_m1_set_parent(clk, parent); + case CLK_GMAC_TX_RX: + return rv1126_gmac_tx_rx_set_parent(clk, parent); + default: + return -ENOENT; + } + + return 0; +} +#endif + +static struct clk_ops rv1126_clk_ops = { + .get_rate = rv1126_clk_get_rate, + .set_rate = rv1126_clk_set_rate, +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) + .set_parent = rv1126_clk_set_parent, +#endif +}; + +static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv, + struct rv1126_pmuclk_priv *pmu_priv, + ulong rate) +{ + ulong emmc_rate, sfc_rate, nandc_rate; + bool restore = false; + + if (priv->gpll_hz != OSC_HZ) { + emmc_rate = rv1126_mmc_get_clk(priv, CLK_EMMC); + sfc_rate = rv1126_sfc_get_clk(priv); + nandc_rate = rv1126_nand_get_clk(priv); + debug("%s emmc=%lu, sfc=%lu, nandc=%lu\n", __func__, + emmc_rate, sfc_rate, nandc_rate); + restore = true; + } + + /* + * the child div is big enough for gpll 1188MHz, + * even maskrom has change some clocks. + */ + if (rockchip_pll_set_rate(&rv1126_pll_clks[GPLL], + pmu_priv->pmucru, GPLL, rate)) + return -EINVAL; + pmu_priv->gpll_hz = rate; + priv->gpll_hz = rate; + + if (restore) { + rv1126_mmc_set_clk(priv, CLK_EMMC, emmc_rate); + rv1126_sfc_set_clk(priv, sfc_rate); + rv1126_nand_set_clk(priv, nandc_rate); + } + + return 0; +} + +static int rv1126_gpll_set_clk(struct rv1126_clk_priv *priv, ulong rate) +{ + struct udevice *pmucru_dev; + struct rv1126_pmuclk_priv *pmu_priv; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(rockchip_rv1126_pmucru), + &pmucru_dev); + if (ret) { + printf("%s: could not find pmucru device\n", __func__); + return ret; + } + pmu_priv = dev_get_priv(pmucru_dev); + priv->gpll_hz = pmu_priv->gpll_hz; + + if (rv1126_gpll_set_rate(priv, pmu_priv, rate)) { + printf("%s: failed to set gpll rate %lu\n", __func__, rate); + return -EINVAL; + } + + rv1126_pdpmu_set_pmuclk(pmu_priv, PCLK_PDPMU_HZ); + rv1126_rtc32k_set_pmuclk(pmu_priv, CLK_OSC0_DIV_HZ); + + return 0; +} + +static void rv1126_clk_init(struct rv1126_clk_priv *priv) +{ + int ret; + + priv->sync_kernel = false; + if (!priv->armclk_enter_hz) { + priv->armclk_enter_hz = + rockchip_pll_get_rate(&rv1126_pll_clks[APLL], + priv->cru, APLL); + priv->armclk_init_hz = priv->armclk_enter_hz; + } + + if (priv->armclk_init_hz != APLL_HZ) { + ret = rv1126_armclk_set_clk(priv, APLL_HZ); + if (!ret) + priv->armclk_init_hz = APLL_HZ; + } + if (priv->cpll_hz != CPLL_HZ) { + ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru, + CPLL, CPLL_HZ); + if (!ret) + priv->cpll_hz = CPLL_HZ; + } + if (priv->hpll_hz != HPLL_HZ) { + ret = rockchip_pll_set_rate(&rv1126_pll_clks[HPLL], priv->cru, + HPLL, HPLL_HZ); + if (!ret) + priv->hpll_hz = HPLL_HZ; + } + if (priv->gpll_hz != GPLL_HZ) + rv1126_gpll_set_clk(priv, GPLL_HZ); + + rv1126_pdbus_set_clk(priv, ACLK_PDBUS, ACLK_PDBUS_HZ); + rv1126_pdbus_set_clk(priv, HCLK_PDBUS, HCLK_PDBUS_HZ); + rv1126_pdbus_set_clk(priv, PCLK_PDBUS, PCLK_PDBUS_HZ); + rv1126_pdphp_set_clk(priv, ACLK_PDPHP, ACLK_PDPHP_HZ); + rv1126_pdphp_set_clk(priv, HCLK_PDPHP, HCLK_PDPHP_HZ); + rv1126_pdcore_set_clk(priv, HCLK_PDCORE_HZ); + rv1126_pdaudio_set_clk(priv, HCLK_PDAUDIO_HZ); +} + +static int rv1126_clk_probe(struct udevice *dev) +{ + struct rv1126_clk_priv *priv = dev_get_priv(dev); + int ret; + + priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + if (IS_ERR(priv->grf)) + return PTR_ERR(priv->grf); + + rv1126_clk_init(priv); + + /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ + ret = clk_set_defaults(dev, 1); + if (ret) + debug("%s clk_set_defaults failed %d\n", __func__, ret); + else + priv->sync_kernel = true; + + return 0; +} + +static int rv1126_clk_of_to_plat(struct udevice *dev) +{ + struct rv1126_clk_priv *priv = dev_get_priv(dev); + + priv->cru = dev_read_addr_ptr(dev); + + return 0; +} + +static int rv1126_clk_bind(struct udevice *dev) +{ + int ret; + struct udevice *sys_child; + struct sysreset_reg *priv; + + /* The reset driver does not have a device node, so bind it here */ + ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", + &sys_child); + if (ret) { + debug("Warning: No sysreset driver: ret=%d\n", ret); + } else { + priv = malloc(sizeof(struct sysreset_reg)); + priv->glb_srst_fst_value = offsetof(struct rv1126_cru, + glb_srst_fst); + priv->glb_srst_snd_value = offsetof(struct rv1126_cru, + glb_srst_snd); + dev_set_priv(sys_child, priv); + } + +#if CONFIG_IS_ENABLED(RESET_ROCKCHIP) + ret = offsetof(struct rv1126_cru, softrst_con[0]); + ret = rockchip_reset_bind(dev, ret, 15); + if (ret) + debug("Warning: software reset driver bind faile\n"); +#endif + return 0; +} + +static const struct udevice_id rv1126_clk_ids[] = { + { .compatible = "rockchip,rv1126-cru" }, + { } +}; + +U_BOOT_DRIVER(rockchip_rv1126_cru) = { + .name = "rockchip_rv1126_cru", + .id = UCLASS_CLK, + .of_match = rv1126_clk_ids, + .priv_auto = sizeof(struct rv1126_clk_priv), + .of_to_plat = rv1126_clk_of_to_plat, + .ops = &rv1126_clk_ops, + .bind = rv1126_clk_bind, + .probe = rv1126_clk_probe, +}; diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile index 7d03f81..9884355 100644 --- a/drivers/pinctrl/rockchip/Makefile +++ b/drivers/pinctrl/rockchip/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o +obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o diff --git a/drivers/pinctrl/rockchip/pinctrl-px30.c b/drivers/pinctrl/rockchip/pinctrl-px30.c index 9de29c0..2c35491 100644 --- a/drivers/pinctrl/rockchip/pinctrl-px30.c +++ b/drivers/pinctrl/rockchip/pinctrl-px30.c @@ -80,7 +80,7 @@ static int px30_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) struct regmap *regmap; int reg, ret, mask, mux_type; u8 bit; - u32 data, route_reg, route_val; + u32 data; regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) ? priv->regmap_pmu : priv->regmap_base; @@ -90,15 +90,6 @@ static int px30_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) reg = bank->iomux[iomux_num].offset; reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); - if (bank->route_mask & BIT(pin)) { - if (rockchip_get_mux_route(bank, pin, mux, &route_reg, - &route_val)) { - ret = regmap_write(regmap, route_reg, route_val); - if (ret) - return ret; - } - } - data = (mask << (bit + 16)); data |= (mux & mask) << bit; ret = regmap_write(regmap, reg, data); diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3128.c b/drivers/pinctrl/rockchip/pinctrl-rk3128.c index e6dc1af..355c45e 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3128.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3128.c @@ -106,7 +106,7 @@ static int rk3128_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) struct regmap *regmap; int reg, ret, mask, mux_type; u8 bit; - u32 data, route_reg, route_val; + u32 data; regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) ? priv->regmap_pmu : priv->regmap_base; @@ -119,15 +119,6 @@ static int rk3128_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) if (bank->recalced_mask & BIT(pin)) rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); - if (bank->route_mask & BIT(pin)) { - if (rockchip_get_mux_route(bank, pin, mux, &route_reg, - &route_val)) { - ret = regmap_write(regmap, route_reg, route_val); - if (ret) - return ret; - } - } - data = (mask << (bit + 16)); data |= (mux & mask) << bit; ret = regmap_write(regmap, reg, data); diff --git a/drivers/pinctrl/rockchip/pinctrl-rk322x.c b/drivers/pinctrl/rockchip/pinctrl-rk322x.c index 7c58f40..351406d 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk322x.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk322x.c @@ -150,7 +150,7 @@ static int rk3228_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) struct regmap *regmap; int reg, ret, mask, mux_type; u8 bit; - u32 data, route_reg, route_val; + u32 data; regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) ? priv->regmap_pmu : priv->regmap_base; @@ -160,15 +160,6 @@ static int rk3228_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) reg = bank->iomux[iomux_num].offset; reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); - if (bank->route_mask & BIT(pin)) { - if (rockchip_get_mux_route(bank, pin, mux, &route_reg, - &route_val)) { - ret = regmap_write(regmap, route_reg, route_val); - if (ret) - return ret; - } - } - data = (mask << (bit + 16)); data |= (mux & mask) << bit; ret = regmap_write(regmap, reg, data); diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 5894f47..a976b7a 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -37,7 +37,7 @@ static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) struct regmap *regmap; int reg, ret, mask, mux_type; u8 bit; - u32 data, route_reg, route_val; + u32 data; regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) ? priv->regmap_pmu : priv->regmap_base; @@ -47,15 +47,6 @@ static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) reg = bank->iomux[iomux_num].offset; reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); - if (bank->route_mask & BIT(pin)) { - if (rockchip_get_mux_route(bank, pin, mux, &route_reg, - &route_val)) { - ret = regmap_write(regmap, route_reg, route_val); - if (ret) - return ret; - } - } - /* bank0 is special, there are no higher 16 bit writing bits. */ if (bank->bank_num == 0) { regmap_read(regmap, reg, &data); diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3308.c b/drivers/pinctrl/rockchip/pinctrl-rk3308.c index 83186f4..f9ac634 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3308.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3308.c @@ -258,7 +258,7 @@ static int rk3308_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) struct regmap *regmap; int reg, ret, mask, mux_type; u8 bit; - u32 data, route_reg, route_val; + u32 data; regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) ? priv->regmap_pmu : priv->regmap_base; @@ -271,15 +271,6 @@ static int rk3308_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) if (bank->recalced_mask & BIT(pin)) rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); - if (bank->route_mask & BIT(pin)) { - if (rockchip_get_mux_route(bank, pin, mux, &route_reg, - &route_val)) { - ret = regmap_write(regmap, route_reg, route_val); - if (ret) - return ret; - } - } - data = (mask << (bit + 16)); data |= (mux & mask) << bit; ret = regmap_write(regmap, reg, data); diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3328.c b/drivers/pinctrl/rockchip/pinctrl-rk3328.c index 1c3c598..65a7500 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3328.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3328.c @@ -130,7 +130,7 @@ static int rk3328_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) struct regmap *regmap; int reg, ret, mask, mux_type; u8 bit; - u32 data, route_reg, route_val; + u32 data; regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) ? priv->regmap_pmu : priv->regmap_base; @@ -143,15 +143,6 @@ static int rk3328_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) if (bank->recalced_mask & BIT(pin)) rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); - if (bank->route_mask & BIT(pin)) { - if (rockchip_get_mux_route(bank, pin, mux, &route_reg, - &route_val)) { - ret = regmap_write(regmap, route_reg, route_val); - if (ret) - return ret; - } - } - data = (mask << (bit + 16)); data |= (mux & mask) << bit; ret = regmap_write(regmap, reg, data); diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3399.c b/drivers/pinctrl/rockchip/pinctrl-rk3399.c index caa9220..ae78557 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3399.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3399.c @@ -59,7 +59,7 @@ static int rk3399_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) struct regmap *regmap; int reg, ret, mask, mux_type; u8 bit; - u32 data, route_reg, route_val; + u32 data; regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) ? priv->regmap_pmu : priv->regmap_base; @@ -69,15 +69,6 @@ static int rk3399_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) reg = bank->iomux[iomux_num].offset; reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); - if (bank->route_mask & BIT(pin)) { - if (rockchip_get_mux_route(bank, pin, mux, &route_reg, - &route_val)) { - ret = regmap_write(regmap, route_reg, route_val); - if (ret) - return ret; - } - } - data = (mask << (bit + 16)); data |= (mux & mask) << bit; ret = regmap_write(regmap, reg, data); diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c index 630513b..d9d61fd 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c @@ -62,8 +62,9 @@ void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin, *bit = data->bit; } -bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, - int mux, u32 *reg, u32 *value) +static enum rockchip_pin_route_type +rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, + int mux, u32 *reg, u32 *value) { struct rockchip_pinctrl_priv *priv = bank->priv; struct rockchip_pin_ctrl *ctrl = priv->ctrl; @@ -78,12 +79,12 @@ bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, } if (i >= ctrl->niomux_routes) - return false; + return ROUTE_TYPE_INVALID; *reg = data->route_offset; *value = data->route_val; - return true; + return data->route_type; } int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask) @@ -214,8 +215,40 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) return -ENOTSUPP; ret = ctrl->set_mux(bank, pin, mux); + if (ret) + return ret; - return ret; + if (bank->route_mask & BIT(pin)) { + struct regmap *regmap; + u32 route_reg = 0, route_val = 0; + + ret = rockchip_get_mux_route(bank, pin, mux, + &route_reg, &route_val); + switch (ret) { + case ROUTE_TYPE_DEFAULT: + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) + regmap = priv->regmap_pmu; + else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU) + regmap = (pin % 8 < 4) ? priv->regmap_pmu : priv->regmap_base; + else + regmap = priv->regmap_base; + + regmap_write(regmap, route_reg, route_val); + break; + case ROUTE_TYPE_TOPGRF: + regmap_write(priv->regmap_base, route_reg, route_val); + break; + case ROUTE_TYPE_PMUGRF: + regmap_write(priv->regmap_pmu, route_reg, route_val); + break; + case ROUTE_TYPE_INVALID: + fallthrough; + default: + break; + } + } + + return 0; } static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { @@ -545,7 +578,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d inc = (iom->type & (IOMUX_WIDTH_4BIT | IOMUX_WIDTH_3BIT | IOMUX_8WIDTH_2BIT)) ? 8 : 4; - if (iom->type & IOMUX_SOURCE_PMU) + if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU)) pmu_offs += inc; else grf_offs += inc; diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip.h b/drivers/pinctrl/rockchip/pinctrl-rockchip.h index d969c20..8dfaba5 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rockchip.h +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip.h @@ -9,6 +9,9 @@ #include <linux/bitops.h> #include <linux/types.h> +#define RK_GENMASK_VAL(h, l, v) \ + (GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l)))) + /** * Encode variants of iomux registers into a type variable */ @@ -18,6 +21,7 @@ #define IOMUX_UNROUTED BIT(3) #define IOMUX_WIDTH_3BIT BIT(4) #define IOMUX_8WIDTH_2BIT BIT(5) +#define IOMUX_L_SOURCE_PMU BIT(6) /** * Defined some common pins constants @@ -63,6 +67,22 @@ enum rockchip_pin_pull_type { }; /** + * Rockchip pinctrl route type + * + * DEFAULT : Same regmap as pin iomux + * TOPGRF : Mux route setting in topgrf + * PMUGRF : Mux route setting in pmugrf + * INVALID : Nnot need to set mux route + */ +enum rockchip_pin_route_type { + ROUTE_TYPE_DEFAULT = 0, + ROUTE_TYPE_TOPGRF = 1, + ROUTE_TYPE_PMUGRF = 2, + + ROUTE_TYPE_INVALID = -1, +}; + +/** * @drv_type: drive strength variant using rockchip_perpin_drv_type * @offset: if initialized to -1 it will be autocalculated, by specifying * an initial offset value the relevant source offset can be reset @@ -126,6 +146,21 @@ struct rockchip_pin_bank { }, \ } +#define PIN_BANK_IOMUX_FLAGS_OFFSET(id, pins, label, iom0, iom1, iom2, \ + iom3, offset0, offset1, offset2, \ + offset3) \ + { \ + .bank_num = id, \ + .nr_pins = pins, \ + .name = label, \ + .iomux = { \ + { .type = iom0, .offset = offset0 }, \ + { .type = iom1, .offset = offset1 }, \ + { .type = iom2, .offset = offset2 }, \ + { .type = iom3, .offset = offset3 }, \ + }, \ + } + #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \ { \ .bank_num = id, \ @@ -220,6 +255,25 @@ struct rockchip_pin_bank { .pull_type[3] = pull3, \ } +#define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG) \ + { \ + .bank_num = ID, \ + .pin = PIN, \ + .func = FUNC, \ + .route_offset = REG, \ + .route_val = VAL, \ + .route_type = FLAG, \ + } + +#define MR_DEFAULT(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_DEFAULT) + +#define MR_TOPGRF(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_TOPGRF) + +#define MR_PMUGRF(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_PMUGRF) + /** * struct rockchip_mux_recalced_data: recalculate a pin iomux data. * @num: bank number. @@ -241,6 +295,7 @@ struct rockchip_mux_recalced_data { * @bank_num: bank number. * @pin: index at register or used to calc index. * @func: the min pin. + * @route_type: the register type. * @route_offset: the max pin. * @route_val: the register offset. */ @@ -248,6 +303,7 @@ struct rockchip_mux_route_data { u8 bank_num; u8 pin; u8 func; + enum rockchip_pin_route_type route_type : 8; u32 route_offset; u32 route_val; }; @@ -289,8 +345,6 @@ extern const struct pinctrl_ops rockchip_pinctrl_ops; int rockchip_pinctrl_probe(struct udevice *dev); void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin, int *reg, u8 *bit, int *mask); -bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, - int mux, u32 *reg, u32 *value); int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask); int rockchip_translate_drive_value(int type, int strength); int rockchip_translate_pull_value(int type, int pull); diff --git a/drivers/pinctrl/rockchip/pinctrl-rv1126.c b/drivers/pinctrl/rockchip/pinctrl-rv1126.c new file mode 100644 index 0000000..eefb8b1 --- /dev/null +++ b/drivers/pinctrl/rockchip/pinctrl-rv1126.c @@ -0,0 +1,416 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2020 Rockchip Electronics Co., Ltd + */ + +#include <common.h> +#include <dm.h> +#include <log.h> +#include <dm/pinctrl.h> +#include <regmap.h> +#include <syscon.h> +#include <linux/bitops.h> +#include <dt-bindings/pinctrl/rockchip.h> + +#include "pinctrl-rockchip.h" + +static struct rockchip_mux_recalced_data rv1126_mux_recalced_data[] = { + { + .num = 0, + .pin = 20, + .reg = 0x10000, + .bit = 0, + .mask = 0xf + }, + { + .num = 0, + .pin = 21, + .reg = 0x10000, + .bit = 4, + .mask = 0xf + }, + { + .num = 0, + .pin = 22, + .reg = 0x10000, + .bit = 8, + .mask = 0xf + }, + { + .num = 0, + .pin = 23, + .reg = 0x10000, + .bit = 12, + .mask = 0xf + }, +}; + +static struct rockchip_mux_route_data rv1126_mux_route_data[] = { + MR_TOPGRF(RK_GPIO3, RK_PD2, 1, 0x10260, RK_GENMASK_VAL(0, 0, 0)), /* I2S0_MCLK_M0 */ + MR_TOPGRF(RK_GPIO3, RK_PB0, 3, 0x10260, RK_GENMASK_VAL(0, 0, 1)), /* I2S0_MCLK_M1 */ + + MR_TOPGRF(RK_GPIO0, RK_PD4, 4, 0x10260, RK_GENMASK_VAL(3, 2, 0)), /* I2S1_MCLK_M0 */ + MR_TOPGRF(RK_GPIO1, RK_PD5, 2, 0x10260, RK_GENMASK_VAL(3, 2, 1)), /* I2S1_MCLK_M1 */ + MR_TOPGRF(RK_GPIO2, RK_PC7, 6, 0x10260, RK_GENMASK_VAL(3, 2, 2)), /* I2S1_MCLK_M2 */ + + MR_TOPGRF(RK_GPIO1, RK_PD0, 1, 0x10260, RK_GENMASK_VAL(4, 4, 0)), /* I2S2_MCLK_M0 */ + MR_TOPGRF(RK_GPIO2, RK_PB3, 2, 0x10260, RK_GENMASK_VAL(4, 4, 1)), /* I2S2_MCLK_M1 */ + + MR_TOPGRF(RK_GPIO3, RK_PD4, 2, 0x10260, RK_GENMASK_VAL(12, 12, 0)), /* PDM_CLK0_M0 */ + MR_TOPGRF(RK_GPIO3, RK_PC0, 3, 0x10260, RK_GENMASK_VAL(12, 12, 1)), /* PDM_CLK0_M1 */ + + MR_TOPGRF(RK_GPIO3, RK_PC6, 1, 0x10264, RK_GENMASK_VAL(0, 0, 0)), /* CIF_CLKOUT_M0 */ + MR_TOPGRF(RK_GPIO2, RK_PD1, 3, 0x10264, RK_GENMASK_VAL(0, 0, 1)), /* CIF_CLKOUT_M1 */ + + MR_TOPGRF(RK_GPIO3, RK_PA4, 5, 0x10264, RK_GENMASK_VAL(5, 4, 0)), /* I2C3_SCL_M0 */ + MR_TOPGRF(RK_GPIO2, RK_PD4, 7, 0x10264, RK_GENMASK_VAL(5, 4, 1)), /* I2C3_SCL_M1 */ + MR_TOPGRF(RK_GPIO1, RK_PD6, 3, 0x10264, RK_GENMASK_VAL(5, 4, 2)), /* I2C3_SCL_M2 */ + + MR_TOPGRF(RK_GPIO3, RK_PA0, 7, 0x10264, RK_GENMASK_VAL(6, 6, 0)), /* I2C4_SCL_M0 */ + MR_TOPGRF(RK_GPIO4, RK_PA0, 4, 0x10264, RK_GENMASK_VAL(6, 6, 1)), /* I2C4_SCL_M1 */ + + MR_TOPGRF(RK_GPIO2, RK_PA5, 7, 0x10264, RK_GENMASK_VAL(9, 8, 0)), /* I2C5_SCL_M0 */ + MR_TOPGRF(RK_GPIO3, RK_PB0, 5, 0x10264, RK_GENMASK_VAL(9, 8, 1)), /* I2C5_SCL_M1 */ + MR_TOPGRF(RK_GPIO1, RK_PD0, 4, 0x10264, RK_GENMASK_VAL(9, 8, 2)), /* I2C5_SCL_M2 */ + + MR_TOPGRF(RK_GPIO3, RK_PC0, 5, 0x10264, RK_GENMASK_VAL(11, 10, 0)), /* SPI1_CLK_M0 */ + MR_TOPGRF(RK_GPIO1, RK_PC6, 3, 0x10264, RK_GENMASK_VAL(11, 10, 1)), /* SPI1_CLK_M1 */ + MR_TOPGRF(RK_GPIO2, RK_PD5, 6, 0x10264, RK_GENMASK_VAL(11, 10, 2)), /* SPI1_CLK_M2 */ + + MR_TOPGRF(RK_GPIO3, RK_PC0, 2, 0x10264, RK_GENMASK_VAL(12, 12, 0)), /* RGMII_CLK_M0 */ + MR_TOPGRF(RK_GPIO2, RK_PB7, 2, 0x10264, RK_GENMASK_VAL(12, 12, 1)), /* RGMII_CLK_M1 */ + + MR_TOPGRF(RK_GPIO3, RK_PA1, 3, 0x10264, RK_GENMASK_VAL(13, 13, 0)), /* CAN_TXD_M0 */ + MR_TOPGRF(RK_GPIO3, RK_PA7, 5, 0x10264, RK_GENMASK_VAL(13, 13, 1)), /* CAN_TXD_M1 */ + + MR_TOPGRF(RK_GPIO3, RK_PA4, 6, 0x10268, RK_GENMASK_VAL(0, 0, 0)), /* PWM8_M0 */ + MR_TOPGRF(RK_GPIO2, RK_PD7, 5, 0x10268, RK_GENMASK_VAL(0, 0, 1)), /* PWM8_M1 */ + + MR_TOPGRF(RK_GPIO3, RK_PA5, 6, 0x10268, RK_GENMASK_VAL(2, 2, 0)), /* PWM9_M0 */ + MR_TOPGRF(RK_GPIO2, RK_PD6, 5, 0x10268, RK_GENMASK_VAL(2, 2, 1)), /* PWM9_M1 */ + + MR_TOPGRF(RK_GPIO3, RK_PA6, 6, 0x10268, RK_GENMASK_VAL(4, 4, 0)), /* PWM10_M0 */ + MR_TOPGRF(RK_GPIO2, RK_PD5, 5, 0x10268, RK_GENMASK_VAL(4, 4, 1)), /* PWM10_M1 */ + + MR_TOPGRF(RK_GPIO3, RK_PA7, 6, 0x10268, RK_GENMASK_VAL(6, 6, 0)), /* PWM11_IR_M0 */ + MR_TOPGRF(RK_GPIO3, RK_PA1, 5, 0x10268, RK_GENMASK_VAL(6, 6, 1)), /* PWM11_IR_M1 */ + + MR_TOPGRF(RK_GPIO1, RK_PA5, 3, 0x10268, RK_GENMASK_VAL(8, 8, 0)), /* UART2_TX_M0 */ + MR_TOPGRF(RK_GPIO3, RK_PA2, 1, 0x10268, RK_GENMASK_VAL(8, 8, 1)), /* UART2_TX_M1 */ + + MR_TOPGRF(RK_GPIO3, RK_PC6, 3, 0x10268, RK_GENMASK_VAL(11, 10, 0)), /* UART3_TX_M0 */ + MR_TOPGRF(RK_GPIO1, RK_PA7, 2, 0x10268, RK_GENMASK_VAL(11, 10, 1)), /* UART3_TX_M1 */ + MR_TOPGRF(RK_GPIO3, RK_PA0, 4, 0x10268, RK_GENMASK_VAL(11, 10, 2)), /* UART3_TX_M2 */ + + MR_TOPGRF(RK_GPIO3, RK_PA4, 4, 0x10268, RK_GENMASK_VAL(13, 12, 0)), /* UART4_TX_M0 */ + MR_TOPGRF(RK_GPIO2, RK_PA6, 4, 0x10268, RK_GENMASK_VAL(13, 12, 1)), /* UART4_TX_M1 */ + MR_TOPGRF(RK_GPIO1, RK_PD5, 3, 0x10268, RK_GENMASK_VAL(13, 12, 2)), /* UART4_TX_M2 */ + + MR_TOPGRF(RK_GPIO3, RK_PA6, 4, 0x10268, RK_GENMASK_VAL(15, 14, 0)), /* UART5_TX_M0 */ + MR_TOPGRF(RK_GPIO2, RK_PB0, 4, 0x10268, RK_GENMASK_VAL(15, 14, 1)), /* UART5_TX_M1 */ + MR_TOPGRF(RK_GPIO2, RK_PA0, 3, 0x10268, RK_GENMASK_VAL(15, 14, 2)), /* UART5_TX_M2 */ + + MR_PMUGRF(RK_GPIO0, RK_PB6, 3, 0x0114, RK_GENMASK_VAL(0, 0, 0)), /* PWM0_M0 */ + MR_PMUGRF(RK_GPIO2, RK_PB3, 5, 0x0114, RK_GENMASK_VAL(0, 0, 1)), /* PWM0_M1 */ + + MR_PMUGRF(RK_GPIO0, RK_PB7, 3, 0x0114, RK_GENMASK_VAL(2, 2, 0)), /* PWM1_M0 */ + MR_PMUGRF(RK_GPIO2, RK_PB2, 5, 0x0114, RK_GENMASK_VAL(2, 2, 1)), /* PWM1_M1 */ + + MR_PMUGRF(RK_GPIO0, RK_PC0, 3, 0x0114, RK_GENMASK_VAL(4, 4, 0)), /* PWM2_M0 */ + MR_PMUGRF(RK_GPIO2, RK_PB1, 5, 0x0114, RK_GENMASK_VAL(4, 4, 1)), /* PWM2_M1 */ + + MR_PMUGRF(RK_GPIO0, RK_PC1, 3, 0x0114, RK_GENMASK_VAL(6, 6, 0)), /* PWM3_IR_M0 */ + MR_PMUGRF(RK_GPIO2, RK_PB0, 5, 0x0114, RK_GENMASK_VAL(6, 6, 1)), /* PWM3_IR_M1 */ + + MR_PMUGRF(RK_GPIO0, RK_PC2, 3, 0x0114, RK_GENMASK_VAL(8, 8, 0)), /* PWM4_M0 */ + MR_PMUGRF(RK_GPIO2, RK_PA7, 5, 0x0114, RK_GENMASK_VAL(8, 8, 1)), /* PWM4_M1 */ + + MR_PMUGRF(RK_GPIO0, RK_PC3, 3, 0x0114, RK_GENMASK_VAL(10, 10, 0)), /* PWM5_M0 */ + MR_PMUGRF(RK_GPIO2, RK_PA6, 5, 0x0114, RK_GENMASK_VAL(10, 10, 1)), /* PWM5_M1 */ + + MR_PMUGRF(RK_GPIO0, RK_PB2, 3, 0x0114, RK_GENMASK_VAL(12, 12, 0)), /* PWM6_M0 */ + MR_PMUGRF(RK_GPIO2, RK_PD4, 5, 0x0114, RK_GENMASK_VAL(12, 12, 1)), /* PWM6_M1 */ + + MR_PMUGRF(RK_GPIO0, RK_PB1, 3, 0x0114, RK_GENMASK_VAL(14, 14, 0)), /* PWM7_IR_M0 */ + MR_PMUGRF(RK_GPIO3, RK_PA0, 5, 0x0114, RK_GENMASK_VAL(14, 14, 1)), /* PWM7_IR_M1 */ + + MR_PMUGRF(RK_GPIO0, RK_PB0, 1, 0x0118, RK_GENMASK_VAL(1, 0, 0)), /* SPI0_CLK_M0 */ + MR_PMUGRF(RK_GPIO2, RK_PA1, 1, 0x0118, RK_GENMASK_VAL(1, 0, 1)), /* SPI0_CLK_M1 */ + MR_PMUGRF(RK_GPIO2, RK_PB2, 6, 0x0118, RK_GENMASK_VAL(1, 0, 2)), /* SPI0_CLK_M2 */ + + MR_PMUGRF(RK_GPIO0, RK_PB6, 2, 0x0118, RK_GENMASK_VAL(2, 2, 0)), /* UART1_TX_M0 */ + MR_PMUGRF(RK_GPIO1, RK_PD0, 5, 0x0118, RK_GENMASK_VAL(2, 2, 1)), /* UART1_TX_M1 */ + MR_PMUGRF(RK_GPIO0, RK_PC3, 1, 0x0118, RK_GENMASK_VAL(4, 4, 1)), /* I2C2 */ +}; + +static int rv1126_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) +{ + struct rockchip_pinctrl_priv *priv = bank->priv; + int iomux_num = (pin / 8); + struct regmap *regmap; + int reg, ret, mask, mux_type; + u8 bit; + u32 data; + + debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); + + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) + regmap = priv->regmap_pmu; + else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU) + regmap = (pin % 8 < 4) ? priv->regmap_pmu : priv->regmap_base; + else + regmap = priv->regmap_base; + + /* get basic quadrupel of mux registers and the correct reg inside */ + mux_type = bank->iomux[iomux_num].type; + reg = bank->iomux[iomux_num].offset; + if (mux_type & IOMUX_WIDTH_4BIT) { + if ((pin % 8) >= 4) + reg += 0x4; + bit = (pin % 4) * 4; + mask = 0xf; + } else { + bit = (pin % 8) * 2; + mask = 0x3; + } + + if (bank->recalced_mask & BIT(pin)) + rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); + + data = (mask << (bit + 16)); + data |= (mux & mask) << bit; + ret = regmap_write(regmap, reg, data); + + return ret; +} + +#define RV1126_PULL_PMU_OFFSET 0x40 +#define RV1126_PULL_GRF_GPIO1A0_OFFSET 0x10108 +#define RV1126_PULL_PINS_PER_REG 8 +#define RV1126_PULL_BITS_PER_PIN 2 +#define RV1126_PULL_BANK_STRIDE 16 +#define RV1126_GPIO_C4_D7(p) (p >= 20 && p <= 31) /* GPIO0_C4 ~ GPIO0_D7 */ + +static void rv1126_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl_priv *priv = bank->priv; + + /* The first 24 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + if (RV1126_GPIO_C4_D7(pin_num)) { + *regmap = priv->regmap_base; + *reg = RV1126_PULL_GRF_GPIO1A0_OFFSET; + *reg -= (((31 - pin_num) / RV1126_PULL_PINS_PER_REG + 1) * 4); + *bit = pin_num % RV1126_PULL_PINS_PER_REG; + *bit *= RV1126_PULL_BITS_PER_PIN; + return; + } + *regmap = priv->regmap_pmu; + *reg = RV1126_PULL_PMU_OFFSET; + } else { + *reg = RV1126_PULL_GRF_GPIO1A0_OFFSET; + *regmap = priv->regmap_base; + *reg += (bank->bank_num - 1) * RV1126_PULL_BANK_STRIDE; + } + + *reg += ((pin_num / RV1126_PULL_PINS_PER_REG) * 4); + *bit = (pin_num % RV1126_PULL_PINS_PER_REG); + *bit *= RV1126_PULL_BITS_PER_PIN; +} + +static int rv1126_set_pull(struct rockchip_pin_bank *bank, + int pin_num, int pull) +{ + struct regmap *regmap; + int reg, ret; + u8 bit, type; + u32 data; + + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) + return -EOPNOTSUPP; + + rv1126_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); + type = bank->pull_type[pin_num / 8]; + ret = rockchip_translate_pull_value(type, pull); + if (ret < 0) { + debug("unsupported pull setting %d\n", pull); + return ret; + } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); + + data |= (ret << bit); + ret = regmap_write(regmap, reg, data); + + return ret; +} + +#define RV1126_DRV_PMU_OFFSET 0x20 +#define RV1126_DRV_GRF_GPIO1A0_OFFSET 0x10090 +#define RV1126_DRV_BITS_PER_PIN 4 +#define RV1126_DRV_PINS_PER_REG 4 +#define RV1126_DRV_BANK_STRIDE 32 + +static void rv1126_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl_priv *priv = bank->priv; + + /* The first 24 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + if (RV1126_GPIO_C4_D7(pin_num)) { + *regmap = priv->regmap_base; + *reg = RV1126_DRV_GRF_GPIO1A0_OFFSET; + *reg -= (((31 - pin_num) / RV1126_DRV_PINS_PER_REG + 1) * 4); + *reg -= 0x4; + *bit = pin_num % RV1126_DRV_PINS_PER_REG; + *bit *= RV1126_DRV_BITS_PER_PIN; + return; + } + *regmap = priv->regmap_pmu; + *reg = RV1126_DRV_PMU_OFFSET; + } else { + *regmap = priv->regmap_base; + *reg = RV1126_DRV_GRF_GPIO1A0_OFFSET; + *reg += (bank->bank_num - 1) * RV1126_DRV_BANK_STRIDE; + } + + *reg += ((pin_num / RV1126_DRV_PINS_PER_REG) * 4); + *bit = pin_num % RV1126_DRV_PINS_PER_REG; + *bit *= RV1126_DRV_BITS_PER_PIN; +} + +static int rv1126_set_drive(struct rockchip_pin_bank *bank, + int pin_num, int strength) +{ + struct regmap *regmap; + int reg; + u32 data; + u8 bit; + + rv1126_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); + data |= (strength << bit); + + return regmap_write(regmap, reg, data); +} + +#define RV1126_SCHMITT_PMU_OFFSET 0x60 +#define RV1126_SCHMITT_GRF_GPIO1A0_OFFSET 0x10188 +#define RV1126_SCHMITT_BANK_STRIDE 16 +#define RV1126_SCHMITT_PINS_PER_GRF_REG 8 +#define RV1126_SCHMITT_PINS_PER_PMU_REG 8 + +static int rv1126_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, + struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl_priv *priv = bank->priv; + int pins_per_reg; + + if (bank->bank_num == 0) { + if (RV1126_GPIO_C4_D7(pin_num)) { + *regmap = priv->regmap_base; + *reg = RV1126_SCHMITT_GRF_GPIO1A0_OFFSET; + *reg -= (((31 - pin_num) / RV1126_SCHMITT_PINS_PER_GRF_REG + 1) * 4); + *bit = pin_num % RV1126_SCHMITT_PINS_PER_GRF_REG; + return 0; + } + *regmap = priv->regmap_pmu; + *reg = RV1126_SCHMITT_PMU_OFFSET; + pins_per_reg = RV1126_SCHMITT_PINS_PER_PMU_REG; + } else { + *regmap = priv->regmap_base; + *reg = RV1126_SCHMITT_GRF_GPIO1A0_OFFSET; + pins_per_reg = RV1126_SCHMITT_PINS_PER_GRF_REG; + *reg += (bank->bank_num - 1) * RV1126_SCHMITT_BANK_STRIDE; + } + *reg += ((pin_num / pins_per_reg) * 4); + *bit = pin_num % pins_per_reg; + + return 0; +} + +static int rv1126_set_schmitt(struct rockchip_pin_bank *bank, + int pin_num, int enable) +{ + struct regmap *regmap; + int reg; + u8 bit; + u32 data; + + rv1126_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); + /* enable the write to the equivalent lower bits */ + data = BIT(bit + 16) | (enable << bit); + + return regmap_write(regmap, reg, data); +} + +static struct rockchip_pin_bank rv1126_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", + IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU, + IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU, + IOMUX_WIDTH_4BIT | IOMUX_L_SOURCE_PMU, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + 0x10010, 0x10018, 0x10020, 0x10028), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(4, 2, "gpio4", + IOMUX_WIDTH_4BIT, 0, 0, 0), +}; + +static const struct rockchip_pin_ctrl rv1126_pin_ctrl = { + .pin_banks = rv1126_pin_banks, + .nr_banks = ARRAY_SIZE(rv1126_pin_banks), + .nr_pins = 130, + .grf_mux_offset = 0x10004, /* mux offset from GPIO0_D0 */ + .pmu_mux_offset = 0x0, + .iomux_routes = rv1126_mux_route_data, + .niomux_routes = ARRAY_SIZE(rv1126_mux_route_data), + .iomux_recalced = rv1126_mux_recalced_data, + .niomux_recalced = ARRAY_SIZE(rv1126_mux_recalced_data), + .set_mux = rv1126_set_mux, + .set_pull = rv1126_set_pull, + .set_drive = rv1126_set_drive, + .set_schmitt = rv1126_set_schmitt, +}; + +static const struct udevice_id rv1126_pinctrl_ids[] = { + { + .compatible = "rockchip,rv1126-pinctrl", + .data = (ulong)&rv1126_pin_ctrl + }, + { } +}; + +U_BOOT_DRIVER(pinctrl_rv1126) = { + .name = "rockchip_rv1126_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = rv1126_pinctrl_ids, + .priv_auto = sizeof(struct rockchip_pinctrl_priv), + .ops = &rockchip_pinctrl_ops, +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + .bind = dm_scan_fdt_dev, +#endif + .probe = rockchip_pinctrl_probe, +}; diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile index 5a39611..83948e2 100644 --- a/drivers/ram/Makefile +++ b/drivers/ram/Makefile @@ -3,7 +3,7 @@ # Copyright (c) 2015 Google, Inc # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # -obj-$(CONFIG_RAM) += ram-uclass.o +obj-$(CONFIG_$(SPL_TPL_)DM) += ram-uclass.o obj-$(CONFIG_MPC83XX_SDRAM) += mpc83xx_sdram.o obj-$(CONFIG_SANDBOX) += sandbox_ram.o obj-$(CONFIG_STM32MP1_DDR) += stm32mp1/ diff --git a/drivers/ram/rockchip/Kconfig b/drivers/ram/rockchip/Kconfig index c29d5e8..67c63ec 100644 --- a/drivers/ram/rockchip/Kconfig +++ b/drivers/ram/rockchip/Kconfig @@ -11,9 +11,10 @@ config ROCKCHIP_SDRAM_COMMON help This enable sdram common driver +if RAM_ROCKCHIP + config RAM_ROCKCHIP_DEBUG bool "Rockchip ram drivers debugging" - depends on RAM_ROCKCHIP default y help This enables debugging ram driver API's for the platforms @@ -22,31 +23,28 @@ config RAM_ROCKCHIP_DEBUG This is an option for developers to understand the ram drivers initialization, configurations and etc. -config RAM_PX30_DDR4 - bool "DDR4 support for Rockchip PX30" - depends on RAM_ROCKCHIP && ROCKCHIP_PX30 +config RAM_ROCKCHIP_DDR4 + bool "DDR4 support for Rockchip SoCs" help This enables DDR4 sdram support instead of the default DDR3 support - on Rockchip PC30 SoCs. + on Rockchip SoCs. -config RAM_PX30_LPDDR2 - bool "LPDDR2 support for Rockchip PX30" - depends on RAM_ROCKCHIP && ROCKCHIP_PX30 +config RAM_ROCKCHIP_LPDDR2 + bool "LPDDR2 support for Rockchip SoCs" help This enables LPDDR2 sdram support instead of the default DDR3 support - on Rockchip PC30 SoCs. + on Rockchip SoCs. -config RAM_PX30_LPDDR3 - bool "LPDDR3 support for Rockchip PX30" - depends on RAM_ROCKCHIP && ROCKCHIP_PX30 +config RAM_ROCKCHIP_LPDDR3 + bool "LPDDR3 support for Rockchip SoCs" help This enables LPDDR3 sdram support instead of the default DDR3 support - on Rockchip PC30 SoCs. + on Rockchip SoCs. -config RAM_RK3399_LPDDR4 - bool "LPDDR4 support for Rockchip RK3399" - depends on RAM_ROCKCHIP && ROCKCHIP_RK3399 +config RAM_ROCKCHIP_LPDDR4 + bool "LPDDR4 support for Rockchip SoCs" help This enables LPDDR4 sdram code support for the platforms based - on Rockchip RK3399 SoC. + on Rockchip SoCs. +endif # RAM_ROCKCHIP diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile index 6d530c2..98839ad 100644 --- a/drivers/ram/rockchip/Makefile +++ b/drivers/ram/rockchip/Makefile @@ -14,4 +14,5 @@ obj-$(CONFIG_ROCKCHIP_RK3308) = sdram_rk3308.o obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o sdram_pctl_px30.o sdram_phy_px30.o obj-$(CONFIG_ROCKCHIP_RK3399) += sdram_rk3399.o obj-$(CONFIG_ROCKCHIP_RK3568) += sdram_rk3568.o +obj-$(CONFIG_ROCKCHIP_RV1126) += sdram_rv1126.o sdram_pctl_px30.o obj-$(CONFIG_ROCKCHIP_SDRAM_COMMON) += sdram_common.o diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-1056.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-1056.inc new file mode 100644 index 0000000..4cde215 --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-1056.inc @@ -0,0 +1,72 @@ +{ + { + { + .rank = 0x1, + .col = 0xC, + .bk = 0x3, + .bw = 0x0, + .dbw = 0x0, + .row_3_4 = 0x0, + .cs0_row = 0x10, + .cs1_row = 0x10, + .cs0_high16bit_row = 0x10, + .cs1_high16bit_row = 0x10, + .ddrconfig = 0 + }, + { + {0x351b1019}, + {0x12030903}, + {0x00000002}, + {0x00001111}, + {0x0000000c}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 1056, /* clock rate(MHz) */ + .dramtype = DDR3, + .num_channels = 1, + .stride = 0, + .odt = 1 + }, + { + { + {0x00000000, 0x43042001}, /* MSTR */ + {0x00000064, 0x008000b9}, /* RFSHTMG */ + {0x000000d0, 0x00020103}, /* INIT0 */ + {0x000000d4, 0x00690000}, /* INIT1 */ + {0x000000d8, 0x00000100}, /* INIT2 */ + {0x000000dc, 0x01240040}, /* INIT3 */ + {0x000000e0, 0x00280000}, /* INIT4 */ + {0x000000e4, 0x000c0000}, /* INIT5 */ + {0x000000f4, 0x000f011f}, /* RANKCTL */ + {0x00000100, 0x0f132414}, /* DRAMTMG0 */ + {0x00000104, 0x000d0419}, /* DRAMTMG1 */ + {0x00000108, 0x0507050b}, /* DRAMTMG2 */ + {0x0000010c, 0x00202008}, /* DRAMTMG3 */ + {0x00000110, 0x07020408}, /* DRAMTMG4 */ + {0x00000114, 0x06060404}, /* DRAMTMG5 */ + {0x00000120, 0x00000907}, /* DRAMTMG8 */ + {0x00000180, 0x00a9002b}, /* ZQCTL0 */ + {0x00000184, 0x00000000}, /* ZQCTL1 */ + {0x00000190, 0x07050003}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x06000610}, /* ODTCFG */ + {0x00000244, 0x00000201}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008a}, /* PHYREG01 */ + {0x00000014, 0x0000000e}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x0000000a}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-328.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-328.inc new file mode 100644 index 0000000..eef61ab --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-328.inc @@ -0,0 +1,72 @@ +{ + { + { + .rank = 0x1, + .col = 0xC, + .bk = 0x3, + .bw = 0x0, + .dbw = 0x0, + .row_3_4 = 0x0, + .cs0_row = 0x10, + .cs1_row = 0x10, + .cs0_high16bit_row = 0x10, + .cs1_high16bit_row = 0x10, + .ddrconfig = 0 + }, + { + {0x270a0509}, + {0x08020401}, + {0x00000002}, + {0x00001111}, + {0x0000000c}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 328, /* clock rate(MHz) */ + .dramtype = DDR3, + .num_channels = 1, + .stride = 0, + .odt = 0 + }, + { + { + {0x00000000, 0x43042001}, /* MSTR */ + {0x00000064, 0x0027003a}, /* RFSHTMG */ + {0x000000d0, 0x00020052}, /* INIT0 */ + {0x000000d4, 0x00220000}, /* INIT1 */ + {0x000000d8, 0x00000100}, /* INIT2 */ + {0x000000dc, 0x03100000}, /* INIT3 */ + {0x000000e0, 0x00000000}, /* INIT4 */ + {0x000000e4, 0x00090000}, /* INIT5 */ + {0x000000f4, 0x000f011f}, /* RANKCTL */ + {0x00000100, 0x07090b06}, /* DRAMTMG0 */ + {0x00000104, 0x00050209}, /* DRAMTMG1 */ + {0x00000108, 0x03030307}, /* DRAMTMG2 */ + {0x0000010c, 0x00202006}, /* DRAMTMG3 */ + {0x00000110, 0x03020203}, /* DRAMTMG4 */ + {0x00000114, 0x03030202}, /* DRAMTMG5 */ + {0x00000120, 0x00000903}, /* DRAMTMG8 */ + {0x00000180, 0x00800020}, /* ZQCTL0 */ + {0x00000184, 0x00000000}, /* ZQCTL1 */ + {0x00000190, 0x07010001}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x06000600}, /* ODTCFG */ + {0x00000244, 0x00000201}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008a}, /* PHYREG01 */ + {0x00000014, 0x00000005}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x00000005}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-396.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-396.inc new file mode 100644 index 0000000..39a8271 --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-396.inc @@ -0,0 +1,72 @@ +{ + { + { + .rank = 0x1, + .col = 0xC, + .bk = 0x3, + .bw = 0x0, + .dbw = 0x0, + .row_3_4 = 0x0, + .cs0_row = 0x10, + .cs1_row = 0x10, + .cs0_high16bit_row = 0x10, + .cs1_high16bit_row = 0x10, + .ddrconfig = 0 + }, + { + {0x290b060a}, + {0x0a020401}, + {0x00000002}, + {0x00001111}, + {0x0000000c}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 396, /* clock rate(MHz) */ + .dramtype = DDR3, + .num_channels = 1, + .stride = 0, + .odt = 0 + }, + { + { + {0x00000000, 0x43042001}, /* MSTR */ + {0x00000064, 0x00300046}, /* RFSHTMG */ + {0x000000d0, 0x00020062}, /* INIT0 */ + {0x000000d4, 0x00280000}, /* INIT1 */ + {0x000000d8, 0x00000100}, /* INIT2 */ + {0x000000dc, 0x05200000}, /* INIT3 */ + {0x000000e0, 0x00000000}, /* INIT4 */ + {0x000000e4, 0x00090000}, /* INIT5 */ + {0x000000f4, 0x000f011f}, /* RANKCTL */ + {0x00000100, 0x070a0d07}, /* DRAMTMG0 */ + {0x00000104, 0x0005020b}, /* DRAMTMG1 */ + {0x00000108, 0x03030407}, /* DRAMTMG2 */ + {0x0000010c, 0x00202006}, /* DRAMTMG3 */ + {0x00000110, 0x03020204}, /* DRAMTMG4 */ + {0x00000114, 0x03030202}, /* DRAMTMG5 */ + {0x00000120, 0x00000904}, /* DRAMTMG8 */ + {0x00000180, 0x00800020}, /* ZQCTL0 */ + {0x00000184, 0x00000000}, /* ZQCTL1 */ + {0x00000190, 0x07010001}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x06000604}, /* ODTCFG */ + {0x00000244, 0x00000201}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008a}, /* PHYREG01 */ + {0x00000014, 0x00000006}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x00000005}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-528.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-528.inc new file mode 100644 index 0000000..9dbbb1a --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-528.inc @@ -0,0 +1,72 @@ +{ + { + { + .rank = 0x1, + .col = 0xC, + .bk = 0x3, + .bw = 0x0, + .dbw = 0x0, + .row_3_4 = 0x0, + .cs0_row = 0x10, + .cs1_row = 0x10, + .cs0_high16bit_row = 0x10, + .cs1_high16bit_row = 0x10, + .ddrconfig = 0 + }, + { + {0x2c0f080e}, + {0x0d030502}, + {0x00000002}, + {0x00001111}, + {0x0000000c}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 528, /* clock rate(MHz) */ + .dramtype = DDR3, + .num_channels = 1, + .stride = 0, + .odt = 0 + }, + { + { + {0x00000000, 0x43042001}, /* MSTR */ + {0x00000064, 0x0040005d}, /* RFSHTMG */ + {0x000000d0, 0x00020082}, /* INIT0 */ + {0x000000d4, 0x00350000}, /* INIT1 */ + {0x000000d8, 0x00000100}, /* INIT2 */ + {0x000000dc, 0x09400000}, /* INIT3 */ + {0x000000e0, 0x00080000}, /* INIT4 */ + {0x000000e4, 0x00090000}, /* INIT5 */ + {0x000000f4, 0x000f011f}, /* RANKCTL */ + {0x00000100, 0x090e120a}, /* DRAMTMG0 */ + {0x00000104, 0x0007020e}, /* DRAMTMG1 */ + {0x00000108, 0x03040407}, /* DRAMTMG2 */ + {0x0000010c, 0x00202006}, /* DRAMTMG3 */ + {0x00000110, 0x04020305}, /* DRAMTMG4 */ + {0x00000114, 0x03030302}, /* DRAMTMG5 */ + {0x00000120, 0x00000904}, /* DRAMTMG8 */ + {0x00000180, 0x00800020}, /* ZQCTL0 */ + {0x00000184, 0x00000000}, /* ZQCTL1 */ + {0x00000190, 0x07020001}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x06000608}, /* ODTCFG */ + {0x00000244, 0x00000201}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008a}, /* PHYREG01 */ + {0x00000014, 0x00000008}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x00000006}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-664.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-664.inc new file mode 100644 index 0000000..2b57132 --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-664.inc @@ -0,0 +1,72 @@ +{ + { + { + .rank = 0x1, + .col = 0xC, + .bk = 0x3, + .bw = 0x0, + .dbw = 0x0, + .row_3_4 = 0x0, + .cs0_row = 0x10, + .cs1_row = 0x10, + .cs0_high16bit_row = 0x10, + .cs1_high16bit_row = 0x10, + .ddrconfig = 0 + }, + { + {0x2f120a11}, + {0x0f020602}, + {0x00000002}, + {0x00001111}, + {0x0000000c}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 664, /* clock rate(MHz) */ + .dramtype = DDR3, + .num_channels = 1, + .stride = 0, + .odt = 1 + }, + { + { + {0x00000000, 0x43042001}, /* MSTR */ + {0x00000064, 0x00500075}, /* RFSHTMG */ + {0x000000d0, 0x000200a4}, /* INIT0 */ + {0x000000d4, 0x00420000}, /* INIT1 */ + {0x000000d8, 0x00000100}, /* INIT2 */ + {0x000000dc, 0x0b600040}, /* INIT3 */ + {0x000000e0, 0x00100000}, /* INIT4 */ + {0x000000e4, 0x00090000}, /* INIT5 */ + {0x000000f4, 0x000f011f}, /* RANKCTL */ + {0x00000100, 0x0a0f160c}, /* DRAMTMG0 */ + {0x00000104, 0x00080211}, /* DRAMTMG1 */ + {0x00000108, 0x04050508}, /* DRAMTMG2 */ + {0x0000010c, 0x00202006}, /* DRAMTMG3 */ + {0x00000110, 0x05020306}, /* DRAMTMG4 */ + {0x00000114, 0x04040302}, /* DRAMTMG5 */ + {0x00000120, 0x00000905}, /* DRAMTMG8 */ + {0x00000180, 0x00800020}, /* ZQCTL0 */ + {0x00000184, 0x00000000}, /* ZQCTL1 */ + {0x00000190, 0x07030002}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x0600060c}, /* ODTCFG */ + {0x00000244, 0x00000201}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008a}, /* PHYREG01 */ + {0x00000014, 0x0000000a}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x00000007}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-784.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-784.inc new file mode 100644 index 0000000..8ad2272 --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-784.inc @@ -0,0 +1,72 @@ +{ + { + { + .rank = 0x1, + .col = 0xC, + .bk = 0x3, + .bw = 0x0, + .dbw = 0x0, + .row_3_4 = 0x0, + .cs0_row = 0x10, + .cs1_row = 0x10, + .cs0_high16bit_row = 0x10, + .cs1_high16bit_row = 0x10, + .ddrconfig = 0 + }, + { + {0x30150c13}, + {0x10030702}, + {0x00000002}, + {0x00001111}, + {0x0000000c}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 784, /* clock rate(MHz) */ + .dramtype = DDR3, + .num_channels = 1, + .stride = 0, + .odt = 1 + }, + { + { + {0x00000000, 0x43042001}, /* MSTR */ + {0x00000064, 0x005f008a}, /* RFSHTMG */ + {0x000000d0, 0x000200c1}, /* INIT0 */ + {0x000000d4, 0x004e0000}, /* INIT1 */ + {0x000000d8, 0x00000100}, /* INIT2 */ + {0x000000dc, 0x0d700040}, /* INIT3 */ + {0x000000e0, 0x00180000}, /* INIT4 */ + {0x000000e4, 0x00090000}, /* INIT5 */ + {0x000000f4, 0x000f011f}, /* RANKCTL */ + {0x00000100, 0x0c101a0f}, /* DRAMTMG0 */ + {0x00000104, 0x000a0314}, /* DRAMTMG1 */ + {0x00000108, 0x04060509}, /* DRAMTMG2 */ + {0x0000010c, 0x00202006}, /* DRAMTMG3 */ + {0x00000110, 0x06020306}, /* DRAMTMG4 */ + {0x00000114, 0x04040303}, /* DRAMTMG5 */ + {0x00000120, 0x00000906}, /* DRAMTMG8 */ + {0x00000180, 0x00800020}, /* ZQCTL0 */ + {0x00000184, 0x00000000}, /* ZQCTL1 */ + {0x00000190, 0x07040002}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x0600060c}, /* ODTCFG */ + {0x00000244, 0x00000201}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008a}, /* PHYREG01 */ + {0x00000014, 0x0000000b}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x00000008}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-924.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-924.inc new file mode 100644 index 0000000..4cc36b0 --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-924.inc @@ -0,0 +1,72 @@ +{ + { + { + .rank = 0x1, + .col = 0xC, + .bk = 0x3, + .bw = 0x0, + .dbw = 0x0, + .row_3_4 = 0x0, + .cs0_row = 0x10, + .cs1_row = 0x10, + .cs0_high16bit_row = 0x10, + .cs1_high16bit_row = 0x10, + .ddrconfig = 0 + }, + { + {0x33180e16}, + {0x10030803}, + {0x00000002}, + {0x00001111}, + {0x0000000c}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 924, /* clock rate(MHz) */ + .dramtype = DDR3, + .num_channels = 1, + .stride = 0, + .odt = 1 + }, + { + { + {0x00000000, 0x43042001}, /* MSTR */ + {0x00000064, 0x007000a2}, /* RFSHTMG */ + {0x000000d0, 0x000200e3}, /* INIT0 */ + {0x000000d4, 0x005c0000}, /* INIT1 */ + {0x000000d8, 0x00000100}, /* INIT2 */ + {0x000000dc, 0x0f140040}, /* INIT3 */ + {0x000000e0, 0x00200000}, /* INIT4 */ + {0x000000e4, 0x000b0000}, /* INIT5 */ + {0x000000f4, 0x000f011f}, /* RANKCTL */ + {0x00000100, 0x0d111f11}, /* DRAMTMG0 */ + {0x00000104, 0x000c0317}, /* DRAMTMG1 */ + {0x00000108, 0x0507050a}, /* DRAMTMG2 */ + {0x0000010c, 0x00202007}, /* DRAMTMG3 */ + {0x00000110, 0x07020307}, /* DRAMTMG4 */ + {0x00000114, 0x05050403}, /* DRAMTMG5 */ + {0x00000120, 0x00000907}, /* DRAMTMG8 */ + {0x00000180, 0x00940025}, /* ZQCTL0 */ + {0x00000184, 0x00000000}, /* ZQCTL1 */ + {0x00000190, 0x07050003}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x06000610}, /* ODTCFG */ + {0x00000244, 0x00000201}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008a}, /* PHYREG01 */ + {0x00000014, 0x0000000d}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x00000009}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-loader_params.inc b/drivers/ram/rockchip/sdram-rv1126-loader_params.inc new file mode 100644 index 0000000..a4c9e7f --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-loader_params.inc @@ -0,0 +1,197 @@ +0x12345678, +2,/* version */ +(0 << 0) | (1 << 8) | (9 << 16) | (8 << 24),/* cpu_gen,global index */ +(0 << 0) | (9 << 8) | (17 << 16) | (9 << 24),/* d2,d3 index */ +(26 << 0) | (9 << 8) | (0 << 16) | (0 << 24),/* d4,d5 index */ +(0 << 0) | (9 << 8) | (35 << 16) | (9 << 24),/* lp2,lp3 index */ +(44 << 0) | (13 << 8) | (0 << 16) | (0 << 24),/* lp4,lp5 index */ +(0 << 0) | (0 << 8) | (57 << 16) | (8 << 24),/* skew index, dq_map index */ +(65 << 0) | (13 << 8) | (0 << 16) | (0 << 24), /*lp4x index*/ +/* global info */ +0, +(93 << 16) | 13,/* sr_idle << 16 | pd_idle */ +0,/* channel info */ +1,/* 2t info */ +0, 0, 0, 0,/* reserved */ + +/* ddr3 */ +(924 << DDR_FREQ_F0_SHIFT) | (328 << DDR_FREQ_F1_SHIFT), +(528 << DDR_FREQ_F2_SHIFT) | (784 << DDR_FREQ_F3_SHIFT), +(0 << DDR_FREQ_F4_SHIFT) | (0 << DDR_FREQ_F5_SHIFT), +/* drv when odt on */ +(30 << PHY_DQ_DRV_SHIFT) | (41 << PHY_CA_DRV_SHIFT) | + (38 << PHY_CLK_DRV_SHIFT) | (34 << DRAM_DQ_DRV_SHIFT), +/* drv when odt off */ +(30 << PHY_DQ_DRV_SHIFT) | (30 << PHY_CA_DRV_SHIFT) | + (38 << PHY_CLK_DRV_SHIFT) | (34 << DRAM_DQ_DRV_SHIFT), +/* odt info */ +(120 << DRAM_ODT_SHIFT) | (141 << PHY_ODT_SHIFT) | + (1 << PHY_ODT_PUUP_EN_SHIFT) | + (0 << PHY_ODT_PUDN_EN_SHIFT), +/* odt enable freq */ +(333 << DRAM_ODT_EN_FREQ_SHIFT) | (333 << PHY_ODT_EN_FREQ_SHIFT), +/* slew rate when odt enable */ +(0x1f << PHY_DQ_SR_SHIFT) | (0x1f << PHY_CA_SR_SHIFT) | + (0x1f << PHY_CLK_SR_SHIFT), +/* slew ratee when odt disable */ +(0x1f << PHY_DQ_SR_SHIFT) | (0x1f << PHY_CA_SR_SHIFT) | + (0x1f << PHY_CLK_SR_SHIFT), + +/* ddr4 */ +(924 << DDR_FREQ_F0_SHIFT) | (328 << DDR_FREQ_F1_SHIFT), +(528 << DDR_FREQ_F2_SHIFT) | (784 << DDR_FREQ_F3_SHIFT), +(0 << DDR_FREQ_F4_SHIFT) | (0 << DDR_FREQ_F5_SHIFT), +/* drv when odt on */ +(37 << PHY_DQ_DRV_SHIFT) | (44 << PHY_CA_DRV_SHIFT) | + (37 << PHY_CLK_DRV_SHIFT) | (34 << DRAM_DQ_DRV_SHIFT), +/* drv when odt off */ +(37 << PHY_DQ_DRV_SHIFT) | (44 << PHY_CA_DRV_SHIFT) | + (37 << PHY_CLK_DRV_SHIFT) | (34 << DRAM_DQ_DRV_SHIFT), +/* odt info */ +(120 << DRAM_ODT_SHIFT) | (148 << PHY_ODT_SHIFT) | + (1 << PHY_ODT_PUUP_EN_SHIFT) | (1 << PHY_ODT_PUDN_EN_SHIFT), +/* odt enable freq */ +(625 << DRAM_ODT_EN_FREQ_SHIFT) | (625 << PHY_ODT_EN_FREQ_SHIFT), +/* slew rate when odt enable */ +(0xe << PHY_DQ_SR_SHIFT) | (0x3 << PHY_CA_SR_SHIFT) | + (0x3 << PHY_CLK_SR_SHIFT), +/* slew ratee when odt disable */ +(0xe << PHY_DQ_SR_SHIFT) | (0x3 << PHY_CA_SR_SHIFT) | + (0x3 << PHY_CLK_SR_SHIFT), + +/* lpddr3 */ +(924 << DDR_FREQ_F0_SHIFT) | (328 << DDR_FREQ_F1_SHIFT), +(528 << DDR_FREQ_F2_SHIFT) | (784 << DDR_FREQ_F3_SHIFT), +(0 << DDR_FREQ_F4_SHIFT) | (0 << DDR_FREQ_F5_SHIFT), +/* drv when odt on */ +(28 << PHY_DQ_DRV_SHIFT) | (37 << PHY_CA_DRV_SHIFT) | + (34 << PHY_CLK_DRV_SHIFT) | (34 << DRAM_DQ_DRV_SHIFT), +/* drv when odt off */ +(28 << PHY_DQ_DRV_SHIFT) | (37 << PHY_CA_DRV_SHIFT) | + (34 << PHY_CLK_DRV_SHIFT) | (34 << DRAM_DQ_DRV_SHIFT), +/* odt info */ +(120 << DRAM_ODT_SHIFT) | (148 << PHY_ODT_SHIFT) | + (1 << PHY_ODT_PUUP_EN_SHIFT) | (1 << PHY_ODT_PUDN_EN_SHIFT), +/* odt enable freq */ +(333 << DRAM_ODT_EN_FREQ_SHIFT) | (333 << PHY_ODT_EN_FREQ_SHIFT), + +/* slew rate when odt enable */ +(0xe << PHY_DQ_SR_SHIFT) | (0x0 << PHY_CA_SR_SHIFT) | + (0x0 << PHY_CLK_SR_SHIFT), +/* slew ratee when odt disable */ +(0xe << PHY_DQ_SR_SHIFT) | (0x0 << PHY_CA_SR_SHIFT) | + (0x0 << PHY_CLK_SR_SHIFT), + +/* lpddr4 */ +(924 << DDR_FREQ_F0_SHIFT) | (328 << DDR_FREQ_F1_SHIFT), +(528 << DDR_FREQ_F2_SHIFT) | (784 << DDR_FREQ_F3_SHIFT), +(0 << DDR_FREQ_F4_SHIFT) | (0 << DDR_FREQ_F5_SHIFT), + +/* drv when odt on */ +(38 << PHY_DQ_DRV_SHIFT) | (46 << PHY_CA_DRV_SHIFT) | + (38 << PHY_CLK_DRV_SHIFT) | (40 << DRAM_DQ_DRV_SHIFT), +/* drv when odt off */ +(38 << PHY_DQ_DRV_SHIFT) | (46 << PHY_CA_DRV_SHIFT) | + (38 << PHY_CLK_DRV_SHIFT) | (40 << DRAM_DQ_DRV_SHIFT), +/* odt info and PU-cal info */ +(240 << DRAM_ODT_SHIFT) | (80 << PHY_ODT_SHIFT) | + (0 << LP4_CA_ODT_SHIFT) | + (LPDDR4_VDDQ_2_5 << LP4_DRV_PU_CAL_ODTEN_SHIFT) | + (LPDDR4_VDDQ_2_5 << LP4_DRV_PU_CAL_ODTOFF_SHIFT) | + (0 << PHY_LP4_DRV_PULLDOWN_EN_ODTEN_SHIFT) | + (0 << PHY_LP4_DRV_PULLDOWN_EN_ODTOFF_SHIFT), +/* odt enable freq */ +(333 << PHY_LP4_ODT_EN_FREQ_SHIFT) | (333 << LP4_DQ_ODT_EN_FREQ_SHIFT), +/* slew rate when odt enable */ +(0xf << PHY_DQ_SR_SHIFT) | (0xf << PHY_CA_SR_SHIFT) | + (0xf << PHY_CLK_SR_SHIFT), +/* slew ratee when odt disable */ +(0xf << PHY_DQ_SR_SHIFT) | (0xf << PHY_CA_SR_SHIFT) | + (0xf << PHY_CLK_SR_SHIFT), +/* ca odt en freq */ +(333 << LP4_CA_ODT_EN_FREQ_SHIFT), +/* cs drv info and ca odt info */ +(0 << PHY_LP4_CS_DRV_ODTEN_SHIFT) | + (0 << PHY_LP4_CS_DRV_ODTOFF_SHIFT) | + (0 << LP4_ODTE_CK_SHIFT) | (0 << LP4_ODTE_CS_EN_SHIFT) | + (0 << LP4_ODTD_CA_EN_SHIFT), +/* vref info when odt enable */ +(200 << PHY_LP4_DQ_VREF_SHIFT) | (420 << LP4_DQ_VREF_SHIFT) | + (420 << LP4_CA_VREF_SHIFT), +/* vref info when odt disable */ +(420 << PHY_LP4_DQ_VREF_SHIFT) | (420 << LP4_DQ_VREF_SHIFT) | + (420 << LP4_CA_VREF_SHIFT), +/* ddr4 map << 0 | ddr3 map << 24 */ +((0x2 << 6) | (0x1 << 4) | (0x3 << 2) | (0x0 << 0)) | + (0 << 8) | (0 << 16) | + (((0x2 << 6) | (0x1 << 4) | (0x3 << 2) | (0x0 << 0)) << 24), +/* lp3 map << 16 | lp4 map << 24 */ +/* lp4 should equal to 0xc9 */ +(((0x3 << 6) | (0x2 << 4) | (0x1 << 2) | (0x0 << 0)) << 16) | + (((0x3 << 6) | (0x0 << 4) | (0x2 << 2) | (0x1 << 0)) << 24), +/* lp3 dq0-7 map */ +(2 << 0) | (6 << 4) | (4 << 8) | (0 << 12) | (3 << 16) | (7 << 20) | + ( 5 << 24) | (1 << 28), +/* lp2 dq0-7 map */ +0, +/* ddr4 dq map */ +/* cs0 dq0-15 */ + ((2 << 0 | 0 << 2 | 3 << 4 | 1 << 6) << 0) | + ((0 << 0 | 2 << 2 | 3 << 4 | 1 << 6) << 8) | + ((2 << 0 | 2 << 2 | 1 << 4 | 3 << 6) << 16) | + ((1 << 0 | 3 << 2 | 0 << 4 | 0 << 6) << 24), +/* cs0 dq16-31 */ + ((2 << 0 | 0 << 2 | 2 << 4 | 0 << 6) << 0) | + ((1 << 0 | 3 << 2 | 3 << 4 | 1 << 6) << 8) | + ((0 << 0 | 0 << 2 | 1 << 4 | 3 << 6) << 16) | + ((1 << 0 | 3 << 2 | 2 << 4 | 2 << 6) << 24), +/* cs1 dq0-15 */ + ((2 << 0 | 0 << 2 | 3 << 4 | 1 << 6) << 0) | + ((0 << 0 | 2 << 2 | 3 << 4 | 1 << 6) << 8) | + ((2 << 0 | 2 << 2 | 1 << 4 | 3 << 6) << 16) | + ((1 << 0 | 3 << 2 | 0 << 4 | 0 << 6) << 24), +/* cs1 dq16-31 */ + ((2 << 0 | 0 << 2 | 2 << 4 | 0 << 6) << 0) | + ((1 << 0 | 3 << 2 | 3 << 4 | 1 << 6) << 8) | + ((0 << 0 | 0 << 2 | 1 << 4 | 3 << 6) << 16) | + ((1 << 0 | 3 << 2 | 2 << 4 | 2 << 6) << 24), + +/* lpddr4x */ +(1056 << DDR_FREQ_F0_SHIFT) | (328 << DDR_FREQ_F1_SHIFT), +(528 << DDR_FREQ_F2_SHIFT) | (784 << DDR_FREQ_F3_SHIFT), +(0 << DDR_FREQ_F4_SHIFT) | (0 << DDR_FREQ_F5_SHIFT), + +/* drv when odt on */ +(38 << PHY_DQ_DRV_SHIFT) | (38 << PHY_CA_DRV_SHIFT) | + (38 << PHY_CLK_DRV_SHIFT) | (40 << DRAM_DQ_DRV_SHIFT), +/* drv when odt off */ +(38 << PHY_DQ_DRV_SHIFT) | (38 << PHY_CA_DRV_SHIFT) | + (38 << PHY_CLK_DRV_SHIFT) | (40 << DRAM_DQ_DRV_SHIFT), +/* odt info and PU-cal info */ +(48 << DRAM_ODT_SHIFT) | (60 << PHY_ODT_SHIFT) | + (120 << LP4_CA_ODT_SHIFT) | + (LPDDR4X_VDDQ_0_6 << LP4_DRV_PU_CAL_ODTEN_SHIFT) | + (LPDDR4X_VDDQ_0_6 << LP4_DRV_PU_CAL_ODTOFF_SHIFT) | + (0 << PHY_LP4_DRV_PULLDOWN_EN_ODTEN_SHIFT) | + (0 << PHY_LP4_DRV_PULLDOWN_EN_ODTOFF_SHIFT), +/* odt enable freq */ +(0 << PHY_LP4_ODT_EN_FREQ_SHIFT) | (0 << LP4_DQ_ODT_EN_FREQ_SHIFT), +/* slew rate when odt enable */ +(0xf << PHY_DQ_SR_SHIFT) | (0xf << PHY_CA_SR_SHIFT) | + (0xf << PHY_CLK_SR_SHIFT), +/* slew ratee when odt disable */ +(0xf << PHY_DQ_SR_SHIFT) | (0xf << PHY_CA_SR_SHIFT) | + (0xf << PHY_CLK_SR_SHIFT), +/* ca odt en freq */ +(333 << LP4_CA_ODT_EN_FREQ_SHIFT), +/* cs drv info and ca odt info */ +(0 << PHY_LP4_CS_DRV_ODTEN_SHIFT) | + (0 << PHY_LP4_CS_DRV_ODTOFF_SHIFT) | + (0 << LP4_ODTE_CK_SHIFT) | (0 << LP4_ODTE_CS_EN_SHIFT) | + (0 << LP4_ODTD_CA_EN_SHIFT), +/* vref info when odt enable, phy vddq=1.1V, lp4x vddq=0.6V */ +(153 << PHY_LP4_DQ_VREF_SHIFT) | (515 << LP4_DQ_VREF_SHIFT) | + (629 << LP4_CA_VREF_SHIFT), +/* vref info when odt disable */ +(153 << PHY_LP4_DQ_VREF_SHIFT) | (629 << LP4_DQ_VREF_SHIFT) | + (629 << LP4_CA_VREF_SHIFT), diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-1056.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-1056.inc new file mode 100644 index 0000000..705cbfb --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-1056.inc @@ -0,0 +1,78 @@ +{ + { + { + .rank = 0x1, + .col = 0xB, + .bk = 0x3, + .bw = 0x1, + .dbw = 0x1, + .row_3_4 = 0x0, + .cs0_row = 0x11, + .cs1_row = 0x11, + .cs0_high16bit_row = 0x0, + .cs1_high16bit_row = 0x0, + .ddrconfig = 0 + }, + { + {0x41241522}, + {0x15050b07}, + {0x00000602}, + {0x00001111}, + {0x00000054}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 1056, /* clock rate(MHz) */ + .dramtype = LPDDR4, + .num_channels = 1, + .stride = 0, + .odt = 1 + }, + { + { + {0x00000000, 0x81081020}, /* MSTR */ + {0x00000064, 0x00400094}, /* RFSHTMG */ + {0x000000d0, 0x00030409}, /* INIT0 */ + {0x000000d4, 0x00690000}, /* INIT1 */ + {0x000000d8, 0x00000206}, /* INIT2 */ + {0x000000dc, 0x0034001b}, /* INIT3 */ + {0x000000e0, 0x00310000}, /* INIT4 */ + {0x000000e8, 0x00110000}, /* INIT6 */ + {0x000000ec, 0x00000000}, /* INIT7 */ + {0x000000f4, 0x000f033f}, /* RANKCTL */ + {0x00000100, 0x14161217}, /* DRAMTMG0 */ + {0x00000104, 0x00040422}, /* DRAMTMG1 */ + {0x00000108, 0x050a0e0f}, /* DRAMTMG2 */ + {0x0000010c, 0x00808000}, /* DRAMTMG3 */ + {0x00000110, 0x0a04060c}, /* DRAMTMG4 */ + {0x00000114, 0x02040808}, /* DRAMTMG5 */ + {0x00000118, 0x01010005}, /* DRAMTMG6 */ + {0x0000011c, 0x00000401}, /* DRAMTMG7 */ + {0x00000120, 0x00000606}, /* DRAMTMG8 */ + {0x00000130, 0x00020000}, /* DRAMTMG12 */ + {0x00000134, 0x0a100002}, /* DRAMTMG13 */ + {0x00000138, 0x00000098}, /* DRAMTMG14 */ + {0x00000180, 0x02100010}, /* ZQCTL0 */ + {0x00000184, 0x01b00000}, /* ZQCTL1 */ + {0x00000190, 0x07070001}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x0b050d3c}, /* ODTCFG */ + {0x00000244, 0x00000101}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008d}, /* PHYREG01 */ + {0x00000014, 0x00000014}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x0000000a}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-328.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-328.inc new file mode 100644 index 0000000..3864b00 --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-328.inc @@ -0,0 +1,78 @@ +{ + { + { + .rank = 0x1, + .col = 0xB, + .bk = 0x3, + .bw = 0x1, + .dbw = 0x1, + .row_3_4 = 0x0, + .cs0_row = 0x11, + .cs1_row = 0x11, + .cs0_high16bit_row = 0x0, + .cs1_high16bit_row = 0x0, + .ddrconfig = 0 + }, + { + {0x2f0d060a}, + {0x07020804}, + {0x00000602}, + {0x00001111}, + {0x00000054}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 328, /* clock rate(MHz) */ + .dramtype = LPDDR4, + .num_channels = 1, + .stride = 0, + .odt = 0 + }, + { + { + {0x00000000, 0x81081020}, /* MSTR */ + {0x00000064, 0x0014002e}, /* RFSHTMG */ + {0x000000d0, 0x00020142}, /* INIT0 */ + {0x000000d4, 0x00220000}, /* INIT1 */ + {0x000000d8, 0x00000202}, /* INIT2 */ + {0x000000dc, 0x00240012}, /* INIT3 */ + {0x000000e0, 0x00310000}, /* INIT4 */ + {0x000000e8, 0x00100000}, /* INIT6 */ + {0x000000ec, 0x00000000}, /* INIT7 */ + {0x000000f4, 0x000f033f}, /* RANKCTL */ + {0x00000100, 0x0c070507}, /* DRAMTMG0 */ + {0x00000104, 0x0003040b}, /* DRAMTMG1 */ + {0x00000108, 0x04070c0d}, /* DRAMTMG2 */ + {0x0000010c, 0x00505000}, /* DRAMTMG3 */ + {0x00000110, 0x03040204}, /* DRAMTMG4 */ + {0x00000114, 0x02030303}, /* DRAMTMG5 */ + {0x00000118, 0x01010004}, /* DRAMTMG6 */ + {0x0000011c, 0x00000301}, /* DRAMTMG7 */ + {0x00000120, 0x00000303}, /* DRAMTMG8 */ + {0x00000130, 0x00020000}, /* DRAMTMG12 */ + {0x00000134, 0x00100002}, /* DRAMTMG13 */ + {0x00000138, 0x00000030}, /* DRAMTMG14 */ + {0x00000180, 0x00a40005}, /* ZQCTL0 */ + {0x00000184, 0x00900000}, /* ZQCTL1 */ + {0x00000190, 0x07040000}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x0905092c}, /* ODTCFG */ + {0x00000244, 0x00000101}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008d}, /* PHYREG01 */ + {0x00000014, 0x0000000e}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x00000008}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-396.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-396.inc new file mode 100644 index 0000000..9018c3a --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-396.inc @@ -0,0 +1,78 @@ +{ + { + { + .rank = 0x1, + .col = 0xB, + .bk = 0x3, + .bw = 0x1, + .dbw = 0x1, + .row_3_4 = 0x0, + .cs0_row = 0x11, + .cs1_row = 0x11, + .cs0_high16bit_row = 0x0, + .cs1_high16bit_row = 0x0, + .ddrconfig = 0 + }, + { + {0x3110080d}, + {0x08020804}, + {0x00000602}, + {0x00001111}, + {0x00000054}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 396, /* clock rate(MHz) */ + .dramtype = LPDDR4, + .num_channels = 1, + .stride = 0, + .odt = 0 + }, + { + { + {0x00000000, 0x81081020}, /* MSTR */ + {0x00000064, 0x00180038}, /* RFSHTMG */ + {0x000000d0, 0x00020184}, /* INIT0 */ + {0x000000d4, 0x00280000}, /* INIT1 */ + {0x000000d8, 0x00000202}, /* INIT2 */ + {0x000000dc, 0x00240012}, /* INIT3 */ + {0x000000e0, 0x00310000}, /* INIT4 */ + {0x000000e8, 0x00100000}, /* INIT6 */ + {0x000000ec, 0x00000000}, /* INIT7 */ + {0x000000f4, 0x000f033f}, /* RANKCTL */ + {0x00000100, 0x0d080609}, /* DRAMTMG0 */ + {0x00000104, 0x0003040d}, /* DRAMTMG1 */ + {0x00000108, 0x04070c0d}, /* DRAMTMG2 */ + {0x0000010c, 0x00505000}, /* DRAMTMG3 */ + {0x00000110, 0x04040205}, /* DRAMTMG4 */ + {0x00000114, 0x02030303}, /* DRAMTMG5 */ + {0x00000118, 0x01010004}, /* DRAMTMG6 */ + {0x0000011c, 0x00000301}, /* DRAMTMG7 */ + {0x00000120, 0x00000303}, /* DRAMTMG8 */ + {0x00000130, 0x00020000}, /* DRAMTMG12 */ + {0x00000134, 0x00100002}, /* DRAMTMG13 */ + {0x00000138, 0x00000039}, /* DRAMTMG14 */ + {0x00000180, 0x00c60006}, /* ZQCTL0 */ + {0x00000184, 0x00a00000}, /* ZQCTL1 */ + {0x00000190, 0x07040000}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x0905092c}, /* ODTCFG */ + {0x00000244, 0x00000101}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008d}, /* PHYREG01 */ + {0x00000014, 0x0000000e}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x00000008}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-528.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-528.inc new file mode 100644 index 0000000..8c8e14c --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-528.inc @@ -0,0 +1,78 @@ +{ + { + { + .rank = 0x1, + .col = 0xB, + .bk = 0x3, + .bw = 0x1, + .dbw = 0x1, + .row_3_4 = 0x0, + .cs0_row = 0x11, + .cs1_row = 0x11, + .cs0_high16bit_row = 0x0, + .cs1_high16bit_row = 0x0, + .ddrconfig = 0 + }, + { + {0x34140b11}, + {0x0b030804}, + {0x00000602}, + {0x00001111}, + {0x00000054}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 528, /* clock rate(MHz) */ + .dramtype = LPDDR4, + .num_channels = 1, + .stride = 0, + .odt = 0 + }, + { + { + {0x00000000, 0x81081020}, /* MSTR */ + {0x00000064, 0x0020004a}, /* RFSHTMG */ + {0x000000d0, 0x00020205}, /* INIT0 */ + {0x000000d4, 0x00350000}, /* INIT1 */ + {0x000000d8, 0x00000203}, /* INIT2 */ + {0x000000dc, 0x00240012}, /* INIT3 */ + {0x000000e0, 0x00310000}, /* INIT4 */ + {0x000000e8, 0x00100000}, /* INIT6 */ + {0x000000ec, 0x00000000}, /* INIT7 */ + {0x000000f4, 0x000f033f}, /* RANKCTL */ + {0x00000100, 0x0e0b090c}, /* DRAMTMG0 */ + {0x00000104, 0x00030412}, /* DRAMTMG1 */ + {0x00000108, 0x04070c0d}, /* DRAMTMG2 */ + {0x0000010c, 0x00505000}, /* DRAMTMG3 */ + {0x00000110, 0x05040306}, /* DRAMTMG4 */ + {0x00000114, 0x02030404}, /* DRAMTMG5 */ + {0x00000118, 0x01010004}, /* DRAMTMG6 */ + {0x0000011c, 0x00000301}, /* DRAMTMG7 */ + {0x00000120, 0x00000404}, /* DRAMTMG8 */ + {0x00000130, 0x00020000}, /* DRAMTMG12 */ + {0x00000134, 0x00100002}, /* DRAMTMG13 */ + {0x00000138, 0x0000004c}, /* DRAMTMG14 */ + {0x00000180, 0x01080008}, /* ZQCTL0 */ + {0x00000184, 0x00e00000}, /* ZQCTL1 */ + {0x00000190, 0x07040000}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x0905092c}, /* ODTCFG */ + {0x00000244, 0x00000101}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008d}, /* PHYREG01 */ + {0x00000014, 0x0000000e}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x00000008}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-664.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-664.inc new file mode 100644 index 0000000..f601fe5 --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-664.inc @@ -0,0 +1,78 @@ +{ + { + { + .rank = 0x1, + .col = 0xB, + .bk = 0x3, + .bw = 0x1, + .dbw = 0x1, + .row_3_4 = 0x0, + .cs0_row = 0x11, + .cs1_row = 0x11, + .cs0_high16bit_row = 0x0, + .cs1_high16bit_row = 0x0, + .ddrconfig = 0 + }, + { + {0x36170d15}, + {0x0d030805}, + {0x00000602}, + {0x00001111}, + {0x00000054}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 664, /* clock rate(MHz) */ + .dramtype = LPDDR4, + .num_channels = 1, + .stride = 0, + .odt = 1 + }, + { + { + {0x00000000, 0x81081020}, /* MSTR */ + {0x00000064, 0x0028005d}, /* RFSHTMG */ + {0x000000d0, 0x0002028a}, /* INIT0 */ + {0x000000d4, 0x00420000}, /* INIT1 */ + {0x000000d8, 0x00000204}, /* INIT2 */ + {0x000000dc, 0x00240012}, /* INIT3 */ + {0x000000e0, 0x00310000}, /* INIT4 */ + {0x000000e8, 0x00110000}, /* INIT6 */ + {0x000000ec, 0x00000000}, /* INIT7 */ + {0x000000f4, 0x000f033f}, /* RANKCTL */ + {0x00000100, 0x0f0e0b0e}, /* DRAMTMG0 */ + {0x00000104, 0x00030415}, /* DRAMTMG1 */ + {0x00000108, 0x04070d0d}, /* DRAMTMG2 */ + {0x0000010c, 0x00505000}, /* DRAMTMG3 */ + {0x00000110, 0x06040407}, /* DRAMTMG4 */ + {0x00000114, 0x02030505}, /* DRAMTMG5 */ + {0x00000118, 0x01010004}, /* DRAMTMG6 */ + {0x0000011c, 0x00000301}, /* DRAMTMG7 */ + {0x00000120, 0x00000404}, /* DRAMTMG8 */ + {0x00000130, 0x00020000}, /* DRAMTMG12 */ + {0x00000134, 0x00100002}, /* DRAMTMG13 */ + {0x00000138, 0x00000060}, /* DRAMTMG14 */ + {0x00000180, 0x014c000a}, /* ZQCTL0 */ + {0x00000184, 0x01100000}, /* ZQCTL1 */ + {0x00000190, 0x07040000}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x0a040b28}, /* ODTCFG */ + {0x00000244, 0x00000101}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008d}, /* PHYREG01 */ + {0x00000014, 0x0000000e}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x00000008}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-784.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-784.inc new file mode 100644 index 0000000..b8d9d5f --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-784.inc @@ -0,0 +1,78 @@ +{ + { + { + .rank = 0x1, + .col = 0xB, + .bk = 0x3, + .bw = 0x1, + .dbw = 0x1, + .row_3_4 = 0x0, + .cs0_row = 0x11, + .cs1_row = 0x11, + .cs0_high16bit_row = 0x0, + .cs1_high16bit_row = 0x0, + .ddrconfig = 0 + }, + { + {0x391b1019}, + {0x10040805}, + {0x00000602}, + {0x00001111}, + {0x00000054}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 784, /* clock rate(MHz) */ + .dramtype = LPDDR4, + .num_channels = 1, + .stride = 0, + .odt = 1 + }, + { + { + {0x00000000, 0x81081020}, /* MSTR */ + {0x00000064, 0x002f006e}, /* RFSHTMG */ + {0x000000d0, 0x000202ff}, /* INIT0 */ + {0x000000d4, 0x004e0000}, /* INIT1 */ + {0x000000d8, 0x00000204}, /* INIT2 */ + {0x000000dc, 0x00240012}, /* INIT3 */ + {0x000000e0, 0x00310000}, /* INIT4 */ + {0x000000e8, 0x00110000}, /* INIT6 */ + {0x000000ec, 0x00000000}, /* INIT7 */ + {0x000000f4, 0x000f033f}, /* RANKCTL */ + {0x00000100, 0x10100d11}, /* DRAMTMG0 */ + {0x00000104, 0x00030419}, /* DRAMTMG1 */ + {0x00000108, 0x04070c0d}, /* DRAMTMG2 */ + {0x0000010c, 0x00606000}, /* DRAMTMG3 */ + {0x00000110, 0x08040409}, /* DRAMTMG4 */ + {0x00000114, 0x02030606}, /* DRAMTMG5 */ + {0x00000118, 0x01010004}, /* DRAMTMG6 */ + {0x0000011c, 0x00000301}, /* DRAMTMG7 */ + {0x00000120, 0x00000505}, /* DRAMTMG8 */ + {0x00000130, 0x00020000}, /* DRAMTMG12 */ + {0x00000134, 0x00100002}, /* DRAMTMG13 */ + {0x00000138, 0x00000071}, /* DRAMTMG14 */ + {0x00000180, 0x0188000c}, /* ZQCTL0 */ + {0x00000184, 0x01400000}, /* ZQCTL1 */ + {0x00000190, 0x07040000}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x0a040b28}, /* ODTCFG */ + {0x00000244, 0x00000101}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008d}, /* PHYREG01 */ + {0x00000014, 0x0000000e}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x00000008}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-924.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-924.inc new file mode 100644 index 0000000..a2050f6 --- /dev/null +++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-924.inc @@ -0,0 +1,78 @@ +{ + { + { + .rank = 0x1, + .col = 0xB, + .bk = 0x3, + .bw = 0x1, + .dbw = 0x1, + .row_3_4 = 0x0, + .cs0_row = 0x11, + .cs1_row = 0x11, + .cs0_high16bit_row = 0x0, + .cs1_high16bit_row = 0x0, + .ddrconfig = 0 + }, + { + {0x3e20121d}, + {0x12050a07}, + {0x00000602}, + {0x00001111}, + {0x00000054}, + {0x00000000}, + 0x000000ff + } + }, + { + .ddr_freq = 924, /* clock rate(MHz) */ + .dramtype = LPDDR4, + .num_channels = 1, + .stride = 0, + .odt = 1 + }, + { + { + {0x00000000, 0x81081020}, /* MSTR */ + {0x00000064, 0x00380082}, /* RFSHTMG */ + {0x000000d0, 0x00020388}, /* INIT0 */ + {0x000000d4, 0x005c0000}, /* INIT1 */ + {0x000000d8, 0x00000205}, /* INIT2 */ + {0x000000dc, 0x0034001b}, /* INIT3 */ + {0x000000e0, 0x00310000}, /* INIT4 */ + {0x000000e8, 0x00110000}, /* INIT6 */ + {0x000000ec, 0x00000000}, /* INIT7 */ + {0x000000f4, 0x000f033f}, /* RANKCTL */ + {0x00000100, 0x12130f14}, /* DRAMTMG0 */ + {0x00000104, 0x0004041e}, /* DRAMTMG1 */ + {0x00000108, 0x050a0e0f}, /* DRAMTMG2 */ + {0x0000010c, 0x00707000}, /* DRAMTMG3 */ + {0x00000110, 0x0904050a}, /* DRAMTMG4 */ + {0x00000114, 0x02040707}, /* DRAMTMG5 */ + {0x00000118, 0x01010005}, /* DRAMTMG6 */ + {0x0000011c, 0x00000401}, /* DRAMTMG7 */ + {0x00000120, 0x00000606}, /* DRAMTMG8 */ + {0x00000130, 0x00020000}, /* DRAMTMG12 */ + {0x00000134, 0x0a100002}, /* DRAMTMG13 */ + {0x00000138, 0x00000085}, /* DRAMTMG14 */ + {0x00000180, 0x01ce000e}, /* ZQCTL0 */ + {0x00000184, 0x01800000}, /* ZQCTL1 */ + {0x00000190, 0x07070001}, /* DFITMG0 */ + {0x00000198, 0x07000101}, /* DFILPCFG0 */ + {0x000001a0, 0xc0400003}, /* DFIUPD0 */ + {0x00000240, 0x0b050d3c}, /* ODTCFG */ + {0x00000244, 0x00000101}, /* ODTMAP */ + {0x00000250, 0x00001f00}, /* SCHED */ + {0x00000490, 0x00000001}, /* PCTRL_0 */ + {0xffffffff, 0xffffffff} + } + }, + { + { + {0x00000004, 0x0000008d}, /* PHYREG01 */ + {0x00000014, 0x00000014}, /* PHYREG05 */ + {0x00000018, 0x00000000}, /* PHYREG06 */ + {0x0000001c, 0x0000000a}, /* PHYREG07 */ + {0xffffffff, 0xffffffff} + } + } +}, diff --git a/drivers/ram/rockchip/sdram_common.c b/drivers/ram/rockchip/sdram_common.c index ec46ba5..60fc90d 100644 --- a/drivers/ram/rockchip/sdram_common.c +++ b/drivers/ram/rockchip/sdram_common.c @@ -36,7 +36,7 @@ void sdram_print_dram_type(unsigned char dramtype) } void sdram_print_ddr_info(struct sdram_cap_info *cap_info, - struct sdram_base_params *base) + struct sdram_base_params *base, u32 split) { u64 cap; u32 bg; @@ -83,6 +83,8 @@ void sdram_print_ddr_info(struct sdram_cap_info *cap_info, cap = sdram_get_cs_cap(cap_info, 3, base->dramtype); if (cap_info->row_3_4) cap = cap * 3 / 4; + else if (split) + cap = cap / 2 + (split << 24) / 2; printascii(" Size="); printdec(cap >> 20); @@ -123,7 +125,7 @@ inline void sdram_print_dram_type(unsigned char dramtype) } inline void sdram_print_ddr_info(struct sdram_cap_info *cap_info, - struct sdram_base_params *base) + struct sdram_base_params *base, u32 split) { } diff --git a/drivers/ram/rockchip/sdram_pctl_px30.c b/drivers/ram/rockchip/sdram_pctl_px30.c index 331d85f..e5c80fb 100644 --- a/drivers/ram/rockchip/sdram_pctl_px30.c +++ b/drivers/ram/rockchip/sdram_pctl_px30.c @@ -21,7 +21,7 @@ void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num) setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31); while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31)) continue; - while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY) + while (readl(pctl_base + DDR_PCTL2_MRSTAT) & PCTL2_MR_WR_BUSY) continue; } @@ -33,7 +33,7 @@ void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num) int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg, u32 dramtype) { - while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY) + while (readl(pctl_base + DDR_PCTL2_MRSTAT) & PCTL2_MR_WR_BUSY) continue; if (dramtype == DDR3 || dramtype == DDR4) { writel((mr_num << 12) | (rank << 4) | (0 << 0), @@ -49,7 +49,7 @@ int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg, setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31); while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31)) continue; - while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY) + while (readl(pctl_base + DDR_PCTL2_MRSTAT) & PCTL2_MR_WR_BUSY) continue; return 0; diff --git a/drivers/ram/rockchip/sdram_px30.c b/drivers/ram/rockchip/sdram_px30.c index 98b2593..2728d93 100644 --- a/drivers/ram/rockchip/sdram_px30.c +++ b/drivers/ram/rockchip/sdram_px30.c @@ -125,11 +125,11 @@ u32 addrmap[][8] = { struct dram_info dram_info; struct px30_sdram_params sdram_configs[] = { -#if defined(CONFIG_RAM_PX30_DDR4) +#if defined(CONFIG_RAM_ROCKCHIP_DDR4) #include "sdram-px30-ddr4-detect-333.inc" -#elif defined(CONFIG_RAM_PX30_LPDDR2) +#elif defined(CONFIG_RAM_ROCKCHIP_LPDDR2) #include "sdram-px30-lpddr2-detect-333.inc" -#elif defined(CONFIG_RAM_PX30_LPDDR3) +#elif defined(CONFIG_RAM_ROCKCHIP_LPDDR3) #include "sdram-px30-lpddr3-detect-333.inc" #else #include "sdram-px30-ddr3-detect-333.inc" @@ -711,7 +711,7 @@ int sdram_init(void) if (ret) goto error; - sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base); + sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base, 0); printascii("out\n"); return ret; diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c index b511c6b..184c93f 100644 --- a/drivers/ram/rockchip/sdram_rk3328.c +++ b/drivers/ram/rockchip/sdram_rk3328.c @@ -506,7 +506,7 @@ static int sdram_init_detect(struct dram_info *dram, writel(sys_reg3, &dram->grf->os_reg[3]); } - sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base); + sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base, 0); return 0; } diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c index 136e4ed..b1fea04 100644 --- a/drivers/ram/rockchip/sdram_rk3399.c +++ b/drivers/ram/rockchip/sdram_rk3399.c @@ -1625,7 +1625,7 @@ static void set_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf, u32 stride) rk_clrsetreg(&pmusgrf->soc_con4, 0x1f << 10, stride << 10); } -#if !defined(CONFIG_RAM_RK3399_LPDDR4) +#if !defined(CONFIG_RAM_ROCKCHIP_LPDDR4) static int data_training_first(struct dram_info *dram, u32 channel, u8 rank, struct rk3399_sdram_params *params) { @@ -2558,8 +2558,7 @@ static int lpddr4_set_rate(struct dram_info *dram, return 0; } - -#endif /* CONFIG_RAM_RK3399_LPDDR4 */ +#endif /* CONFIG_RAM_ROCKCHIP_LPDDR4 */ /* CS0,n=1 * CS1,n=2 @@ -2987,7 +2986,7 @@ static int sdram_init(struct dram_info *dram, continue; } - sdram_print_ddr_info(cap_info, ¶ms->base); + sdram_print_ddr_info(cap_info, ¶ms->base, 0); set_memory_map(chan, channel, params); cap_info->ddrconfig = calculate_ddrconfig(params, channel); @@ -3059,7 +3058,7 @@ static int conv_of_plat(struct udevice *dev) #endif static const struct sdram_rk3399_ops rk3399_ops = { -#if !defined(CONFIG_RAM_RK3399_LPDDR4) +#if !defined(CONFIG_RAM_ROCKCHIP_LPDDR4) .data_training_first = data_training_first, .set_rate_index = switch_to_phy_index1, .modify_param = modify_param, diff --git a/drivers/ram/rockchip/sdram_rv1126.c b/drivers/ram/rockchip/sdram_rv1126.c new file mode 100644 index 0000000..9e1376a --- /dev/null +++ b/drivers/ram/rockchip/sdram_rv1126.c @@ -0,0 +1,3543 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * (C) Copyright 2020 Rockchip Electronics Co., Ltd. + * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. + */ + +#include <common.h> +#include <debug_uart.h> +#include <dm.h> +#include <ram.h> +#include <syscon.h> +#include <asm/io.h> +#include <asm/arch-rockchip/clock.h> +#include <asm/arch-rockchip/hardware.h> +#include <asm/arch-rockchip/cru_rv1126.h> +#include <asm/arch-rockchip/grf_rv1126.h> +#include <asm/arch-rockchip/sdram_common.h> +#include <asm/arch-rockchip/sdram_rv1126.h> +#include <linux/delay.h> + +/* define training flag */ +#define CA_TRAINING (0x1 << 0) +#define READ_GATE_TRAINING (0x1 << 1) +#define WRITE_LEVELING (0x1 << 2) +#define WRITE_TRAINING (0x1 << 3) +#define READ_TRAINING (0x1 << 4) +#define FULL_TRAINING (0xff) + +#define SKEW_RX_SIGNAL (0) +#define SKEW_TX_SIGNAL (1) +#define SKEW_CA_SIGNAL (2) + +#define DESKEW_MDF_ABS_VAL (0) +#define DESKEW_MDF_DIFF_VAL (1) + +struct dram_info { +#if defined(CONFIG_TPL_BUILD) || \ + (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD)) + void __iomem *pctl; + void __iomem *phy; + struct rv1126_cru *cru; + struct msch_regs *msch; + struct rv1126_ddrgrf *ddrgrf; + struct rv1126_grf *grf; + u32 sr_idle; + u32 pd_idle; +#endif + struct ram_info info; + struct rv1126_pmugrf *pmugrf; +}; + +#if defined(CONFIG_TPL_BUILD) || \ + (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD)) + +#define GRF_BASE_ADDR 0xfe000000 +#define PMU_GRF_BASE_ADDR 0xfe020000 +#define DDR_GRF_BASE_ADDR 0xfe030000 +#define BUS_SGRF_BASE_ADDR 0xfe0a0000 +#define SERVER_MSCH_BASE_ADDR 0xfe800000 +#define CRU_BASE_ADDR 0xff490000 +#define DDR_PHY_BASE_ADDR 0xff4a0000 +#define UPCTL2_BASE_ADDR 0xffa50000 + +#define SGRF_SOC_CON2 0x8 +#define SGRF_SOC_CON12 0x30 +#define SGRF_SOC_CON13 0x34 + +struct dram_info dram_info; + +struct rv1126_sdram_params sdram_configs[] = { +#if defined(CONFIG_RAM_ROCKCHIP_LPDDR4) +# include "sdram-rv1126-lpddr4-detect-328.inc" +# include "sdram-rv1126-lpddr4-detect-396.inc" +# include "sdram-rv1126-lpddr4-detect-528.inc" +# include "sdram-rv1126-lpddr4-detect-664.inc" +# include "sdram-rv1126-lpddr4-detect-784.inc" +# include "sdram-rv1126-lpddr4-detect-924.inc" +# include "sdram-rv1126-lpddr4-detect-1056.inc" +#else +# include "sdram-rv1126-ddr3-detect-328.inc" +# include "sdram-rv1126-ddr3-detect-396.inc" +# include "sdram-rv1126-ddr3-detect-528.inc" +# include "sdram-rv1126-ddr3-detect-664.inc" +# include "sdram-rv1126-ddr3-detect-784.inc" +# include "sdram-rv1126-ddr3-detect-924.inc" +# include "sdram-rv1126-ddr3-detect-1056.inc" +#endif +}; + +u32 common_info[] = { +#include "sdram-rv1126-loader_params.inc" +}; + +#if defined(CONFIG_CMD_DDR_TEST_TOOL) +static struct rw_trn_result rw_trn_result; +#endif + +static struct rv1126_fsp_param fsp_param[MAX_IDX]; + +static u8 lp3_odt_value; + +static s8 wrlvl_result[2][4]; + +/* DDR configuration 0-9 */ +u16 ddr_cfg_2_rbc[] = { + ((0 << 8) | (3 << 5) | (0 << 4) | (1 << 3) | 3), /* 0 */ + ((1 << 8) | (3 << 5) | (0 << 4) | (1 << 3) | 2), /* 1 */ + ((1 << 8) | (2 << 5) | (0 << 4) | (1 << 3) | 3), /* 2 */ + ((1 << 8) | (3 << 5) | (0 << 4) | (1 << 3) | 1), /* 3 */ + ((0 << 8) | (2 << 5) | (0 << 4) | (1 << 3) | 4), /* 4 */ + ((0 << 8) | (3 << 5) | (1 << 4) | (1 << 3) | 1), /* 5 */ + ((0 << 8) | (3 << 5) | (1 << 4) | (1 << 3) | 2), /* 6 */ + ((0 << 8) | (2 << 5) | (1 << 4) | (1 << 3) | 3), /* 7 */ + ((1 << 8) | (3 << 5) | (0 << 4) | (0 << 3) | 2), /* 8 */ + ((1 << 8) | (2 << 5) | (0 << 4) | (1 << 3) | 2) /* 9 */ +}; + +/* DDR configuration 10-21 */ +u8 ddr4_cfg_2_rbc[] = { + ((0 << 7) | (3 << 4) | (0 << 3) | (2 << 1) | 0), /* 10 */ + ((1 << 7) | (2 << 4) | (0 << 3) | (2 << 1) | 0), /* 11 */ + ((0 << 7) | (4 << 4) | (0 << 3) | (1 << 1) | 0), /* 12 */ + ((1 << 7) | (3 << 4) | (0 << 3) | (1 << 1) | 0), /* 13 */ + ((0 << 7) | (4 << 4) | (0 << 3) | (2 << 1) | 1), /* 14 */ + ((1 << 7) | (3 << 4) | (0 << 3) | (2 << 1) | 1), /* 15 */ + ((1 << 7) | (4 << 4) | (0 << 3) | (1 << 1) | 1), /* 16 */ + ((0 << 7) | (2 << 4) | (1 << 3) | (2 << 1) | 0), /* 17 */ + ((0 << 7) | (3 << 4) | (1 << 3) | (1 << 1) | 0), /* 18 */ + ((0 << 7) | (3 << 4) | (1 << 3) | (2 << 1) | 1), /* 19 */ + ((0 << 7) | (4 << 4) | (1 << 3) | (1 << 1) | 1), /* 20 */ + ((1 << 7) | (4 << 4) | (0 << 3) | (0 << 1) | 0) /* 21 */ +}; + +/* DDR configuration 22-28 */ +u16 ddr_cfg_2_rbc_p2[] = { + ((1 << 8) | (3 << 5) | (0 << 4) | (1 << 3) | 0), /* 22 */ + ((0 << 8) | (4 << 5) | (0 << 4) | (1 << 3) | 2), /* 23 */ + ((1 << 8) | (3 << 5) | (0 << 4) | (0 << 3) | 3), /* 24 */ + ((0 << 8) | (3 << 5) | (1 << 4) | (0 << 3) | 3), /* 25 */ + ((0 << 8) | (4 << 5) | (1 << 4) | (0 << 3) | 2), /* 26 */ + ((1 << 8) | (4 << 5) | (0 << 4) | (0 << 3) | 2), /* 27 */ + ((0 << 8) | (4 << 5) | (0 << 4) | (0 << 3) | 3) /* 28 */ +}; + +u8 d4_rbc_2_d3_rbc[][2] = { + {10, 0}, + {11, 2}, + {12, 23}, + {13, 1}, + {14, 28}, + {15, 24}, + {16, 27}, + {17, 7}, + {18, 6}, + {19, 25}, + {20, 26}, + {21, 3} +}; + +u32 addrmap[29][9] = { + {24, 0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808, + 0x08080808, 0x00000f0f, 0x3f3f}, /* 0 */ + {23, 0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707, + 0x07070707, 0x00000f0f, 0x3f3f}, /* 1 */ + {23, 0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808, + 0x0f080808, 0x00000f0f, 0x3f3f}, /* 2 */ + {22, 0x00070707, 0x00000000, 0x1f000000, 0x00001f1f, 0x06060606, + 0x06060606, 0x00000f0f, 0x3f3f}, /* 3 */ + {24, 0x000a0a0a, 0x00000000, 0x00000000, 0x00000000, 0x09090909, + 0x0f090909, 0x00000f0f, 0x3f3f}, /* 4 */ + {6, 0x00070707, 0x00000000, 0x1f000000, 0x00001f1f, 0x07070707, + 0x07070707, 0x00000f0f, 0x3f3f}, /* 5 */ + {7, 0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x08080808, + 0x08080808, 0x00000f0f, 0x3f3f}, /* 6 */ + {8, 0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x09090909, + 0x0f090909, 0x00000f0f, 0x3f3f}, /* 7 */ + {22, 0x001f0808, 0x00000000, 0x00000000, 0x00001f1f, 0x06060606, + 0x06060606, 0x00000f0f, 0x3f3f}, /* 8 */ + {23, 0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707, + 0x0f070707, 0x00000f0f, 0x3f3f}, /* 9 */ + + {24, 0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808, + 0x08080808, 0x00000f0f, 0x0801}, /* 10 */ + {23, 0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808, + 0x0f080808, 0x00000f0f, 0x0801}, /* 11 */ + {24, 0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707, + 0x07070707, 0x00000f07, 0x0700}, /* 12 */ + {23, 0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707, + 0x07070707, 0x00000f0f, 0x0700}, /* 13 */ + {24, 0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707, + 0x07070707, 0x00000f07, 0x3f01}, /* 14 */ + {23, 0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707, + 0x07070707, 0x00000f0f, 0x3f01}, /* 15 */ + {23, 0x003f0808, 0x00000007, 0x1f000000, 0x00001f1f, 0x06060606, + 0x06060606, 0x00000f06, 0x3f00}, /* 16 */ + {8, 0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x09090909, + 0x0f090909, 0x00000f0f, 0x0801}, /* 17 */ + {7, 0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x08080808, + 0x08080808, 0x00000f0f, 0x0700}, /* 18 */ + {7, 0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808, + 0x08080808, 0x00000f0f, 0x3f01}, /* 19 */ + + {6, 0x003f0808, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707, + 0x07070707, 0x00000f07, 0x3f00}, /* 20 */ + {23, 0x003f0909, 0x00000006, 0x1f1f0000, 0x00001f1f, 0x06060606, + 0x06060606, 0x00000f06, 0x0600}, /* 21 */ + {21, 0x00060606, 0x00000000, 0x1f1f0000, 0x00001f1f, 0x05050505, + 0x05050505, 0x00000f0f, 0x3f3f}, /* 22 */ + + {24, 0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707, + 0x07070707, 0x00000f07, 0x3f3f}, /* 23 */ + {23, 0x003f0909, 0x00000000, 0x00000000, 0x00001f00, 0x07070707, + 0x07070707, 0x00000f0f, 0x3f3f}, /* 24 */ + {7, 0x003f0909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808, + 0x08080808, 0x00000f0f, 0x3f3f}, /* 25 */ + {6, 0x003f0808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707, + 0x07070707, 0x00000f07, 0x3f3f}, /* 26 */ + {23, 0x003f0808, 0x00000000, 0x00000000, 0x00001f1f, 0x06060606, + 0x06060606, 0x00000f06, 0x3f3f}, /* 27 */ + {24, 0x003f0909, 0x00000000, 0x00000000, 0x00001f00, 0x07070707, + 0x07070707, 0x00000f07, 0x3f3f} /* 28 */ +}; + +static u8 dq_sel[22][3] = { + {0x0, 0x17, 0x22}, + {0x1, 0x18, 0x23}, + {0x2, 0x19, 0x24}, + {0x3, 0x1a, 0x25}, + {0x4, 0x1b, 0x26}, + {0x5, 0x1c, 0x27}, + {0x6, 0x1d, 0x28}, + {0x7, 0x1e, 0x29}, + {0x8, 0x16, 0x21}, + {0x9, 0x1f, 0x2a}, + {0xa, 0x20, 0x2b}, + {0x10, 0x1, 0xc}, + {0x11, 0x2, 0xd}, + {0x12, 0x3, 0xe}, + {0x13, 0x4, 0xf}, + {0x14, 0x5, 0x10}, + {0x15, 0x6, 0x11}, + {0x16, 0x7, 0x12}, + {0x17, 0x8, 0x13}, + {0x18, 0x0, 0xb}, + {0x19, 0x9, 0x14}, + {0x1a, 0xa, 0x15} +}; + +static u16 grp_addr[4] = { + ADD_GROUP_CS0_A, + ADD_GROUP_CS0_B, + ADD_GROUP_CS1_A, + ADD_GROUP_CS1_B +}; + +static u8 wrlvl_result_offset[2][4] = { + {0xa0 + 0x26, 0xa0 + 0x27, 0xd0 + 0x26, 0xd0 + 0x27}, + {0xa0 + 0x28, 0xa0 + 0x29, 0xd0 + 0x28, 0xd0 + 0x29}, +}; + +static u16 dqs_dq_skew_adr[16] = { + 0x170 + 0, /* SKEW_UPDATE_RX_CS0_DQS0 */ + 0x170 + 0xb, /* SKEW_UPDATE_RX_CS0_DQS1 */ + 0x1d0 + 0, /* SKEW_UPDATE_RX_CS0_DQS2 */ + 0x1d0 + 0xb, /* SKEW_UPDATE_RX_CS0_DQS3 */ + 0x1a0 + 0, /* SKEW_UPDATE_RX_CS1_DQS0 */ + 0x1a0 + 0xb, /* SKEW_UPDATE_RX_CS1_DQS1 */ + 0x200 + 0, /* SKEW_UPDATE_RX_CS1_DQS2 */ + 0x200 + 0xb, /* SKEW_UPDATE_RX_CS1_DQS3 */ + 0x170 + 0x16, /* SKEW_UPDATE_TX_CS0_DQS0 */ + 0x170 + 0x21, /* SKEW_UPDATE_TX_CS0_DQS1 */ + 0x1d0 + 0x16, /* SKEW_UPDATE_TX_CS0_DQS2 */ + 0x1d0 + 0x21, /* SKEW_UPDATE_TX_CS0_DQS3 */ + 0x1a0 + 0x16, /* SKEW_UPDATE_TX_CS1_DQS0 */ + 0x1a0 + 0x21, /* SKEW_UPDATE_TX_CS1_DQS1 */ + 0x200 + 0x16, /* SKEW_UPDATE_TX_CS1_DQS2 */ + 0x200 + 0x21, /* SKEW_UPDATE_TX_CS1_DQS3 */ +}; + +static void rkclk_ddr_reset(struct dram_info *dram, + u32 ctl_srstn, u32 ctl_psrstn, + u32 phy_srstn, u32 phy_psrstn) +{ + writel(UPCTL2_SRSTN_REQ(ctl_srstn) | UPCTL2_PSRSTN_REQ(ctl_psrstn) | + UPCTL2_ASRSTN_REQ(ctl_srstn), + BUS_SGRF_BASE_ADDR + SGRF_SOC_CON13); + + writel(DDRPHY_SRSTN_REQ(phy_srstn) | DDRPHY_PSRSTN_REQ(phy_psrstn), + &dram->cru->softrst_con[12]); +} + +static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz) +{ + unsigned int refdiv, postdiv1, postdiv2, fbdiv; + int delay = 1000; + u32 mhz = hz / MHz; + struct global_info *gbl_info; + struct sdram_head_info_index_v2 *index = + (struct sdram_head_info_index_v2 *)common_info; + u32 ssmod_info; + u32 dsmpd = 1; + + gbl_info = (struct global_info *)((void *)common_info + + index->global_index.offset * 4); + ssmod_info = gbl_info->info_2t; + refdiv = 1; + if (mhz <= 100) { + postdiv1 = 6; + postdiv2 = 4; + } else if (mhz <= 150) { + postdiv1 = 4; + postdiv2 = 4; + } else if (mhz <= 200) { + postdiv1 = 6; + postdiv2 = 2; + } else if (mhz <= 300) { + postdiv1 = 4; + postdiv2 = 2; + } else if (mhz <= 400) { + postdiv1 = 6; + postdiv2 = 1; + } else { + postdiv1 = 4; + postdiv2 = 1; + } + fbdiv = (mhz * refdiv * postdiv1 * postdiv2) / 24; + + writel(DPLL_MODE(CLOCK_FROM_XIN_OSC), &dram->cru->mode); + + writel(0x1f000000, &dram->cru->clksel_con[64]); + writel(POSTDIV1(postdiv1) | FBDIV(fbdiv), &dram->cru->pll[1].con0); + /* enable ssmod */ + if (PLL_SSMOD_SPREAD(ssmod_info)) { + dsmpd = 0; + clrsetbits_le32(&dram->cru->pll[1].con2, + 0xffffff << 0, 0x0 << 0); + writel(SSMOD_SPREAD(PLL_SSMOD_SPREAD(ssmod_info)) | + SSMOD_DIVVAL(PLL_SSMOD_DIV(ssmod_info)) | + SSMOD_DOWNSPREAD(PLL_SSMOD_DOWNSPREAD(ssmod_info)) | + SSMOD_RESET(0) | + SSMOD_DIS_SSCG(0) | + SSMOD_BP(0), + &dram->cru->pll[1].con3); + } + writel(DSMPD(dsmpd) | POSTDIV2(postdiv2) | REFDIV(refdiv), + &dram->cru->pll[1].con1); + + while (delay > 0) { + udelay(1); + if (LOCK(readl(&dram->cru->pll[1].con1))) + break; + delay--; + } + + writel(DPLL_MODE(CLOCK_FROM_PLL), &dram->cru->mode); +} + +static void rkclk_configure_ddr(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params) +{ + /* for inno ddr phy need freq / 2 */ + rkclk_set_dpll(dram, sdram_params->base.ddr_freq * MHZ / 2); +} + +static unsigned int + calculate_ddrconfig(struct rv1126_sdram_params *sdram_params) +{ + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info; + u32 cs, bw, die_bw, col, row, bank; + u32 cs1_row; + u32 i, tmp; + u32 ddrconf = -1; + u32 row_3_4; + + cs = cap_info->rank; + bw = cap_info->bw; + die_bw = cap_info->dbw; + col = cap_info->col; + row = cap_info->cs0_row; + cs1_row = cap_info->cs1_row; + bank = cap_info->bk; + row_3_4 = cap_info->row_3_4; + + if (sdram_params->base.dramtype == DDR4) { + if (cs == 2 && row == cs1_row && !row_3_4) { + tmp = ((row - 13) << 4) | (1 << 3) | (bw << 1) | + die_bw; + for (i = 17; i < 21; i++) { + if (((tmp & 0xf) == + (ddr4_cfg_2_rbc[i - 10] & 0xf)) && + ((tmp & 0x70) <= + (ddr4_cfg_2_rbc[i - 10] & 0x70))) { + ddrconf = i; + goto out; + } + } + } + + tmp = ((cs - 1) << 7) | ((row - 13) << 4) | (bw << 1) | die_bw; + for (i = 10; i < 21; i++) { + if (((tmp & 0xf) == (ddr4_cfg_2_rbc[i - 10] & 0xf)) && + ((tmp & 0x70) <= (ddr4_cfg_2_rbc[i - 10] & 0x70)) && + ((tmp & 0x80) <= (ddr4_cfg_2_rbc[i - 10] & 0x80))) { + ddrconf = i; + goto out; + } + } + } else { + if (cs == 2 && row == cs1_row && bank == 3) { + for (i = 5; i < 8; i++) { + if (((bw + col - 10) == (ddr_cfg_2_rbc[i] & + 0x7)) && + ((row - 13) << 5) <= (ddr_cfg_2_rbc[i] & + (0x7 << 5))) { + ddrconf = i; + goto out; + } + } + } + + tmp = ((cs - 1) << 8) | ((row - 13) << 5) | + ((bw + col - 10) << 0); + if (bank == 3) + tmp |= (1 << 3); + + for (i = 0; i < 9; i++) + if (((tmp & 0x1f) == (ddr_cfg_2_rbc[i] & 0x1f)) && + ((tmp & (7 << 5)) <= + (ddr_cfg_2_rbc[i] & (7 << 5))) && + ((tmp & (1 << 8)) <= + (ddr_cfg_2_rbc[i] & (1 << 8)))) { + ddrconf = i; + goto out; + } + + for (i = 0; i < 7; i++) + if (((tmp & 0x1f) == (ddr_cfg_2_rbc_p2[i] & 0x1f)) && + ((tmp & (7 << 5)) <= + (ddr_cfg_2_rbc_p2[i] & (7 << 5))) && + ((tmp & (1 << 8)) <= + (ddr_cfg_2_rbc_p2[i] & (1 << 8)))) { + ddrconf = i + 22; + goto out; + } + + if (cs == 1 && bank == 3 && row <= 17 && + (col + bw) == 12) + ddrconf = 23; + } + +out: + if (ddrconf > 28) + printascii("calculate ddrconfig error\n"); + + if (sdram_params->base.dramtype == DDR4) { + for (i = 0; i < ARRAY_SIZE(d4_rbc_2_d3_rbc) ; i++) { + if (ddrconf == d4_rbc_2_d3_rbc[i][0]) { + if (ddrconf == 21 && row > 16) + printascii("warn:ddrconf21 row > 16\n"); + else + ddrconf = d4_rbc_2_d3_rbc[i][1]; + break; + } + } + } + + return ddrconf; +} + +static void sw_set_req(struct dram_info *dram) +{ + void __iomem *pctl_base = dram->pctl; + + /* clear sw_done=0 */ + writel(PCTL2_SW_DONE_CLEAR, pctl_base + DDR_PCTL2_SWCTL); +} + +static void sw_set_ack(struct dram_info *dram) +{ + void __iomem *pctl_base = dram->pctl; + + /* set sw_done=1 */ + writel(PCTL2_SW_DONE, pctl_base + DDR_PCTL2_SWCTL); + while (1) { + /* wait programming done */ + if (readl(pctl_base + DDR_PCTL2_SWSTAT) & + PCTL2_SW_DONE_ACK) + break; + } +} + +static void set_ctl_address_map(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params) +{ + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info; + void __iomem *pctl_base = dram->pctl; + u32 ddrconf = cap_info->ddrconfig; + u32 i, row; + + row = cap_info->cs0_row; + if (sdram_params->base.dramtype == DDR4) { + for (i = 0; i < ARRAY_SIZE(d4_rbc_2_d3_rbc) ; i++) { + if (ddrconf == d4_rbc_2_d3_rbc[i][1]) { + ddrconf = d4_rbc_2_d3_rbc[i][0]; + break; + } + } + } + + if (ddrconf >= ARRAY_SIZE(addrmap)) { + printascii("set ctl address map fail\n"); + return; + } + + sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0), + &addrmap[ddrconf][0], ARRAY_SIZE(addrmap[ddrconf]) * 4); + + /* unused row set to 0xf */ + for (i = 17; i >= row; i--) + setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6 + + ((i - 12) * 8 / 32) * 4, + 0xf << ((i - 12) * 8 % 32)); + + if (sdram_params->base.dramtype == LPDDR3 && cap_info->row_3_4) + setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31); + if (sdram_params->base.dramtype == DDR4 && cap_info->bw == 0x1) + setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8); + + if (cap_info->rank == 1) + clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP0, 0x1f, 0x1f); +} + +static void phy_pll_set(struct dram_info *dram, u32 freq, u32 wait) +{ + void __iomem *phy_base = dram->phy; + u32 fbdiv, prediv, postdiv, postdiv_en; + + if (wait) { + clrbits_le32(PHY_REG(phy_base, 0x53), PHY_PD_DISB); + while (!(readl(PHY_REG(phy_base, 0x90)) & PHY_PLL_LOCK)) + continue; + } else { + freq /= MHz; + prediv = 1; + if (freq <= 200) { + fbdiv = 16; + postdiv = 2; + postdiv_en = 1; + } else if (freq <= 456) { + fbdiv = 8; + postdiv = 1; + postdiv_en = 1; + } else { + fbdiv = 4; + postdiv = 0; + postdiv_en = 0; + } + writel(fbdiv & 0xff, PHY_REG(phy_base, 0x50)); + clrsetbits_le32(PHY_REG(phy_base, 0x51), PHY_PBDIV_BIT9_MASK, + (fbdiv >> 8) & 1); + clrsetbits_le32(PHY_REG(phy_base, 0x51), PHY_POSTDIV_EN_MASK, + postdiv_en << PHY_POSTDIV_EN_SHIFT); + + clrsetbits_le32(PHY_REG(phy_base, 0x52), + PHY_PREDIV_MASK << PHY_PREDIV_SHIFT, prediv); + clrsetbits_le32(PHY_REG(phy_base, 0x53), + PHY_POSTDIV_MASK << PHY_POSTDIV_SHIFT, + postdiv << PHY_POSTDIV_SHIFT); + } +} + +static const u16 d3_phy_drv_2_ohm[][2] = { + {PHY_DDR3_RON_455ohm, 455}, + {PHY_DDR3_RON_230ohm, 230}, + {PHY_DDR3_RON_153ohm, 153}, + {PHY_DDR3_RON_115ohm, 115}, + {PHY_DDR3_RON_91ohm, 91}, + {PHY_DDR3_RON_76ohm, 76}, + {PHY_DDR3_RON_65ohm, 65}, + {PHY_DDR3_RON_57ohm, 57}, + {PHY_DDR3_RON_51ohm, 51}, + {PHY_DDR3_RON_46ohm, 46}, + {PHY_DDR3_RON_41ohm, 41}, + {PHY_DDR3_RON_38ohm, 38}, + {PHY_DDR3_RON_35ohm, 35}, + {PHY_DDR3_RON_32ohm, 32}, + {PHY_DDR3_RON_30ohm, 30}, + {PHY_DDR3_RON_28ohm, 28}, + {PHY_DDR3_RON_27ohm, 27}, + {PHY_DDR3_RON_25ohm, 25}, + {PHY_DDR3_RON_24ohm, 24}, + {PHY_DDR3_RON_23ohm, 23}, + {PHY_DDR3_RON_22ohm, 22}, + {PHY_DDR3_RON_21ohm, 21}, + {PHY_DDR3_RON_20ohm, 20} +}; + +static u16 d3_phy_odt_2_ohm[][2] = { + {PHY_DDR3_RTT_DISABLE, 0}, + {PHY_DDR3_RTT_561ohm, 561}, + {PHY_DDR3_RTT_282ohm, 282}, + {PHY_DDR3_RTT_188ohm, 188}, + {PHY_DDR3_RTT_141ohm, 141}, + {PHY_DDR3_RTT_113ohm, 113}, + {PHY_DDR3_RTT_94ohm, 94}, + {PHY_DDR3_RTT_81ohm, 81}, + {PHY_DDR3_RTT_72ohm, 72}, + {PHY_DDR3_RTT_64ohm, 64}, + {PHY_DDR3_RTT_58ohm, 58}, + {PHY_DDR3_RTT_52ohm, 52}, + {PHY_DDR3_RTT_48ohm, 48}, + {PHY_DDR3_RTT_44ohm, 44}, + {PHY_DDR3_RTT_41ohm, 41}, + {PHY_DDR3_RTT_38ohm, 38}, + {PHY_DDR3_RTT_37ohm, 37}, + {PHY_DDR3_RTT_34ohm, 34}, + {PHY_DDR3_RTT_32ohm, 32}, + {PHY_DDR3_RTT_31ohm, 31}, + {PHY_DDR3_RTT_29ohm, 29}, + {PHY_DDR3_RTT_28ohm, 28}, + {PHY_DDR3_RTT_27ohm, 27}, + {PHY_DDR3_RTT_25ohm, 25} +}; + +static u16 d4lp3_phy_drv_2_ohm[][2] = { + {PHY_DDR4_LPDDR3_RON_482ohm, 482}, + {PHY_DDR4_LPDDR3_RON_244ohm, 244}, + {PHY_DDR4_LPDDR3_RON_162ohm, 162}, + {PHY_DDR4_LPDDR3_RON_122ohm, 122}, + {PHY_DDR4_LPDDR3_RON_97ohm, 97}, + {PHY_DDR4_LPDDR3_RON_81ohm, 81}, + {PHY_DDR4_LPDDR3_RON_69ohm, 69}, + {PHY_DDR4_LPDDR3_RON_61ohm, 61}, + {PHY_DDR4_LPDDR3_RON_54ohm, 54}, + {PHY_DDR4_LPDDR3_RON_48ohm, 48}, + {PHY_DDR4_LPDDR3_RON_44ohm, 44}, + {PHY_DDR4_LPDDR3_RON_40ohm, 40}, + {PHY_DDR4_LPDDR3_RON_37ohm, 37}, + {PHY_DDR4_LPDDR3_RON_34ohm, 34}, + {PHY_DDR4_LPDDR3_RON_32ohm, 32}, + {PHY_DDR4_LPDDR3_RON_30ohm, 30}, + {PHY_DDR4_LPDDR3_RON_28ohm, 28}, + {PHY_DDR4_LPDDR3_RON_27ohm, 27}, + {PHY_DDR4_LPDDR3_RON_25ohm, 25}, + {PHY_DDR4_LPDDR3_RON_24ohm, 24}, + {PHY_DDR4_LPDDR3_RON_23ohm, 23}, + {PHY_DDR4_LPDDR3_RON_22ohm, 22}, + {PHY_DDR4_LPDDR3_RON_21ohm, 21} +}; + +static u16 d4lp3_phy_odt_2_ohm[][2] = { + {PHY_DDR4_LPDDR3_RTT_DISABLE, 0}, + {PHY_DDR4_LPDDR3_RTT_586ohm, 586}, + {PHY_DDR4_LPDDR3_RTT_294ohm, 294}, + {PHY_DDR4_LPDDR3_RTT_196ohm, 196}, + {PHY_DDR4_LPDDR3_RTT_148ohm, 148}, + {PHY_DDR4_LPDDR3_RTT_118ohm, 118}, + {PHY_DDR4_LPDDR3_RTT_99ohm, 99}, + {PHY_DDR4_LPDDR3_RTT_85ohm, 58}, + {PHY_DDR4_LPDDR3_RTT_76ohm, 76}, + {PHY_DDR4_LPDDR3_RTT_67ohm, 67}, + {PHY_DDR4_LPDDR3_RTT_60ohm, 60}, + {PHY_DDR4_LPDDR3_RTT_55ohm, 55}, + {PHY_DDR4_LPDDR3_RTT_50ohm, 50}, + {PHY_DDR4_LPDDR3_RTT_46ohm, 46}, + {PHY_DDR4_LPDDR3_RTT_43ohm, 43}, + {PHY_DDR4_LPDDR3_RTT_40ohm, 40}, + {PHY_DDR4_LPDDR3_RTT_38ohm, 38}, + {PHY_DDR4_LPDDR3_RTT_36ohm, 36}, + {PHY_DDR4_LPDDR3_RTT_34ohm, 34}, + {PHY_DDR4_LPDDR3_RTT_32ohm, 32}, + {PHY_DDR4_LPDDR3_RTT_31ohm, 31}, + {PHY_DDR4_LPDDR3_RTT_29ohm, 29}, + {PHY_DDR4_LPDDR3_RTT_28ohm, 28}, + {PHY_DDR4_LPDDR3_RTT_27ohm, 27} +}; + +static u16 lp4_phy_drv_2_ohm[][2] = { + {PHY_LPDDR4_RON_501ohm, 501}, + {PHY_LPDDR4_RON_253ohm, 253}, + {PHY_LPDDR4_RON_168ohm, 168}, + {PHY_LPDDR4_RON_126ohm, 126}, + {PHY_LPDDR4_RON_101ohm, 101}, + {PHY_LPDDR4_RON_84ohm, 84}, + {PHY_LPDDR4_RON_72ohm, 72}, + {PHY_LPDDR4_RON_63ohm, 63}, + {PHY_LPDDR4_RON_56ohm, 56}, + {PHY_LPDDR4_RON_50ohm, 50}, + {PHY_LPDDR4_RON_46ohm, 46}, + {PHY_LPDDR4_RON_42ohm, 42}, + {PHY_LPDDR4_RON_38ohm, 38}, + {PHY_LPDDR4_RON_36ohm, 36}, + {PHY_LPDDR4_RON_33ohm, 33}, + {PHY_LPDDR4_RON_31ohm, 31}, + {PHY_LPDDR4_RON_29ohm, 29}, + {PHY_LPDDR4_RON_28ohm, 28}, + {PHY_LPDDR4_RON_26ohm, 26}, + {PHY_LPDDR4_RON_25ohm, 25}, + {PHY_LPDDR4_RON_24ohm, 24}, + {PHY_LPDDR4_RON_23ohm, 23}, + {PHY_LPDDR4_RON_22ohm, 22} +}; + +static u16 lp4_phy_odt_2_ohm[][2] = { + {PHY_LPDDR4_RTT_DISABLE, 0}, + {PHY_LPDDR4_RTT_604ohm, 604}, + {PHY_LPDDR4_RTT_303ohm, 303}, + {PHY_LPDDR4_RTT_202ohm, 202}, + {PHY_LPDDR4_RTT_152ohm, 152}, + {PHY_LPDDR4_RTT_122ohm, 122}, + {PHY_LPDDR4_RTT_101ohm, 101}, + {PHY_LPDDR4_RTT_87ohm, 87}, + {PHY_LPDDR4_RTT_78ohm, 78}, + {PHY_LPDDR4_RTT_69ohm, 69}, + {PHY_LPDDR4_RTT_62ohm, 62}, + {PHY_LPDDR4_RTT_56ohm, 56}, + {PHY_LPDDR4_RTT_52ohm, 52}, + {PHY_LPDDR4_RTT_48ohm, 48}, + {PHY_LPDDR4_RTT_44ohm, 44}, + {PHY_LPDDR4_RTT_41ohm, 41}, + {PHY_LPDDR4_RTT_39ohm, 39}, + {PHY_LPDDR4_RTT_37ohm, 37}, + {PHY_LPDDR4_RTT_35ohm, 35}, + {PHY_LPDDR4_RTT_33ohm, 33}, + {PHY_LPDDR4_RTT_32ohm, 32}, + {PHY_LPDDR4_RTT_30ohm, 30}, + {PHY_LPDDR4_RTT_29ohm, 29}, + {PHY_LPDDR4_RTT_27ohm, 27} +}; + +static u32 lp4_odt_calc(u32 odt_ohm) +{ + u32 odt; + + if (odt_ohm == 0) + odt = LPDDR4_DQODT_DIS; + else if (odt_ohm <= 40) + odt = LPDDR4_DQODT_40; + else if (odt_ohm <= 48) + odt = LPDDR4_DQODT_48; + else if (odt_ohm <= 60) + odt = LPDDR4_DQODT_60; + else if (odt_ohm <= 80) + odt = LPDDR4_DQODT_80; + else if (odt_ohm <= 120) + odt = LPDDR4_DQODT_120; + else + odt = LPDDR4_DQODT_240; + + return odt; +} + +static void *get_ddr_drv_odt_info(u32 dramtype) +{ + struct sdram_head_info_index_v2 *index = + (struct sdram_head_info_index_v2 *)common_info; + void *ddr_info = 0; + + if (dramtype == DDR4) + ddr_info = (void *)common_info + index->ddr4_index.offset * 4; + else if (dramtype == DDR3) + ddr_info = (void *)common_info + index->ddr3_index.offset * 4; + else if (dramtype == LPDDR3) + ddr_info = (void *)common_info + index->lp3_index.offset * 4; + else if (dramtype == LPDDR4) + ddr_info = (void *)common_info + index->lp4_index.offset * 4; + else + printascii("unsupported dram type\n"); + return ddr_info; +} + +static void set_lp4_vref(struct dram_info *dram, struct lp4_info *lp4_info, + u32 freq_mhz, u32 dst_fsp, u32 dramtype) +{ + void __iomem *pctl_base = dram->pctl; + u32 ca_vref, dq_vref; + + if (freq_mhz <= LP4_CA_ODT_EN_FREQ(lp4_info->ca_odten_freq)) + ca_vref = LP4_CA_VREF(lp4_info->vref_when_odtoff); + else + ca_vref = LP4_CA_VREF(lp4_info->vref_when_odten); + + if (freq_mhz <= LP4_DQ_ODT_EN_FREQ(lp4_info->dq_odten_freq)) + dq_vref = LP4_DQ_VREF(lp4_info->vref_when_odtoff); + else + dq_vref = LP4_DQ_VREF(lp4_info->vref_when_odten); + + if (dramtype == LPDDR4) { + if (ca_vref < 100) + ca_vref = 100; + if (ca_vref > 420) + ca_vref = 420; + + if (ca_vref <= 300) + ca_vref = (0 << 6) | (ca_vref - 100) / 4; + else + ca_vref = (1 << 6) | (ca_vref - 220) / 4; + + if (dq_vref < 100) + dq_vref = 100; + if (dq_vref > 420) + dq_vref = 420; + + if (dq_vref <= 300) + dq_vref = (0 << 6) | (dq_vref - 100) / 4; + else + dq_vref = (1 << 6) | (dq_vref - 220) / 4; + } else { + ca_vref = ca_vref * 11 / 6; + if (ca_vref < 150) + ca_vref = 150; + if (ca_vref > 629) + ca_vref = 629; + + if (ca_vref <= 449) + ca_vref = (0 << 6) | (ca_vref - 150) / 4; + else + ca_vref = (1 << 6) | (ca_vref - 329) / 4; + + if (dq_vref < 150) + dq_vref = 150; + if (dq_vref > 629) + dq_vref = 629; + + if (dq_vref <= 449) + dq_vref = (0 << 6) | (dq_vref - 150) / 6; + else + dq_vref = (1 << 6) | (dq_vref - 329) / 6; + } + sw_set_req(dram); + clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT6, + PCTL2_MR_MASK << PCTL2_LPDDR4_MR12_SHIFT, + ca_vref << PCTL2_LPDDR4_MR12_SHIFT); + + clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT7, + PCTL2_MR_MASK << PCTL2_LPDDR4_MR14_SHIFT, + dq_vref << PCTL2_LPDDR4_MR14_SHIFT); + sw_set_ack(dram); +} + +static void set_ds_odt(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params, u32 dst_fsp) +{ + void __iomem *phy_base = dram->phy; + void __iomem *pctl_base = dram->pctl; + u32 dramtype = sdram_params->base.dramtype; + struct ddr2_3_4_lp2_3_info *ddr_info; + struct lp4_info *lp4_info; + u32 i, j, tmp; + const u16 (*p_drv)[2]; + const u16 (*p_odt)[2]; + u32 drv_info, sr_info; + u32 phy_dq_drv_ohm, phy_clk_drv_ohm, phy_ca_drv_ohm, dram_drv_ohm; + u32 phy_odt_ohm, dram_odt_ohm; + u32 lp4_pu_cal, phy_lp4_drv_pd_en; + u32 phy_odt_up_en, phy_odt_dn_en; + u32 sr_dq, sr_clk; + u32 freq = sdram_params->base.ddr_freq; + u32 mr1_mr3, mr11, mr22, vref_out, vref_inner; + u32 phy_clk_drv = 0, phy_odt = 0, phy_ca_drv = 0, dram_caodt_ohm = 0; + u32 phy_dq_drv = 0; + u32 phy_odt_up = 0, phy_odt_dn = 0; + + ddr_info = get_ddr_drv_odt_info(dramtype); + lp4_info = (void *)ddr_info; + + if (!ddr_info) + return; + + /* dram odt en freq control phy drv, dram odt and phy sr */ + if (freq <= DRAMODT_EN_FREQ(ddr_info->odten_freq)) { + drv_info = ddr_info->drv_when_odtoff; + dram_odt_ohm = 0; + sr_info = ddr_info->sr_when_odtoff; + phy_lp4_drv_pd_en = + PHY_LP4_DRV_PULLDOWN_EN_ODTOFF(lp4_info->odt_info); + } else { + drv_info = ddr_info->drv_when_odten; + dram_odt_ohm = ODT_INFO_DRAM_ODT(ddr_info->odt_info); + sr_info = ddr_info->sr_when_odten; + phy_lp4_drv_pd_en = + PHY_LP4_DRV_PULLDOWN_EN_ODTEN(lp4_info->odt_info); + } + phy_dq_drv_ohm = + DRV_INFO_PHY_DQ_DRV(drv_info); + phy_clk_drv_ohm = + DRV_INFO_PHY_CLK_DRV(drv_info); + phy_ca_drv_ohm = + DRV_INFO_PHY_CA_DRV(drv_info); + + sr_dq = DQ_SR_INFO(sr_info); + sr_clk = CLK_SR_INFO(sr_info); + + /* phy odt en freq control dram drv and phy odt */ + if (freq <= PHYODT_EN_FREQ(ddr_info->odten_freq)) { + dram_drv_ohm = DRV_INFO_DRAM_DQ_DRV(ddr_info->drv_when_odtoff); + lp4_pu_cal = LP4_DRV_PU_CAL_ODTOFF(lp4_info->odt_info); + phy_odt_ohm = 0; + phy_odt_up_en = 0; + phy_odt_dn_en = 0; + } else { + dram_drv_ohm = + DRV_INFO_DRAM_DQ_DRV(ddr_info->drv_when_odten); + phy_odt_ohm = ODT_INFO_PHY_ODT(ddr_info->odt_info); + phy_odt_up_en = + ODT_INFO_PULLUP_EN(ddr_info->odt_info); + phy_odt_dn_en = + ODT_INFO_PULLDOWN_EN(ddr_info->odt_info); + lp4_pu_cal = LP4_DRV_PU_CAL_ODTEN(lp4_info->odt_info); + } + + if (dramtype == LPDDR4) { + if (phy_odt_ohm) { + phy_odt_up_en = 0; + phy_odt_dn_en = 1; + } + if (freq <= LP4_CA_ODT_EN_FREQ(lp4_info->ca_odten_freq)) + dram_caodt_ohm = 0; + else + dram_caodt_ohm = + ODT_INFO_LP4_CA_ODT(lp4_info->odt_info); + } + + if (dramtype == DDR3) { + p_drv = d3_phy_drv_2_ohm; + p_odt = d3_phy_odt_2_ohm; + } else if (dramtype == LPDDR4) { + p_drv = lp4_phy_drv_2_ohm; + p_odt = lp4_phy_odt_2_ohm; + } else { + p_drv = d4lp3_phy_drv_2_ohm; + p_odt = d4lp3_phy_odt_2_ohm; + } + + for (i = ARRAY_SIZE(d3_phy_drv_2_ohm) - 1; ; i--) { + if (phy_dq_drv_ohm <= *(*(p_drv + i) + 1)) { + phy_dq_drv = **(p_drv + i); + break; + } + if (i == 0) + break; + } + for (i = ARRAY_SIZE(d3_phy_drv_2_ohm) - 1; ; i--) { + if (phy_clk_drv_ohm <= *(*(p_drv + i) + 1)) { + phy_clk_drv = **(p_drv + i); + break; + } + if (i == 0) + break; + } + for (i = ARRAY_SIZE(d3_phy_drv_2_ohm) - 1; ; i--) { + if (phy_ca_drv_ohm <= *(*(p_drv + i) + 1)) { + phy_ca_drv = **(p_drv + i); + break; + } + if (i == 0) + break; + } + if (!phy_odt_ohm) + phy_odt = 0; + else + for (i = ARRAY_SIZE(d4lp3_phy_odt_2_ohm) - 1; ; i--) { + if (phy_odt_ohm <= *(*(p_odt + i) + 1)) { + phy_odt = **(p_odt + i); + break; + } + if (i == 0) + break; + } + + if (dramtype != LPDDR4) { + if (!phy_odt_ohm || (phy_odt_up_en && phy_odt_dn_en)) + vref_inner = 0x80; + else if (phy_odt_up_en) + vref_inner = (2 * dram_drv_ohm + phy_odt_ohm) * 128 / + (dram_drv_ohm + phy_odt_ohm); + else + vref_inner = phy_odt_ohm * 128 / + (phy_odt_ohm + dram_drv_ohm); + + if (dramtype != DDR3 && dram_odt_ohm) + vref_out = (2 * phy_dq_drv_ohm + dram_odt_ohm) * 128 / + (phy_dq_drv_ohm + dram_odt_ohm); + else + vref_out = 0x80; + } else { + /* for lp4 and lp4x*/ + if (phy_odt_ohm) + vref_inner = + (PHY_LP4_DQ_VREF(lp4_info->vref_when_odten) * + 256) / 1000; + else + vref_inner = + (PHY_LP4_DQ_VREF(lp4_info->vref_when_odtoff) * + 256) / 1000; + + vref_out = 0x80; + } + + /* default ZQCALIB bypass mode */ + clrsetbits_le32(PHY_REG(phy_base, 0x100), 0x1f, phy_ca_drv); + clrsetbits_le32(PHY_REG(phy_base, 0x101), 0x1f, phy_ca_drv); + clrsetbits_le32(PHY_REG(phy_base, 0x102), 0x1f, phy_clk_drv); + clrsetbits_le32(PHY_REG(phy_base, 0x103), 0x1f, phy_clk_drv); + if (dramtype == LPDDR4) { + clrsetbits_le32(PHY_REG(phy_base, 0x107), 0x1f, phy_clk_drv); + clrsetbits_le32(PHY_REG(phy_base, 0x108), 0x1f, phy_clk_drv); + } else { + clrsetbits_le32(PHY_REG(phy_base, 0x107), 0x1f, phy_ca_drv); + clrsetbits_le32(PHY_REG(phy_base, 0x108), 0x1f, phy_ca_drv); + } + /* clk / cmd slew rate */ + clrsetbits_le32(PHY_REG(phy_base, 0x106), 0x1f, sr_clk); + + phy_lp4_drv_pd_en = (~phy_lp4_drv_pd_en) & 1; + if (phy_odt_up_en) + phy_odt_up = phy_odt; + if (phy_odt_dn_en) + phy_odt_dn = phy_odt; + + for (i = 0; i < 4; i++) { + j = 0x110 + i * 0x10; + clrsetbits_le32(PHY_REG(phy_base, j + 1), 0x1f, phy_odt_up); + clrsetbits_le32(PHY_REG(phy_base, j), 0x1f, phy_odt_dn); + clrsetbits_le32(PHY_REG(phy_base, j + 2), 0x1f, phy_dq_drv); + clrsetbits_le32(PHY_REG(phy_base, j + 3), 0x1f, phy_dq_drv); + writel(vref_inner, PHY_REG(phy_base, 0x118 + i * 0x10)); + + clrsetbits_le32(PHY_REG(phy_base, 0x114 + i * 0x10), + 1 << 3, phy_lp4_drv_pd_en << 3); + if (dramtype == LPDDR4) + clrbits_le32(PHY_REG(phy_base, 0x114 + i * 0x10), BIT(5)); + /* dq slew rate */ + clrsetbits_le32(PHY_REG(phy_base, 0x117 + i * 0x10), + 0x1f, sr_dq); + } + + /* reg_rx_vref_value_update */ + setbits_le32(PHY_REG(phy_base, 0x71), 1 << 5); + clrbits_le32(PHY_REG(phy_base, 0x71), 1 << 5); + + /* RAM VREF */ + writel(vref_out, PHY_REG(phy_base, 0x105)); + if (dramtype == LPDDR3) + udelay(100); + + if (dramtype == LPDDR4) + set_lp4_vref(dram, lp4_info, freq, dst_fsp, dramtype); + + if (dramtype == DDR3 || dramtype == DDR4) { + mr1_mr3 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT3); + mr1_mr3 = mr1_mr3 >> PCTL2_DDR34_MR1_SHIFT & PCTL2_MR_MASK; + } else { + mr1_mr3 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT4); + mr1_mr3 = mr1_mr3 >> PCTL2_LPDDR234_MR3_SHIFT & PCTL2_MR_MASK; + } + + if (dramtype == DDR3) { + mr1_mr3 &= ~(DDR3_DS_MASK | DDR3_RTT_NOM_MASK); + if (dram_drv_ohm == 34) + mr1_mr3 |= DDR3_DS_34; + + if (dram_odt_ohm == 0) + mr1_mr3 |= DDR3_RTT_NOM_DIS; + else if (dram_odt_ohm <= 40) + mr1_mr3 |= DDR3_RTT_NOM_40; + else if (dram_odt_ohm <= 60) + mr1_mr3 |= DDR3_RTT_NOM_60; + else + mr1_mr3 |= DDR3_RTT_NOM_120; + + } else if (dramtype == DDR4) { + mr1_mr3 &= ~(DDR4_DS_MASK | DDR4_RTT_NOM_MASK); + if (dram_drv_ohm == 48) + mr1_mr3 |= DDR4_DS_48; + + if (dram_odt_ohm == 0) + mr1_mr3 |= DDR4_RTT_NOM_DIS; + else if (dram_odt_ohm <= 34) + mr1_mr3 |= DDR4_RTT_NOM_34; + else if (dram_odt_ohm <= 40) + mr1_mr3 |= DDR4_RTT_NOM_40; + else if (dram_odt_ohm <= 48) + mr1_mr3 |= DDR4_RTT_NOM_48; + else if (dram_odt_ohm <= 60) + mr1_mr3 |= DDR4_RTT_NOM_60; + else + mr1_mr3 |= DDR4_RTT_NOM_120; + + } else if (dramtype == LPDDR3) { + if (dram_drv_ohm <= 34) + mr1_mr3 |= LPDDR3_DS_34; + else if (dram_drv_ohm <= 40) + mr1_mr3 |= LPDDR3_DS_40; + else if (dram_drv_ohm <= 48) + mr1_mr3 |= LPDDR3_DS_48; + else if (dram_drv_ohm <= 60) + mr1_mr3 |= LPDDR3_DS_60; + else if (dram_drv_ohm <= 80) + mr1_mr3 |= LPDDR3_DS_80; + + if (dram_odt_ohm == 0) + lp3_odt_value = LPDDR3_ODT_DIS; + else if (dram_odt_ohm <= 60) + lp3_odt_value = LPDDR3_ODT_60; + else if (dram_odt_ohm <= 120) + lp3_odt_value = LPDDR3_ODT_120; + else + lp3_odt_value = LPDDR3_ODT_240; + } else {/* for lpddr4 and lpddr4x */ + /* MR3 for lp4 PU-CAL and PDDS */ + mr1_mr3 &= ~(LPDDR4_PDDS_MASK | LPDDR4_PU_CAL_MASK); + mr1_mr3 |= lp4_pu_cal; + + tmp = lp4_odt_calc(dram_drv_ohm); + if (!tmp) + tmp = LPDDR4_PDDS_240; + mr1_mr3 |= (tmp << LPDDR4_PDDS_SHIFT); + + /* MR11 for lp4 ca odt, dq odt set */ + mr11 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT6); + mr11 = mr11 >> PCTL2_LPDDR4_MR11_SHIFT & PCTL2_MR_MASK; + + mr11 &= ~(LPDDR4_DQODT_MASK | LPDDR4_CAODT_MASK); + + tmp = lp4_odt_calc(dram_odt_ohm); + mr11 |= (tmp << LPDDR4_DQODT_SHIFT); + + tmp = lp4_odt_calc(dram_caodt_ohm); + mr11 |= (tmp << LPDDR4_CAODT_SHIFT); + sw_set_req(dram); + clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT6, + PCTL2_MR_MASK << PCTL2_LPDDR4_MR11_SHIFT, + mr11 << PCTL2_LPDDR4_MR11_SHIFT); + sw_set_ack(dram); + + /* MR22 for soc odt/odt-ck/odt-cs/odt-ca */ + mr22 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT7); + mr22 = mr22 >> PCTL2_LPDDR4_MR22_SHIFT & PCTL2_MR_MASK; + mr22 &= ~LPDDR4_SOC_ODT_MASK; + + tmp = lp4_odt_calc(phy_odt_ohm); + mr22 |= tmp; + mr22 = mr22 | + (LP4_ODTE_CK_EN(lp4_info->cs_drv_ca_odt_info) << + LPDDR4_ODTE_CK_SHIFT) | + (LP4_ODTE_CS_EN(lp4_info->cs_drv_ca_odt_info) << + LPDDR4_ODTE_CS_SHIFT) | + (LP4_ODTD_CA_EN(lp4_info->cs_drv_ca_odt_info) << + LPDDR4_ODTD_CA_SHIFT); + + sw_set_req(dram); + clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT7, + PCTL2_MR_MASK << PCTL2_LPDDR4_MR22_SHIFT, + mr22 << PCTL2_LPDDR4_MR22_SHIFT); + sw_set_ack(dram); + } + + if (dramtype == DDR4 || dramtype == DDR3) { + sw_set_req(dram); + clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT3, + PCTL2_MR_MASK << PCTL2_DDR34_MR1_SHIFT, + mr1_mr3 << PCTL2_DDR34_MR1_SHIFT); + sw_set_ack(dram); + } else { + sw_set_req(dram); + clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT4, + PCTL2_MR_MASK << PCTL2_LPDDR234_MR3_SHIFT, + mr1_mr3 << PCTL2_LPDDR234_MR3_SHIFT); + sw_set_ack(dram); + } +} + +static int sdram_cmd_dq_path_remap(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params) +{ + void __iomem *phy_base = dram->phy; + u32 dramtype = sdram_params->base.dramtype; + struct sdram_head_info_index_v2 *index = + (struct sdram_head_info_index_v2 *)common_info; + struct dq_map_info *map_info; + + map_info = (struct dq_map_info *)((void *)common_info + + index->dq_map_index.offset * 4); + + if (dramtype <= LPDDR4) + writel((map_info->byte_map[dramtype / 4] >> + ((dramtype % 4) * 8)) & 0xff, + PHY_REG(phy_base, 0x4f)); + + return 0; +} + +static void phy_cfg(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params) +{ + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info; + void __iomem *phy_base = dram->phy; + u32 i, dq_map, tmp; + u32 byte1 = 0, byte0 = 0; + + sdram_cmd_dq_path_remap(dram, sdram_params); + + phy_pll_set(dram, sdram_params->base.ddr_freq * MHZ, 0); + for (i = 0; sdram_params->phy_regs.phy[i][0] != 0xFFFFFFFF; i++) { + writel(sdram_params->phy_regs.phy[i][1], + phy_base + sdram_params->phy_regs.phy[i][0]); + } + + clrbits_le32(PHY_REG(phy_base, 0x62), BIT(5)); + dq_map = readl(PHY_REG(phy_base, 0x4f)); + for (i = 0; i < 4; i++) { + if (((dq_map >> (i * 2)) & 0x3) == 0) + byte0 = i; + if (((dq_map >> (i * 2)) & 0x3) == 1) + byte1 = i; + } + + tmp = readl(PHY_REG(phy_base, 0xf)) & (~PHY_DQ_WIDTH_MASK); + if (cap_info->bw == 2) + tmp |= 0xf; + else if (cap_info->bw == 1) + tmp |= ((1 << byte0) | (1 << byte1)); + else + tmp |= (1 << byte0); + + writel(tmp, PHY_REG(phy_base, 0xf)); + + /* lpddr4 odt control by phy, enable cs0 odt */ + if (sdram_params->base.dramtype == LPDDR4) + clrsetbits_le32(PHY_REG(phy_base, 0x20), 0x7 << 4, + (1 << 6) | (1 << 4)); + /* for ca training ca vref choose range1 */ + setbits_le32(PHY_REG(phy_base, 0x1e), BIT(6)); + setbits_le32(PHY_REG(phy_base, 0x1f), BIT(6)); + /* for wr training PHY_0x7c[5], choose range0 */ + clrbits_le32(PHY_REG(phy_base, 0x7c), BIT(5)); +} + +static int update_refresh_reg(struct dram_info *dram) +{ + void __iomem *pctl_base = dram->pctl; + u32 ret; + + ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1); + writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3); + + return 0; +} + +/* + * rank = 1: cs0 + * rank = 2: cs1 + */ +int read_mr(struct dram_info *dram, u32 rank, u32 mr_num, u32 dramtype) +{ + u32 ret; + u32 i, temp; + u32 dqmap; + + void __iomem *pctl_base = dram->pctl; + struct sdram_head_info_index_v2 *index = + (struct sdram_head_info_index_v2 *)common_info; + struct dq_map_info *map_info; + + map_info = (struct dq_map_info *)((void *)common_info + + index->dq_map_index.offset * 4); + + if (dramtype == LPDDR2) + dqmap = map_info->lp2_dq0_7_map; + else + dqmap = map_info->lp3_dq0_7_map; + + pctl_read_mr(pctl_base, rank, mr_num); + + ret = (readl(&dram->ddrgrf->ddr_grf_status[0]) & 0xff); + + if (dramtype != LPDDR4) { + temp = 0; + for (i = 0; i < 8; i++) { + temp = temp | (((ret >> i) & 0x1) << + ((dqmap >> (i * 4)) & 0xf)); + } + } else { + temp = (readl(&dram->ddrgrf->ddr_grf_status[1]) & 0xff); + } + + return temp; +} + +/* before call this function autorefresh should be disabled */ +void send_a_refresh(struct dram_info *dram) +{ + void __iomem *pctl_base = dram->pctl; + + while (readl(pctl_base + DDR_PCTL2_DBGSTAT) & 0x3) + continue; + writel(0x3, pctl_base + DDR_PCTL2_DBGCMD); +} + +static void enter_sr(struct dram_info *dram, u32 en) +{ + void __iomem *pctl_base = dram->pctl; + + if (en) { + setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, PCTL2_SELFREF_SW); + while (1) { + if (((readl(pctl_base + DDR_PCTL2_STAT) & + PCTL2_SELFREF_TYPE_MASK) == + PCTL2_SELFREF_TYPE_SR_NOT_AUTO) && + ((readl(pctl_base + DDR_PCTL2_STAT) & + PCTL2_OPERATING_MODE_MASK) == + PCTL2_OPERATING_MODE_SR)) + break; + } + } else { + clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, PCTL2_SELFREF_SW); + while ((readl(pctl_base + DDR_PCTL2_STAT) & + PCTL2_OPERATING_MODE_MASK) == PCTL2_OPERATING_MODE_SR) + continue; + } +} + +void record_dq_prebit(struct dram_info *dram) +{ + u32 group, i, tmp; + void __iomem *phy_base = dram->phy; + + for (group = 0; group < 4; group++) { + for (i = 0; i < ARRAY_SIZE(dq_sel); i++) { + /* l_loop_invdelaysel */ + writel(dq_sel[i][0], PHY_REG(phy_base, + grp_addr[group] + 0x2c)); + tmp = readl(PHY_REG(phy_base, grp_addr[group] + 0x2e)); + writel(tmp, PHY_REG(phy_base, + grp_addr[group] + dq_sel[i][1])); + + /* r_loop_invdelaysel */ + writel(dq_sel[i][0], PHY_REG(phy_base, + grp_addr[group] + 0x2d)); + tmp = readl(PHY_REG(phy_base, grp_addr[group] + 0x2f)); + writel(tmp, PHY_REG(phy_base, + grp_addr[group] + dq_sel[i][2])); + } + } +} + +static void update_dq_rx_prebit(struct dram_info *dram) +{ + void __iomem *phy_base = dram->phy; + + clrsetbits_le32(PHY_REG(phy_base, 0x70), BIT(1) | BIT(6) | BIT(4), + BIT(4)); + udelay(1); + clrbits_le32(PHY_REG(phy_base, 0x70), BIT(4)); +} + +static void update_dq_tx_prebit(struct dram_info *dram) +{ + void __iomem *phy_base = dram->phy; + + clrbits_le32(PHY_REG(phy_base, 0x7a), BIT(1)); + setbits_le32(PHY_REG(phy_base, 0x2), BIT(3)); + setbits_le32(PHY_REG(phy_base, 0xc), BIT(6)); + udelay(1); + clrbits_le32(PHY_REG(phy_base, 0xc), BIT(6)); +} + +static void update_ca_prebit(struct dram_info *dram) +{ + void __iomem *phy_base = dram->phy; + + clrbits_le32(PHY_REG(phy_base, 0x25), BIT(2)); + setbits_le32(PHY_REG(phy_base, 0x22), BIT(6)); + udelay(1); + clrbits_le32(PHY_REG(phy_base, 0x22), BIT(6)); +} + +/* + * dir: 0: de-skew = delta_* + * 1: de-skew = reg val - delta_* + * delta_dir: value for differential signal: clk/ + * delta_sig: value for single signal: ca/cmd + */ +static void modify_ca_deskew(struct dram_info *dram, u32 dir, int delta_dif, + int delta_sig, u32 cs, u32 dramtype) +{ + void __iomem *phy_base = dram->phy; + u32 i, cs_en, tmp; + u32 dfi_lp_stat = 0; + + if (cs == 0) + cs_en = 1; + else if (cs == 2) + cs_en = 2; + else + cs_en = 3; + + if (dramtype == LPDDR4 && + ((readl(PHY_REG(phy_base, 0x60)) & BIT(5)) == 0)) { + dfi_lp_stat = 1; + setbits_le32(PHY_REG(phy_base, 0x60), BIT(5)); + } + enter_sr(dram, 1); + + for (i = 0; i < 0x20; i++) { + if (dir == DESKEW_MDF_ABS_VAL) + tmp = delta_sig; + else + tmp = readl(PHY_REG(phy_base, 0x150 + i)) + + delta_sig; + writel(tmp, PHY_REG(phy_base, 0x150 + i)); + } + + if (dir == DESKEW_MDF_ABS_VAL) + tmp = delta_dif; + else + tmp = readl(PHY_REG(phy_base, 0x150 + 0x17)) - + delta_sig + delta_dif; + writel(tmp, PHY_REG(phy_base, 0x150 + 0x17)); + writel(tmp, PHY_REG(phy_base, 0x150 + 0x18)); + if (dramtype == LPDDR4) { + writel(tmp, PHY_REG(phy_base, 0x150 + 0x4)); + writel(tmp, PHY_REG(phy_base, 0x150 + 0xa)); + + clrbits_le32(PHY_REG(phy_base, 0x10), cs_en << 6); + update_ca_prebit(dram); + } + enter_sr(dram, 0); + + if (dfi_lp_stat) + clrbits_le32(PHY_REG(phy_base, 0x60), BIT(5)); +} + +static u32 get_min_value(struct dram_info *dram, u32 signal, u32 rank) +{ + u32 i, j, offset = 0; + u32 min = 0x3f; + void __iomem *phy_base = dram->phy; + u32 byte_en; + + if (signal == SKEW_TX_SIGNAL) + offset = 8; + + if (signal == SKEW_CA_SIGNAL) { + for (i = 0; i < 0x20; i++) + min = MIN(min, readl(PHY_REG(phy_base, 0x150 + i))); + } else { + byte_en = readl(PHY_REG(phy_base, 0xf)) & 0xf; + for (j = offset; j < offset + rank * 4; j++) { + if (!((byte_en >> (j % 4)) & 1)) + continue; + for (i = 0; i < 11; i++) + min = MIN(min, + readl(PHY_REG(phy_base, + dqs_dq_skew_adr[j] + + i))); + } + } + + return min; +} + +static u32 low_power_update(struct dram_info *dram, u32 en) +{ + void __iomem *pctl_base = dram->pctl; + u32 lp_stat = 0; + + if (en) { + setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, en & 0xf); + } else { + lp_stat = readl(pctl_base + DDR_PCTL2_PWRCTL) & 0xf; + clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 0xf); + } + + return lp_stat; +} + +/* + * signal: + * dir: 0: de-skew = delta_* + * 1: de-skew = reg val - delta_* + * delta_dir: value for differential signal: dqs + * delta_sig: value for single signal: dq/dm + */ +static void modify_dq_deskew(struct dram_info *dram, u32 signal, u32 dir, + int delta_dif, int delta_sig, u32 rank) +{ + void __iomem *phy_base = dram->phy; + u32 i, j, tmp, offset; + u32 byte_en; + + byte_en = readl(PHY_REG(phy_base, 0xf)) & 0xf; + + if (signal == SKEW_RX_SIGNAL) + offset = 0; + else + offset = 8; + + for (j = offset; j < (offset + rank * 4); j++) { + if (!((byte_en >> (j % 4)) & 1)) + continue; + for (i = 0; i < 0x9; i++) { + if (dir == DESKEW_MDF_ABS_VAL) + tmp = delta_sig; + else + tmp = delta_sig + readl(PHY_REG(phy_base, + dqs_dq_skew_adr[j] + + i)); + writel(tmp, PHY_REG(phy_base, dqs_dq_skew_adr[j] + i)); + } + if (dir == DESKEW_MDF_ABS_VAL) + tmp = delta_dif; + else + tmp = delta_dif + readl(PHY_REG(phy_base, + dqs_dq_skew_adr[j] + 9)); + writel(tmp, PHY_REG(phy_base, dqs_dq_skew_adr[j] + 9)); + writel(tmp, PHY_REG(phy_base, dqs_dq_skew_adr[j] + 0xa)); + } + if (signal == SKEW_RX_SIGNAL) + update_dq_rx_prebit(dram); + else + update_dq_tx_prebit(dram); +} + +static int data_training_rg(struct dram_info *dram, u32 cs, u32 dramtype) +{ + void __iomem *phy_base = dram->phy; + u32 ret; + u32 dis_auto_zq = 0; + u32 odt_val_up, odt_val_dn; + u32 i, j; + + odt_val_dn = readl(PHY_REG(phy_base, 0x110)); + odt_val_up = readl(PHY_REG(phy_base, 0x111)); + + if (dramtype != LPDDR4) { + for (i = 0; i < 4; i++) { + j = 0x110 + i * 0x10; + writel(PHY_DDR4_LPDDR3_RTT_294ohm, + PHY_REG(phy_base, j)); + writel(PHY_DDR4_LPDDR3_RTT_DISABLE, + PHY_REG(phy_base, j + 0x1)); + } + } + dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl); + /* use normal read mode for data training */ + clrbits_le32(PHY_REG(phy_base, 0xc), BIT(1)); + + if (dramtype == DDR4) + setbits_le32(PHY_REG(phy_base, 0xc), BIT(1)); + + /* choose training cs */ + clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs)); + /* enable gate training */ + clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1); + udelay(50); + ret = readl(PHY_REG(phy_base, 0x91)); + /* disable gate training */ + clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0); + clrbits_le32(PHY_REG(phy_base, 2), 0x30); + pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq); + + ret = (ret & 0x2f) ^ (readl(PHY_REG(phy_base, 0xf)) & 0xf); + + if (dramtype != LPDDR4) { + for (i = 0; i < 4; i++) { + j = 0x110 + i * 0x10; + writel(odt_val_dn, PHY_REG(phy_base, j)); + writel(odt_val_up, PHY_REG(phy_base, j + 0x1)); + } + } + return ret; +} + +static int data_training_wl(struct dram_info *dram, u32 cs, u32 dramtype, + u32 rank) +{ + void __iomem *pctl_base = dram->pctl; + void __iomem *phy_base = dram->phy; + u32 dis_auto_zq = 0; + u32 tmp; + u32 cur_fsp; + u32 timeout_us = 1000; + + dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl); + + clrbits_le32(PHY_REG(phy_base, 0x7a), 0x1); + + cur_fsp = readl(pctl_base + DDR_PCTL2_MSTR2) & 0x3; + tmp = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) + DDR_PCTL2_INIT3) & + 0xffff; + writel(tmp & 0xff, PHY_REG(phy_base, 0x3)); + + /* disable another cs's output */ + if ((dramtype == DDR3 || dramtype == DDR4) && rank == 2) + pctl_write_mr(dram->pctl, (cs + 1) & 1, 1, tmp | (1 << 12), + dramtype); + if (dramtype == DDR3 || dramtype == DDR4) + writel(0x40 | ((tmp >> 8) & 0x3f), PHY_REG(phy_base, 0x4)); + else + writel(0x80 | ((tmp >> 8) & 0x3f), PHY_REG(phy_base, 0x4)); + + /* choose cs */ + clrsetbits_le32(PHY_REG(phy_base, 2), (0x3 << 6) | (0x3 << 2), + ((0x2 >> cs) << 6) | (0 << 2)); + /* enable write leveling */ + clrsetbits_le32(PHY_REG(phy_base, 2), (0x3 << 6) | (0x3 << 2), + ((0x2 >> cs) << 6) | (1 << 2)); + + while (1) { + if ((readl(PHY_REG(phy_base, 0x92)) & 0xf) == + (readl(PHY_REG(phy_base, 0xf)) & 0xf)) + break; + + udelay(1); + if (timeout_us-- == 0) { + printascii("error: write leveling timeout\n"); + while (1) + ; + } + } + + /* disable write leveling */ + clrsetbits_le32(PHY_REG(phy_base, 2), (0x3 << 6) | (0x3 << 2), + ((0x2 >> cs) << 6) | (0 << 2)); + clrsetbits_le32(PHY_REG(phy_base, 2), 0x3 << 6, 0 << 6); + + /* enable another cs's output */ + if ((dramtype == DDR3 || dramtype == DDR4) && rank == 2) + pctl_write_mr(dram->pctl, (cs + 1) & 1, 1, tmp & ~(1 << 12), + dramtype); + + pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq); + + return 0; +} + +char pattern[32] = { + 0xaa, 0x55, 0xaa, 0x55, 0x55, 0xaa, 0x55, 0xaa, + 0x55, 0xaa, 0x55, 0xaa, 0xaa, 0x55, 0xaa, 0x55, + 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, + 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa +}; + +static int data_training_rd(struct dram_info *dram, u32 cs, u32 dramtype, + u32 mhz) +{ + void __iomem *pctl_base = dram->pctl; + void __iomem *phy_base = dram->phy; + u32 trefi_1x, trfc_1x; + u32 dis_auto_zq = 0; + u32 timeout_us = 1000; + u32 dqs_default; + u32 cur_fsp; + u32 vref_inner; + u32 i; + struct sdram_head_info_index_v2 *index = + (struct sdram_head_info_index_v2 *)common_info; + struct dq_map_info *map_info; + + vref_inner = readl(PHY_REG(phy_base, 0x128)) & 0xff; + if (dramtype == DDR3 && vref_inner == 0x80) { + for (i = 0; i < 4; i++) + writel(vref_inner - 0xa, + PHY_REG(phy_base, 0x118 + i * 0x10)); + + /* reg_rx_vref_value_update */ + setbits_le32(PHY_REG(phy_base, 0x71), 1 << 5); + clrbits_le32(PHY_REG(phy_base, 0x71), 1 << 5); + } + + map_info = (struct dq_map_info *)((void *)common_info + + index->dq_map_index.offset * 4); + /* only 1cs a time, 0:cs0 1 cs1 */ + if (cs > 1) + return -1; + + dqs_default = 0xf; + dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl); + + cur_fsp = readl(pctl_base + DDR_PCTL2_MSTR2) & 0x3; + /* config refresh timing */ + trefi_1x = ((readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) + + DDR_PCTL2_RFSHTMG) >> 16) & 0xfff) * 32; + trfc_1x = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) + + DDR_PCTL2_RFSHTMG) & 0x3ff; + /* reg_phy_trefi[7:0] and reg_phy_trefi[13:8] */ + clrsetbits_le32(PHY_REG(phy_base, 0x6e), 0xff, trefi_1x & 0xff); + clrsetbits_le32(PHY_REG(phy_base, 0x6f), 0x3f, (trefi_1x >> 8) & 0x3f); + /* reg_phy_trfc */ + clrsetbits_le32(PHY_REG(phy_base, 0x57), 0xff, trfc_1x); + /* reg_max_refi_cnt */ + clrsetbits_le32(PHY_REG(phy_base, 0x61), 0xf << 4, 0x8 << 4); + + /* choose training cs */ + clrsetbits_le32(PHY_REG(phy_base, 0x71), 0x3 << 6, (0x2 >> cs) << 6); + + /* set dq map for ddr4 */ + if (dramtype == DDR4) { + setbits_le32(PHY_REG(phy_base, 0x70), BIT(7)); + for (i = 0; i < 4; i++) { + writel((map_info->ddr4_dq_map[cs * 2] >> + ((i % 4) * 8)) & 0xff, + PHY_REG(phy_base, 0x238 + i)); + writel((map_info->ddr4_dq_map[cs * 2 + 1] >> + ((i % 4) * 8)) & 0xff, + PHY_REG(phy_base, 0x2b8 + i)); + } + } + + /* cha_l reg_l_rd_train_dqs_default[5:0] */ + clrsetbits_le32(PHY_REG(phy_base, 0x230), 0x3f, dqs_default); + /* cha_h reg_h_rd_train_dqs_default[5:0] */ + clrsetbits_le32(PHY_REG(phy_base, 0x234), 0x3f, dqs_default); + /* chb_l reg_l_rd_train_dqs_default[5:0] */ + clrsetbits_le32(PHY_REG(phy_base, 0x2b0), 0x3f, dqs_default); + /* chb_h reg_h_rd_train_dqs_default[5:0] */ + clrsetbits_le32(PHY_REG(phy_base, 0x2b4), 0x3f, dqs_default); + + /* Choose the read train auto mode */ + clrsetbits_le32(PHY_REG(phy_base, 0x70), 0x3, 0x1); + /* Enable the auto train of the read train */ + clrsetbits_le32(PHY_REG(phy_base, 0x70), 0x3, 0x3); + + /* Wait the train done. */ + while (1) { + if ((readl(PHY_REG(phy_base, 0x93)) >> 7) & 0x1) + break; + + udelay(1); + if (timeout_us-- == 0) { + printascii("error: read training timeout\n"); + return -1; + } + } + + /* Check the read train state */ + if ((readl(PHY_REG(phy_base, 0x240)) & 0x3) || + (readl(PHY_REG(phy_base, 0x2c0)) & 0x3)) { + printascii("error: read training error\n"); + return -1; + } + + /* Exit the Read Training by setting */ + clrbits_le32(PHY_REG(phy_base, 0x70), BIT(1)); + + pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq); + + if (dramtype == DDR3 && vref_inner == 0x80) { + for (i = 0; i < 4; i++) + writel(vref_inner, + PHY_REG(phy_base, 0x118 + i * 0x10)); + + /* reg_rx_vref_value_update */ + setbits_le32(PHY_REG(phy_base, 0x71), 1 << 5); + clrbits_le32(PHY_REG(phy_base, 0x71), 1 << 5); + } + + return 0; +} + +static int data_training_wr(struct dram_info *dram, u32 cs, u32 dramtype, + u32 mhz, u32 dst_fsp) +{ + void __iomem *pctl_base = dram->pctl; + void __iomem *phy_base = dram->phy; + u32 trefi_1x, trfc_1x; + u32 dis_auto_zq = 0; + u32 timeout_us = 1000; + u32 cur_fsp; + u32 mr_tmp, cl, cwl, phy_fsp, offset = 0; + + if (dramtype == LPDDR3 && mhz <= 400) { + phy_fsp = (readl(PHY_REG(phy_base, 0xc)) >> 0x2) & 0x3; + offset = (phy_fsp == 0) ? 0x5 : 0x387 + (phy_fsp - 1) * 3; + cl = readl(PHY_REG(phy_base, offset)); + cwl = readl(PHY_REG(phy_base, offset + 2)); + + clrsetbits_le32(PHY_REG(phy_base, offset), 0x1f, 0x8); + clrsetbits_le32(PHY_REG(phy_base, offset + 2), 0x1f, 0x4); + pctl_write_mr(dram->pctl, 3, 2, 0x6, dramtype); + } + + dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl); + + /* PHY_0x7b[7:0] reg_train_col_addr[7:0] */ + clrsetbits_le32(PHY_REG(phy_base, 0x7b), 0xff, 0x0); + /* PHY_0x7c[4:2] reg_train_ba_addr[2:0] */ + clrsetbits_le32(PHY_REG(phy_base, 0x7c), 0x7 << 2, 0x0 << 2); + /* PHY_0x7c[1:0] reg_train_col_addr[9:8] */ + clrsetbits_le32(PHY_REG(phy_base, 0x7c), 0x3, 0x0); + /* PHY_0x7d[7:0] reg_train_row_addr[7:0] */ + clrsetbits_le32(PHY_REG(phy_base, 0x7d), 0xff, 0x0); + /* PHY_0x7e[7:0] reg_train_row_addr[15:8] */ + clrsetbits_le32(PHY_REG(phy_base, 0x7e), 0xff, 0x0); + + /* PHY_0x71[3] wrtrain_check_data_value_random_gen */ + clrbits_le32(PHY_REG(phy_base, 0x71), BIT(3)); + + /* config refresh timing */ + cur_fsp = readl(pctl_base + DDR_PCTL2_MSTR2) & 0x3; + trefi_1x = ((readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) + + DDR_PCTL2_RFSHTMG) >> 16) & 0xfff) * 32; + trfc_1x = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) + + DDR_PCTL2_RFSHTMG) & 0x3ff; + /* reg_phy_trefi[7:0] and reg_phy_trefi[13:8] */ + clrsetbits_le32(PHY_REG(phy_base, 0x6e), 0xff, trefi_1x & 0xff); + clrsetbits_le32(PHY_REG(phy_base, 0x6f), 0x3f, (trefi_1x >> 8) & 0x3f); + /* reg_phy_trfc */ + clrsetbits_le32(PHY_REG(phy_base, 0x57), 0xff, trfc_1x); + /* reg_max_refi_cnt */ + clrsetbits_le32(PHY_REG(phy_base, 0x61), 0xf << 4, 0x8 << 4); + + /* choose training cs */ + clrsetbits_le32(PHY_REG(phy_base, 0x7c), 0x3 << 6, (0x2 >> cs) << 6); + + /* PHY_0x7a [4] reg_wr_train_dqs_default_bypass */ + /* 0: Use the write-leveling value. */ + /* 1: use reg0x233 0x237 0x2b3 0x2b7 */ + setbits_le32(PHY_REG(phy_base, 0x7a), BIT(4)); + + /* PHY_0x7a [0] reg_dq_wr_train_auto */ + setbits_le32(PHY_REG(phy_base, 0x7a), 0x1); + + /* PHY_0x7a [1] reg_dq_wr_train_en */ + setbits_le32(PHY_REG(phy_base, 0x7a), BIT(1)); + + send_a_refresh(dram); + + while (1) { + if ((readl(PHY_REG(phy_base, 0x92)) >> 7) & 0x1) + break; + + udelay(1); + if (timeout_us-- == 0) { + printascii("error: write training timeout\n"); + while (1) + ; + } + } + + /* Check the write train state */ + if ((readl(PHY_REG(phy_base, 0x90)) >> 5) & 0x7) { + printascii("error: write training error\n"); + return -1; + } + + /* PHY_0x7a [1] reg_dq_wr_train_en */ + clrbits_le32(PHY_REG(phy_base, 0x7a), BIT(1)); + + pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq); + + /* save LPDDR4 write vref to fsp_param for dfs */ + if (dramtype == LPDDR4) { + fsp_param[dst_fsp].vref_dq[cs] = + ((readl(PHY_REG(phy_base, 0x384)) & 0x3f) + + (readl(PHY_REG(phy_base, 0x385)) & 0x3f)) / 2; + /* add range info */ + fsp_param[dst_fsp].vref_dq[cs] |= + ((readl(PHY_REG(phy_base, 0x7c)) & BIT(5)) << 1); + } + + if (dramtype == LPDDR3 && mhz <= 400) { + clrsetbits_le32(PHY_REG(phy_base, offset), 0x1f, cl); + clrsetbits_le32(PHY_REG(phy_base, offset + 2), 0x1f, cwl); + mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) + + DDR_PCTL2_INIT3); + pctl_write_mr(dram->pctl, 3, 2, mr_tmp & PCTL2_MR_MASK, + dramtype); + } + + return 0; +} + +static int data_training(struct dram_info *dram, u32 cs, + struct rv1126_sdram_params *sdram_params, u32 dst_fsp, + u32 training_flag) +{ + u32 ret = 0; + + if (training_flag == FULL_TRAINING) + training_flag = READ_GATE_TRAINING | WRITE_LEVELING | + WRITE_TRAINING | READ_TRAINING; + + if ((training_flag & WRITE_LEVELING) == WRITE_LEVELING) { + ret = data_training_wl(dram, cs, + sdram_params->base.dramtype, + sdram_params->ch.cap_info.rank); + if (ret != 0) + goto out; + } + + if ((training_flag & READ_GATE_TRAINING) == READ_GATE_TRAINING) { + ret = data_training_rg(dram, cs, + sdram_params->base.dramtype); + if (ret != 0) + goto out; + } + + if ((training_flag & READ_TRAINING) == READ_TRAINING) { + ret = data_training_rd(dram, cs, + sdram_params->base.dramtype, + sdram_params->base.ddr_freq); + if (ret != 0) + goto out; + } + + if ((training_flag & WRITE_TRAINING) == WRITE_TRAINING) { + ret = data_training_wr(dram, cs, + sdram_params->base.dramtype, + sdram_params->base.ddr_freq, dst_fsp); + if (ret != 0) + goto out; + } + +out: + return ret; +} + +static int get_wrlvl_val(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params) +{ + int i, j, clk_skew; + void __iomem *phy_base = dram->phy; + u32 lp_stat; + int ret; + + lp_stat = low_power_update(dram, 0); + + clk_skew = 0x1f; + modify_ca_deskew(dram, DESKEW_MDF_ABS_VAL, clk_skew, clk_skew, 3, + sdram_params->base.dramtype); + + ret = data_training(dram, 0, sdram_params, 0, WRITE_LEVELING); + if (sdram_params->ch.cap_info.rank == 2) + ret |= data_training(dram, 1, sdram_params, 0, WRITE_LEVELING); + + for (j = 0; j < 2; j++) + for (i = 0; i < 4; i++) + wrlvl_result[j][i] = + (readl(PHY_REG(phy_base, wrlvl_result_offset[j][i])) & 0x3f) - + clk_skew; + + low_power_update(dram, lp_stat); + + return ret; +} + +#if defined(CONFIG_CMD_DDR_TEST_TOOL) +static void init_rw_trn_result_struct(struct rw_trn_result *result, + void __iomem *phy_base, u8 cs_num) +{ + int i; + + result->cs_num = cs_num; + result->byte_en = readb(PHY_REG(dram_info.phy, 0xf)) & + PHY_DQ_WIDTH_MASK; + for (i = 0; i < FSP_NUM; i++) + result->fsp_mhz[i] = 0; +} + +static void save_rw_trn_min_max(void __iomem *phy_base, + struct cs_rw_trn_result *rd_result, + struct cs_rw_trn_result *wr_result, + u8 byte_en) +{ + u16 phy_ofs; + u8 dqs; + u8 dq; + + for (dqs = 0; dqs < BYTE_NUM; dqs++) { + if ((byte_en & BIT(dqs)) == 0) + continue; + + /* Channel A or B (low or high 16 bit) */ + phy_ofs = dqs < 2 ? 0x230 : 0x2b0; + /* low or high 8 bit */ + phy_ofs += (dqs & 0x1) == 0 ? 0 : 0x9; + for (dq = 0; dq < 8; dq++) { + rd_result->dqs[dqs].dq_min[dq] = + readb(PHY_REG(phy_base, phy_ofs + 0x15 + dq)); + rd_result->dqs[dqs].dq_max[dq] = + readb(PHY_REG(phy_base, phy_ofs + 0x27 + dq)); + wr_result->dqs[dqs].dq_min[dq] = + readb(PHY_REG(phy_base, phy_ofs + 0x3d + dq)); + wr_result->dqs[dqs].dq_max[dq] = + readb(PHY_REG(phy_base, phy_ofs + 0x4f + dq)); + } + } +} + +static void save_rw_trn_deskew(void __iomem *phy_base, + struct fsp_rw_trn_result *result, u8 cs_num, + int min_val, bool rw) +{ + u16 phy_ofs; + u8 cs; + u8 dq; + + result->min_val = min_val; + + for (cs = 0; cs < cs_num; cs++) { + phy_ofs = cs == 0 ? 0x170 : 0x1a0; + phy_ofs += rw == SKEW_RX_SIGNAL ? 0x1 : 0x17; + for (dq = 0; dq < 8; dq++) { + result->cs[cs].dqs[0].dq_deskew[dq] = + readb(PHY_REG(phy_base, phy_ofs + dq)); + result->cs[cs].dqs[1].dq_deskew[dq] = + readb(PHY_REG(phy_base, phy_ofs + 0xb + dq)); + result->cs[cs].dqs[2].dq_deskew[dq] = + readb(PHY_REG(phy_base, phy_ofs + 0x60 + dq)); + result->cs[cs].dqs[3].dq_deskew[dq] = + readb(PHY_REG(phy_base, phy_ofs + 0x60 + 0xb + dq)); + } + + result->cs[cs].dqs[0].dqs_deskew = + readb(PHY_REG(phy_base, phy_ofs + 0x8)); + result->cs[cs].dqs[1].dqs_deskew = + readb(PHY_REG(phy_base, phy_ofs + 0xb + 0x8)); + result->cs[cs].dqs[2].dqs_deskew = + readb(PHY_REG(phy_base, phy_ofs + 0x60 + 0x8)); + result->cs[cs].dqs[3].dqs_deskew = + readb(PHY_REG(phy_base, phy_ofs + 0x60 + 0xb + 0x8)); + } +} + +static void save_rw_trn_result_to_ddr(struct rw_trn_result *result) +{ + result->flag = DDR_DQ_EYE_FLAG; + memcpy((void *)(RW_TRN_RESULT_ADDR), result, sizeof(*result)); +} +#endif + +static int high_freq_training(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params, + u32 fsp) +{ + u32 i, j; + void __iomem *phy_base = dram->phy; + u32 dramtype = sdram_params->base.dramtype; + int min_val; + int dqs_skew, clk_skew, ca_skew; + u8 byte_en; + int ret; + + byte_en = readl(PHY_REG(phy_base, 0xf)) & PHY_DQ_WIDTH_MASK; + dqs_skew = 0; + for (j = 0; j < sdram_params->ch.cap_info.rank; j++) { + for (i = 0; i < ARRAY_SIZE(wrlvl_result[0]); i++) { + if ((byte_en & BIT(i)) != 0) + dqs_skew += wrlvl_result[j][i]; + } + } + dqs_skew = dqs_skew / + (int)(sdram_params->ch.cap_info.rank * (1 << sdram_params->ch.cap_info.bw)); + + clk_skew = 0x20 - dqs_skew; + dqs_skew = 0x20; + + if (dramtype == LPDDR4) { + min_val = 0xff; + for (j = 0; j < sdram_params->ch.cap_info.rank; j++) + for (i = 0; i < sdram_params->ch.cap_info.bw; i++) + min_val = MIN(wrlvl_result[j][i], min_val); + + if (min_val < 0) { + clk_skew = -min_val; + ca_skew = -min_val; + } else { + clk_skew = 0; + ca_skew = 0; + } + } else if (dramtype == LPDDR3) { + ca_skew = clk_skew - 4; + } else { + ca_skew = clk_skew; + } + modify_ca_deskew(dram, DESKEW_MDF_ABS_VAL, clk_skew, ca_skew, 3, + dramtype); + + writel(wrlvl_result[0][0] + clk_skew, PHY_REG(phy_base, 0x233)); + writel(wrlvl_result[0][1] + clk_skew, PHY_REG(phy_base, 0x237)); + writel(wrlvl_result[0][2] + clk_skew, PHY_REG(phy_base, 0x2b3)); + writel(wrlvl_result[0][3] + clk_skew, PHY_REG(phy_base, 0x2b7)); + ret = data_training(dram, 0, sdram_params, fsp, READ_GATE_TRAINING | + READ_TRAINING | WRITE_TRAINING); +#if defined(CONFIG_CMD_DDR_TEST_TOOL) + rw_trn_result.fsp_mhz[fsp] = (u16)sdram_params->base.ddr_freq; + save_rw_trn_min_max(phy_base, &rw_trn_result.rd_fsp[fsp].cs[0], + &rw_trn_result.wr_fsp[fsp].cs[0], + rw_trn_result.byte_en); +#endif + if (sdram_params->ch.cap_info.rank == 2) { + writel(wrlvl_result[1][0] + clk_skew, PHY_REG(phy_base, 0x233)); + writel(wrlvl_result[1][1] + clk_skew, PHY_REG(phy_base, 0x237)); + writel(wrlvl_result[1][2] + clk_skew, PHY_REG(phy_base, 0x2b3)); + writel(wrlvl_result[1][3] + clk_skew, PHY_REG(phy_base, 0x2b7)); + ret |= data_training(dram, 1, sdram_params, fsp, + READ_GATE_TRAINING | READ_TRAINING | + WRITE_TRAINING); +#if defined(CONFIG_CMD_DDR_TEST_TOOL) + save_rw_trn_min_max(phy_base, &rw_trn_result.rd_fsp[fsp].cs[1], + &rw_trn_result.wr_fsp[fsp].cs[1], + rw_trn_result.byte_en); +#endif + } + if (ret) + goto out; + + record_dq_prebit(dram); + + min_val = get_min_value(dram, SKEW_RX_SIGNAL, + sdram_params->ch.cap_info.rank) * -1; + modify_dq_deskew(dram, SKEW_RX_SIGNAL, DESKEW_MDF_DIFF_VAL, + min_val, min_val, sdram_params->ch.cap_info.rank); +#if defined(CONFIG_CMD_DDR_TEST_TOOL) + save_rw_trn_deskew(phy_base, &rw_trn_result.rd_fsp[fsp], + rw_trn_result.cs_num, (u8)(min_val * (-1)), + SKEW_RX_SIGNAL); +#endif + + min_val = MIN(get_min_value(dram, SKEW_TX_SIGNAL, + sdram_params->ch.cap_info.rank), + get_min_value(dram, SKEW_CA_SIGNAL, + sdram_params->ch.cap_info.rank)) * -1; + + /* clk = 0, rx all skew -7, tx - min_value */ + modify_ca_deskew(dram, DESKEW_MDF_DIFF_VAL, min_val, min_val, 3, + dramtype); + + modify_dq_deskew(dram, SKEW_TX_SIGNAL, DESKEW_MDF_DIFF_VAL, + min_val, min_val, sdram_params->ch.cap_info.rank); +#if defined(CONFIG_CMD_DDR_TEST_TOOL) + save_rw_trn_deskew(phy_base, &rw_trn_result.wr_fsp[fsp], + rw_trn_result.cs_num, (u8)(min_val * (-1)), + SKEW_TX_SIGNAL); +#endif + + ret = data_training(dram, 0, sdram_params, 0, READ_GATE_TRAINING); + if (sdram_params->ch.cap_info.rank == 2) + ret |= data_training(dram, 1, sdram_params, 0, + READ_GATE_TRAINING); +out: + return ret; +} + +static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig) +{ + writel(ddrconfig, &dram->msch->deviceconf); + clrsetbits_le32(&dram->grf->noc_con0, 0x3 << 0, 0 << 0); +} + +static void update_noc_timing(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params) +{ + void __iomem *pctl_base = dram->pctl; + u32 bw, bl; + + bw = 8 << sdram_params->ch.cap_info.bw; + bl = ((readl(pctl_base + DDR_PCTL2_MSTR) >> 16) & 0xf) * 2; + + /* update the noc timing related to data bus width */ + if ((bw / 8 * bl) <= 16) + sdram_params->ch.noc_timings.ddrmode.b.burstsize = 0; + else if ((bw / 8 * bl) == 32) + sdram_params->ch.noc_timings.ddrmode.b.burstsize = 1; + else if ((bw / 8 * bl) == 64) + sdram_params->ch.noc_timings.ddrmode.b.burstsize = 2; + else + sdram_params->ch.noc_timings.ddrmode.b.burstsize = 3; + + sdram_params->ch.noc_timings.ddrtimingc0.b.burstpenalty = + (bl * bw / 8) > 16 ? (bl / 4) : (16 / (bl * bw / 8)) * bl / 4; + + if (sdram_params->base.dramtype == LPDDR4) { + sdram_params->ch.noc_timings.ddrmode.b.mwrsize = + (bw == 16) ? 0x1 : 0x2; + sdram_params->ch.noc_timings.ddrtimingc0.b.wrtomwr = + 3 * sdram_params->ch.noc_timings.ddrtimingc0.b.burstpenalty; + } + + writel(sdram_params->ch.noc_timings.ddrtiminga0.d32, + &dram->msch->ddrtiminga0); + writel(sdram_params->ch.noc_timings.ddrtimingb0.d32, + &dram->msch->ddrtimingb0); + writel(sdram_params->ch.noc_timings.ddrtimingc0.d32, + &dram->msch->ddrtimingc0); + writel(sdram_params->ch.noc_timings.devtodev0.d32, + &dram->msch->devtodev0); + writel(sdram_params->ch.noc_timings.ddrmode.d32, &dram->msch->ddrmode); + writel(sdram_params->ch.noc_timings.ddr4timing.d32, + &dram->msch->ddr4timing); +} + +static int split_setup(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params) +{ + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info; + u32 dramtype = sdram_params->base.dramtype; + u32 split_size, split_mode; + u64 cs_cap[2], cap; + + cs_cap[0] = sdram_get_cs_cap(cap_info, 0, dramtype); + cs_cap[1] = sdram_get_cs_cap(cap_info, 1, dramtype); + /* only support the larger cap is in low 16bit */ + if (cap_info->cs0_high16bit_row < cap_info->cs0_row) { + cap = cs_cap[0] / (1 << (cap_info->cs0_row - + cap_info->cs0_high16bit_row)); + } else if ((cap_info->cs1_high16bit_row < cap_info->cs1_row) && + (cap_info->rank == 2)) { + if (!cap_info->cs1_high16bit_row) + cap = cs_cap[0]; + else + cap = cs_cap[0] + cs_cap[1] / (1 << (cap_info->cs1_row - + cap_info->cs1_high16bit_row)); + } else { + goto out; + } + split_size = (u32)(cap >> 24) & SPLIT_SIZE_MASK; + if (cap_info->bw == 2) + split_mode = SPLIT_MODE_32_L16_VALID; + else + split_mode = SPLIT_MODE_16_L8_VALID; + + rk_clrsetreg(&dram->ddrgrf->grf_ddrsplit_con, + (SPLIT_MODE_MASK << SPLIT_MODE_OFFSET) | + (SPLIT_BYPASS_MASK << SPLIT_BYPASS_OFFSET) | + (SPLIT_SIZE_MASK << SPLIT_SIZE_OFFSET), + (split_mode << SPLIT_MODE_OFFSET) | + (0x0 << SPLIT_BYPASS_OFFSET) | + (split_size << SPLIT_SIZE_OFFSET)); + + rk_clrsetreg(BUS_SGRF_BASE_ADDR + SGRF_SOC_CON2, + MSCH_AXI_BYPASS_ALL_MASK << MSCH_AXI_BYPASS_ALL_SHIFT, + 0x0 << MSCH_AXI_BYPASS_ALL_SHIFT); + +out: + return 0; +} + +static void split_bypass(struct dram_info *dram) +{ + if ((readl(&dram->ddrgrf->grf_ddrsplit_con) & + (1 << SPLIT_BYPASS_OFFSET)) != 0) + return; + + /* bypass split */ + rk_clrsetreg(&dram->ddrgrf->grf_ddrsplit_con, + (SPLIT_BYPASS_MASK << SPLIT_BYPASS_OFFSET) | + (SPLIT_SIZE_MASK << SPLIT_SIZE_OFFSET), + (0x1 << SPLIT_BYPASS_OFFSET) | + (0x0 << SPLIT_SIZE_OFFSET)); +} + +static void dram_all_config(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params) +{ + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info; + u32 dram_type = sdram_params->base.dramtype; + void __iomem *pctl_base = dram->pctl; + u32 sys_reg2 = 0; + u32 sys_reg3 = 0; + u64 cs_cap[2]; + u32 cs_pst; + + set_ddrconfig(dram, cap_info->ddrconfig); + sdram_org_config(cap_info, &sdram_params->base, &sys_reg2, + &sys_reg3, 0); + writel(sys_reg2, &dram->pmugrf->os_reg[2]); + writel(sys_reg3, &dram->pmugrf->os_reg[3]); + + cs_cap[0] = sdram_get_cs_cap(cap_info, 0, dram_type); + cs_cap[1] = sdram_get_cs_cap(cap_info, 1, dram_type); + + if (cap_info->rank == 2) { + cs_pst = (readl(pctl_base + DDR_PCTL2_ADDRMAP0) & 0x1f) + + 6 + 2; + if (cs_pst > 28) + cs_cap[0] = 1llu << cs_pst; + } + + writel(((((cs_cap[1] >> 20) / 64) & 0xff) << 8) | + (((cs_cap[0] >> 20) / 64) & 0xff), + &dram->msch->devicesize); + update_noc_timing(dram, sdram_params); +} + +static void enable_low_power(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params) +{ + void __iomem *pctl_base = dram->pctl; + u32 grf_lp_con; + + writel(0x1f1f0617, &dram->ddrgrf->ddr_grf_con[1]); + + if (sdram_params->base.dramtype == DDR4) + grf_lp_con = (0x7 << 16) | (1 << 1); + else if (sdram_params->base.dramtype == DDR3) + grf_lp_con = (0x7 << 16) | (1 << 0); + else + grf_lp_con = (0x7 << 16) | (1 << 2); + + /* en lpckdis_en */ + grf_lp_con = grf_lp_con | (0x1 << (9 + 16)) | (0x1 << 9); + writel(grf_lp_con, &dram->ddrgrf->ddr_grf_lp_con); + + /* enable sr, pd */ + if (dram->pd_idle == 0) + clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1)); + else + setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1)); + if (dram->sr_idle == 0) + clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1); + else + setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1); + setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 3)); +} + +static void print_ddr_info(struct rv1126_sdram_params *sdram_params) +{ + u32 split; + + if ((readl(DDR_GRF_BASE_ADDR + DDR_GRF_SPLIT_CON) & + (1 << SPLIT_BYPASS_OFFSET)) != 0) + split = 0; + else + split = readl(DDR_GRF_BASE_ADDR + DDR_GRF_SPLIT_CON) & + SPLIT_SIZE_MASK; + + sdram_print_ddr_info(&sdram_params->ch.cap_info, + &sdram_params->base, split); +} + +static int sdram_init_(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params, u32 post_init) +{ + void __iomem *pctl_base = dram->pctl; + void __iomem *phy_base = dram->phy; + u32 ddr4_vref; + u32 mr_tmp; + + rkclk_configure_ddr(dram, sdram_params); + + rkclk_ddr_reset(dram, 1, 1, 1, 1); + udelay(10); + + rkclk_ddr_reset(dram, 1, 1, 1, 0); + phy_cfg(dram, sdram_params); + + rkclk_ddr_reset(dram, 1, 1, 0, 0); + phy_pll_set(dram, sdram_params->base.ddr_freq * MHZ, 1); + + rkclk_ddr_reset(dram, 1, 0, 0, 0); + pctl_cfg(dram->pctl, &sdram_params->pctl_regs, + dram->sr_idle, dram->pd_idle); + + if (sdram_params->ch.cap_info.bw == 2) { + /* 32bit interface use pageclose */ + setbits_le32(pctl_base + DDR_PCTL2_SCHED, 1 << 2); + /* pageclose = 1, pageclose_timer = 0 will err in lp4 328MHz */ + clrsetbits_le32(pctl_base + DDR_PCTL2_SCHED1, 0xff, 0x1 << 0); + } else { + clrbits_le32(pctl_base + DDR_PCTL2_SCHED, 1 << 2); + } + +#ifdef CONFIG_ROCKCHIP_DRAM_EXTENDED_TEMP_SUPPORT + u32 tmp, trefi; + + tmp = readl(pctl_base + DDR_PCTL2_RFSHTMG); + trefi = (tmp >> 16) & 0xfff; + writel((tmp & 0xf000ffff) | (trefi / 2) << 16, + pctl_base + DDR_PCTL2_RFSHTMG); +#endif + + /* set frequency_mode */ + setbits_le32(pctl_base + DDR_PCTL2_MSTR, 0x1 << 29); + /* set target_frequency to Frequency 0 */ + clrsetbits_le32(pctl_base + DDR_PCTL2_MSTR2, 0x3, 0); + + set_ds_odt(dram, sdram_params, 0); + sdram_params->ch.cap_info.ddrconfig = calculate_ddrconfig(sdram_params); + set_ctl_address_map(dram, sdram_params); + + setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4)); + + rkclk_ddr_reset(dram, 0, 0, 0, 0); + + while ((readl(pctl_base + DDR_PCTL2_STAT) & 0x7) == 0) + continue; + + if (sdram_params->base.dramtype == LPDDR3) { + pctl_write_mr(dram->pctl, 3, 11, lp3_odt_value, LPDDR3); + } else if (sdram_params->base.dramtype == LPDDR4) { + mr_tmp = readl(pctl_base + DDR_PCTL2_INIT6); + /* MR11 */ + pctl_write_mr(dram->pctl, 3, 11, + mr_tmp >> PCTL2_LPDDR4_MR11_SHIFT & PCTL2_MR_MASK, + LPDDR4); + /* MR12 */ + pctl_write_mr(dram->pctl, 3, 12, + mr_tmp >> PCTL2_LPDDR4_MR12_SHIFT & PCTL2_MR_MASK, + LPDDR4); + + mr_tmp = readl(pctl_base + DDR_PCTL2_INIT7); + /* MR22 */ + pctl_write_mr(dram->pctl, 3, 22, + mr_tmp >> PCTL2_LPDDR4_MR22_SHIFT & PCTL2_MR_MASK, + LPDDR4); + } + + if (data_training(dram, 0, sdram_params, 0, READ_GATE_TRAINING) != 0) { + if (post_init != 0) + printascii("DTT cs0 error\n"); + return -1; + } + + if (sdram_params->base.dramtype == LPDDR4) { + mr_tmp = read_mr(dram, 1, 14, LPDDR4); + + if (mr_tmp != 0x4d) + return -1; + } + + if (sdram_params->base.dramtype == LPDDR4) { + mr_tmp = readl(pctl_base + DDR_PCTL2_INIT7); + /* MR14 */ + pctl_write_mr(dram->pctl, 3, 14, + mr_tmp >> PCTL2_LPDDR4_MR14_SHIFT & PCTL2_MR_MASK, + LPDDR4); + } + if (post_init != 0 && sdram_params->ch.cap_info.rank == 2) { + if (data_training(dram, 1, sdram_params, 0, + READ_GATE_TRAINING) != 0) { + printascii("DTT cs1 error\n"); + return -1; + } + } + + if (sdram_params->base.dramtype == DDR4) { + ddr4_vref = readl(PHY_REG(phy_base, 0x105)) * 39; + pctl_write_vrefdq(dram->pctl, 0x3, ddr4_vref, + sdram_params->base.dramtype); + } + + dram_all_config(dram, sdram_params); + enable_low_power(dram, sdram_params); + + return 0; +} + +static u64 dram_detect_cap(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params, + unsigned char channel) +{ + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info; + void __iomem *pctl_base = dram->pctl; + void __iomem *phy_base = dram->phy; + u32 mr8; + + u32 bktmp; + u32 coltmp; + u32 rowtmp; + u32 cs; + u32 dram_type = sdram_params->base.dramtype; + u32 pwrctl; + u32 i, dq_map; + u32 byte1 = 0, byte0 = 0; + u32 tmp, byte; + struct sdram_head_info_index_v2 *index = (struct sdram_head_info_index_v2 *)common_info; + struct dq_map_info *map_info = (struct dq_map_info *) + ((void *)common_info + index->dq_map_index.offset * 4); + + cap_info->bw = dram_type == DDR3 ? 0 : 1; + if (dram_type != LPDDR4) { + if (dram_type != DDR4) { + coltmp = 12; + bktmp = 3; + if (dram_type == LPDDR2) + rowtmp = 15; + else + rowtmp = 16; + + if (sdram_detect_col(cap_info, coltmp) != 0) + goto cap_err; + + sdram_detect_bank(cap_info, coltmp, bktmp); + if (dram_type != LPDDR3) + sdram_detect_dbw(cap_info, dram_type); + } else { + coltmp = 10; + bktmp = 4; + rowtmp = 17; + + cap_info->col = 10; + cap_info->bk = 2; + sdram_detect_bg(cap_info, coltmp); + } + + if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0) + goto cap_err; + + sdram_detect_row_3_4(cap_info, coltmp, bktmp); + } else { + cap_info->col = 10; + cap_info->bk = 3; + mr8 = read_mr(dram, 1, 8, dram_type); + cap_info->dbw = ((mr8 >> 6) & 0x3) == 0 ? 1 : 0; + mr8 = (mr8 >> 2) & 0xf; + if (mr8 >= 0 && mr8 <= 6) { + cap_info->cs0_row = 14 + (mr8 + 1) / 2; + } else if (mr8 == 0xc) { + cap_info->cs0_row = 13; + } else { + printascii("Cap ERR: Fail to get cap of LPDDR4/X from MR8\n"); + goto cap_err; + } + if (cap_info->dbw == 0) + cap_info->cs0_row++; + cap_info->row_3_4 = mr8 % 2 == 1 ? 1 : 0; + if (cap_info->cs0_row >= 17) { + printascii("Cap ERR: "); + printascii("RV1126 LPDDR4/X cannot support row >= 17\n"); + goto cap_err; + // cap_info->cs0_row = 16; + // cap_info->row_3_4 = 0; + } + } + + pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL); + writel(0, pctl_base + DDR_PCTL2_PWRCTL); + + if (data_training(dram, 1, sdram_params, 0, READ_GATE_TRAINING) == 0) + cs = 1; + else + cs = 0; + cap_info->rank = cs + 1; + + setbits_le32(PHY_REG(phy_base, 0xf), 0xf); + + tmp = data_training_rg(dram, 0, dram_type) & 0xf; + + if (tmp == 0) { + cap_info->bw = 2; + } else { + if (dram_type == DDR3 || dram_type == DDR4) { + dq_map = 0; + byte = 0; + for (i = 0; i < 4; i++) { + if ((tmp & BIT(i)) == 0) { + dq_map |= byte << (i * 2); + byte++; + } + } + cap_info->bw = byte / 2; + for (i = 0; i < 4; i++) { + if ((tmp & BIT(i)) != 0) { + dq_map |= byte << (i * 2); + byte++; + } + } + clrsetbits_le32(&map_info->byte_map[0], 0xff << 24, dq_map << 24); + } else { + dq_map = readl(PHY_REG(phy_base, 0x4f)); + for (i = 0; i < 4; i++) { + if (((dq_map >> (i * 2)) & 0x3) == 0) + byte0 = i; + if (((dq_map >> (i * 2)) & 0x3) == 1) + byte1 = i; + } + clrsetbits_le32(PHY_REG(phy_base, 0xf), PHY_DQ_WIDTH_MASK, + BIT(byte0) | BIT(byte1)); + if (data_training(dram, 0, sdram_params, 0, READ_GATE_TRAINING) == 0) + cap_info->bw = 1; + else + cap_info->bw = 0; + } + } + if (cap_info->bw > 0) + cap_info->dbw = 1; + + writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL); + + cap_info->cs0_high16bit_row = cap_info->cs0_row; + if (cs) { + cap_info->cs1_row = cap_info->cs0_row; + cap_info->cs1_high16bit_row = cap_info->cs0_row; + } else { + cap_info->cs1_row = 0; + cap_info->cs1_high16bit_row = 0; + } + + if (dram_type == LPDDR3) + sdram_detect_dbw(cap_info, dram_type); + + return 0; +cap_err: + return -1; +} + +static int dram_detect_cs1_row(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params, + unsigned char channel) +{ + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info; + void __iomem *pctl_base = dram->pctl; + u32 ret = 0; + void __iomem *test_addr; + u32 row, bktmp, coltmp, bw; + u64 cs0_cap; + u32 byte_mask; + u32 cs_pst; + u32 cs_add = 0; + u32 max_row; + + if (cap_info->rank == 2) { + cs_pst = (readl(pctl_base + DDR_PCTL2_ADDRMAP0) & 0x1f) + + 6 + 2; + if (cs_pst < 28) + cs_add = 1; + + cs0_cap = 1 << cs_pst; + + if (sdram_params->base.dramtype == DDR4) { + if (cap_info->dbw == 0) + bktmp = cap_info->bk + 2; + else + bktmp = cap_info->bk + 1; + } else { + bktmp = cap_info->bk; + } + bw = cap_info->bw; + coltmp = cap_info->col; + + if (bw == 2) + byte_mask = 0xFFFF; + else + byte_mask = 0xFF; + + max_row = (cs_pst == 31) ? 30 : 31; + + max_row = max_row - bktmp - coltmp - bw - cs_add + 1; + + row = (cap_info->cs0_row > max_row) ? max_row : + cap_info->cs0_row; + + for (; row > 12; row--) { + test_addr = (void __iomem *)(CFG_SYS_SDRAM_BASE + + (u32)cs0_cap + + (1ul << (row + bktmp + coltmp + + cs_add + bw - 1ul))); + + writel(0, CFG_SYS_SDRAM_BASE + (u32)cs0_cap); + writel(PATTERN, test_addr); + + if (((readl(test_addr) & byte_mask) == + (PATTERN & byte_mask)) && + ((readl(CFG_SYS_SDRAM_BASE + (u32)cs0_cap) & + byte_mask) == 0)) { + ret = row; + break; + } + } + } + + return ret; +} + +/* return: 0 = success, other = fail */ +static int sdram_init_detect(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params) +{ + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info; + u32 ret; + u32 sys_reg = 0; + u32 sys_reg3 = 0; + struct sdram_head_info_index_v2 *index = + (struct sdram_head_info_index_v2 *)common_info; + struct dq_map_info *map_info; + + map_info = (struct dq_map_info *)((void *)common_info + + index->dq_map_index.offset * 4); + + if (sdram_init_(dram, sdram_params, 0)) { + if (sdram_params->base.dramtype == DDR3) { + clrsetbits_le32(&map_info->byte_map[0], 0xff << 24, + ((0x1 << 6) | (0x3 << 4) | (0x2 << 2) | + (0x0 << 0)) << 24); + if (sdram_init_(dram, sdram_params, 0)) + return -1; + } else { + return -1; + } + } + + if (sdram_params->base.dramtype == DDR3) { + writel(PATTERN, CFG_SYS_SDRAM_BASE); + if (readl(CFG_SYS_SDRAM_BASE) != PATTERN) + return -1; + } + + split_bypass(dram); + if (dram_detect_cap(dram, sdram_params, 0) != 0) + return -1; + + pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info, + sdram_params->base.dramtype); + ret = sdram_init_(dram, sdram_params, 1); + if (ret != 0) + goto out; + + cap_info->cs1_row = + dram_detect_cs1_row(dram, sdram_params, 0); + if (cap_info->cs1_row) { + sys_reg = readl(&dram->pmugrf->os_reg[2]); + sys_reg3 = readl(&dram->pmugrf->os_reg[3]); + SYS_REG_ENC_CS1_ROW(cap_info->cs1_row, + sys_reg, sys_reg3, 0); + writel(sys_reg, &dram->pmugrf->os_reg[2]); + writel(sys_reg3, &dram->pmugrf->os_reg[3]); + } + + sdram_detect_high_row(cap_info); + split_setup(dram, sdram_params); +out: + return ret; +} + +struct rv1126_sdram_params *get_default_sdram_config(u32 freq_mhz) +{ + u32 i; + u32 offset = 0; + struct ddr2_3_4_lp2_3_info *ddr_info; + + if (!freq_mhz) { + ddr_info = get_ddr_drv_odt_info(sdram_configs[0].base.dramtype); + if (ddr_info) + freq_mhz = + (ddr_info->ddr_freq0_1 >> DDR_FREQ_F0_SHIFT) & + DDR_FREQ_MASK; + else + freq_mhz = 0; + } + + for (i = 0; i < ARRAY_SIZE(sdram_configs); i++) { + if (sdram_configs[i].base.ddr_freq == 0 || + freq_mhz < sdram_configs[i].base.ddr_freq) + break; + } + offset = i == 0 ? 0 : i - 1; + + return &sdram_configs[offset]; +} + +static const u16 pctl_need_update_reg[] = { + DDR_PCTL2_RFSHTMG, + DDR_PCTL2_INIT3, + DDR_PCTL2_INIT4, + DDR_PCTL2_INIT6, + DDR_PCTL2_INIT7, + DDR_PCTL2_DRAMTMG0, + DDR_PCTL2_DRAMTMG1, + DDR_PCTL2_DRAMTMG2, + DDR_PCTL2_DRAMTMG3, + DDR_PCTL2_DRAMTMG4, + DDR_PCTL2_DRAMTMG5, + DDR_PCTL2_DRAMTMG6, + DDR_PCTL2_DRAMTMG7, + DDR_PCTL2_DRAMTMG8, + DDR_PCTL2_DRAMTMG9, + DDR_PCTL2_DRAMTMG12, + DDR_PCTL2_DRAMTMG13, + DDR_PCTL2_DRAMTMG14, + DDR_PCTL2_ZQCTL0, + DDR_PCTL2_DFITMG0, + DDR_PCTL2_ODTCFG +}; + +static const u16 phy_need_update_reg[] = { + 0x14, + 0x18, + 0x1c +}; + +static void pre_set_rate(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params, + u32 dst_fsp, u32 dst_fsp_lp4) +{ + u32 i, j, find; + void __iomem *pctl_base = dram->pctl; + void __iomem *phy_base = dram->phy; + u32 phy_offset; + u32 mr_tmp; + u32 dramtype = sdram_params->base.dramtype; + + sw_set_req(dram); + /* pctl timing update */ + for (i = 0, find = 0; i < ARRAY_SIZE(pctl_need_update_reg); i++) { + for (j = find; sdram_params->pctl_regs.pctl[j][0] != 0xFFFFFFFF; + j++) { + if (sdram_params->pctl_regs.pctl[j][0] == + pctl_need_update_reg[i]) { + writel(sdram_params->pctl_regs.pctl[j][1], + pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + pctl_need_update_reg[i]); + find = j; + break; + } + } + } + +#ifdef CONFIG_ROCKCHIP_DRAM_EXTENDED_TEMP_SUPPORT + u32 tmp, trefi; + + tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + DDR_PCTL2_RFSHTMG); + trefi = (tmp >> 16) & 0xfff; + writel((tmp & 0xf000ffff) | (trefi / 2) << 16, + pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + DDR_PCTL2_RFSHTMG); +#endif + + sw_set_ack(dram); + + /* phy timing update */ + if (dst_fsp == 0) + phy_offset = 0; + else + phy_offset = PHY_REG(0, 0x387 - 5 + (dst_fsp - 1) * 3); + /* cl cwl al update */ + for (i = 0, find = 0; i < ARRAY_SIZE(phy_need_update_reg); i++) { + for (j = find; sdram_params->phy_regs.phy[j][0] != 0xFFFFFFFF; + j++) { + if (sdram_params->phy_regs.phy[j][0] == + phy_need_update_reg[i]) { + writel(sdram_params->phy_regs.phy[j][1], + phy_base + phy_offset + + phy_need_update_reg[i]); + find = j; + break; + } + } + } + + set_ds_odt(dram, sdram_params, dst_fsp); + if (dramtype == LPDDR4) { + mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT4); + /* MR13 */ + pctl_write_mr(dram->pctl, 3, 13, + ((mr_tmp >> PCTL2_LPDDR4_MR13_SHIFT & + PCTL2_MR_MASK) & (~(BIT(7) | BIT(6)))) | + ((0x2 << 6) >> dst_fsp_lp4), dramtype); + writel(((mr_tmp >> PCTL2_LPDDR4_MR13_SHIFT & + PCTL2_MR_MASK) & (~(BIT(7) | BIT(6)))) | + ((0x2 << 6) >> dst_fsp_lp4), + PHY_REG(phy_base, 0x1b)); + /* MR3 */ + pctl_write_mr(dram->pctl, 3, 3, + mr_tmp >> PCTL2_LPDDR234_MR3_SHIFT & + PCTL2_MR_MASK, + dramtype); + writel(mr_tmp >> PCTL2_LPDDR234_MR3_SHIFT & PCTL2_MR_MASK, + PHY_REG(phy_base, 0x19)); + + mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT3); + /* MR1 */ + pctl_write_mr(dram->pctl, 3, 1, + mr_tmp >> PCTL2_LPDDR234_MR1_SHIFT & + PCTL2_MR_MASK, + dramtype); + writel(mr_tmp >> PCTL2_LPDDR234_MR1_SHIFT & PCTL2_MR_MASK, + PHY_REG(phy_base, 0x17)); + /* MR2 */ + pctl_write_mr(dram->pctl, 3, 2, mr_tmp & PCTL2_MR_MASK, + dramtype); + writel(mr_tmp & PCTL2_MR_MASK, + PHY_REG(phy_base, 0x18)); + + mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT6); + /* MR11 */ + pctl_write_mr(dram->pctl, 3, 11, + mr_tmp >> PCTL2_LPDDR4_MR11_SHIFT & PCTL2_MR_MASK, + dramtype); + writel(mr_tmp >> PCTL2_LPDDR4_MR11_SHIFT & PCTL2_MR_MASK, + PHY_REG(phy_base, 0x1a)); + /* MR12 */ + pctl_write_mr(dram->pctl, 3, 12, + mr_tmp >> PCTL2_LPDDR4_MR12_SHIFT & PCTL2_MR_MASK, + dramtype); + + mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT7); + /* MR22 */ + pctl_write_mr(dram->pctl, 3, 22, + mr_tmp >> PCTL2_LPDDR4_MR22_SHIFT & PCTL2_MR_MASK, + dramtype); + writel(mr_tmp >> PCTL2_LPDDR4_MR22_SHIFT & PCTL2_MR_MASK, + PHY_REG(phy_base, 0x1d)); + /* MR14 */ + pctl_write_mr(dram->pctl, 3, 14, + mr_tmp >> PCTL2_LPDDR4_MR14_SHIFT & PCTL2_MR_MASK, + dramtype); + writel(mr_tmp >> PCTL2_LPDDR4_MR14_SHIFT & PCTL2_MR_MASK, + PHY_REG(phy_base, 0x1c)); + } + + update_noc_timing(dram, sdram_params); +} + +static void save_fsp_param(struct dram_info *dram, u32 dst_fsp, + struct rv1126_sdram_params *sdram_params) +{ + void __iomem *pctl_base = dram->pctl; + void __iomem *phy_base = dram->phy; + struct rv1126_fsp_param *p_fsp_param = &fsp_param[dst_fsp]; + u32 temp, temp1; + struct ddr2_3_4_lp2_3_info *ddr_info; + + ddr_info = get_ddr_drv_odt_info(sdram_params->base.dramtype); + + p_fsp_param->freq_mhz = sdram_params->base.ddr_freq; + + if (sdram_params->base.dramtype == LPDDR4) { + p_fsp_param->rd_odt_up_en = 0; + p_fsp_param->rd_odt_down_en = 1; + } else { + p_fsp_param->rd_odt_up_en = + ODT_INFO_PULLUP_EN(ddr_info->odt_info); + p_fsp_param->rd_odt_down_en = + ODT_INFO_PULLDOWN_EN(ddr_info->odt_info); + } + + if (p_fsp_param->rd_odt_up_en) + p_fsp_param->rd_odt = readl(PHY_REG(phy_base, 0x111)); + else if (p_fsp_param->rd_odt_down_en) + p_fsp_param->rd_odt = readl(PHY_REG(phy_base, 0x110)); + else + p_fsp_param->rd_odt = 0; + p_fsp_param->wr_dq_drv = readl(PHY_REG(phy_base, 0x112)); + p_fsp_param->wr_ca_drv = readl(PHY_REG(phy_base, 0x100)); + p_fsp_param->wr_ckcs_drv = readl(PHY_REG(phy_base, 0x102)); + p_fsp_param->vref_inner = readl(PHY_REG(phy_base, 0x128)); + p_fsp_param->vref_out = readl(PHY_REG(phy_base, 0x105)); + + if (sdram_params->base.dramtype == DDR3) { + temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT3); + temp = (temp >> PCTL2_DDR34_MR1_SHIFT) & PCTL2_MR_MASK; + p_fsp_param->ds_pdds = temp & DDR3_DS_MASK; + p_fsp_param->dq_odt = temp & DDR3_RTT_NOM_MASK; + p_fsp_param->ca_odt = p_fsp_param->dq_odt; + } else if (sdram_params->base.dramtype == DDR4) { + temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT3); + temp = (temp >> PCTL2_DDR34_MR1_SHIFT) & PCTL2_MR_MASK; + p_fsp_param->ds_pdds = temp & DDR4_DS_MASK; + p_fsp_param->dq_odt = temp & DDR4_RTT_NOM_MASK; + p_fsp_param->ca_odt = p_fsp_param->dq_odt; + } else if (sdram_params->base.dramtype == LPDDR3) { + temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT4); + temp = (temp >> PCTL2_LPDDR234_MR3_SHIFT) & PCTL2_MR_MASK; + p_fsp_param->ds_pdds = temp & 0xf; + + p_fsp_param->dq_odt = lp3_odt_value; + p_fsp_param->ca_odt = p_fsp_param->dq_odt; + } else if (sdram_params->base.dramtype == LPDDR4) { + temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT4); + temp = (temp >> PCTL2_LPDDR234_MR3_SHIFT) & PCTL2_MR_MASK; + p_fsp_param->ds_pdds = temp & LPDDR4_PDDS_MASK; + + temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT6); + temp = (temp >> PCTL2_LPDDR4_MR11_SHIFT) & PCTL2_MR_MASK; + p_fsp_param->dq_odt = temp & LPDDR4_DQODT_MASK; + p_fsp_param->ca_odt = temp & LPDDR4_CAODT_MASK; + + temp = MAX(readl(PHY_REG(phy_base, 0x3ae)), + readl(PHY_REG(phy_base, 0x3ce))); + temp1 = MIN(readl(PHY_REG(phy_base, 0x3be)), + readl(PHY_REG(phy_base, 0x3de))); + p_fsp_param->vref_ca[0] = (temp + temp1) / 2; + temp = MAX(readl(PHY_REG(phy_base, 0x3af)), + readl(PHY_REG(phy_base, 0x3cf))); + temp1 = MIN(readl(PHY_REG(phy_base, 0x3bf)), + readl(PHY_REG(phy_base, 0x3df))); + p_fsp_param->vref_ca[1] = (temp + temp1) / 2; + p_fsp_param->vref_ca[0] |= + (readl(PHY_REG(phy_base, 0x1e)) & BIT(6)); + p_fsp_param->vref_ca[1] |= + (readl(PHY_REG(phy_base, 0x1e)) & BIT(6)); + + p_fsp_param->lp4_drv_pd_en = (readl(PHY_REG(phy_base, 0x114)) >> + 3) & 0x1; + } + + p_fsp_param->noc_timings.ddrtiminga0 = + sdram_params->ch.noc_timings.ddrtiminga0; + p_fsp_param->noc_timings.ddrtimingb0 = + sdram_params->ch.noc_timings.ddrtimingb0; + p_fsp_param->noc_timings.ddrtimingc0 = + sdram_params->ch.noc_timings.ddrtimingc0; + p_fsp_param->noc_timings.devtodev0 = + sdram_params->ch.noc_timings.devtodev0; + p_fsp_param->noc_timings.ddrmode = + sdram_params->ch.noc_timings.ddrmode; + p_fsp_param->noc_timings.ddr4timing = + sdram_params->ch.noc_timings.ddr4timing; + p_fsp_param->noc_timings.agingx0 = + sdram_params->ch.noc_timings.agingx0; + p_fsp_param->noc_timings.aging0 = + sdram_params->ch.noc_timings.aging0; + p_fsp_param->noc_timings.aging1 = + sdram_params->ch.noc_timings.aging1; + p_fsp_param->noc_timings.aging2 = + sdram_params->ch.noc_timings.aging2; + p_fsp_param->noc_timings.aging3 = + sdram_params->ch.noc_timings.aging3; + + p_fsp_param->flag = FSP_FLAG; +} + +static void copy_fsp_param_to_ddr(void) +{ + memcpy((void *)FSP_PARAM_STORE_ADDR, (void *)&fsp_param, + sizeof(fsp_param)); +} + +static void pctl_modify_trfc(struct ddr_pctl_regs *pctl_regs, + struct sdram_cap_info *cap_info, u32 dram_type, + u32 freq) +{ + u64 cs0_cap; + u32 die_cap; + u32 trfc_ns, trfc4_ns; + u32 trfc, txsnr; + u32 txs_abort_fast = 0; + u32 tmp; + + cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type); + die_cap = (u32)(cs0_cap >> (20 + (cap_info->bw - cap_info->dbw))); + + switch (dram_type) { + case DDR3: + if (die_cap <= DIE_CAP_512MBIT) + trfc_ns = 90; + else if (die_cap <= DIE_CAP_1GBIT) + trfc_ns = 110; + else if (die_cap <= DIE_CAP_2GBIT) + trfc_ns = 160; + else if (die_cap <= DIE_CAP_4GBIT) + trfc_ns = 260; + else + trfc_ns = 350; + txsnr = MAX(5, ((trfc_ns + 10) * freq + 999) / 1000); + break; + + case DDR4: + if (die_cap <= DIE_CAP_2GBIT) { + trfc_ns = 160; + trfc4_ns = 90; + } else if (die_cap <= DIE_CAP_4GBIT) { + trfc_ns = 260; + trfc4_ns = 110; + } else if (die_cap <= DIE_CAP_8GBIT) { + trfc_ns = 350; + trfc4_ns = 160; + } else { + trfc_ns = 550; + trfc4_ns = 260; + } + txsnr = ((trfc_ns + 10) * freq + 999) / 1000; + txs_abort_fast = ((trfc4_ns + 10) * freq + 999) / 1000; + break; + + case LPDDR3: + if (die_cap <= DIE_CAP_4GBIT) + trfc_ns = 130; + else + trfc_ns = 210; + txsnr = MAX(2, ((trfc_ns + 10) * freq + 999) / 1000); + break; + + case LPDDR4: + if (die_cap <= DIE_CAP_2GBIT) + trfc_ns = 130; + else if (die_cap <= DIE_CAP_4GBIT) + trfc_ns = 180; + else if (die_cap <= DIE_CAP_8GBIT) + trfc_ns = 280; + else + trfc_ns = 380; + txsnr = MAX(2, ((trfc_ns + 10) * freq + 999) / 1000); + break; + + default: + return; + } + trfc = (trfc_ns * freq + 999) / 1000; + + for (int i = 0; pctl_regs->pctl[i][0] != 0xffffffff; i++) { + switch (pctl_regs->pctl[i][0]) { + case DDR_PCTL2_RFSHTMG: + tmp = pctl_regs->pctl[i][1]; + /* t_rfc_min */ + tmp &= ~((u32)0x3ff); + tmp |= ((trfc + 1) / 2) & 0x3ff; + pctl_regs->pctl[i][1] = tmp; + break; + + case DDR_PCTL2_DRAMTMG8: + if (dram_type == DDR3 || dram_type == DDR4) { + tmp = pctl_regs->pctl[i][1]; + /* t_xs_x32 */ + tmp &= ~((u32)0x7f); + tmp |= ((txsnr + 63) / 64) & 0x7f; + + if (dram_type == DDR4) { + /* t_xs_abort_x32 */ + tmp &= ~((u32)(0x7f << 16)); + tmp |= (((txs_abort_fast + 63) / 64) & 0x7f) << 16; + /* t_xs_fast_x32 */ + tmp &= ~((u32)(0x7f << 24)); + tmp |= (((txs_abort_fast + 63) / 64) & 0x7f) << 24; + } + + pctl_regs->pctl[i][1] = tmp; + } + break; + + case DDR_PCTL2_DRAMTMG14: + if (dram_type == LPDDR3 || + dram_type == LPDDR4) { + tmp = pctl_regs->pctl[i][1]; + /* t_xsr */ + tmp &= ~((u32)0xfff); + tmp |= ((txsnr + 1) / 2) & 0xfff; + pctl_regs->pctl[i][1] = tmp; + } + break; + + default: + break; + } + } +} + +void ddr_set_rate(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params, + u32 freq, u32 cur_freq, u32 dst_fsp, + u32 dst_fsp_lp4, u32 training_en) +{ + u32 dest_dll_off, cur_init3, dst_init3, cur_fsp, cur_dll_off; + u32 mr_tmp; + u32 lp_stat; + u32 dramtype = sdram_params->base.dramtype; + struct rv1126_sdram_params *sdram_params_new; + void __iomem *pctl_base = dram->pctl; + void __iomem *phy_base = dram->phy; + + lp_stat = low_power_update(dram, 0); + sdram_params_new = get_default_sdram_config(freq); + sdram_params_new->ch.cap_info.rank = sdram_params->ch.cap_info.rank; + sdram_params_new->ch.cap_info.bw = sdram_params->ch.cap_info.bw; + + pctl_modify_trfc(&sdram_params_new->pctl_regs, + &sdram_params->ch.cap_info, dramtype, freq); + pre_set_rate(dram, sdram_params_new, dst_fsp, dst_fsp_lp4); + + while ((readl(pctl_base + DDR_PCTL2_STAT) & + PCTL2_OPERATING_MODE_MASK) == + PCTL2_OPERATING_MODE_SR) + continue; + + dest_dll_off = 0; + dst_init3 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT3); + if ((dramtype == DDR3 && (dst_init3 & 1)) || + (dramtype == DDR4 && !(dst_init3 & 1))) + dest_dll_off = 1; + + cur_fsp = readl(pctl_base + DDR_PCTL2_MSTR2) & 0x3; + cur_init3 = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) + + DDR_PCTL2_INIT3); + cur_init3 &= PCTL2_MR_MASK; + cur_dll_off = 1; + if ((dramtype == DDR3 && !(cur_init3 & 1)) || + (dramtype == DDR4 && (cur_init3 & 1))) + cur_dll_off = 0; + + if (!cur_dll_off) { + if (dramtype == DDR3) + cur_init3 |= 1; + else + cur_init3 &= ~1; + pctl_write_mr(dram->pctl, 2, 1, cur_init3, dramtype); + } + + setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, + PCTL2_DIS_AUTO_REFRESH); + update_refresh_reg(dram); + + enter_sr(dram, 1); + + writel(PMUGRF_CON_DDRPHY_BUFFEREN_MASK | + PMUGRF_CON_DDRPHY_BUFFEREN_EN, + &dram->pmugrf->soc_con[0]); + sw_set_req(dram); + clrbits_le32(pctl_base + DDR_PCTL2_DFIMISC, + PCTL2_DFI_INIT_COMPLETE_EN); + sw_set_ack(dram); + + sw_set_req(dram); + if ((dramtype == DDR3 || dramtype == DDR4) && dest_dll_off) + setbits_le32(pctl_base + DDR_PCTL2_MSTR, PCTL2_DLL_OFF_MODE); + else + clrbits_le32(pctl_base + DDR_PCTL2_MSTR, PCTL2_DLL_OFF_MODE); + + setbits_le32(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) + DDR_PCTL2_ZQCTL0, + PCTL2_DIS_SRX_ZQCL); + setbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + DDR_PCTL2_ZQCTL0, + PCTL2_DIS_SRX_ZQCL); + sw_set_ack(dram); + + writel(DDR_MSCH_EN_MASK | (0x1 << DDR_MSCH_EN_SHIFT), + &dram->cru->clkgate_con[21]); + writel(CLK_DDR_UPCTL_EN_MASK | ACLK_DDR_UPCTL_EN_MASK | + (0x1 << CLK_DDR_UPCTL_EN_SHIFT) | + (0x1 << ACLK_DDR_UPCTL_EN_SHIFT), + BUS_SGRF_BASE_ADDR + SGRF_SOC_CON12); + + clrbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET | DIGITAL_DERESET); + rkclk_set_dpll(dram, freq * MHz / 2); + phy_pll_set(dram, freq * MHz, 0); + phy_pll_set(dram, freq * MHz, 1); + setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET | DIGITAL_DERESET); + + writel(PMUGRF_CON_DDRPHY_BUFFEREN_MASK | + PMUGRF_CON_DDRPHY_BUFFEREN_DIS, + &dram->pmugrf->soc_con[0]); + writel(DDR_MSCH_EN_MASK | (0x0 << DDR_MSCH_EN_SHIFT), + &dram->cru->clkgate_con[21]); + writel(CLK_DDR_UPCTL_EN_MASK | ACLK_DDR_UPCTL_EN_MASK | + (0x0 << CLK_DDR_UPCTL_EN_SHIFT) | + (0x0 << ACLK_DDR_UPCTL_EN_SHIFT), + BUS_SGRF_BASE_ADDR + SGRF_SOC_CON12); + while ((readl(pctl_base + DDR_PCTL2_DFISTAT) & + PCTL2_DFI_INIT_COMPLETE) != PCTL2_DFI_INIT_COMPLETE) + continue; + + sw_set_req(dram); + setbits_le32(pctl_base + DDR_PCTL2_MSTR, 0x1 << 29); + clrsetbits_le32(pctl_base + DDR_PCTL2_MSTR2, 0x3, dst_fsp); + sw_set_ack(dram); + update_refresh_reg(dram); + clrsetbits_le32(PHY_REG(phy_base, 0xc), 0x3 << 2, dst_fsp << 2); + + enter_sr(dram, 0); + + setbits_le32(PHY_REG(phy_base, 0x71), 1 << 5); + clrbits_le32(PHY_REG(phy_base, 0x71), 1 << 5); + + mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + DDR_PCTL2_INIT4); + if (dramtype == LPDDR3) { + pctl_write_mr(dram->pctl, 3, 1, + (dst_init3 >> PCTL2_LPDDR234_MR1_SHIFT) & + PCTL2_MR_MASK, + dramtype); + pctl_write_mr(dram->pctl, 3, 2, dst_init3 & PCTL2_MR_MASK, + dramtype); + pctl_write_mr(dram->pctl, 3, 3, + (mr_tmp >> PCTL2_LPDDR234_MR3_SHIFT) & + PCTL2_MR_MASK, + dramtype); + pctl_write_mr(dram->pctl, 3, 11, lp3_odt_value, dramtype); + } else if ((dramtype == DDR3) || (dramtype == DDR4)) { + pctl_write_mr(dram->pctl, 3, 1, dst_init3 & PCTL2_MR_MASK, + dramtype); + if (!dest_dll_off) { + pctl_write_mr(dram->pctl, 3, 0, + ((dst_init3 >> PCTL2_DDR34_MR0_SHIFT) & + PCTL2_MR_MASK) | DDR3_DLL_RESET, + dramtype); + udelay(2); + } + pctl_write_mr(dram->pctl, 3, 0, + (dst_init3 >> PCTL2_DDR34_MR0_SHIFT & + PCTL2_MR_MASK) & (~DDR3_DLL_RESET), + dramtype); + pctl_write_mr(dram->pctl, 3, 2, + ((mr_tmp >> PCTL2_DDR34_MR2_SHIFT) & + PCTL2_MR_MASK), dramtype); + if (dramtype == DDR4) { + pctl_write_mr(dram->pctl, 3, 3, mr_tmp & PCTL2_MR_MASK, + dramtype); + mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT6); + pctl_write_mr(dram->pctl, 3, 4, + (mr_tmp >> PCTL2_DDR4_MR4_SHIFT) & + PCTL2_MR_MASK, + dramtype); + pctl_write_mr(dram->pctl, 3, 5, + mr_tmp >> PCTL2_DDR4_MR5_SHIFT & + PCTL2_MR_MASK, + dramtype); + + mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + + DDR_PCTL2_INIT7); + pctl_write_mr(dram->pctl, 3, 6, + mr_tmp >> PCTL2_DDR4_MR6_SHIFT & + PCTL2_MR_MASK, + dramtype); + } + } else if (dramtype == LPDDR4) { + pctl_write_mr(dram->pctl, 3, 13, + ((mr_tmp >> PCTL2_LPDDR4_MR13_SHIFT & + PCTL2_MR_MASK) & (~(BIT(7)))) | + dst_fsp_lp4 << 7, dramtype); + } + clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, + PCTL2_DIS_AUTO_REFRESH); + update_refresh_reg(dram); + + /* training */ + high_freq_training(dram, sdram_params_new, dst_fsp); + low_power_update(dram, lp_stat); + + save_fsp_param(dram, dst_fsp, sdram_params_new); +} + +static void ddr_set_rate_for_fsp(struct dram_info *dram, + struct rv1126_sdram_params *sdram_params) +{ + struct ddr2_3_4_lp2_3_info *ddr_info; + u32 f0; + u32 dramtype = sdram_params->base.dramtype; + u32 f1, f2, f3; + + ddr_info = get_ddr_drv_odt_info(dramtype); + if (!ddr_info) + return; + + f0 = (ddr_info->ddr_freq0_1 >> DDR_FREQ_F0_SHIFT) & + DDR_FREQ_MASK; + + memset((void *)FSP_PARAM_STORE_ADDR, 0, sizeof(fsp_param)); + memset((void *)&fsp_param, 0, sizeof(fsp_param)); + + f1 = (ddr_info->ddr_freq0_1 >> DDR_FREQ_F1_SHIFT) & + DDR_FREQ_MASK; + f2 = (ddr_info->ddr_freq2_3 >> DDR_FREQ_F2_SHIFT) & + DDR_FREQ_MASK; + f3 = (ddr_info->ddr_freq2_3 >> DDR_FREQ_F3_SHIFT) & + DDR_FREQ_MASK; + + if (get_wrlvl_val(dram, sdram_params)) + printascii("get wrlvl value fail\n"); + + if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) { + printascii("change to: "); + printdec(f1); + printascii("MHz\n"); + } + ddr_set_rate(&dram_info, sdram_params, f1, + sdram_params->base.ddr_freq, 1, 1, 1); + + if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) { + printascii("change to: "); + printdec(f2); + printascii("MHz\n"); + } + ddr_set_rate(&dram_info, sdram_params, f2, f1, 2, 0, 1); + + if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) { + printascii("change to: "); + printdec(f3); + printascii("MHz\n"); + } + ddr_set_rate(&dram_info, sdram_params, f3, f2, 3, 1, 1); + + if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) { + printascii("change to: "); + printdec(f0); + printascii("MHz(final freq)\n"); + } + ddr_set_rate(&dram_info, sdram_params, f0, f3, 0, 0, 1); +} + +int get_uart_config(void) +{ + struct sdram_head_info_index_v2 *index = + (struct sdram_head_info_index_v2 *)common_info; + struct global_info *gbl_info; + + gbl_info = (struct global_info *)((void *)common_info + + index->global_index.offset * 4); + + return gbl_info->uart_info; +} + +/* return: 0 = success, other = fail */ +static int rv1126_dmc_init(struct udevice *dev) +{ + struct rv1126_sdram_params *sdram_params; + int ret = 0; + struct sdram_head_info_index_v2 *index = + (struct sdram_head_info_index_v2 *)common_info; + struct global_info *gbl_info; + + dram_info.phy = (void *)DDR_PHY_BASE_ADDR; + dram_info.pctl = (void *)UPCTL2_BASE_ADDR; + dram_info.grf = (void *)GRF_BASE_ADDR; + dram_info.cru = (void *)CRU_BASE_ADDR; + dram_info.msch = (void *)SERVER_MSCH_BASE_ADDR; + dram_info.ddrgrf = (void *)DDR_GRF_BASE_ADDR; + dram_info.pmugrf = (void *)PMU_GRF_BASE_ADDR; + +#ifdef CONFIG_ROCKCHIP_DRAM_EXTENDED_TEMP_SUPPORT + printascii("extended temp support\n"); +#endif + if (index->version_info != 2 || + (index->global_index.size != sizeof(struct global_info) / 4) || + (index->ddr3_index.size != + sizeof(struct ddr2_3_4_lp2_3_info) / 4) || + (index->ddr4_index.size != + sizeof(struct ddr2_3_4_lp2_3_info) / 4) || + (index->lp3_index.size != + sizeof(struct ddr2_3_4_lp2_3_info) / 4) || + (index->lp4_index.size != (sizeof(struct lp4_info) / 4)) || + (index->lp4x_index.size != (sizeof(struct lp4_info) / 4)) || + index->global_index.offset == 0 || + index->ddr3_index.offset == 0 || + index->ddr4_index.offset == 0 || + index->lp3_index.offset == 0 || + index->lp4_index.offset == 0 || + index->lp4x_index.offset == 0) { + printascii("common info error\n"); + goto error; + } + + gbl_info = (struct global_info *)((void *)common_info + + index->global_index.offset * 4); + + dram_info.sr_idle = SR_INFO(gbl_info->sr_pd_info); + dram_info.pd_idle = PD_INFO(gbl_info->sr_pd_info); + + sdram_params = &sdram_configs[0]; + if (sdram_params->base.dramtype == DDR3 || + sdram_params->base.dramtype == DDR4) { + if (DDR_2T_INFO(gbl_info->info_2t)) + sdram_params->pctl_regs.pctl[0][1] |= 0x1 << 10; + else + sdram_params->pctl_regs.pctl[0][1] &= + ~(0x1 << 10); + } + ret = sdram_init_detect(&dram_info, sdram_params); + if (ret) { + sdram_print_dram_type(sdram_params->base.dramtype); + printascii(", "); + printdec(sdram_params->base.ddr_freq); + printascii("MHz\n"); + goto error; + } + print_ddr_info(sdram_params); +#if defined(CONFIG_CMD_DDR_TEST_TOOL) + init_rw_trn_result_struct(&rw_trn_result, dram_info.phy, + (u8)sdram_params->ch.cap_info.rank); +#endif + + ddr_set_rate_for_fsp(&dram_info, sdram_params); + copy_fsp_param_to_ddr(); + +#if defined(CONFIG_CMD_DDR_TEST_TOOL) + save_rw_trn_result_to_ddr(&rw_trn_result); +#endif + + if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) + printascii("out\n"); + + return ret; +error: + printascii("error\n"); + return (-1); +} + +#endif + +static int rv1126_dmc_probe(struct udevice *dev) +{ +#if defined(CONFIG_TPL_BUILD) || \ + (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD)) + if (rv1126_dmc_init(dev)) + return 0; +#else + struct dram_info *priv = dev_get_priv(dev); + + priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF); + debug("%s: grf=%p\n", __func__, priv->pmugrf); + priv->info.base = CFG_SYS_SDRAM_BASE; + priv->info.size = + rockchip_sdram_size((phys_addr_t)&priv->pmugrf->os_reg[2]); +#endif + return 0; +} + +static int rv1126_dmc_get_info(struct udevice *dev, struct ram_info *info) +{ + struct dram_info *priv = dev_get_priv(dev); + + *info = priv->info; + + return 0; +} + +static struct ram_ops rv1126_dmc_ops = { + .get_info = rv1126_dmc_get_info, +}; + +static const struct udevice_id rv1126_dmc_ids[] = { + { .compatible = "rockchip,rv1126-dmc" }, + { } +}; + +U_BOOT_DRIVER(dmc_rv1126) = { + .name = "rockchip_rv1126_dmc", + .id = UCLASS_RAM, + .of_match = rv1126_dmc_ids, + .ops = &rv1126_dmc_ops, + .probe = rv1126_dmc_probe, + .priv_auto = sizeof(struct dram_info), +}; diff --git a/include/configs/neural-compute-module-2.h b/include/configs/neural-compute-module-2.h new file mode 100644 index 0000000..f0934ae --- /dev/null +++ b/include/configs/neural-compute-module-2.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. + */ + +#ifndef __NEURAL_COMPUTE_MODULE_2_H +#define __NEURAL_COMPUTE_MODULE_2_H + +#define ROCKCHIP_DEVICE_SETTINGS \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" + +#include <configs/rv1126_common.h> + +#undef BOOT_TARGET_DEVICES + +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 0) \ + func(MMC, mmc, 1) + +#endif /* __NEURAL_COMPUTE_MODULE_2_H */ diff --git a/include/configs/pinephone-pro-rk3399.h b/include/configs/pinephone-pro-rk3399.h new file mode 100644 index 0000000..78017d6 --- /dev/null +++ b/include/configs/pinephone-pro-rk3399.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016 Rockchip Electronics Co., Ltd + * Copyright (C) 2022 Peter Robinson <pbrobinson at gmail.com> + */ + +#ifndef __PINEPHONE_PRO_RK3399_H +#define __PINEPHONE_PRO_RK3399_H + +#define ROCKCHIP_DEVICE_SETTINGS \ + "stdin=serial,usbkbd\0" \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" + +#include <configs/rk3399_common.h> + +#define SDRAM_BANK_SIZE (2UL << 30) + +#endif diff --git a/include/configs/px30_common.h b/include/configs/px30_common.h index 3f1595c..c0896e5 100644 --- a/include/configs/px30_common.h +++ b/include/configs/px30_common.h @@ -8,8 +8,7 @@ #include "rockchip-common.h" -/* FIXME: ff020000 is pmu_mem (10k), while ff0e0000 is regular int_mem */ -#define CFG_IRAM_BASE 0xff020000 +#define CFG_IRAM_BASE 0xff0e0000 #define GICD_BASE 0xff131000 #define GICC_BASE 0xff132000 diff --git a/include/configs/ringneck_px30.h b/include/configs/ringneck_px30.h new file mode 100644 index 0000000..c63c935 --- /dev/null +++ b/include/configs/ringneck_px30.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2022 Theobroma Systems Design und Consulting GmbH + */ + +#ifndef __RINGNECK_PX30_H +#define __RINGNECK_PX30_H + +#include <configs/px30_common.h> + +#define ROCKCHIP_DEVICE_SETTINGS \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" + +#endif diff --git a/include/configs/rv1126_common.h b/include/configs/rv1126_common.h new file mode 100644 index 0000000..1ec1640 --- /dev/null +++ b/include/configs/rv1126_common.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2019 Rockchip Electronics Co., Ltd + * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd. + */ + +#ifndef __CONFIG_RV1126_COMMON_H +#define __CONFIG_RV1126_COMMON_H + +#include "rockchip-common.h" + +#define CFG_SYS_HZ_CLOCK 24000000 + +#define CFG_IRAM_BASE 0xff700000 + +#define GICD_BASE 0xfeff1000 +#define GICC_BASE 0xfeff2000 + +#define CFG_SYS_SDRAM_BASE 0 +#define SDRAM_MAX_SIZE 0xfd000000 + +/* memory size > 128MB */ +#define ENV_MEM_LAYOUT_SETTINGS \ + "scriptaddr=0x00000000\0" \ + "pxefile_addr_r=0x00100000\0" \ + "fdt_addr_r=0x08300000\0" \ + "kernel_addr_r=0x02008000\0" \ + "ramdisk_addr_r=0x0a200000\0" + +#include <config_distro_bootcmd.h> +#define CFG_EXTRA_ENV_SETTINGS \ + "fdt_high=0x0fffffff\0" \ + "initrd_high=0x0fffffff\0" \ + "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ + "partitions=" PARTS_DEFAULT \ + ENV_MEM_LAYOUT_SETTINGS \ + ROCKCHIP_DEVICE_SETTINGS \ + BOOTENV + +#endif /* __CONFIG_RV1126_COMMON_H */ diff --git a/include/dt-bindings/clock/rockchip,rv1126-cru.h b/include/dt-bindings/clock/rockchip,rv1126-cru.h new file mode 100644 index 0000000..e89a3a5 --- /dev/null +++ b/include/dt-bindings/clock/rockchip,rv1126-cru.h @@ -0,0 +1,632 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2019 Rockchip Electronics Co. Ltd. + * Author: Finley Xiao <finley.xiao@rock-chips.com> + */ + +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1126_H +#define _DT_BINDINGS_CLK_ROCKCHIP_RV1126_H + +/* pmucru-clocks indices */ + +/* pll clocks */ +#define PLL_GPLL 1 + +/* sclk (special clocks) */ +#define CLK_OSC0_DIV32K 2 +#define CLK_RTC32K 3 +#define CLK_WIFI_DIV 4 +#define CLK_WIFI_OSC0 5 +#define CLK_WIFI 6 +#define CLK_PMU 7 +#define SCLK_UART1_DIV 8 +#define SCLK_UART1_FRACDIV 9 +#define SCLK_UART1_MUX 10 +#define SCLK_UART1 11 +#define CLK_I2C0 12 +#define CLK_I2C2 13 +#define CLK_CAPTURE_PWM0 14 +#define CLK_PWM0 15 +#define CLK_CAPTURE_PWM1 16 +#define CLK_PWM1 17 +#define CLK_SPI0 18 +#define DBCLK_GPIO0 19 +#define CLK_PMUPVTM 20 +#define CLK_CORE_PMUPVTM 21 +#define CLK_REF12M 22 +#define CLK_USBPHY_OTG_REF 23 +#define CLK_USBPHY_HOST_REF 24 +#define CLK_REF24M 25 +#define CLK_MIPIDSIPHY_REF 26 + +/* pclk */ +#define PCLK_PDPMU 30 +#define PCLK_PMU 31 +#define PCLK_UART1 32 +#define PCLK_I2C0 33 +#define PCLK_I2C2 34 +#define PCLK_PWM0 35 +#define PCLK_PWM1 36 +#define PCLK_SPI0 37 +#define PCLK_GPIO0 38 +#define PCLK_PMUSGRF 39 +#define PCLK_PMUGRF 40 +#define PCLK_PMUCRU 41 +#define PCLK_CHIPVEROTP 42 +#define PCLK_PDPMU_NIU 43 +#define PCLK_PMUPVTM 44 +#define PCLK_SCRKEYGEN 45 + +#define CLKPMU_NR_CLKS (PCLK_SCRKEYGEN + 1) + +/* cru-clocks indices */ + +/* pll clocks */ +#define PLL_APLL 1 +#define PLL_DPLL 2 +#define PLL_CPLL 3 +#define PLL_HPLL 4 + +/* sclk (special clocks) */ +#define ARMCLK 5 +#define USB480M 6 +#define CLK_CORE_CPUPVTM 7 +#define CLK_CPUPVTM 8 +#define CLK_SCR1 9 +#define CLK_SCR1_CORE 10 +#define CLK_SCR1_RTC 11 +#define CLK_SCR1_JTAG 12 +#define SCLK_UART0_DIV 13 +#define SCLK_UART0_FRAC 14 +#define SCLK_UART0_MUX 15 +#define SCLK_UART0 16 +#define SCLK_UART2_DIV 17 +#define SCLK_UART2_FRAC 18 +#define SCLK_UART2_MUX 19 +#define SCLK_UART2 20 +#define SCLK_UART3_DIV 21 +#define SCLK_UART3_FRAC 22 +#define SCLK_UART3_MUX 23 +#define SCLK_UART3 24 +#define SCLK_UART4_DIV 25 +#define SCLK_UART4_FRAC 26 +#define SCLK_UART4_MUX 27 +#define SCLK_UART4 28 +#define SCLK_UART5_DIV 29 +#define SCLK_UART5_FRAC 30 +#define SCLK_UART5_MUX 31 +#define SCLK_UART5 32 +#define CLK_I2C1 33 +#define CLK_I2C3 34 +#define CLK_I2C4 35 +#define CLK_I2C5 36 +#define CLK_SPI1 37 +#define CLK_CAPTURE_PWM2 38 +#define CLK_PWM2 39 +#define DBCLK_GPIO1 40 +#define DBCLK_GPIO2 41 +#define DBCLK_GPIO3 42 +#define DBCLK_GPIO4 43 +#define CLK_SARADC 44 +#define CLK_TIMER0 45 +#define CLK_TIMER1 46 +#define CLK_TIMER2 47 +#define CLK_TIMER3 48 +#define CLK_TIMER4 49 +#define CLK_TIMER5 50 +#define CLK_CAN 51 +#define CLK_NPU_TSADC 52 +#define CLK_NPU_TSADCPHY 53 +#define CLK_CPU_TSADC 54 +#define CLK_CPU_TSADCPHY 55 +#define CLK_CRYPTO_CORE 56 +#define CLK_CRYPTO_PKA 57 +#define MCLK_I2S0_TX_DIV 58 +#define MCLK_I2S0_TX_FRACDIV 59 +#define MCLK_I2S0_TX_MUX 60 +#define MCLK_I2S0_TX 61 +#define MCLK_I2S0_RX_DIV 62 +#define MCLK_I2S0_RX_FRACDIV 63 +#define MCLK_I2S0_RX_MUX 64 +#define MCLK_I2S0_RX 65 +#define MCLK_I2S0_TX_OUT2IO 66 +#define MCLK_I2S0_RX_OUT2IO 67 +#define MCLK_I2S1_DIV 68 +#define MCLK_I2S1_FRACDIV 69 +#define MCLK_I2S1_MUX 70 +#define MCLK_I2S1 71 +#define MCLK_I2S1_OUT2IO 72 +#define MCLK_I2S2_DIV 73 +#define MCLK_I2S2_FRACDIV 74 +#define MCLK_I2S2_MUX 75 +#define MCLK_I2S2 76 +#define MCLK_I2S2_OUT2IO 77 +#define MCLK_PDM 78 +#define SCLK_ADUPWM_DIV 79 +#define SCLK_AUDPWM_FRACDIV 80 +#define SCLK_AUDPWM_MUX 81 +#define SCLK_AUDPWM 82 +#define CLK_ACDCDIG_ADC 83 +#define CLK_ACDCDIG_DAC 84 +#define CLK_ACDCDIG_I2C 85 +#define CLK_VENC_CORE 86 +#define CLK_VDEC_CORE 87 +#define CLK_VDEC_CA 88 +#define CLK_VDEC_HEVC_CA 89 +#define CLK_RGA_CORE 90 +#define CLK_IEP_CORE 91 +#define CLK_ISP_DIV 92 +#define CLK_ISP_NP5 93 +#define CLK_ISP_NUX 94 +#define CLK_ISP 95 +#define CLK_CIF_OUT_DIV 96 +#define CLK_CIF_OUT_FRACDIV 97 +#define CLK_CIF_OUT_MUX 98 +#define CLK_CIF_OUT 99 +#define CLK_MIPICSI_OUT_DIV 100 +#define CLK_MIPICSI_OUT_FRACDIV 101 +#define CLK_MIPICSI_OUT_MUX 102 +#define CLK_MIPICSI_OUT 103 +#define CLK_ISPP_DIV 104 +#define CLK_ISPP_NP5 105 +#define CLK_ISPP_NUX 106 +#define CLK_ISPP 107 +#define CLK_SDMMC 108 +#define SCLK_SDMMC_DRV 109 +#define SCLK_SDMMC_SAMPLE 110 +#define CLK_SDIO 111 +#define SCLK_SDIO_DRV 112 +#define SCLK_SDIO_SAMPLE 113 +#define CLK_EMMC 114 +#define SCLK_EMMC_DRV 115 +#define SCLK_EMMC_SAMPLE 116 +#define CLK_NANDC 117 +#define SCLK_SFC 118 +#define CLK_USBHOST_UTMI_OHCI 119 +#define CLK_USBOTG_REF 120 +#define CLK_GMAC_DIV 121 +#define CLK_GMAC_RGMII_M0 122 +#define CLK_GMAC_SRC_M0 123 +#define CLK_GMAC_RGMII_M1 124 +#define CLK_GMAC_SRC_M1 125 +#define CLK_GMAC_SRC 126 +#define CLK_GMAC_REF 127 +#define CLK_GMAC_TX_SRC 128 +#define CLK_GMAC_TX_DIV5 129 +#define CLK_GMAC_TX_DIV50 130 +#define RGMII_MODE_CLK 131 +#define CLK_GMAC_RX_SRC 132 +#define CLK_GMAC_RX_DIV2 133 +#define CLK_GMAC_RX_DIV20 134 +#define RMII_MODE_CLK 135 +#define CLK_GMAC_TX_RX 136 +#define CLK_GMAC_PTPREF 137 +#define CLK_GMAC_ETHERNET_OUT 138 +#define CLK_DDRPHY 139 +#define CLK_DDR_MON 140 +#define TMCLK_DDR_MON 141 +#define CLK_NPU_DIV 142 +#define CLK_NPU_NP5 143 +#define CLK_CORE_NPU 144 +#define CLK_CORE_NPUPVTM 145 +#define CLK_NPUPVTM 146 +#define SCLK_DDRCLK 147 +#define CLK_OTP 148 + +/* dclk */ +#define DCLK_DECOM 150 +#define DCLK_VOP_DIV 151 +#define DCLK_VOP_FRACDIV 152 +#define DCLK_VOP_MUX 153 +#define DCLK_VOP 154 +#define DCLK_CIF 155 +#define DCLK_CIFLITE 156 + +/* aclk */ +#define ACLK_PDBUS 160 +#define ACLK_DMAC 161 +#define ACLK_DCF 162 +#define ACLK_SPINLOCK 163 +#define ACLK_DECOM 164 +#define ACLK_PDCRYPTO 165 +#define ACLK_CRYPTO 166 +#define ACLK_PDVEPU 167 +#define ACLK_VENC 168 +#define ACLK_PDVDEC 169 +#define ACLK_PDJPEG 170 +#define ACLK_VDEC 171 +#define ACLK_JPEG 172 +#define ACLK_PDVO 173 +#define ACLK_RGA 174 +#define ACLK_VOP 175 +#define ACLK_IEP 176 +#define ACLK_PDVI_DIV 177 +#define ACLK_PDVI_NP5 178 +#define ACLK_PDVI 179 +#define ACLK_ISP 180 +#define ACLK_CIF 181 +#define ACLK_CIFLITE 182 +#define ACLK_PDISPP_DIV 183 +#define ACLK_PDISPP_NP5 184 +#define ACLK_PDISPP 185 +#define ACLK_ISPP 186 +#define ACLK_PDPHP 187 +#define ACLK_PDUSB 188 +#define ACLK_USBOTG 189 +#define ACLK_PDGMAC 190 +#define ACLK_GMAC 191 +#define ACLK_PDNPU_DIV 192 +#define ACLK_PDNPU_NP5 193 +#define ACLK_PDNPU 194 +#define ACLK_NPU 195 + +/* hclk */ +#define HCLK_PDCORE_NIU 200 +#define HCLK_PDUSB 201 +#define HCLK_PDCRYPTO 202 +#define HCLK_CRYPTO 203 +#define HCLK_PDAUDIO 204 +#define HCLK_I2S0 205 +#define HCLK_I2S1 206 +#define HCLK_I2S2 207 +#define HCLK_PDM 208 +#define HCLK_AUDPWM 209 +#define HCLK_PDVEPU 210 +#define HCLK_VENC 211 +#define HCLK_PDVDEC 212 +#define HCLK_PDJPEG 213 +#define HCLK_VDEC 214 +#define HCLK_JPEG 215 +#define HCLK_PDVO 216 +#define HCLK_RGA 217 +#define HCLK_VOP 218 +#define HCLK_IEP 219 +#define HCLK_PDVI 220 +#define HCLK_ISP 221 +#define HCLK_CIF 222 +#define HCLK_CIFLITE 223 +#define HCLK_PDISPP 224 +#define HCLK_ISPP 225 +#define HCLK_PDPHP 226 +#define HCLK_PDSDMMC 227 +#define HCLK_SDMMC 228 +#define HCLK_PDSDIO 229 +#define HCLK_SDIO 230 +#define HCLK_PDNVM 231 +#define HCLK_EMMC 232 +#define HCLK_NANDC 233 +#define HCLK_SFC 234 +#define HCLK_SFCXIP 235 +#define HCLK_PDBUS 236 +#define HCLK_USBHOST 237 +#define HCLK_USBHOST_ARB 238 +#define HCLK_PDNPU 239 +#define HCLK_NPU 240 + +/* pclk */ +#define PCLK_CPUPVTM 245 +#define PCLK_PDBUS 246 +#define PCLK_DCF 247 +#define PCLK_WDT 248 +#define PCLK_MAILBOX 249 +#define PCLK_UART0 250 +#define PCLK_UART2 251 +#define PCLK_UART3 252 +#define PCLK_UART4 253 +#define PCLK_UART5 254 +#define PCLK_I2C1 255 +#define PCLK_I2C3 256 +#define PCLK_I2C4 257 +#define PCLK_I2C5 258 +#define PCLK_SPI1 259 +#define PCLK_PWM2 261 +#define PCLK_GPIO1 262 +#define PCLK_GPIO2 263 +#define PCLK_GPIO3 264 +#define PCLK_GPIO4 265 +#define PCLK_SARADC 266 +#define PCLK_TIMER 267 +#define PCLK_DECOM 268 +#define PCLK_CAN 269 +#define PCLK_NPU_TSADC 270 +#define PCLK_CPU_TSADC 271 +#define PCLK_ACDCDIG 272 +#define PCLK_PDVO 273 +#define PCLK_DSIHOST 274 +#define PCLK_PDVI 275 +#define PCLK_CSIHOST 276 +#define PCLK_PDGMAC 277 +#define PCLK_GMAC 278 +#define PCLK_PDDDR 279 +#define PCLK_DDR_MON 280 +#define PCLK_PDNPU 281 +#define PCLK_NPUPVTM 282 +#define PCLK_PDTOP 283 +#define PCLK_TOPCRU 284 +#define PCLK_TOPGRF 285 +#define PCLK_CPUEMADET 286 +#define PCLK_DDRPHY 287 +#define PCLK_DSIPHY 289 +#define PCLK_CSIPHY0 290 +#define PCLK_CSIPHY1 291 +#define PCLK_USBPHY_HOST 292 +#define PCLK_USBPHY_OTG 293 +#define PCLK_OTP 294 + +#define CLK_NR_CLKS (PCLK_OTP + 1) + +/* pmu soft-reset indices */ + +/* pmu_cru_softrst_con0 */ +#define SRST_PDPMU_NIU_P 0 +#define SRST_PMU_SGRF_P 1 +#define SRST_PMU_SGRF_REMAP_P 2 +#define SRST_I2C0_P 3 +#define SRST_I2C0 4 +#define SRST_I2C2_P 7 +#define SRST_I2C2 8 +#define SRST_UART1_P 9 +#define SRST_UART1 10 +#define SRST_PWM0_P 11 +#define SRST_PWM0 12 +#define SRST_PWM1_P 13 +#define SRST_PWM1 14 +#define SRST_DDR_FAIL_SAFE 15 + +/* pmu_cru_softrst_con1 */ +#define SRST_GPIO0_P 17 +#define SRST_GPIO0_DB 18 +#define SRST_SPI0_P 19 +#define SRST_SPI0 20 +#define SRST_PMUGRF_P 21 +#define SRST_CHIPVEROTP_P 22 +#define SRST_PMUPVTM 24 +#define SRST_PMUPVTM_P 25 +#define SRST_PMUCRU_P 30 + +/* soft-reset indices */ + +/* cru_softrst_con0 */ +#define SRST_CORE0_PO 0 +#define SRST_CORE1_PO 1 +#define SRST_CORE2_PO 2 +#define SRST_CORE3_PO 3 +#define SRST_CORE0 4 +#define SRST_CORE1 5 +#define SRST_CORE2 6 +#define SRST_CORE3 7 +#define SRST_CORE0_DBG 8 +#define SRST_CORE1_DBG 9 +#define SRST_CORE2_DBG 10 +#define SRST_CORE3_DBG 11 +#define SRST_NL2 12 +#define SRST_CORE_NIU_A 13 +#define SRST_DBG_DAPLITE_P 14 +#define SRST_DAPLITE_P 15 + +/* cru_softrst_con1 */ +#define SRST_PDBUS_NIU1_A 16 +#define SRST_PDBUS_NIU1_H 17 +#define SRST_PDBUS_NIU1_P 18 +#define SRST_PDBUS_NIU2_A 19 +#define SRST_PDBUS_NIU2_H 20 +#define SRST_PDBUS_NIU3_A 21 +#define SRST_PDBUS_NIU3_H 22 +#define SRST_PDBUS_HOLD_NIU1_A 23 +#define SRST_DBG_NIU_P 24 +#define SRST_PDCORE_NIIU_H 25 +#define SRST_MUC_NIU 26 +#define SRST_DCF_A 29 +#define SRST_DCF_P 30 +#define SRST_SYSTEM_SRAM_A 31 + +/* cru_softrst_con2 */ +#define SRST_I2C1_P 32 +#define SRST_I2C1 33 +#define SRST_I2C3_P 34 +#define SRST_I2C3 35 +#define SRST_I2C4_P 36 +#define SRST_I2C4 37 +#define SRST_I2C5_P 38 +#define SRST_I2C5 39 +#define SRST_SPI1_P 40 +#define SRST_SPI1 41 +#define SRST_MCU_CORE 42 +#define SRST_PWM2_P 44 +#define SRST_PWM2 45 +#define SRST_SPINLOCK_A 46 + +/* cru_softrst_con3 */ +#define SRST_UART0_P 48 +#define SRST_UART0 49 +#define SRST_UART2_P 50 +#define SRST_UART2 51 +#define SRST_UART3_P 52 +#define SRST_UART3 53 +#define SRST_UART4_P 54 +#define SRST_UART4 55 +#define SRST_UART5_P 56 +#define SRST_UART5 57 +#define SRST_WDT_P 58 +#define SRST_SARADC_P 59 +#define SRST_GRF_P 61 +#define SRST_TIMER_P 62 +#define SRST_MAILBOX_P 63 + +/* cru_softrst_con4 */ +#define SRST_TIMER0 64 +#define SRST_TIMER1 65 +#define SRST_TIMER2 66 +#define SRST_TIMER3 67 +#define SRST_TIMER4 68 +#define SRST_TIMER5 69 +#define SRST_INTMUX_P 70 +#define SRST_GPIO1_P 72 +#define SRST_GPIO1_DB 73 +#define SRST_GPIO2_P 74 +#define SRST_GPIO2_DB 75 +#define SRST_GPIO3_P 76 +#define SRST_GPIO3_DB 77 +#define SRST_GPIO4_P 78 +#define SRST_GPIO4_DB 79 + +/* cru_softrst_con5 */ +#define SRST_CAN_P 80 +#define SRST_CAN 81 +#define SRST_DECOM_A 85 +#define SRST_DECOM_P 86 +#define SRST_DECOM_D 87 +#define SRST_PDCRYPTO_NIU_A 88 +#define SRST_PDCRYPTO_NIU_H 89 +#define SRST_CRYPTO_A 90 +#define SRST_CRYPTO_H 91 +#define SRST_CRYPTO_CORE 92 +#define SRST_CRYPTO_PKA 93 +#define SRST_SGRF_P 95 + +/* cru_softrst_con6 */ +#define SRST_PDAUDIO_NIU_H 96 +#define SRST_PDAUDIO_NIU_P 97 +#define SRST_I2S0_H 98 +#define SRST_I2S0_TX_M 99 +#define SRST_I2S0_RX_M 100 +#define SRST_I2S1_H 101 +#define SRST_I2S1_M 102 +#define SRST_I2S2_H 103 +#define SRST_I2S2_M 104 +#define SRST_PDM_H 105 +#define SRST_PDM_M 106 +#define SRST_AUDPWM_H 107 +#define SRST_AUDPWM 108 +#define SRST_ACDCDIG_P 109 +#define SRST_ACDCDIG 110 + +/* cru_softrst_con7 */ +#define SRST_PDVEPU_NIU_A 112 +#define SRST_PDVEPU_NIU_H 113 +#define SRST_VENC_A 114 +#define SRST_VENC_H 115 +#define SRST_VENC_CORE 116 +#define SRST_PDVDEC_NIU_A 117 +#define SRST_PDVDEC_NIU_H 118 +#define SRST_VDEC_A 119 +#define SRST_VDEC_H 120 +#define SRST_VDEC_CORE 121 +#define SRST_VDEC_CA 122 +#define SRST_VDEC_HEVC_CA 123 +#define SRST_PDJPEG_NIU_A 124 +#define SRST_PDJPEG_NIU_H 125 +#define SRST_JPEG_A 126 +#define SRST_JPEG_H 127 + +/* cru_softrst_con8 */ +#define SRST_PDVO_NIU_A 128 +#define SRST_PDVO_NIU_H 129 +#define SRST_PDVO_NIU_P 130 +#define SRST_RGA_A 131 +#define SRST_RGA_H 132 +#define SRST_RGA_CORE 133 +#define SRST_VOP_A 134 +#define SRST_VOP_H 135 +#define SRST_VOP_D 136 +#define SRST_TXBYTEHS_DSIHOST 137 +#define SRST_DSIHOST_P 138 +#define SRST_IEP_A 139 +#define SRST_IEP_H 140 +#define SRST_IEP_CORE 141 +#define SRST_ISP_RX_P 142 + +/* cru_softrst_con9 */ +#define SRST_PDVI_NIU_A 144 +#define SRST_PDVI_NIU_H 145 +#define SRST_PDVI_NIU_P 146 +#define SRST_ISP 147 +#define SRST_CIF_A 148 +#define SRST_CIF_H 149 +#define SRST_CIF_D 150 +#define SRST_CIF_P 151 +#define SRST_CIF_I 152 +#define SRST_CIF_RX_P 153 +#define SRST_PDISPP_NIU_A 154 +#define SRST_PDISPP_NIU_H 155 +#define SRST_ISPP_A 156 +#define SRST_ISPP_H 157 +#define SRST_ISPP 158 +#define SRST_CSIHOST_P 159 + +/* cru_softrst_con10 */ +#define SRST_PDPHPMID_NIU_A 160 +#define SRST_PDPHPMID_NIU_H 161 +#define SRST_PDNVM_NIU_H 163 +#define SRST_SDMMC_H 164 +#define SRST_SDIO_H 165 +#define SRST_EMMC_H 166 +#define SRST_SFC_H 167 +#define SRST_SFCXIP_H 168 +#define SRST_SFC 169 +#define SRST_NANDC_H 170 +#define SRST_NANDC 171 +#define SRST_PDSDMMC_H 173 +#define SRST_PDSDIO_H 174 + +/* cru_softrst_con11 */ +#define SRST_PDUSB_NIU_A 176 +#define SRST_PDUSB_NIU_H 177 +#define SRST_USBHOST_H 178 +#define SRST_USBHOST_ARB_H 179 +#define SRST_USBHOST_UTMI 180 +#define SRST_USBOTG_A 181 +#define SRST_USBPHY_OTG_P 182 +#define SRST_USBPHY_HOST_P 183 +#define SRST_USBPHYPOR_OTG 184 +#define SRST_USBPHYPOR_HOST 185 +#define SRST_PDGMAC_NIU_A 188 +#define SRST_PDGMAC_NIU_P 189 +#define SRST_GMAC_A 190 + +/* cru_softrst_con12 */ +#define SRST_DDR_DFICTL_P 193 +#define SRST_DDR_MON_P 194 +#define SRST_DDR_STANDBY_P 195 +#define SRST_DDR_GRF_P 196 +#define SRST_DDR_MSCH_P 197 +#define SRST_DDR_SPLIT_A 198 +#define SRST_DDR_MSCH 199 +#define SRST_DDR_DFICTL 202 +#define SRST_DDR_STANDBY 203 +#define SRST_NPUMCU_NIU 205 +#define SRST_DDRPHY_P 206 +#define SRST_DDRPHY 207 + +/* cru_softrst_con13 */ +#define SRST_PDNPU_NIU_A 208 +#define SRST_PDNPU_NIU_H 209 +#define SRST_PDNPU_NIU_P 210 +#define SRST_NPU_A 211 +#define SRST_NPU_H 212 +#define SRST_NPU 213 +#define SRST_NPUPVTM_P 214 +#define SRST_NPUPVTM 215 +#define SRST_NPU_TSADC_P 216 +#define SRST_NPU_TSADC 217 +#define SRST_NPU_TSADCPHY 218 +#define SRST_CIFLITE_A 220 +#define SRST_CIFLITE_H 221 +#define SRST_CIFLITE_D 222 +#define SRST_CIFLITE_RX_P 223 + +/* cru_softrst_con14 */ +#define SRST_TOPNIU_P 224 +#define SRST_TOPCRU_P 225 +#define SRST_TOPGRF_P 226 +#define SRST_CPUEMADET_P 227 +#define SRST_CSIPHY0_P 228 +#define SRST_CSIPHY1_P 229 +#define SRST_DSIPHY_P 230 +#define SRST_CPU_TSADC_P 232 +#define SRST_CPU_TSADC 233 +#define SRST_CPU_TSADCPHY 234 +#define SRST_CPUPVTM_P 235 +#define SRST_CPUPVTM 236 + +#endif diff --git a/include/dt-bindings/power/rockchip,rv1126-power.h b/include/dt-bindings/power/rockchip,rv1126-power.h new file mode 100644 index 0000000..38a68e0 --- /dev/null +++ b/include/dt-bindings/power/rockchip,rv1126-power.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __DT_BINDINGS_POWER_RV1126_POWER_H__ +#define __DT_BINDINGS_POWER_RV1126_POWER_H__ + +/* VD_CORE */ +#define RV1126_PD_CPU_0 0 +#define RV1126_PD_CPU_1 1 +#define RV1126_PD_CPU_2 2 +#define RV1126_PD_CPU_3 3 +#define RV1126_PD_CORE_ALIVE 4 + +/* VD_PMU */ +#define RV1126_PD_PMU 5 +#define RV1126_PD_PMU_ALIVE 6 + +/* VD_NPU */ +#define RV1126_PD_NPU 7 + +/* VD_VEPU */ +#define RV1126_PD_VEPU 8 + +/* VD_LOGIC */ +#define RV1126_PD_VI 9 +#define RV1126_PD_VO 10 +#define RV1126_PD_ISPP 11 +#define RV1126_PD_VDPU 12 +#define RV1126_PD_CRYPTO 13 +#define RV1126_PD_DDR 14 +#define RV1126_PD_NVM 15 +#define RV1126_PD_SDIO 16 +#define RV1126_PD_USB 17 +#define RV1126_PD_LOGIC_ALIVE 18 + +#endif diff --git a/include/rc4.h b/include/rc4.h index c1ff134..d1257f2 100644 --- a/include/rc4.h +++ b/include/rc4.h @@ -15,6 +15,6 @@ * @len: Length of buffer in bytes * @key: 16-byte key to use */ -void rc4_encode(unsigned char *buf, unsigned int len, unsigned char key[16]); +void rc4_encode(unsigned char *buf, unsigned int len, const unsigned char key[16]); #endif @@ -12,7 +12,7 @@ #endif #include <rc4.h> -void rc4_encode(unsigned char *buf, unsigned int len, unsigned char key[16]) +void rc4_encode(unsigned char *buf, unsigned int len, const unsigned char key[16]) { unsigned char s[256], k[256], temp; unsigned short i, j, t; diff --git a/tools/rkcommon.c b/tools/rkcommon.c index 0db45c2..1f1eaa1 100644 --- a/tools/rkcommon.c +++ b/tools/rkcommon.c @@ -133,6 +133,7 @@ static struct spl_info spl_infos[] = { { "rk3368", "RK33", 0x8000 - 0x1000, false, RK_HEADER_V1 }, { "rk3399", "RK33", 0x30000 - 0x2000, false, RK_HEADER_V1 }, { "rv1108", "RK11", 0x1800, false, RK_HEADER_V1 }, + { "rv1126", "110B", 0x10000 - 0x1000, false, RK_HEADER_V1 }, { "rk3568", "RK35", 0x14000 - 0x1000, false, RK_HEADER_V2 }, }; @@ -154,7 +155,7 @@ struct spl_params { static struct spl_params spl_params = { 0 }; -static unsigned char rc4_key[16] = { +static const unsigned char rc4_key[16] = { 124, 78, 3, 4, 85, 5, 9, 7, 45, 44, 123, 56, 23, 13, 23, 17 }; |