mirror of
https://gitee.com/bianbu-linux/uboot-2022.10
synced 2025-04-24 06:47:16 -04:00
Compare commits
6 commits
Author | SHA1 | Date | |
---|---|---|---|
|
60297de7dc | ||
|
8bdc7887dc | ||
|
a996a74cc1 | ||
|
ad097c0e1d | ||
|
f91a284fab | ||
|
c83b48d3b0 |
109 changed files with 5390 additions and 516 deletions
|
@ -43,5 +43,6 @@ CFLAGS_EFI += $(ARCH_FLAGS)
|
|||
head-y := arch/riscv/cpu/start.o
|
||||
|
||||
libs-y += arch/riscv/cpu/
|
||||
libs-y += arch/riscv/kernel/
|
||||
libs-y += arch/riscv/cpu/$(CPU)/
|
||||
libs-y += arch/riscv/lib/
|
||||
|
|
|
@ -13,6 +13,8 @@ dtb-$(CONFIG_TARGET_SPACEMIT_K1X) += k1-x_evb.dtb k1-x_deb2.dtb k1-x_deb1.dtb k1
|
|||
k1-x_MUSE-Pi.dtb k1-x_spl.dtb k1-x_milkv-jupiter.dtb \
|
||||
k1-x_MUSE-Book.dtb m1-x_milkv-jupiter.dtb \
|
||||
k1-x_lpi3a.dtb k1-x_MUSE-Card.dtb k1-x_MUSE-Paper.dtb \
|
||||
k1-x_MUSE-Paper-mini-4g.dtb k1-x_baton-camera.dtb \
|
||||
k1-x_FusionOne.dtb
|
||||
|
||||
include $(srctree)/scripts/Makefile.dts
|
||||
|
||||
|
|
|
@ -529,6 +529,16 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm1: pwm@d401a400 {
|
||||
compatible = "spacemit,k1x-pwm";
|
||||
reg = <0x0 0xd401a000 0x0 0x10>;
|
||||
#pwm-cells = <2>;
|
||||
clocks = <&ccu CLK_PWM0>;
|
||||
resets = <&reset RESET_PWM0>;
|
||||
k1x,pwm-disable-fd = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm14: pwm@d4021800 {
|
||||
compatible = "spacemit,k1x-pwm";
|
||||
reg = <0x0 0xd4021800 0x0 0x10>;
|
||||
|
@ -539,6 +549,12 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
backlight: backlight {
|
||||
compatible = "pwm-backlight";
|
||||
brightness-levels = <0 4 8 16 32 64 100 128 255>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pcie0_rc: pcie@ca000000 {
|
||||
compatible = "k1x,dwc-pcie";
|
||||
reg = <0x0 0xca000000 0x0 0x00001000>, /* dbi */
|
||||
|
@ -841,6 +857,10 @@
|
|||
};
|
||||
};
|
||||
|
||||
shutdown_charging: charging {
|
||||
compatible = "k1,shutdown-charging";
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
binman: binman {
|
||||
|
|
207
arch/riscv/dts/k1-x_FusionOne.dts
Normal file
207
arch/riscv/dts/k1-x_FusionOne.dts
Normal file
|
@ -0,0 +1,207 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/* Copyright (c) 2023 Spacemit, Inc */
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "k1-x.dtsi"
|
||||
#include "k1-x_pinctrl.dtsi"
|
||||
#include "k1-x_spm8821.dtsi"
|
||||
|
||||
/ {
|
||||
model = "spacemit k1-x FusionOne board";
|
||||
|
||||
aliases {
|
||||
efuse_power = &ldo_31;
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x00000000 0x00000000 0x80000000>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs = "earlycon=sbi console=ttyS0,115200 debug loglevel=8,initcall_debug=1 rdinit=/init.tmp";
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
usb3hub:usb3hub {
|
||||
compatible = "spacemit,usb-hub";
|
||||
vbus-gpios = <&gpio 127 0>; /* gpio_97 for usb3 hub output vbus */
|
||||
regulator-force-boot-off;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&cpus {
|
||||
timebase-frequency = <24000000>;
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c2_0>;
|
||||
status = "okay";
|
||||
|
||||
eeprom@50{
|
||||
compatible = "atmel,24c02";
|
||||
reg = <0x50>;
|
||||
vin-supply-names = "eeprom_1v8";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&i2c4 {
|
||||
clock-frequency = <400000>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
pinctrl-single,gpio-range = <
|
||||
&range GPIO_49 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4)
|
||||
&range GPIO_58 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_63 2 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_65 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_66 2 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_75 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_90 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_110 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_115 2 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_125 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_127 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
>;
|
||||
|
||||
gpio80_pmx_func0: gpio80_pmx_func0 {
|
||||
pinctrl-single,pins = <
|
||||
K1X_PADCONF(GPIO_80, MUX_MODE0, (EDGE_BOTH | PULL_UP | PAD_3V_DS4)) /* mmc cd */
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
&gpio{
|
||||
gpio-ranges = <
|
||||
&pinctrl 49 GPIO_49 2
|
||||
&pinctrl 58 GPIO_58 1
|
||||
&pinctrl 63 GPIO_63 5
|
||||
&pinctrl 75 GPIO_75 1
|
||||
&pinctrl 79 GPIO_79 1
|
||||
&pinctrl 90 GPIO_90 1
|
||||
&pinctrl 110 GPIO_110 1
|
||||
&pinctrl 115 GPIO_115 2
|
||||
&pinctrl 125 GPIO_125 1
|
||||
&pinctrl 127 GPIO_127 1
|
||||
>;
|
||||
};
|
||||
|
||||
&udc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb2phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&combphy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usbdrd3 {
|
||||
status = "okay";
|
||||
vbus-supply = <&usb3hub>;
|
||||
dwc3@c0a00000 {
|
||||
dr_mode = "host";
|
||||
phy_type = "utmi";
|
||||
snps,dis_enblslpm_quirk;
|
||||
snps,dis_u2_susphy_quirk;
|
||||
snps,dis_u3_susphy_quirk;
|
||||
snps,dis-del-phy-power-chg-quirk;
|
||||
snps,dis-tx-ipgap-linecheck-quirk;
|
||||
};
|
||||
};
|
||||
|
||||
&sdhci0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mmc1 &gpio80_pmx_func0>;
|
||||
bus-width = <4>;
|
||||
cd-gpios = <&gpio 80 0>;
|
||||
cd-inverted;
|
||||
cap-sd-highspeed;
|
||||
sdh-phy-module = <0>;
|
||||
clk-src-freq = <204800000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
/* eMMC */
|
||||
&sdhci2 {
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
mmc-hs400-1_8v;
|
||||
mmc-hs400-enhanced-strobe;
|
||||
sdh-phy-module = <1>;
|
||||
clk-src-freq = <375000000>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ð0 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_gmac0>;
|
||||
|
||||
phy-reset-pin = <110>;
|
||||
|
||||
clk_tuning_enable;
|
||||
clk-tuning-by-delayline;
|
||||
tx-phase = <90>;
|
||||
rx-phase = <73>;
|
||||
|
||||
phy-mode = "rgmii";
|
||||
phy-addr = <1>;
|
||||
phy-handle = <&rgmii>;
|
||||
|
||||
ref-clock-from-phy;
|
||||
|
||||
mdio {
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x0>;
|
||||
rgmii: phy@0 {
|
||||
compatible = "ethernet-phy-id001c.c916";
|
||||
device_type = "ethernet-phy";
|
||||
reg = <0x1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pcie1_rc {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pcie1_3>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&pcie2_rc {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pcie2_4>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&qspi {
|
||||
status = "disabled";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_qspi>;
|
||||
|
||||
flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <26500000>;
|
||||
m25p,fast-read;
|
||||
broken-flash-reset;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
&efuse {
|
||||
status = "okay";
|
||||
};
|
|
@ -240,6 +240,18 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <8>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -247,7 +259,7 @@
|
|||
&panel {
|
||||
dcp-gpios = <&gpio 82 0>;
|
||||
dcn-gpios = <&gpio 83 0>;
|
||||
bl-gpios = <&gpio 44 0>;
|
||||
backlight = <&backlight>;
|
||||
reset-gpios = <&gpio 81 0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -23,6 +23,13 @@
|
|||
bootargs = "earlycon=sbi console=ttyS0,115200 debug loglevel=8,initcall_debug=1 rdinit=/init.tmp";
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
usb3hub: usb3hub {
|
||||
compatible = "spacemit,usb-hub";
|
||||
vbus-gpios = <&gpio 123 0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&cpus {
|
||||
|
@ -127,10 +134,36 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&usbphy1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ehci1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb2phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&combphy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usbdrd3 {
|
||||
status = "okay";
|
||||
vbus-supply = <&usb3hub>;
|
||||
dwc3@c0a00000 {
|
||||
dr_mode = "host";
|
||||
phy_type = "utmi";
|
||||
snps,dis_enblslpm_quirk;
|
||||
snps,dis_u2_susphy_quirk;
|
||||
snps,dis_u3_susphy_quirk;
|
||||
snps,dis-del-phy-power-chg-quirk;
|
||||
snps,dis-tx-ipgap-linecheck-quirk;
|
||||
};
|
||||
};
|
||||
|
||||
&sdhci0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mmc1 &gpio80_pmx_func0>;
|
||||
|
@ -195,6 +228,18 @@
|
|||
};
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <7>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
bit-clk = <933000000>;
|
||||
pix-clk = <142000000>;
|
||||
|
@ -214,7 +259,7 @@
|
|||
|
||||
&panel {
|
||||
force-attached = "lt8911ext_edp_1080p";
|
||||
bl-gpios = <&gpio 44 0>;
|
||||
backlight = <&backlight>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
14
arch/riscv/dts/k1-x_MUSE-Card.dts
Executable file → Normal file
14
arch/riscv/dts/k1-x_MUSE-Card.dts
Executable file → Normal file
|
@ -258,6 +258,18 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <6>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -265,7 +277,7 @@
|
|||
&panel {
|
||||
dcp-gpios = <&gpio 40 0>;
|
||||
dcn-gpios = <&gpio 83 0>;
|
||||
bl-gpios = <&gpio 44 0>;
|
||||
backlight = <&backlight>;
|
||||
reset-gpios = <&gpio 41 0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
271
arch/riscv/dts/k1-x_MUSE-Paper-mini-4g.dts
Normal file
271
arch/riscv/dts/k1-x_MUSE-Paper-mini-4g.dts
Normal file
|
@ -0,0 +1,271 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/* Copyright (c) 2023 Spacemit, Inc */
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "k1-x.dtsi"
|
||||
#include "k1-x_pinctrl.dtsi"
|
||||
#include "k1-x_spm8821.dtsi"
|
||||
|
||||
/ {
|
||||
model = "MUSE-PAPER-MINI-4G";
|
||||
|
||||
aliases {
|
||||
efuse_power = &ldo_31;
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x00000000 0x00000000 0x80000000>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs = "earlycon=sbi console=ttyS0,115200 debug loglevel=8,initcall_debug=1 rdinit=/init.tmp";
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
usb2hub: usb2hub {
|
||||
compatible = "spacemit,usb-hub";
|
||||
vbus-gpios = <&gpio 123 0>; /* for usb2 hub output vbus */
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb3hub: usb3hub {
|
||||
compatible = "spacemit,usb-hub";
|
||||
vbus-gpios = <&gpio 79 0>; /* gpio_79 for usb3 pwren */
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&cpus {
|
||||
timebase-frequency = <24000000>;
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c2_0>;
|
||||
status = "okay";
|
||||
|
||||
eeprom@50{
|
||||
compatible = "atmel,24c02";
|
||||
reg = <0x50>;
|
||||
vin-supply-names = "eeprom_1v8";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&i2c3 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&i2c4 {
|
||||
clock-frequency = <400000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&i2c5 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c5_0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&i2c6 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&i2c7 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
pinctrl-single,gpio-range = <
|
||||
&range GPIO_49 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4)
|
||||
&range GPIO_58 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_63 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_64 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_65 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_66 2 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range PRI_TDI 2 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range PRI_TCK 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range PRI_TDO 1 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_74 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_79 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_80 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4)
|
||||
&range GPIO_81 3 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_90 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_91 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range DVL0 2 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_110 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_114 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_115 2 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_123 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_124 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_125 3 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
>;
|
||||
|
||||
gpio80_pmx_func0: gpio80_pmx_func0 {
|
||||
pinctrl-single,pins = <
|
||||
K1X_PADCONF(GPIO_80, MUX_MODE0, (EDGE_BOTH | PULL_UP | PAD_3V_DS4)) /* mmc cd */
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
&gpio{
|
||||
gpio-ranges = <
|
||||
&pinctrl 49 GPIO_49 2
|
||||
&pinctrl 58 GPIO_58 1
|
||||
&pinctrl 63 GPIO_63 1
|
||||
&pinctrl 65 GPIO_65 3
|
||||
&pinctrl 70 PRI_TDI 4
|
||||
&pinctrl 74 GPIO_74 1
|
||||
&pinctrl 79 GPIO_79 1
|
||||
&pinctrl 80 GPIO_80 4
|
||||
&pinctrl 90 GPIO_90 3
|
||||
&pinctrl 96 DVL0 2
|
||||
&pinctrl 110 GPIO_110 1
|
||||
&pinctrl 114 GPIO_114 3
|
||||
&pinctrl 123 GPIO_123 5
|
||||
>;
|
||||
};
|
||||
|
||||
&udc {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&usbphy1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&ehci1 {
|
||||
vbus-supply = <&usb2hub>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&usb2phy {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&combphy {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
&usbdrd3 {
|
||||
status = "disabled";
|
||||
vbus-supply = <&usb3hub>;
|
||||
dwc3@c0a00000 {
|
||||
dr_mode = "host";
|
||||
phy_type = "utmi";
|
||||
snps,dis_enblslpm_quirk;
|
||||
snps,dis_u2_susphy_quirk;
|
||||
snps,dis_u3_susphy_quirk;
|
||||
snps,dis-del-phy-power-chg-quirk;
|
||||
snps,dis-tx-ipgap-linecheck-quirk;
|
||||
};
|
||||
};
|
||||
|
||||
&sdhci0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mmc1 &gpio80_pmx_func0>;
|
||||
bus-width = <4>;
|
||||
cd-gpios = <&gpio 80 0>;
|
||||
cap-sd-highspeed;
|
||||
sdh-phy-module = <0>;
|
||||
clk-src-freq = <204800000>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* eMMC */
|
||||
&sdhci2 {
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
mmc-hs400-1_8v;
|
||||
mmc-hs400-enhanced-strobe;
|
||||
sdh-phy-module = <1>;
|
||||
clk-src-freq = <375000000>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&qspi {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_qspi>;
|
||||
|
||||
flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <26500000>;
|
||||
m25p,fast-read;
|
||||
broken-flash-reset;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&efuse {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ldo_27 {
|
||||
regulator-init-microvolt = <1200000>;
|
||||
regulator-boot-on;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
&ldo_33 {
|
||||
regulator-init-microvolt = <1800000>;
|
||||
regulator-boot-on;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
&dpu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <6>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
bit-clk = <614400000>;
|
||||
pix-clk = <76800000>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&panel {
|
||||
force-attached = "jd9365dah3";
|
||||
dcp-gpios = <&gpio 34 0>;
|
||||
dcn-gpios = <&gpio 42 0>;
|
||||
avee-gpios = <&gpio 35 0>;
|
||||
avdd-gpios = <&gpio 36 0>;
|
||||
backlight = <&backlight>;
|
||||
enable-gpios = <&gpio 31 0>;
|
||||
reset-gpios = <&gpio 30 0>;
|
||||
status = "okay";
|
||||
};
|
111
arch/riscv/dts/k1-x_MUSE-Paper.dts
Executable file → Normal file
111
arch/riscv/dts/k1-x_MUSE-Paper.dts
Executable file → Normal file
|
@ -6,6 +6,7 @@
|
|||
#include "k1-x.dtsi"
|
||||
#include "k1-x_pinctrl.dtsi"
|
||||
#include "k1-x_spm8821.dtsi"
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
model = "M1-MUSE-PAPER";
|
||||
|
@ -36,6 +37,26 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
gpio_keys: gpio_keys {
|
||||
compatible = "gpio-keys";
|
||||
fastboot-key-combo = "volume-up";
|
||||
fastboot-key-press-time = <2000>; /* in milliseconds */
|
||||
|
||||
volume-up-button {
|
||||
label = "volume-up";
|
||||
linux,code = <KEY_VOLUMEUP>;
|
||||
gpios = <&gpio 70 1>;
|
||||
debounce-interval = <10>;
|
||||
};
|
||||
|
||||
volume-down-button {
|
||||
label = "volume-down";
|
||||
linux,code = <KEY_VOLUMEDOWN>;
|
||||
gpios = <&gpio 71 1>;
|
||||
debounce-interval = <10>;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&cpus {
|
||||
|
@ -74,8 +95,27 @@
|
|||
};
|
||||
|
||||
&i2c4 {
|
||||
clock-frequency = <400000>;
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c4_2>;
|
||||
status = "okay";
|
||||
|
||||
cw2015: cw2015@62 {
|
||||
compatible = "spacemit,cw2015";
|
||||
reg = <0x62>;
|
||||
cellwise,battery-profile = /bits/ 8 <
|
||||
0x17 0x67 0x73 0x69 0x68 0x65 0x64 0x55
|
||||
0x75 0x60 0x4A 0x57 0x57 0x4E 0x42 0x3A
|
||||
0x30 0x28 0x23 0x1E 0x23 0x35 0x46 0x4D
|
||||
0x14 0x86 0x06 0x66 0x25 0x45 0x51 0x63
|
||||
0x72 0x69 0x66 0x6B 0x3F 0x1B 0x78 0x39
|
||||
0x0A 0x2F 0x1A 0x46 0x88 0x94 0x9B 0x12
|
||||
0x3B 0x5F 0x9A 0xB6 0x80 0x57 0x7F 0xCB
|
||||
0x2F 0x00 0x64 0xA5 0xB5 0xC1 0x46 0xAE
|
||||
>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&i2c5 {
|
||||
|
@ -85,13 +125,40 @@
|
|||
};
|
||||
|
||||
&i2c6 {
|
||||
status = "disabled";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c6_0>;
|
||||
status = "okay";
|
||||
secsgm41515: sgm41515-2 {
|
||||
compatible = "spacemit,sgm41515";
|
||||
reg = <0x1a>;
|
||||
ch-en-gpios = <&gpio 46 0>;
|
||||
nqon-gpios = <&gpio 43 0>;
|
||||
|
||||
sgm41515-ichrg-uA = <1000000>;
|
||||
sgm41515-vchrg-uV = <4350000>;
|
||||
sgm41515-cur-input-uA = <2000000>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&i2c7 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&i2c8 {
|
||||
sgm41515: sgm41515 {
|
||||
compatible = "spacemit,sgm41515";
|
||||
reg = <0x1a>;
|
||||
ch-en-gpios = <&gpio 117 0>;
|
||||
nqon-gpios = <&gpio 115 0>;
|
||||
|
||||
sgm41515-ichrg-uA = <1000000>;
|
||||
sgm41515-vchrg-uV = <4350000>;
|
||||
sgm41515-cur-input-uA = <2000000>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
pinctrl-single,gpio-range = <
|
||||
&range GPIO_49 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4)
|
||||
|
@ -240,6 +307,18 @@
|
|||
};
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <4>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -250,8 +329,32 @@
|
|||
dcn-gpios = <&gpio 42 0>;
|
||||
avee-gpios = <&gpio 35 0>;
|
||||
avdd-gpios = <&gpio 36 0>;
|
||||
bl-gpios = <&gpio 44 0>;
|
||||
backlight = <&backlight>;
|
||||
enable-gpios = <&gpio 31 0>;
|
||||
reset-gpios = <&gpio 30 0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&shutdown_charging {
|
||||
electricity-meter = <&cw2015>;
|
||||
power-domains = <&pmu K1X_PMU_WKUP_EVENT_PWR_DOMAIN>;
|
||||
|
||||
wk-name = "pwr_event", "pwr_int", "rtc_ctrl", "rtc_event", "rtc_irq", "sys-shutdown";
|
||||
pwr_event = <&power_event>;
|
||||
pwr_int = <&power_int>;
|
||||
|
||||
rtc_ctrl = <&rtc_ctrl>;
|
||||
rtc_event = <&rtc_event>;
|
||||
rtc_irq = <&rtc_irq>;
|
||||
|
||||
sys-shutdown = <&power_down>;
|
||||
reboot-flag = <&reboot_flag>;
|
||||
|
||||
charge-light = <&gpio 75 0 &gpio 76 0>;
|
||||
|
||||
charger-name = "charger0", "charger1";
|
||||
charger0 = <&sgm41515>;
|
||||
charger1 = <&secsgm41515>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -273,6 +273,18 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <6>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -280,7 +292,7 @@
|
|||
&panel {
|
||||
dcp-gpios = <&gpio 82 0>;
|
||||
dcn-gpios = <&gpio 83 0>;
|
||||
bl-gpios = <&gpio 44 0>;
|
||||
backlight = <&backlight>;
|
||||
reset-gpios = <&gpio 81 0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
295
arch/riscv/dts/k1-x_baton-camera.dts
Normal file
295
arch/riscv/dts/k1-x_baton-camera.dts
Normal file
|
@ -0,0 +1,295 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/* Copyright (c) 2023 Spacemit, Inc */
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "k1-x.dtsi"
|
||||
#include "k1-x_pinctrl.dtsi"
|
||||
#include "k1-x_spm8821.dtsi"
|
||||
|
||||
/ {
|
||||
model = "spacemit k1-x baton-camera board";
|
||||
|
||||
aliases {
|
||||
efuse_power = &ldo_31;
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x00000000 0x00000000 0x80000000>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs = "earlycon=sbi console=ttyS0,115200 debug loglevel=8,initcall_debug=1 rdinit=/init.tmp";
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
usb2hub: usb2hub {
|
||||
compatible = "spacemit,usb-hub";
|
||||
vbus-gpios = <&gpio 123 0>; /* for usb2 hub output vbus */
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usb3hub: usb3hub {
|
||||
compatible = "spacemit,usb-hub";
|
||||
vbus-gpios = <&gpio 79 0>; /* gpio_79 for usb3 pwren */
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&cpus {
|
||||
timebase-frequency = <24000000>;
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c2_0>;
|
||||
status = "okay";
|
||||
|
||||
eeprom@50{
|
||||
compatible = "atmel,24c02";
|
||||
reg = <0x50>;
|
||||
vin-supply-names = "eeprom_1v8";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&i2c3 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&i2c4 {
|
||||
clock-frequency = <400000>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c5 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c5_0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c6 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&i2c7 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
pinctrl-single,gpio-range = <
|
||||
&range GPIO_49 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4)
|
||||
&range GPIO_58 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_63 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_64 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_65 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_66 2 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range PRI_TDI 2 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range PRI_TCK 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range PRI_TDO 1 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_74 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_79 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_80 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4)
|
||||
&range GPIO_81 3 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_90 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_91 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range DVL0 2 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_110 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_114 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_115 2 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_123 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
&range GPIO_124 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
&range GPIO_125 3 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
|
||||
>;
|
||||
|
||||
gpio80_pmx_func0: gpio80_pmx_func0 {
|
||||
pinctrl-single,pins = <
|
||||
K1X_PADCONF(GPIO_80, MUX_MODE0, (EDGE_BOTH | PULL_UP | PAD_3V_DS4)) /* mmc cd */
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
&gpio{
|
||||
gpio-ranges = <
|
||||
&pinctrl 49 GPIO_49 2
|
||||
&pinctrl 58 GPIO_58 1
|
||||
&pinctrl 63 GPIO_63 1
|
||||
&pinctrl 65 GPIO_65 3
|
||||
&pinctrl 70 PRI_TDI 4
|
||||
&pinctrl 74 GPIO_74 1
|
||||
&pinctrl 79 GPIO_79 1
|
||||
&pinctrl 80 GPIO_80 4
|
||||
&pinctrl 90 GPIO_90 3
|
||||
&pinctrl 96 DVL0 2
|
||||
&pinctrl 110 GPIO_110 1
|
||||
&pinctrl 114 GPIO_114 3
|
||||
&pinctrl 123 GPIO_123 5
|
||||
>;
|
||||
};
|
||||
|
||||
&udc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usbphy1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ehci1 {
|
||||
vbus-supply = <&usb2hub>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb2phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&combphy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
&usbdrd3 {
|
||||
status = "okay";
|
||||
vbus-supply = <&usb3hub>;
|
||||
dwc3@c0a00000 {
|
||||
dr_mode = "host";
|
||||
phy_type = "utmi";
|
||||
snps,dis_enblslpm_quirk;
|
||||
snps,dis_u2_susphy_quirk;
|
||||
snps,dis_u3_susphy_quirk;
|
||||
snps,dis-del-phy-power-chg-quirk;
|
||||
snps,dis-tx-ipgap-linecheck-quirk;
|
||||
};
|
||||
};
|
||||
|
||||
&sdhci0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mmc1 &gpio80_pmx_func0>;
|
||||
bus-width = <4>;
|
||||
cd-gpios = <&gpio 80 0>;
|
||||
cap-sd-highspeed;
|
||||
sdh-phy-module = <0>;
|
||||
clk-src-freq = <204800000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
/* eMMC */
|
||||
&sdhci2 {
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
mmc-hs400-1_8v;
|
||||
mmc-hs400-enhanced-strobe;
|
||||
sdh-phy-module = <1>;
|
||||
clk-src-freq = <375000000>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
ð0 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_gmac0>;
|
||||
|
||||
phy-reset-pin = <110>;
|
||||
|
||||
clk_tuning_enable;
|
||||
clk-tuning-by-delayline;
|
||||
tx-phase = <90>;
|
||||
rx-phase = <73>;
|
||||
|
||||
phy-mode = "rgmii";
|
||||
phy-addr = <1>;
|
||||
phy-handle = <&rgmii>;
|
||||
|
||||
ref-clock-from-phy;
|
||||
|
||||
mdio {
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x0>;
|
||||
rgmii: phy@0 {
|
||||
compatible = "ethernet-phy-id001c.c916";
|
||||
device_type = "ethernet-phy";
|
||||
reg = <0x1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pcie0_rc {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&pcie1_rc {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pcie1_3>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&qspi {
|
||||
status = "disabled";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_qspi>;
|
||||
|
||||
flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <26500000>;
|
||||
m25p,fast-read;
|
||||
broken-flash-reset;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
&efuse {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&dpu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&hdmi {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_hdmi_0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <6>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&panel {
|
||||
dcp-gpios = <&gpio 40 0>;
|
||||
dcn-gpios = <&gpio 83 0>;
|
||||
backlight = <&backlight>;
|
||||
reset-gpios = <&gpio 41 0>;
|
||||
status = "disabled";
|
||||
};
|
|
@ -259,6 +259,18 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <6>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -266,7 +278,7 @@
|
|||
&panel {
|
||||
dcp-gpios = <&gpio 82 0>;
|
||||
dcn-gpios = <&gpio 83 0>;
|
||||
bl-gpios = <&gpio 44 0>;
|
||||
backlight = <&backlight>;
|
||||
reset-gpios = <&gpio 81 0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -256,6 +256,18 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <6>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -263,7 +275,7 @@
|
|||
&panel {
|
||||
dcp-gpios = <&gpio 82 0>;
|
||||
dcn-gpios = <&gpio 83 0>;
|
||||
bl-gpios = <&gpio 44 0>;
|
||||
backlight = <&backlight>;
|
||||
reset-gpios = <&gpio 81 0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -236,6 +236,18 @@
|
|||
};
|
||||
};
|
||||
|
||||
&pwm1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm1_2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm1 0 2000>;
|
||||
default-brightness-level = <6>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -200,6 +200,18 @@
|
|||
};
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <7>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
bit-clk = <933000000>;
|
||||
pix-clk = <142000000>;
|
||||
|
@ -219,7 +231,7 @@
|
|||
|
||||
&panel {
|
||||
force-attached = "lt8911ext_edp_1080p";
|
||||
bl-gpios = <&gpio 44 0>;
|
||||
backlight = <&backlight>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
@ -259,6 +259,18 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <6>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -266,7 +278,7 @@
|
|||
&panel {
|
||||
dcp-gpios = <&gpio 82 0>;
|
||||
dcn-gpios = <&gpio 83 0>;
|
||||
bl-gpios = <&gpio 44 0>;
|
||||
backlight = <&backlight>;
|
||||
reset-gpios = <&gpio 81 0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -259,6 +259,18 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <8>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -266,7 +278,7 @@
|
|||
&panel {
|
||||
dcp-gpios = <&gpio 82 0>;
|
||||
dcn-gpios = <&gpio 83 0>;
|
||||
bl-gpios = <&gpio 44 0>;
|
||||
backlight = <&backlight>;
|
||||
reset-gpios = <&gpio 81 0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
regulator-boot-on;
|
||||
u-boot,dm-spl;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <650000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -30,6 +30,9 @@
|
|||
regulator-name = "dcdc2";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3450000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
dcdc_8: DCDC_REG3 {
|
||||
|
@ -38,24 +41,36 @@
|
|||
regulator-max-microvolt = <3450000>;
|
||||
regulator-boot-on;
|
||||
u-boot,dm-spl;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
dcdc_9: DCDC_REG4 {
|
||||
regulator-name = "dcdc4";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3450000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
dcdc_10: DCDC_REG5 {
|
||||
regulator-name = "dcdc5";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3450000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
dcdc_11: DCDC_REG6 {
|
||||
regulator-name = "dcdc6";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3450000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
/* aldo */
|
||||
|
@ -66,24 +81,36 @@
|
|||
regulator-init-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
u-boot,dm-spl;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
ldo_24: LDO_REG2 {
|
||||
regulator-name = "ldo2";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
ldo_25: LDO_REG3 {
|
||||
regulator-name = "ldo3";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
ldo_26: LDO_REG4 {
|
||||
regulator-name = "ldo4";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
/* dldo */
|
||||
|
@ -91,48 +118,97 @@
|
|||
regulator-name = "ldo5";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
ldo_28: LDO_REG6 {
|
||||
regulator-name = "ldo6";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
ldo_29: LDO_REG7 {
|
||||
regulator-name = "ldo7";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
ldo_30: LDO_REG8 {
|
||||
regulator-name = "ldo8";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
ldo_31: LDO_REG9 {
|
||||
regulator-name = "ldo9";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
ldo_32: LDO_REG10 {
|
||||
regulator-name = "ldo10";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
ldo_33: LDO_REG11 {
|
||||
regulator-name = "ldo11";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
sw_2: SWITCH_REG1 {
|
||||
regulator-name = "switch1";
|
||||
};
|
||||
|
||||
power_event: SWITCH_REG2 {
|
||||
regulator-name = "pwr-event";
|
||||
};
|
||||
|
||||
power_int: SWITCH_REG3 {
|
||||
regulator-name = "pwr-int";
|
||||
};
|
||||
|
||||
rtc_ctrl: SWITCH_REG4 {
|
||||
regulator-name = "rtc-ctrl";
|
||||
};
|
||||
|
||||
rtc_event: SWITCH_REG5 {
|
||||
regulator-name = "rtc-event";
|
||||
};
|
||||
|
||||
rtc_irq: SWITCH_REG6 {
|
||||
regulator-name = "rtc-irq";
|
||||
};
|
||||
|
||||
power_down: SWITCH_REG7 {
|
||||
regulator-name = "power-down";
|
||||
};
|
||||
|
||||
reboot_flag: SWITCH_REG8 {
|
||||
regulator-name = "reboot-flag";
|
||||
};
|
||||
|
||||
wdt_pm8821: PMIC_WDT {
|
||||
wdt-name = "wdt_pm8821";
|
||||
};
|
||||
|
|
|
@ -259,6 +259,18 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&pwm14 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm14_1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
pwms = <&pwm14 0 2000>;
|
||||
default-brightness-level = <8>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mipi_dsi {
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -266,7 +278,7 @@
|
|||
&panel {
|
||||
dcp-gpios = <&gpio 82 0>;
|
||||
dcn-gpios = <&gpio 83 0>;
|
||||
bl-gpios = <&gpio 44 0>;
|
||||
backlight = <&backlight>;
|
||||
reset-gpios = <&gpio 81 0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
42
arch/riscv/include/asm/sleep.h
Normal file
42
arch/riscv/include/asm/sleep.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
#ifndef __SLEEP__H_
|
||||
#define __SLEEP__H_
|
||||
|
||||
#define PT_EPC 0 /* offsetof(struct pt_regs, epc) */
|
||||
#define PT_RA 8 /* offsetof(struct pt_regs, ra) */
|
||||
#define PT_S0 64 /* offsetof(struct pt_regs, s0) */
|
||||
#define PT_S1 72 /* offsetof(struct pt_regs, s1) */
|
||||
#define PT_S2 144 /* offsetof(struct pt_regs, s2) */
|
||||
#define PT_S3 152 /* offsetof(struct pt_regs, s3) */
|
||||
#define PT_S4 160 /* offsetof(struct pt_regs, s4) */
|
||||
#define PT_S5 168 /* offsetof(struct pt_regs, s5) */
|
||||
#define PT_S6 176 /* offsetof(struct pt_regs, s6) */
|
||||
#define PT_S7 184 /* offsetof(struct pt_regs, s7) */
|
||||
#define PT_S8 192 /* offsetof(struct pt_regs, s8) */
|
||||
#define PT_S9 200 /* offsetof(struct pt_regs, s9) */
|
||||
#define PT_S10 208 /* offsetof(struct pt_regs, s10) */
|
||||
#define PT_S11 216 /* offsetof(struct pt_regs, s11) */
|
||||
#define PT_SP 16 /* offsetof(struct pt_regs, sp) */
|
||||
#define PT_TP 32 /* offsetof(struct pt_regs, tp) */
|
||||
#define PT_A0 80 /* offsetof(struct pt_regs, a0) */
|
||||
#define PT_A1 88 /* offsetof(struct pt_regs, a1) */
|
||||
#define PT_A2 96 /* offsetof(struct pt_regs, a2) */
|
||||
#define PT_A3 104 /* offsetof(struct pt_regs, a3) */
|
||||
#define PT_A4 112 /* offsetof(struct pt_regs, a4) */
|
||||
#define PT_A5 120 /* offsetof(struct pt_regs, a5) */
|
||||
#define PT_A6 128 /* offsetof(struct pt_regs, a6) */
|
||||
#define PT_A7 136 /* offsetof(struct pt_regs, a7) */
|
||||
#define PT_T0 40 /* offsetof(struct pt_regs, t0) */
|
||||
#define PT_T1 48 /* offsetof(struct pt_regs, t1) */
|
||||
#define PT_T2 56 /* offsetof(struct pt_regs, t2) */
|
||||
#define PT_T3 224 /* offsetof(struct pt_regs, t3) */
|
||||
#define PT_T4 232 /* offsetof(struct pt_regs, t4) */
|
||||
#define PT_T5 240 /* offsetof(struct pt_regs, t5) */
|
||||
#define PT_T6 248 /* offsetof(struct pt_regs, t6) */
|
||||
#define PT_GP 24 /* offsetof(struct pt_regs, gp) */
|
||||
#define PT_ORIG_A0 280 /* offsetof(struct pt_regs, orig_a0) */
|
||||
#define PT_STATUS 256 /* offsetof(struct pt_regs, status) */
|
||||
#define PT_BADADDR 264 /* offsetof(struct pt_regs, badaddr) */
|
||||
#define PT_CAUSE 272 /* offsetof(struct pt_regs, cause) */
|
||||
#define SUSPEND_CONTEXT_REGS 0 /* offsetof(struct suspend_context, regs) */
|
||||
|
||||
#endif
|
1
arch/riscv/kernel/Makefile
Normal file
1
arch/riscv/kernel/Makefile
Normal file
|
@ -0,0 +1 @@
|
|||
obj-y += suspend_entry.o
|
112
arch/riscv/kernel/suspend_entry.S
Normal file
112
arch/riscv/kernel/suspend_entry.S
Normal file
|
@ -0,0 +1,112 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021 Western Digital Corporation or its affiliates.
|
||||
* Copyright (c) 2022 Ventana Micro Systems Inc.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/sleep.h>
|
||||
|
||||
#define LREG ld
|
||||
#define SREG sd
|
||||
|
||||
.text
|
||||
.altmacro
|
||||
.option norelax
|
||||
|
||||
ENTRY(__cpu_suspend_enter)
|
||||
/* Save registers (except A0 and T0-T6) */
|
||||
SREG ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0)
|
||||
SREG sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0)
|
||||
SREG gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0)
|
||||
SREG tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0)
|
||||
SREG s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0)
|
||||
SREG s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0)
|
||||
SREG a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0)
|
||||
SREG a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0)
|
||||
SREG a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0)
|
||||
SREG a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0)
|
||||
SREG a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0)
|
||||
SREG a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0)
|
||||
SREG a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0)
|
||||
SREG s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0)
|
||||
SREG s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0)
|
||||
SREG s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0)
|
||||
SREG s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0)
|
||||
SREG s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0)
|
||||
SREG s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0)
|
||||
SREG s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0)
|
||||
SREG s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0)
|
||||
SREG s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0)
|
||||
SREG s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
|
||||
|
||||
/* Save CSRs */
|
||||
csrr t0, CSR_SEPC
|
||||
SREG t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0)
|
||||
csrr t0, CSR_SSTATUS
|
||||
SREG t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0)
|
||||
csrr t0, CSR_STVAL
|
||||
SREG t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0)
|
||||
csrr t0, CSR_SCAUSE
|
||||
SREG t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0)
|
||||
|
||||
/* Return non-zero value */
|
||||
li a0, 1
|
||||
|
||||
/* Return to C code */
|
||||
ret
|
||||
END(__cpu_suspend_enter)
|
||||
|
||||
ENTRY(__cpu_resume_enter)
|
||||
/* Load the global pointer */
|
||||
# .option push
|
||||
# .option norelax
|
||||
# la gp, gd
|
||||
# .option pop
|
||||
|
||||
/* Make A0 point to suspend context */
|
||||
add a0, a1, zero
|
||||
|
||||
/* Restore CSRs */
|
||||
LREG t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0)
|
||||
csrw CSR_SEPC, t0
|
||||
LREG t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0)
|
||||
csrw CSR_SSTATUS, t0
|
||||
LREG t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0)
|
||||
csrw CSR_STVAL, t0
|
||||
LREG t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0)
|
||||
csrw CSR_SCAUSE, t0
|
||||
|
||||
/* Restore registers (except A0 and T0-T6) */
|
||||
LREG ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0)
|
||||
LREG sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0)
|
||||
LREG gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0)
|
||||
LREG tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0)
|
||||
LREG s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0)
|
||||
LREG s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0)
|
||||
LREG a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0)
|
||||
LREG a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0)
|
||||
LREG a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0)
|
||||
LREG a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0)
|
||||
LREG a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0)
|
||||
LREG a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0)
|
||||
LREG a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0)
|
||||
LREG s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0)
|
||||
LREG s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0)
|
||||
LREG s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0)
|
||||
LREG s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0)
|
||||
LREG s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0)
|
||||
LREG s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0)
|
||||
LREG s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0)
|
||||
LREG s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0)
|
||||
LREG s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0)
|
||||
LREG s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
|
||||
|
||||
/* Return zero value */
|
||||
add a0, zero, zero
|
||||
|
||||
/* Return to C code */
|
||||
ret
|
||||
END(__cpu_resume_enter)
|
|
@ -5,3 +5,4 @@
|
|||
obj-y += k1x.o
|
||||
obj-$(CONFIG_SPL_BUILD) += spl.o k1x-i2c-eeprom.o k1x-tlvinfo.o
|
||||
obj-$(CONFIG_SPLASH_SOURCE) +=splash.o
|
||||
obj-$(CONFIG_ENV_IS_IN_NFS) +=nfs_env.o
|
||||
|
|
|
@ -154,6 +154,33 @@
|
|||
algo = "crc32";
|
||||
};
|
||||
};
|
||||
fdt_16 {
|
||||
description = "k1-x_MUSE-Paper-mini-4g";
|
||||
type = "flat_dt";
|
||||
compression = "none";
|
||||
data = /incbin/("../dtb/k1-x_MUSE-Paper-mini-4g.dtb");
|
||||
hash-1 {
|
||||
algo = "crc32";
|
||||
};
|
||||
};
|
||||
fdt_17 {
|
||||
description = "k1-x_baton-camera";
|
||||
type = "flat_dt";
|
||||
compression = "none";
|
||||
data = /incbin/("../dtb/k1-x_baton-camera.dtb");
|
||||
hash-1 {
|
||||
algo = "crc32";
|
||||
};
|
||||
};
|
||||
fdt_18 {
|
||||
description = "k1-x_FusionOne";
|
||||
type = "flat_dt";
|
||||
compression = "none";
|
||||
data = /incbin/("../dtb/k1-x_FusionOne.dtb");
|
||||
hash-1 {
|
||||
algo = "crc32";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
configurations {
|
||||
|
@ -233,5 +260,20 @@
|
|||
loadables = "uboot";
|
||||
fdt = "fdt_15";
|
||||
};
|
||||
conf_16 {
|
||||
description = "k1-x_MUSE-Paper-mini-4g";
|
||||
loadables = "uboot";
|
||||
fdt = "fdt_16";
|
||||
};
|
||||
conf_17 {
|
||||
description = "k1-x_baton-camera";
|
||||
loadables = "uboot";
|
||||
fdt = "fdt_17";
|
||||
};
|
||||
conf_18 {
|
||||
description = "k1-x_FusionOne";
|
||||
loadables = "uboot";
|
||||
fdt = "fdt_18";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@ bootdelay=0
|
|||
baudrate=115200
|
||||
loglevel=8
|
||||
stderr=serial
|
||||
stdin=serial,usbkbd
|
||||
stdin=serial,usbkbd,usbkbd1
|
||||
stdout=serial
|
||||
workqueue.default_affinity_scope=system
|
||||
|
||||
|
@ -45,11 +45,12 @@ set_nor_root=run get_rootfs_env; run set_rootfs_env;
|
|||
//ethaddr=fe:fe:fe:22:22:01
|
||||
//eth1addr=fe:fe:fe:22:22:02
|
||||
|
||||
ipaddr=10.0.92.100
|
||||
ipaddr=
|
||||
netmask=255.255.255.0
|
||||
serverip=10.0.92.134
|
||||
serverip=10.0.92.148
|
||||
gatewayip=10.0.92.1
|
||||
net_data_path=net_flash_file/net_flash_file/
|
||||
mac_mapping_file=/home/it/nfs/bianbu/mac_mapping.txt
|
||||
|
||||
preboot=
|
||||
ramdisk_size=-
|
||||
|
@ -65,7 +66,7 @@ phy_link_time=10000
|
|||
netdev=eth0
|
||||
|
||||
// Common boot args
|
||||
commonargs=setenv bootargs earlycon=${earlycon} earlyprintk console=tty1 console=${console} loglevel=${loglevel} clk_ignore_unused swiotlb=65536 rdinit=${init} workqueue.default_affinity_scope=${workqueue.default_affinity_scope}
|
||||
commonargs=setenv bootargs earlycon=${earlycon} earlyprintk quiet splash plymouth.ignore-serial-consoles plymouth.prefer-fbcon console=${console} loglevel=${loglevel} clk_ignore_unused swiotlb=65536 rdinit=${init} workqueue.default_affinity_scope=${workqueue.default_affinity_scope}
|
||||
|
||||
//detect product_name from env and select dtb file to load
|
||||
dtb_env=if test -n "${product_name}"; then \
|
||||
|
@ -112,7 +113,7 @@ loaddtb=echo "Loading dtb..."; \
|
|||
fi;
|
||||
|
||||
// Nor+ssd boot combo
|
||||
set_nor_args=setenv bootargs ${bootargs} mtdparts=${mtdparts} root=${blk_root} rootfstype=ext4
|
||||
set_nor_args=setenv bootargs "${bootargs}" mtdparts=${mtdparts} root=${blk_root} rootfstype=ext4
|
||||
nor_boot=echo "Try to boot from ${bootfs_devname}${boot_devnum} ..."; \
|
||||
run commonargs; \
|
||||
run set_nor_root; \
|
||||
|
@ -140,6 +141,26 @@ mmc_boot=echo "Try to boot from ${bootfs_devname}${boot_devnum} ..."; \
|
|||
bootm ${kernel_addr_r} ${ramdisk_combo} ${dtb_addr}; \
|
||||
echo "########### boot kernel failed by default config, check your boot config #############"
|
||||
|
||||
nfs_boot=echo "Try to boot from NFS ..."; \
|
||||
run commonargs; \
|
||||
setenv bootargs "${bootargs}" root=/dev/nfs nfsroot=${serverip}:${rootfs_path} bootfs=${serverip}:${bootfs_path}; \
|
||||
echo "bootargs: ${bootargs}"; \
|
||||
run detect_dtb; \
|
||||
echo "Loading kernel from NFS..."; \
|
||||
nfs ${kernel_addr_r} ${serverip}:${bootfs_path}/${knl_name}; \
|
||||
echo "Loading dtb from NFS..."; \
|
||||
nfs ${dtb_addr} ${serverip}:${bootfs_path}/${dtb_name}; \
|
||||
if test -n "${ramdisk_name}"; then \
|
||||
echo "Loading ramdisk from NFS..."; \
|
||||
nfs ${ramdisk_addr} ${serverip}:${bootfs_path}/${ramdisk_name}; \
|
||||
setenv ramdisk_size ${filesize}; \
|
||||
setenv ramdisk_combo ${ramdisk_addr}:${ramdisk_size}; \
|
||||
else \
|
||||
setenv ramdisk_combo -; \
|
||||
fi; \
|
||||
bootm ${kernel_addr_r} ${ramdisk_combo} ${dtb_addr}; \
|
||||
echo "########### boot kernel failed from NFS, check your boot config #############"
|
||||
|
||||
// Variable "boot_device" is set during board_late_init()
|
||||
autoboot=if test ${boot_device} = nand; then \
|
||||
run nand_boot; \
|
||||
|
@ -147,6 +168,8 @@ autoboot=if test ${boot_device} = nand; then \
|
|||
run nor_boot; \
|
||||
elif test ${boot_device} = mmc; then \
|
||||
run mmc_boot; \
|
||||
elif test ${boot_device} = nfs; then \
|
||||
run nfs_boot; \
|
||||
fi;
|
||||
|
||||
bootcmd=run autoboot; echo "run autoboot"
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <asm/global_data.h>
|
||||
#include <stdlib.h>
|
||||
#include <linux/delay.h>
|
||||
#include <tlv_eeprom.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -23,6 +24,11 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
#define I2C_PIN_CONFIG(x) ((x) | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
|
||||
#define READ_I2C_LINE_LEN (16)
|
||||
|
||||
int _read_from_i2c(int chip, u32 addr, u32 size, uchar *buf);
|
||||
bool _is_valid_tlvinfo_header(struct tlvinfo_header *hdr);
|
||||
|
||||
static __section(".data") uint8_t tlv_data[256];
|
||||
|
||||
char *spacemit_i2c_eeprom[] = {
|
||||
"atmel,24c02",
|
||||
};
|
||||
|
@ -47,24 +53,33 @@ const struct eeprom_config eeprom_info[] = {
|
|||
{6, 0x50, MUX_MODE2, 0xd401e228, 0xd401e22c},
|
||||
};
|
||||
|
||||
int spacemit_eeprom_read(uint8_t chip, uint8_t *buffer, uint8_t id)
|
||||
static void init_tlv_data(uint8_t chip, uint8_t *buffer, uint32_t size)
|
||||
{
|
||||
uint32_t offset;
|
||||
struct tlvinfo_header *hdr = (struct tlvinfo_header*)buffer;
|
||||
|
||||
offset = sizeof(struct tlvinfo_header);
|
||||
_read_from_i2c(chip, 0, offset, buffer);
|
||||
if (!_is_valid_tlvinfo_header(hdr) || ((be16_to_cpu(hdr->totallen) + offset) > size)) {
|
||||
memset(buffer, 0, size);
|
||||
return;
|
||||
}
|
||||
|
||||
_read_from_i2c(chip, offset, be16_to_cpu(hdr->totallen), buffer + offset);
|
||||
}
|
||||
|
||||
int spacemit_eeprom_read(uint8_t *buffer, uint8_t id)
|
||||
{
|
||||
struct tlv_eeprom tlv;
|
||||
int ret;
|
||||
uint8_t buf[1] = {0};
|
||||
uint8_t len[1] = {0};
|
||||
uint16_t i = 0;
|
||||
uint8_t j;
|
||||
uint32_t i;
|
||||
|
||||
tlv.type = 0;
|
||||
tlv.length = 0;
|
||||
|
||||
for (i = 11; i <= 256; i = i + tlv.length + 2) {
|
||||
ret = i2c_read(chip, i, 1, buf, 1);
|
||||
tlv.type = *buf;
|
||||
|
||||
ret = i2c_read(chip, i + 1, 1, len, 1);
|
||||
tlv.length = *len;
|
||||
for (i = sizeof(struct tlvinfo_header); i < sizeof(tlv_data);
|
||||
i = i + tlv.length + 2) {
|
||||
tlv.type = tlv_data[i];
|
||||
tlv.length = tlv_data[i + 1];
|
||||
|
||||
if (tlv.length == 0) {
|
||||
pr_err("Error: wrong tlv length\n");
|
||||
|
@ -72,10 +87,7 @@ int spacemit_eeprom_read(uint8_t chip, uint8_t *buffer, uint8_t id)
|
|||
}
|
||||
|
||||
if (tlv.type == id) {
|
||||
for(j = 0; j < tlv.length; j++) {
|
||||
ret = i2c_read(chip, i + 2 + j, 1, (char *)buffer, 1);
|
||||
buffer++;
|
||||
}
|
||||
memcpy(buffer, &tlv_data[i + 2], tlv.length);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -119,6 +131,7 @@ int k1x_eeprom_init(void)
|
|||
}
|
||||
else {
|
||||
pr_info("find eeprom in bus %d, address %d\n", bus, saddr);
|
||||
init_tlv_data(saddr, tlv_data, sizeof(tlv_data));
|
||||
return saddr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ static bool had_read_tlvinfo = false;
|
|||
* to the allowed maximum (2048-11)
|
||||
*
|
||||
*/
|
||||
static bool _is_valid_tlvinfo_header(struct tlvinfo_header *hdr)
|
||||
bool _is_valid_tlvinfo_header(struct tlvinfo_header *hdr)
|
||||
{
|
||||
return ((strcmp(hdr->signature, TLV_INFO_ID_STRING) == 0) &&
|
||||
(hdr->version == TLV_INFO_VERSION) &&
|
||||
|
|
|
@ -39,6 +39,17 @@
|
|||
#include <fdt_simplefb.h>
|
||||
#include <mtd_node.h>
|
||||
#include <misc.h>
|
||||
#ifdef CONFIG_ENV_IS_IN_NFS
|
||||
#include "nfs_env.h"
|
||||
#endif
|
||||
#ifdef CONFIG_BUTTON
|
||||
#include <button.h>
|
||||
struct fastboot_key_config {
|
||||
const char **key_names;
|
||||
int key_count;
|
||||
u32 press_time;
|
||||
};
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
static char found_partition[64] = {0};
|
||||
|
@ -46,6 +57,7 @@ extern u32 ddr_cs_num;
|
|||
bool is_video_connected = false;
|
||||
uint32_t reboot_config;
|
||||
void refresh_config_info(u8 *eeprom_data);
|
||||
void read_from_eeprom(struct tlvinfo_tlv **tlv_data, u8 tcode);
|
||||
int mac_read_from_buffer(u8 *eeprom_data);
|
||||
|
||||
void set_boot_mode(enum board_boot_mode boot_mode)
|
||||
|
@ -279,11 +291,126 @@ u32 get_reboot_config(void)
|
|||
return reboot_config;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_BUTTON
|
||||
static int button_get_state_by_label(struct udevice *dev, const char *label)
|
||||
{
|
||||
struct udevice *child;
|
||||
struct button_uc_plat *plat;
|
||||
int state;
|
||||
bool invert_state = false;
|
||||
|
||||
pr_debug("Searching for button with label '%s'\n", label);
|
||||
for (device_find_first_child(dev, &child);
|
||||
child;
|
||||
device_find_next_child(&child)) {
|
||||
plat = dev_get_uclass_plat(child);
|
||||
if (plat->label && !strcmp(plat->label, label)) {
|
||||
invert_state = ofnode_read_bool(dev_ofnode(child), "invert-state");
|
||||
|
||||
state = button_get_state(child);
|
||||
pr_debug("Button '%s' found, raw state: %d, invert: %d\n", label, state, invert_state);
|
||||
|
||||
if (invert_state) {
|
||||
state = (state == BUTTON_ON) ? BUTTON_OFF : BUTTON_ON;
|
||||
}
|
||||
pr_debug("Button '%s' final state: %d\n", label, state);
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
pr_err("Button '%s' not found\n", label);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int get_fastboot_key_config(struct fastboot_key_config *config)
|
||||
{
|
||||
ofnode node;
|
||||
int ret;
|
||||
|
||||
node = ofnode_path("/gpio_keys");
|
||||
if (!ofnode_valid(node))
|
||||
return -ENODEV;
|
||||
|
||||
ret = ofnode_read_string_list(node, "fastboot-key-combo", &config->key_names);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
config->key_count = ret;
|
||||
|
||||
ret = ofnode_read_u32(node, "fastboot-key-press-time", &config->press_time);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool check_fastboot_keys(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
struct fastboot_key_config config;
|
||||
int *key_states;
|
||||
ulong press_start = 0;
|
||||
int i, ret;
|
||||
bool all_pressed = true;
|
||||
|
||||
ret = get_fastboot_key_config(&config);
|
||||
if (ret < 0) {
|
||||
pr_err("Failed to get fastboot key config: %d\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
pr_debug("Fastboot key config: count=%d, press_time=%u\n", config.key_count, config.press_time);
|
||||
|
||||
ret = uclass_get_device_by_name(UCLASS_BUTTON, "gpio_keys", &dev);
|
||||
if (ret) {
|
||||
pr_err("Failed to get device for gpio_keys\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
key_states = calloc(config.key_count, sizeof(int));
|
||||
if (!key_states) {
|
||||
pr_err("Failed to allocate memory for key_states\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
press_start = get_timer(0);
|
||||
|
||||
while (get_timer(press_start) < config.press_time) {
|
||||
all_pressed = true;
|
||||
for (i = 0; i < config.key_count; i++) {
|
||||
key_states[i] = button_get_state_by_label(dev, config.key_names[i]);
|
||||
if (key_states[i] < 0 || key_states[i] != BUTTON_ON) {
|
||||
all_pressed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!all_pressed) {
|
||||
/* Key released within the specified time, normal boot */
|
||||
free(key_states);
|
||||
return false;
|
||||
}
|
||||
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
/* Keys held down longer than specified time, enter Fastboot mode */
|
||||
free(key_states);
|
||||
pr_info("Fastboot key combination detected! Duration: %u ms\n", config.press_time);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void run_fastboot_command(void)
|
||||
{
|
||||
u32 boot_mode = get_boot_mode();
|
||||
|
||||
if (boot_mode == BOOT_MODE_USB || BOOT_MODE_USB == get_reboot_config()) {
|
||||
if (boot_mode == BOOT_MODE_USB || BOOT_MODE_USB == get_reboot_config()
|
||||
#ifdef CONFIG_BUTTON
|
||||
|| check_fastboot_keys()
|
||||
#endif
|
||||
) {
|
||||
/* show flash log*/
|
||||
env_set("stdout", env_get("stdout_flash"));
|
||||
|
||||
|
@ -295,6 +422,7 @@ void run_fastboot_command(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int run_uboot_shell(void)
|
||||
{
|
||||
u32 boot_mode = get_boot_mode();
|
||||
|
@ -381,6 +509,20 @@ char* parse_mtdparts_and_find_bootfs(void) {
|
|||
void import_env_from_bootfs(void)
|
||||
{
|
||||
u32 boot_mode = get_boot_mode();
|
||||
|
||||
#ifdef CONFIG_ENV_IS_IN_NFS
|
||||
// Check if local bootfs exists
|
||||
if (check_bootfs_exists() != 0) {
|
||||
#ifdef CONFIG_CMD_NET
|
||||
eth_initialize();
|
||||
#endif
|
||||
// Local bootfs not found, try to load from NFS
|
||||
if (load_env_from_nfs() == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (boot_mode) {
|
||||
case BOOT_MODE_NAND:
|
||||
#if CONFIG_IS_ENABLED(ENV_IS_IN_MTD)
|
||||
|
@ -499,6 +641,16 @@ void run_cardfirmware_flash_command(void)
|
|||
|
||||
void setenv_boot_mode(void)
|
||||
{
|
||||
#ifdef CONFIG_ENV_IS_IN_NFS
|
||||
const char *boot_override = env_get("boot_override");
|
||||
|
||||
if (boot_override) {
|
||||
env_set("boot_device", boot_override);
|
||||
env_set("boot_override", NULL);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
u32 boot_mode = get_boot_mode();
|
||||
switch (boot_mode) {
|
||||
case BOOT_MODE_NAND:
|
||||
|
@ -789,6 +941,13 @@ int board_init(void)
|
|||
ret = regulators_enable_boot_on(true);
|
||||
if (ret)
|
||||
pr_debug("%s: Cannot enable boot on regulator\n", __func__);
|
||||
#endif
|
||||
#ifdef CONFIG_SPACEMIT_SHUTDOWN_CHARGE
|
||||
struct udevice *udev;
|
||||
|
||||
if (get_boot_mode() != BOOT_MODE_USB) {
|
||||
ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(shutdown_charge), &udev);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -840,6 +999,15 @@ int board_late_init(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BUTTON
|
||||
ret = uclass_probe_all(UCLASS_BUTTON);
|
||||
if (ret) {
|
||||
pr_err("Failed to probe all buttons: %d\n", ret);
|
||||
} else {
|
||||
pr_info("All buttons probed successfully\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
run_fastboot_command();
|
||||
|
||||
run_cardfirmware_flash_command();
|
||||
|
|
382
board/spacemit/k1-x/nfs_env.c
Normal file
382
board/spacemit/k1-x/nfs_env.c
Normal file
|
@ -0,0 +1,382 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2023 Spacemit, Inc
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <env.h>
|
||||
#include <log.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <net.h>
|
||||
#include <tlv_eeprom.h>
|
||||
#include <vsprintf.h>
|
||||
#include <ctype.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <u-boot/crc.h>
|
||||
#include <command.h>
|
||||
#include <mmc.h>
|
||||
#include <part.h>
|
||||
#include <net.h>
|
||||
#include <env_flags.h>
|
||||
#include <mtd.h>
|
||||
#include <jffs2/load_kernel.h>
|
||||
#include <mtd.h>
|
||||
#include <jffs2/load_kernel.h>
|
||||
#include <vsprintf.h>
|
||||
#include <ctype.h>
|
||||
#include <dm.h>
|
||||
#include <fb_spacemit.h>
|
||||
#include "nfs_env.h"
|
||||
|
||||
#define NFS_LOAD_ADDR CONFIG_FASTBOOT_BUF_ADDR
|
||||
|
||||
int eth_parse_enetaddr(const char *addr, uint8_t *enetaddr)
|
||||
{
|
||||
char *end;
|
||||
int i;
|
||||
|
||||
if (strlen(addr) != 17) {
|
||||
pr_err("Invalid MAC address length\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
enetaddr[i] = simple_strtoul(addr, &end, 16);
|
||||
if (i < 5 && *end != ':') {
|
||||
pr_err("Invalid MAC address format\n");
|
||||
return -1;
|
||||
}
|
||||
addr = end + 1;
|
||||
}
|
||||
|
||||
pr_info("Successfully parsed MAC address\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int get_mac_address(uint8_t *mac_addr)
|
||||
{
|
||||
const char *mac_str = env_get("ethaddr");
|
||||
if (mac_str) {
|
||||
if (eth_validate_ethaddr_str(mac_str) == 0) {
|
||||
if (eth_parse_enetaddr(mac_str, mac_addr) == 0) {
|
||||
pr_info("Successfully obtained MAC address from environment\n");
|
||||
return 0;
|
||||
} else {
|
||||
pr_err("Failed to parse MAC address from environment\n");
|
||||
}
|
||||
} else {
|
||||
pr_err("Invalid MAC address in environment\n");
|
||||
}
|
||||
} else {
|
||||
pr_debug("MAC address not found in environment\n");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int read_mac_from_eeprom(uint8_t *mac_addr)
|
||||
{
|
||||
struct tlvinfo_tlv *mac_base_tlv = NULL;
|
||||
read_from_eeprom(&mac_base_tlv, TLV_CODE_MAC_BASE);
|
||||
if (mac_base_tlv && mac_base_tlv->length == 6) {
|
||||
memcpy(mac_addr, mac_base_tlv->value, 6);
|
||||
pr_info("Successfully read MAC address from EEPROM: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
return 0;
|
||||
}
|
||||
pr_err("Failed to read valid MAC address from EEPROM\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int get_device_mac_address(uint8_t *mac_addr)
|
||||
{
|
||||
// Try to get MAC address from environment first
|
||||
if (get_mac_address(mac_addr) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If not found in environment, try to read from EEPROM
|
||||
if (read_mac_from_eeprom(mac_addr) == 0) {
|
||||
char mac_str[18];
|
||||
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac_addr[0], mac_addr[1], mac_addr[2],
|
||||
mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
env_set("ethaddr", mac_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_err("Failed to get MAC address\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int strcasecmp_colon(const char *s1, const char *s2, size_t n) {
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
char c1 = tolower((unsigned char)s1[i]);
|
||||
char c2 = tolower((unsigned char)s2[i]);
|
||||
if (c1 != c2) {
|
||||
return c1 - c2;
|
||||
}
|
||||
if (c1 == '\0') {
|
||||
return 0;
|
||||
}
|
||||
if (c1 == ':') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_mac_mapping(struct mac_mapping *mapping, const char *mac_mapping_file)
|
||||
{
|
||||
char cmd[128] = {"\0"};
|
||||
char *buf = (char *)NFS_LOAD_ADDR;
|
||||
char *line, *next_line;
|
||||
int ret = -1;
|
||||
uint8_t mac_addr[6];
|
||||
char mac_str[18];
|
||||
size_t mac_str_len;
|
||||
const char *server_ip;
|
||||
bool found_match = false;
|
||||
|
||||
// Run DHCP
|
||||
sprintf(cmd, "dhcp");
|
||||
ret = run_command(cmd, 0);
|
||||
if (ret != 0) {
|
||||
pr_err("DHCP failed, return value: %d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get server IP address
|
||||
server_ip = env_get("serverip");
|
||||
if (!server_ip) {
|
||||
pr_err("serverip not set in environment\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get device MAC address
|
||||
if (get_device_mac_address(mac_addr) != 0) {
|
||||
pr_err("Failed to get device MAC address\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Convert MAC address to string format
|
||||
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac_addr[0], mac_addr[1], mac_addr[2],
|
||||
mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
mac_str_len = strlen(mac_str);
|
||||
|
||||
// Construct NFS command
|
||||
sprintf(cmd, "nfs %lx %s:%s", (ulong)buf, server_ip, mac_mapping_file);
|
||||
|
||||
// Execute NFS command
|
||||
ret = run_command(cmd, 0);
|
||||
|
||||
if (ret != 0) {
|
||||
pr_err("Failed to load %s from NFS\n", mac_mapping_file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Parse file content
|
||||
line = buf;
|
||||
while (line && *line) {
|
||||
next_line = strchr(line, '\n');
|
||||
if (next_line) {
|
||||
*next_line = '\0';
|
||||
}
|
||||
|
||||
if (strcasecmp_colon(line, mac_str, mac_str_len) == 0) {
|
||||
char *bootfs_start = strchr(line, ',');
|
||||
if (bootfs_start) {
|
||||
bootfs_start++;
|
||||
char *rootfs_start = strchr(bootfs_start, ',');
|
||||
if (rootfs_start) {
|
||||
*rootfs_start = '\0';
|
||||
rootfs_start++;
|
||||
|
||||
// Copy bootfs path
|
||||
strncpy(mapping->bootfs_path, bootfs_start, sizeof(mapping->bootfs_path) - 1);
|
||||
mapping->bootfs_path[sizeof(mapping->bootfs_path) - 1] = '\0';
|
||||
|
||||
// Copy rootfs path
|
||||
strncpy(mapping->rootfs_path, rootfs_start, sizeof(mapping->rootfs_path) - 1);
|
||||
mapping->rootfs_path[sizeof(mapping->rootfs_path) - 1] = '\0';
|
||||
|
||||
found_match = true;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (next_line) {
|
||||
line = next_line + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_match) {
|
||||
pr_err("Failed to find matching MAC address in %s\n", mac_mapping_file);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int check_nand_bootfs(void)
|
||||
{
|
||||
char cmd[128];
|
||||
const char *bootfs_name = BOOTFS_NAME;
|
||||
|
||||
if (!bootfs_name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "ubi part %s", parse_mtdparts_and_find_bootfs());
|
||||
if (run_command(cmd, 0) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "ubifsmount %s", bootfs_name);
|
||||
if (run_command(cmd, 0) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_nor_bootfs(void)
|
||||
{
|
||||
int part, blk_index;
|
||||
char *blk_name;
|
||||
char devpart_str[16];
|
||||
|
||||
if (get_available_boot_blk_dev(&blk_name, &blk_index)) {
|
||||
pr_err("Cannot get available block device\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
part = detect_blk_dev_or_partition_exist(blk_name, blk_index, BOOTFS_NAME);
|
||||
if (part < 0) {
|
||||
pr_err("Failed to detect partition %s on %s:%d\n", BOOTFS_NAME, blk_name, blk_index);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(devpart_str, sizeof(devpart_str), "%d:%d", blk_index, part);
|
||||
|
||||
if (!strcmp("mmc", blk_name)) {
|
||||
pr_info("Found bootfs partition on eMMC device %s\n", devpart_str);
|
||||
} else if (!strcmp("nvme", blk_name)) {
|
||||
pr_info("Found bootfs partition on NVMe device %s\n", devpart_str);
|
||||
} else {
|
||||
pr_info("Not found bootfs partition on %s\n", blk_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_mmc_bootfs(int dev)
|
||||
{
|
||||
struct mmc *mmc;
|
||||
struct blk_desc *desc;
|
||||
struct disk_partition info;
|
||||
int part;
|
||||
|
||||
mmc = find_mmc_device(dev);
|
||||
if (!mmc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mmc_init(mmc)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
desc = mmc_get_blk_desc(mmc);
|
||||
for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
|
||||
if (part_get_info(desc, part, &info) != 0) {
|
||||
continue;
|
||||
}
|
||||
if (strcmp(info.name, BOOTFS_NAME) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int check_bootfs_exists(void)
|
||||
{
|
||||
int ret;
|
||||
u32 boot_mode = get_boot_mode();
|
||||
|
||||
switch (boot_mode) {
|
||||
case BOOT_MODE_NAND:
|
||||
ret = check_nand_bootfs();
|
||||
break;
|
||||
case BOOT_MODE_NOR:
|
||||
ret = check_nor_bootfs();
|
||||
break;
|
||||
case BOOT_MODE_EMMC:
|
||||
ret = check_mmc_bootfs(MMC_DEV_EMMC);
|
||||
break;
|
||||
case BOOT_MODE_SD:
|
||||
ret = check_mmc_bootfs(MMC_DEV_SD);
|
||||
break;
|
||||
default:
|
||||
pr_info("Unsupported boot mode for checking bootfs\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int load_env_from_nfs(void)
|
||||
{
|
||||
const char *mac_mapping_file;
|
||||
struct mac_mapping mapping;
|
||||
char cmd[128] = {"\0"};
|
||||
int ret;
|
||||
|
||||
if (env_get("boot_override")) {
|
||||
env_set("boot_override", NULL);
|
||||
}
|
||||
|
||||
mac_mapping_file = env_get("mac_mapping_file");
|
||||
if (!mac_mapping_file) {
|
||||
pr_err("MAC mapping file path not set in environment\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = load_mac_mapping(&mapping, mac_mapping_file);
|
||||
if (ret == 0) {
|
||||
env_set("bootfs_path", mapping.bootfs_path);
|
||||
env_set("rootfs_path", mapping.rootfs_path);
|
||||
env_set("boot_override", "nfs");
|
||||
|
||||
printf("bootfs_path: %s\n", env_get("bootfs_path"));
|
||||
printf("rootfs_path: %s\n", env_get("rootfs_path"));
|
||||
printf("boot_override: %s\n", env_get("boot_override"));
|
||||
|
||||
sprintf(cmd, "nfs %x %s/env_%s.txt",
|
||||
NFS_LOAD_ADDR,
|
||||
mapping.bootfs_path,
|
||||
CONFIG_SYS_CONFIG_NAME);
|
||||
|
||||
if (run_command(cmd, 0) == 0) {
|
||||
sprintf(cmd, "env import -t %x", NFS_LOAD_ADDR);
|
||||
if (run_command(cmd, 0) == 0) {
|
||||
pr_info("Successfully loaded environment from NFS\n");
|
||||
return 0;
|
||||
} else {
|
||||
pr_err("Failed to import environment\n");
|
||||
}
|
||||
} else {
|
||||
pr_err("Failed to load environment file from NFS\n");
|
||||
}
|
||||
} else {
|
||||
pr_err("Failed to load MAC mapping from NFS. Return code: %d\n", ret);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
24
board/spacemit/k1-x/nfs_env.h
Normal file
24
board/spacemit/k1-x/nfs_env.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef __NFS_ENV_H__
|
||||
#define __NFS_ENV_H__
|
||||
|
||||
#ifdef CONFIG_ENV_IS_IN_NFS
|
||||
|
||||
#define NFS_LOAD_ADDR CONFIG_FASTBOOT_BUF_ADDR
|
||||
|
||||
struct mac_mapping {
|
||||
char mac_addr[18];
|
||||
char bootfs_path[256];
|
||||
char rootfs_path[256];
|
||||
};
|
||||
|
||||
int eth_parse_enetaddr(const char *addr, uint8_t *enetaddr);
|
||||
int check_bootfs_exists(void);
|
||||
int load_env_from_nfs(void);
|
||||
|
||||
char* parse_mtdparts_and_find_bootfs(void);
|
||||
enum board_boot_mode get_boot_mode(void);
|
||||
void read_from_eeprom(struct tlvinfo_tlv **tlv_data, u8 tcode);
|
||||
|
||||
#endif // CONFIG_ENV_IS_IN_NFS
|
||||
|
||||
#endif // __NFS_ENV_H__
|
|
@ -80,13 +80,13 @@
|
|||
|
||||
extern int __data_start[], __data_end[];
|
||||
extern int k1x_eeprom_init(void);
|
||||
extern int spacemit_eeprom_read(uint8_t chip, uint8_t *buffer, uint8_t id);
|
||||
extern int spacemit_eeprom_read(uint8_t *buffer, uint8_t id);
|
||||
extern bool get_mac_address(uint64_t *mac_addr);
|
||||
extern void update_ddr_info(void);
|
||||
extern enum board_boot_mode get_boot_storage(void);
|
||||
extern int spl_mtd_read(struct mtd_info *mtd, ulong sector, ulong count, void *buf);
|
||||
char *product_name;
|
||||
extern u32 ddr_cs_num;
|
||||
extern u32 ddr_cs_num, ddr_datarate;;
|
||||
extern const char *ddr_type;
|
||||
|
||||
int timer_init(void)
|
||||
|
@ -140,7 +140,7 @@ static uint32_t adjust_cpu_freq(uint64_t cluster, uint32_t freq)
|
|||
val &= ~(0x07 | BIT(13));
|
||||
switch(freq) {
|
||||
case 1600000:
|
||||
val |= 0x07 | BIT(13); //set cpu freq to PLL3_DIV1
|
||||
val |= 0x07;
|
||||
break;
|
||||
|
||||
case 1228000:
|
||||
|
@ -180,16 +180,13 @@ void raise_cpu_frequency(void)
|
|||
val |= BIT(16) | BIT(15) | BIT(14) | BIT(13);
|
||||
writel(val, (void __iomem *)(K1X_MPMU_BASE + 0x1024));
|
||||
|
||||
/* set the frequency of pll3 to 1.6G */
|
||||
writel(0x0050cd61, (void __iomem *)(K1X_APB_SPARE_BASE + 0x124));
|
||||
|
||||
/* enable PLL3 */
|
||||
/* enable PLL3(3200Mhz) */
|
||||
val = readl((void __iomem *)(K1X_APB_SPARE_BASE + 0x12C));
|
||||
val |= BIT(31);
|
||||
writel(val, (void __iomem *)(K1X_APB_SPARE_BASE + 0x12C));
|
||||
/* enable PLL3_DIV2 and PLL3_DIV1*/
|
||||
/* enable PLL3_DIV2 */
|
||||
val = readl((void __iomem *)(K1X_APB_SPARE_BASE + 0x128));
|
||||
val |= BIT(1) | BIT(0);
|
||||
val |= BIT(1);
|
||||
writel(val, (void __iomem *)(K1X_APB_SPARE_BASE + 0x128));
|
||||
|
||||
cpu = cpu_get_current_dev();
|
||||
|
@ -639,11 +636,8 @@ static void spl_load_env(void)
|
|||
|
||||
bool get_mac_address(uint64_t *mac_addr)
|
||||
{
|
||||
int eeprom_addr;
|
||||
|
||||
eeprom_addr = k1x_eeprom_init();
|
||||
if ((eeprom_addr >= 0) && (NULL != mac_addr) && (0 == spacemit_eeprom_read(
|
||||
eeprom_addr, (uint8_t*)mac_addr, TLV_CODE_MAC_BASE))) {
|
||||
if ((k1x_eeprom_init() >= 0) && (NULL != mac_addr) &&
|
||||
(0 == spacemit_eeprom_read((uint8_t*)mac_addr, TLV_CODE_MAC_BASE))) {
|
||||
pr_info("Get mac address %llx from eeprom\n", *mac_addr);
|
||||
return true;
|
||||
}
|
||||
|
@ -654,12 +648,10 @@ bool get_mac_address(uint64_t *mac_addr)
|
|||
char *get_product_name(void)
|
||||
{
|
||||
char *name = NULL;
|
||||
int eeprom_addr;
|
||||
|
||||
eeprom_addr = k1x_eeprom_init();
|
||||
name = calloc(1, 64);
|
||||
if ((eeprom_addr >= 0) && (NULL != name) && (0 == spacemit_eeprom_read(
|
||||
eeprom_addr, name, TLV_CODE_PRODUCT_NAME))) {
|
||||
if ((k1x_eeprom_init() >= 0) && (NULL != name) &&
|
||||
(0 == spacemit_eeprom_read(name, TLV_CODE_PRODUCT_NAME))) {
|
||||
pr_info("Get product name from eeprom %s\n", name);
|
||||
return name;
|
||||
}
|
||||
|
@ -673,26 +665,33 @@ char *get_product_name(void)
|
|||
|
||||
void update_ddr_info(void)
|
||||
{
|
||||
int eeprom_addr;
|
||||
uint8_t *info;
|
||||
|
||||
eeprom_addr = k1x_eeprom_init();
|
||||
if (eeprom_addr < 0)
|
||||
if (k1x_eeprom_init() < 0)
|
||||
return;
|
||||
|
||||
// read ddr type from eeprom
|
||||
info = malloc(32);
|
||||
memset(info, 0, 32);
|
||||
if (0 == spacemit_eeprom_read(eeprom_addr, info, TLV_CODE_DDR_TYPE))
|
||||
if (0 == spacemit_eeprom_read(info, TLV_CODE_DDR_TYPE))
|
||||
ddr_type = info;
|
||||
else
|
||||
free(info);
|
||||
|
||||
// if fail to get ddr cs number from eeprom, update it from dts node
|
||||
if (0 == spacemit_eeprom_read(eeprom_addr, (uint8_t*)&ddr_cs_num, TLV_CODE_DDR_CSNUM))
|
||||
if (0 == spacemit_eeprom_read((uint8_t*)&ddr_cs_num, TLV_CODE_DDR_CSNUM))
|
||||
pr_info("Get ddr cs num %d from eeprom\n", ddr_cs_num);
|
||||
else
|
||||
ddr_cs_num = 0;
|
||||
|
||||
// if fail to get ddr cs number from eeprom, update it from dts node
|
||||
if (0 == spacemit_eeprom_read((uint8_t*)&ddr_datarate, TLV_CODE_DDR_DATARATE)) {
|
||||
// convert it from big endian to little endian
|
||||
ddr_datarate = be16_to_cpu(ddr_datarate);
|
||||
pr_info("Get ddr datarate %d from eeprom\n", ddr_datarate);
|
||||
}
|
||||
else
|
||||
ddr_datarate = 0;
|
||||
}
|
||||
|
||||
void spl_board_init(void)
|
||||
|
|
|
@ -56,26 +56,33 @@ int set_nor_splash_location(struct splash_location *locations) {
|
|||
char *blk_name;
|
||||
char devpart_str[16];
|
||||
|
||||
if (get_available_boot_blk_dev(&blk_name, &blk_index)){
|
||||
printf("can not get available blk dev\n");
|
||||
if (get_available_boot_blk_dev(&blk_name, &blk_index)) {
|
||||
pr_err("Error: Cannot get available block device\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
part = detect_blk_dev_or_partition_exist(blk_name, blk_index, BOOTFS_NAME);
|
||||
if (part < 0)
|
||||
if (part < 0) {
|
||||
pr_err("Error: Failed to detect partition %s on %s:%d\n", BOOTFS_NAME, blk_name, blk_index);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(devpart_str, sizeof(devpart_str), "%d:%d", blk_index, part);
|
||||
|
||||
if (!strcmp("mmc", blk_name))
|
||||
if (!strcmp("mmc", blk_name)) {
|
||||
locations[0].name = "emmc_fs";
|
||||
else if (!strcmp("nvme", blk_name))
|
||||
locations[0].storage = SPLASH_STORAGE_MMC;
|
||||
} else if (!strcmp("nvme", blk_name)) {
|
||||
locations[0].name = "nvme_fs";
|
||||
else
|
||||
locations[0].storage = SPLASH_STORAGE_NVME;
|
||||
} else {
|
||||
pr_err("Error: Unsupported block device type: %s\n", blk_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
locations[0].storage = SPLASH_STORAGE_NVME;
|
||||
locations[0].flags = SPLASH_STORAGE_FS;
|
||||
locations[0].devpart = strdup(devpart_str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -618,7 +618,7 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
|
|||
flush_cache((unsigned long)*initrd_start,
|
||||
ALIGN(rd_len, ARCH_DMA_MINALIGN));
|
||||
}
|
||||
puts("OK\n");
|
||||
printf("OK\n");
|
||||
}
|
||||
} else {
|
||||
*initrd_start = 0;
|
||||
|
|
|
@ -1339,7 +1339,7 @@ int fit_image_verify_with_data(const void *fit, int image_noffset,
|
|||
if (fit_image_check_hash(fit, noffset, data, size,
|
||||
&err_msg))
|
||||
goto error;
|
||||
puts("+ ");
|
||||
printf("+ ");
|
||||
} else if (FIT_IMAGE_ENABLE_VERIFY && verify_all &&
|
||||
!strncmp(name, FIT_SIG_NODENAME,
|
||||
strlen(FIT_SIG_NODENAME))) {
|
||||
|
@ -1353,9 +1353,9 @@ int fit_image_verify_with_data(const void *fit, int image_noffset,
|
|||
* fit_image_verify_required_sigs() above.
|
||||
*/
|
||||
if (ret)
|
||||
puts("- ");
|
||||
printf("- ");
|
||||
else
|
||||
puts("+ ");
|
||||
printf("+ ");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1958,12 +1958,12 @@ static int fit_image_select(const void *fit, int rd_noffset, int verify)
|
|||
fit_image_print(fit, rd_noffset, " ");
|
||||
|
||||
if (verify) {
|
||||
puts(" Verifying Hash Integrity ... ");
|
||||
printf(" Verifying Hash Integrity ... ");
|
||||
if (!fit_image_verify(fit, rd_noffset)) {
|
||||
puts("Bad Data Hash\n");
|
||||
printf("Bad Data Hash\n");
|
||||
return -EACCES;
|
||||
}
|
||||
puts("OK\n");
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2085,7 +2085,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
|
|||
fit_uname_config);
|
||||
}
|
||||
if (cfg_noffset < 0) {
|
||||
puts("Could not find configuration node\n");
|
||||
printf("Could not find configuration node\n");
|
||||
bootstage_error(bootstage_id +
|
||||
BOOTSTAGE_SUB_NO_UNIT_NAME);
|
||||
return -ENOENT;
|
||||
|
@ -2098,14 +2098,14 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
|
|||
images->fit_uname_cfg = fit_base_uname_config;
|
||||
|
||||
if (FIT_IMAGE_ENABLE_VERIFY && images->verify) {
|
||||
puts(" Verifying Hash Integrity ... ");
|
||||
printf(" Verifying Hash Integrity ... ");
|
||||
if (fit_config_verify(fit, cfg_noffset)) {
|
||||
puts("Bad Data Hash\n");
|
||||
printf("Bad Data Hash\n");
|
||||
bootstage_error(bootstage_id +
|
||||
BOOTSTAGE_SUB_HASH);
|
||||
return -EACCES;
|
||||
}
|
||||
puts("OK\n");
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
|
||||
|
@ -2131,7 +2131,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
|
|||
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
|
||||
if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX)) {
|
||||
if (!fit_image_check_target_arch(fit, noffset)) {
|
||||
puts("Unsupported Architecture\n");
|
||||
printf("Unsupported Architecture\n");
|
||||
bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
@ -2189,12 +2189,12 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
|
|||
|
||||
/* Decrypt data before uncompress/move */
|
||||
if (IS_ENABLED(CONFIG_FIT_CIPHER) && IMAGE_ENABLE_DECRYPT) {
|
||||
puts(" Decrypting Data ... ");
|
||||
printf(" Decrypting Data ... ");
|
||||
if (fit_image_uncipher(fit, noffset, &buf, &size)) {
|
||||
puts("Error\n");
|
||||
printf("Error\n");
|
||||
return -EACCES;
|
||||
}
|
||||
puts("OK\n");
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
/* perform any post-processing on the image data */
|
||||
|
@ -2267,12 +2267,12 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
|
|||
}
|
||||
|
||||
if (image_type == IH_TYPE_RAMDISK && comp != IH_COMP_NONE)
|
||||
puts("WARNING: 'compression' nodes for ramdisks are deprecated,"
|
||||
printf("WARNING: 'compression' nodes for ramdisks are deprecated,"
|
||||
" please fix your .its file!\n");
|
||||
|
||||
/* verify that image data is a proper FDT blob */
|
||||
if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
|
||||
puts("Subimage data is not a FDT");
|
||||
printf("Subimage data is not a FDT");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
|
|
|
@ -943,6 +943,13 @@ config CMD_BCB
|
|||
https://android.googlesource.com/platform/bootable/recovery
|
||||
- Inspect/dump the contents of the BCB fields
|
||||
|
||||
config CMD_BATTERY
|
||||
bool "battery - information about batteries"
|
||||
depends on DM_BATTERY
|
||||
default y
|
||||
help
|
||||
Provides access to information regarding batteries present on the system.
|
||||
|
||||
config CMD_BIND
|
||||
bool "bind/unbind - Bind or unbind a device to/from a driver"
|
||||
depends on DM
|
||||
|
|
|
@ -23,6 +23,7 @@ obj-$(CONFIG_CMD_BOOTDEV) += bootdev.o
|
|||
obj-$(CONFIG_CMD_BOOTFLOW) += bootflow.o
|
||||
obj-$(CONFIG_CMD_BOOTMETH) += bootmeth.o
|
||||
obj-$(CONFIG_CMD_SOURCE) += source.o
|
||||
obj-$(CONFIG_CMD_BATTERY) += battery.o
|
||||
obj-$(CONFIG_CMD_BCB) += bcb.o
|
||||
obj-$(CONFIG_CMD_BDI) += bdinfo.o
|
||||
obj-$(CONFIG_CMD_BIND) += bind.o
|
||||
|
|
119
cmd/battery.c
Normal file
119
cmd/battery.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (C) 2018 Simon Shields <simon@lineageos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <power/battery.h>
|
||||
|
||||
static struct udevice *currdev;
|
||||
|
||||
#define LIMIT_DEV 32
|
||||
#define LIMIT_PARENT 20
|
||||
|
||||
static const char *bat_states[] = {
|
||||
[BAT_STATE_UNUSED] = "Unknown",
|
||||
[BAT_STATE_NOT_PRESENT] = "Not present",
|
||||
[BAT_STATE_NEED_CHARGING] = "Need charging",
|
||||
[BAT_STATE_NORMAL] = "Present",
|
||||
};
|
||||
|
||||
static int failure(int ret)
|
||||
{
|
||||
printf("Error: %d (%s)\n", ret, errno_str(ret));
|
||||
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
static int do_dev(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
char *name;
|
||||
unsigned int uV = 0;
|
||||
|
||||
switch (argc) {
|
||||
case 2:
|
||||
name = argv[1];
|
||||
ret = battery_get(name, &currdev);
|
||||
if (ret) {
|
||||
printf("Can't get battery: %s!\n", name);
|
||||
return failure(ret);
|
||||
}
|
||||
case 1:
|
||||
if (!currdev) {
|
||||
printf("Battery device is not set!\n\n");
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
|
||||
printf("dev: %d @ %s\n", currdev->seq_, currdev->name);
|
||||
ret = battery_get_voltage(currdev, &uV);
|
||||
if (ret)
|
||||
printf("failed to get voltage: %d\n", ret);
|
||||
printf("voltage: %u uV, charge state: %d%%\n", uV, battery_get_soc(currdev));
|
||||
ret = battery_get_status(currdev);
|
||||
if (ret < 0)
|
||||
printf("failed to get battery status: %d\n", ret);
|
||||
else
|
||||
printf("battery status: %s\n", bat_states[ret]);
|
||||
}
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static int do_list(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
printf("| %-*.*s| %-*.*s| %s @ %s\n",
|
||||
LIMIT_DEV, LIMIT_DEV, "Name",
|
||||
LIMIT_PARENT, LIMIT_PARENT, "Parent name",
|
||||
"Parent uclass", "seq");
|
||||
|
||||
for (ret = uclass_first_device(UCLASS_BATTERY, &dev); dev;
|
||||
ret = uclass_next_device(&dev)) {
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
printf("| %-*.*s| %-*.*s| %s @ %d\n",
|
||||
LIMIT_DEV, LIMIT_DEV, dev->name,
|
||||
LIMIT_PARENT, LIMIT_PARENT, dev->parent->name,
|
||||
dev_get_uclass_name(dev->parent), dev->parent->seq_);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static struct cmd_tbl subcmd[] = {
|
||||
U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""),
|
||||
U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""),
|
||||
};
|
||||
|
||||
static int do_battery(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
struct cmd_tbl *cmd;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
cmd = find_cmd_tbl(argv[0], subcmd, ARRAY_SIZE(subcmd));
|
||||
if (cmd == NULL || argc > cmd->maxargs)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
return cmd->cmd(cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
|
||||
U_BOOT_CMD(battery, CONFIG_SYS_MAXARGS, 1, do_battery,
|
||||
"Battery subsystem",
|
||||
"list - list battery devices\n"
|
||||
"dev [name] - show or [set] operating battery device\n"
|
||||
);
|
|
@ -23,14 +23,14 @@ static int do_echo(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||
|
||||
for (; i < argc; ++i) {
|
||||
if (space) {
|
||||
putc(' ');
|
||||
printf(" ");
|
||||
}
|
||||
puts(argv[i]);
|
||||
printf("%s", argv[i]);
|
||||
space = true;
|
||||
}
|
||||
|
||||
if (newline)
|
||||
putc('\n');
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -660,25 +660,15 @@ static void print_memory_attributes(u64 attributes)
|
|||
static int do_efi_show_memmap(struct cmd_tbl *cmdtp, int flag,
|
||||
int argc, char *const argv[])
|
||||
{
|
||||
struct efi_mem_desc *memmap = NULL, *map;
|
||||
efi_uintn_t map_size = 0;
|
||||
struct efi_mem_desc *memmap, *map;
|
||||
efi_uintn_t map_size;
|
||||
const char *type;
|
||||
int i;
|
||||
efi_status_t ret;
|
||||
|
||||
ret = efi_get_memory_map(&map_size, memmap, NULL, NULL, NULL);
|
||||
if (ret == EFI_BUFFER_TOO_SMALL) {
|
||||
map_size += sizeof(struct efi_mem_desc); /* for my own */
|
||||
ret = efi_allocate_pool(EFI_LOADER_DATA, map_size,
|
||||
(void *)&memmap);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return CMD_RET_FAILURE;
|
||||
ret = efi_get_memory_map(&map_size, memmap, NULL, NULL, NULL);
|
||||
}
|
||||
if (ret != EFI_SUCCESS) {
|
||||
efi_free_pool(memmap);
|
||||
ret = efi_get_memory_map_alloc(&map_size, &memmap);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
printf("Type Start%.*s End%.*s Attributes\n",
|
||||
EFI_PHYS_ADDR_WIDTH - 5, spc, EFI_PHYS_ADDR_WIDTH - 3, spc);
|
||||
|
|
|
@ -321,6 +321,7 @@ static void decode_tlv(struct tlvinfo_tlv *tlv)
|
|||
sprintf(value, "%u", tlv->value[0]);
|
||||
break;
|
||||
case TLV_CODE_MAC_SIZE:
|
||||
case TLV_CODE_DDR_DATARATE:
|
||||
sprintf(value, "%u", (tlv->value[0] << 8) | tlv->value[1]);
|
||||
break;
|
||||
case TLV_CODE_VENDOR_EXT:
|
||||
|
@ -645,6 +646,7 @@ static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval)
|
|||
new_tlv_len = 1;
|
||||
break;
|
||||
case TLV_CODE_MAC_SIZE:
|
||||
case TLV_CODE_DDR_DATARATE:
|
||||
value = simple_strtoul(strval, NULL, 0);
|
||||
if (value >= 65536) {
|
||||
printf("ERROR: MAC Size must be 65535 or less. Value supplied: %u",
|
||||
|
|
|
@ -211,7 +211,7 @@ static int print_cpuinfo(void)
|
|||
|
||||
static int announce_dram_init(void)
|
||||
{
|
||||
puts("DRAM: ");
|
||||
printf("DRAM: ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ static int show_dram_config(void)
|
|||
|
||||
print_size(size, "");
|
||||
board_add_ram_info(0);
|
||||
putc('\n');
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -329,7 +329,7 @@ static int initr_flash(void)
|
|||
if (!is_flash_available())
|
||||
return 0;
|
||||
|
||||
puts("Flash: ");
|
||||
printf("Flash: ");
|
||||
|
||||
if (board_flash_wp_on())
|
||||
printf("Uninitialized - Write Protect On\n");
|
||||
|
@ -379,7 +379,7 @@ static int initr_flash(void)
|
|||
/* go init the NAND */
|
||||
static int initr_nand(void)
|
||||
{
|
||||
puts("NAND: ");
|
||||
printf("NAND: ");
|
||||
nand_init();
|
||||
printf("%lu MiB\n", nand_size() / 1024);
|
||||
return 0;
|
||||
|
@ -390,7 +390,7 @@ static int initr_nand(void)
|
|||
/* go init the NAND */
|
||||
static int initr_onenand(void)
|
||||
{
|
||||
puts("NAND: ");
|
||||
printf("NAND: ");
|
||||
onenand_init();
|
||||
return 0;
|
||||
}
|
||||
|
@ -399,7 +399,7 @@ static int initr_onenand(void)
|
|||
#ifdef CONFIG_MMC
|
||||
static int initr_mmc(void)
|
||||
{
|
||||
puts("MMC: ");
|
||||
printf("MMC: ");
|
||||
mmc_initialize(gd->bd);
|
||||
return 0;
|
||||
}
|
||||
|
@ -408,7 +408,7 @@ static int initr_mmc(void)
|
|||
#ifdef CONFIG_PVBLOCK
|
||||
static int initr_pvblock(void)
|
||||
{
|
||||
puts("PVBLOCK: ");
|
||||
printf("PVBLOCK: ");
|
||||
pvblock_init();
|
||||
return 0;
|
||||
}
|
||||
|
@ -466,7 +466,7 @@ static int initr_malloc_bootparams(void)
|
|||
{
|
||||
gd->bd->bi_boot_params = (ulong)malloc(CONFIG_SYS_BOOTPARAMS_LEN);
|
||||
if (!gd->bd->bi_boot_params) {
|
||||
puts("WARNING: Cannot allocate space for boot parameters\n");
|
||||
printf("WARNING: Cannot allocate space for boot parameters\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
|
@ -488,9 +488,9 @@ static int initr_status_led(void)
|
|||
#if defined(CONFIG_SCSI) && !defined(CONFIG_DM_SCSI)
|
||||
static int initr_scsi(void)
|
||||
{
|
||||
puts("SCSI: ");
|
||||
printf("SCSI: ");
|
||||
scsi_init();
|
||||
puts("\n");
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -499,7 +499,7 @@ static int initr_scsi(void)
|
|||
#ifdef CONFIG_CMD_NET
|
||||
static int initr_net(void)
|
||||
{
|
||||
puts("Net: ");
|
||||
printf("Net: ");
|
||||
eth_initialize();
|
||||
#if defined(CONFIG_RESET_PHY_R)
|
||||
debug("Reset Ethernet PHY\n");
|
||||
|
@ -520,7 +520,7 @@ static int initr_post(void)
|
|||
#if defined(CONFIG_IDE) && !defined(CONFIG_BLK)
|
||||
static int initr_ide(void)
|
||||
{
|
||||
puts("IDE: ");
|
||||
printf("IDE: ");
|
||||
#if defined(CONFIG_START_IDE)
|
||||
if (board_start_ide())
|
||||
ide_init();
|
||||
|
|
|
@ -977,23 +977,23 @@ int console_init_f(void)
|
|||
void stdio_print_current_devices(void)
|
||||
{
|
||||
/* Print information */
|
||||
puts("In: ");
|
||||
printf("In: ");
|
||||
if (stdio_devices[stdin] == NULL) {
|
||||
puts("No input devices available!\n");
|
||||
printf("No input devices available!\n");
|
||||
} else {
|
||||
printf ("%s\n", stdio_devices[stdin]->name);
|
||||
}
|
||||
|
||||
puts("Out: ");
|
||||
printf("Out: ");
|
||||
if (stdio_devices[stdout] == NULL) {
|
||||
puts("No output devices available!\n");
|
||||
printf("No output devices available!\n");
|
||||
} else {
|
||||
printf ("%s\n", stdio_devices[stdout]->name);
|
||||
}
|
||||
|
||||
puts("Err: ");
|
||||
printf("Err: ");
|
||||
if (stdio_devices[stderr] == NULL) {
|
||||
puts("No error devices available!\n");
|
||||
printf("No error devices available!\n");
|
||||
} else {
|
||||
printf ("%s\n", stdio_devices[stderr]->name);
|
||||
}
|
||||
|
|
|
@ -257,7 +257,7 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
|
|||
if (IS_ENABLED(CONFIG_SPL_FPGA) ||
|
||||
(IS_ENABLED(CONFIG_SPL_OS_BOOT) && IS_ENABLED(CONFIG_SPL_GZIP))) {
|
||||
if (fit_image_get_type(fit, node, &type))
|
||||
puts("Cannot get image type.\n");
|
||||
printf("Cannot get image type.\n");
|
||||
else
|
||||
pr_debug("%s ", genimg_get_type_name(type));
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
|
|||
} else {
|
||||
/* Embedded data */
|
||||
if (fit_image_get_data(fit, node, &data, &length)) {
|
||||
puts("Cannot get image data/size\n");
|
||||
printf("Cannot get image data/size\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
pr_debug("Embedded data: dst=%lx, size=%lx\n", load_addr,
|
||||
|
@ -328,7 +328,7 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
|
|||
if (!fit_image_verify_with_data(fit, node, gd_fdt_blob(), src,
|
||||
length))
|
||||
return -EPERM;
|
||||
puts("OK\n");
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
if (CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS))
|
||||
|
@ -338,7 +338,7 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
|
|||
if (IS_ENABLED(CONFIG_SPL_GZIP) && image_comp == IH_COMP_GZIP) {
|
||||
size = length;
|
||||
if (gunzip(load_ptr, CONFIG_SYS_BOOTM_LEN, src, &size)) {
|
||||
puts("Uncompressing error\n");
|
||||
printf("Uncompressing error\n");
|
||||
return -EIO;
|
||||
}
|
||||
length = size;
|
||||
|
@ -613,7 +613,7 @@ static int spl_fit_upload_fpga(struct spl_fit_info *ctx, int node,
|
|||
return ret;
|
||||
}
|
||||
|
||||
puts("FPGA image loaded from FIT\n");
|
||||
printf("FPGA image loaded from FIT\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -690,7 +690,7 @@ static int spl_simple_fit_parse(struct spl_fit_info *ctx)
|
|||
fit_get_name(ctx->fit, ctx->conf_node, NULL));
|
||||
if (fit_config_verify(ctx->fit, ctx->conf_node))
|
||||
return -EPERM;
|
||||
puts("OK\n");
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
/* find the node holding the images information */
|
||||
|
|
136
common/usb_kbd.c
136
common/usb_kbd.c
|
@ -23,6 +23,14 @@
|
|||
|
||||
#include <usb.h>
|
||||
|
||||
/*
|
||||
* USB vendor and product IDs used for quirks.
|
||||
*/
|
||||
#define USB_VENDOR_ID_APPLE 0x05ac
|
||||
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 0x029c
|
||||
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 0x029a
|
||||
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
|
||||
|
||||
/*
|
||||
* If overwrite_console returns 1, the stdin, stderr and stdout
|
||||
* are switched to the serial port, else the settings in the
|
||||
|
@ -41,6 +49,9 @@ int overwrite_console(void)
|
|||
#define REPEAT_RATE 40 /* 40msec -> 25cps */
|
||||
#define REPEAT_DELAY 10 /* 10 x REPEAT_RATE = 400msec */
|
||||
|
||||
/* Timeout for SETLED control transfer */
|
||||
#define SETLED_TIMEOUT 500
|
||||
|
||||
#define NUM_LOCK 0x53
|
||||
#define CAPS_LOCK 0x39
|
||||
#define SCROLL_LOCK 0x47
|
||||
|
@ -60,6 +71,7 @@ int overwrite_console(void)
|
|||
|
||||
/* Device name */
|
||||
#define DEVNAME "usbkbd"
|
||||
static unsigned int usbkbd_count;
|
||||
|
||||
/* Keyboard maps */
|
||||
static const unsigned char usb_kbd_numkey[] = {
|
||||
|
@ -100,12 +112,19 @@ static const u8 usb_special_keys[] = {
|
|||
(USB_KBD_NUMLOCK | USB_KBD_CAPSLOCK | USB_KBD_SCROLLLOCK)
|
||||
|
||||
struct usb_kbd_pdata {
|
||||
struct stdio_dev* sdev;
|
||||
unsigned long intpipe;
|
||||
int intpktsize;
|
||||
int intinterval;
|
||||
unsigned long last_report;
|
||||
|
||||
/* The period of time between two calls of usb_kbd_testc(). */
|
||||
unsigned long kbd_testc_tms;
|
||||
|
||||
struct int_queue *intq;
|
||||
|
||||
uint32_t ifnum;
|
||||
|
||||
uint32_t repeat_delay;
|
||||
|
||||
uint32_t usb_in_pointer;
|
||||
|
@ -116,12 +135,11 @@ struct usb_kbd_pdata {
|
|||
uint8_t old[USB_KBD_BOOT_REPORT_SIZE];
|
||||
|
||||
uint8_t flags;
|
||||
bool gone;
|
||||
};
|
||||
|
||||
extern int __maybe_unused net_busy_flag;
|
||||
|
||||
/* The period of time between two calls of usb_kbd_testc(). */
|
||||
static unsigned long kbd_testc_tms;
|
||||
|
||||
/* Puts character in the queue and sets up the in and out pointer. */
|
||||
static void usb_kbd_put_queue(struct usb_kbd_pdata *data, u8 c)
|
||||
|
@ -150,14 +168,18 @@ static void usb_kbd_put_queue(struct usb_kbd_pdata *data, u8 c)
|
|||
*/
|
||||
static void usb_kbd_setled(struct usb_device *dev)
|
||||
{
|
||||
struct usb_interface *iface = &dev->config.if_desc[0];
|
||||
struct usb_kbd_pdata *data = dev->privptr;
|
||||
struct usb_interface *iface = &dev->config.if_desc[data->ifnum];
|
||||
int ret;
|
||||
ALLOC_ALIGN_BUFFER(uint32_t, leds, 1, USB_DMA_MINALIGN);
|
||||
|
||||
*leds = data->flags & USB_KBD_LEDMASK;
|
||||
usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||
USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
|
||||
0x200, iface->desc.bInterfaceNumber, leds, 1, 0);
|
||||
0x200, iface->desc.bInterfaceNumber, leds, 1, SETLED_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
debug("WARN: usb_kbd_setled failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
#define CAPITAL_MASK 0x20
|
||||
|
@ -361,15 +383,44 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev)
|
|||
data->intpktsize, data->intinterval, true) >= 0)
|
||||
usb_kbd_irq_worker(dev);
|
||||
#elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) || \
|
||||
defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE)
|
||||
defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE) || \
|
||||
defined(CONFIG_SYS_USB_EVENT_POLL_COMPATIBLE)
|
||||
#if defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
|
||||
struct usb_interface *iface;
|
||||
struct usb_kbd_pdata *data = dev->privptr;
|
||||
iface = &dev->config.if_desc[0];
|
||||
iface = &dev->config.if_desc[data->ifnum];
|
||||
usb_get_report(dev, iface->desc.bInterfaceNumber,
|
||||
1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE);
|
||||
if (memcmp(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE)) {
|
||||
usb_kbd_irq_worker(dev);
|
||||
#elif defined(CONFIG_SYS_USB_EVENT_POLL_COMPATIBLE)
|
||||
struct usb_kbd_pdata *data = dev->privptr;
|
||||
struct udevice *bus = dev->controller_dev;
|
||||
bool use_int_queue = !!usb_get_ops(bus)->create_int_queue;
|
||||
int data_pending = 0;
|
||||
/* If keyboard is gone and cannot recover, we stop polling it,
|
||||
* so xhci won't spam a lots of EP reset messages.
|
||||
*/
|
||||
if (data->gone)
|
||||
return;
|
||||
if (use_int_queue) {
|
||||
data_pending = !!poll_int_queue(dev, data->intq);
|
||||
} else {
|
||||
data_pending = usb_int_msg(dev, data->intpipe, &data->new[0],
|
||||
data->intpktsize, data->intinterval, true);
|
||||
if (data_pending == -EINVAL)
|
||||
data->gone = true;
|
||||
data_pending = data_pending >= 0;
|
||||
}
|
||||
if (data_pending) {
|
||||
usb_kbd_irq_worker(dev);
|
||||
if (use_int_queue) {
|
||||
/* We've consumed all queued int packets, create new */
|
||||
destroy_int_queue(dev, data->intq);
|
||||
data->intq = create_int_queue(dev, data->intpipe, 1,
|
||||
USB_KBD_BOOT_REPORT_SIZE, data->new,
|
||||
data->intinterval);
|
||||
}
|
||||
#else
|
||||
struct usb_kbd_pdata *data = dev->privptr;
|
||||
if (poll_int_queue(dev, data->intq)) {
|
||||
|
@ -426,9 +477,9 @@ static int usb_kbd_testc(struct stdio_dev *sdev)
|
|||
usb_kbd_dev = (struct usb_device *)dev->priv;
|
||||
data = usb_kbd_dev->privptr;
|
||||
|
||||
if (get_timer(kbd_testc_tms) >= poll_delay) {
|
||||
if (get_timer(data->kbd_testc_tms) >= poll_delay) {
|
||||
usb_kbd_poll_for_event(usb_kbd_dev);
|
||||
kbd_testc_tms = get_timer(0);
|
||||
data->kbd_testc_tms = get_timer(0);
|
||||
}
|
||||
|
||||
return !(data->usb_in_pointer == data->usb_out_pointer);
|
||||
|
@ -464,6 +515,11 @@ static int usb_kbd_probe_dev(struct usb_device *dev, unsigned int ifnum)
|
|||
struct usb_interface *iface;
|
||||
struct usb_endpoint_descriptor *ep;
|
||||
struct usb_kbd_pdata *data;
|
||||
#if defined(CONFIG_SYS_USB_EVENT_POLL_COMPATIBLE)
|
||||
struct udevice *bus = dev->controller_dev;
|
||||
struct dm_usb_ops *ops = usb_get_ops(bus);
|
||||
bool use_int_queue = !!ops->create_int_queue;
|
||||
#endif
|
||||
int epNum;
|
||||
|
||||
if (dev->descriptor.bNumConfigurations != 1)
|
||||
|
@ -509,6 +565,8 @@ static int usb_kbd_probe_dev(struct usb_device *dev, unsigned int ifnum)
|
|||
data->new = memalign(USB_DMA_MINALIGN,
|
||||
roundup(USB_KBD_BOOT_REPORT_SIZE, USB_DMA_MINALIGN));
|
||||
|
||||
data->ifnum = ifnum;
|
||||
|
||||
/* Insert private data into USB device structure */
|
||||
dev->privptr = data;
|
||||
|
||||
|
@ -526,9 +584,16 @@ static int usb_kbd_probe_dev(struct usb_device *dev, unsigned int ifnum)
|
|||
usb_set_protocol(dev, iface->desc.bInterfaceNumber, 0);
|
||||
|
||||
#if !defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) && \
|
||||
!defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE)
|
||||
!defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE) && \
|
||||
!defined(CONFIG_SYS_USB_EVENT_POLL_COMPATIBLE)
|
||||
debug("USB KBD: set idle interval...\n");
|
||||
usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE / 4, 0);
|
||||
#elif defined(CONFIG_SYS_USB_EVENT_POLL_COMPATIBLE)
|
||||
debug("USB KBD: set idle interval=0...\n");
|
||||
if (use_int_queue)
|
||||
usb_set_idle(dev, iface->desc.bInterfaceNumber, 0, 0);
|
||||
else
|
||||
usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE / 4, 0);
|
||||
#else
|
||||
debug("USB KBD: set idle interval=0...\n");
|
||||
usb_set_idle(dev, iface->desc.bInterfaceNumber, 0, 0);
|
||||
|
@ -540,6 +605,12 @@ static int usb_kbd_probe_dev(struct usb_device *dev, unsigned int ifnum)
|
|||
USB_KBD_BOOT_REPORT_SIZE, data->new,
|
||||
data->intinterval);
|
||||
if (!data->intq) {
|
||||
#elif defined(CONFIG_SYS_USB_EVENT_POLL_COMPATIBLE)
|
||||
data->intq = create_int_queue(dev, data->intpipe, 1,
|
||||
USB_KBD_BOOT_REPORT_SIZE, data->new,
|
||||
data->intinterval);
|
||||
// Only abort when we do support int queue, else we will fallback
|
||||
if (!data->intq && use_int_queue) {
|
||||
#elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
|
||||
if (usb_get_report(dev, iface->desc.bInterfaceNumber,
|
||||
1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE) < 0) {
|
||||
|
@ -561,39 +632,51 @@ static int probe_usb_keyboard(struct usb_device *dev)
|
|||
{
|
||||
char *stdinname;
|
||||
struct stdio_dev usb_kbd_dev;
|
||||
unsigned int ifnum;
|
||||
unsigned int max_ifnum = min((unsigned int)USB_MAX_ACTIVE_INTERFACES,
|
||||
(unsigned int)dev->config.no_of_if);
|
||||
int error;
|
||||
struct usb_kbd_pdata *data;
|
||||
|
||||
/* Try probing the keyboard */
|
||||
if (usb_kbd_probe_dev(dev, 0) != 1)
|
||||
for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
|
||||
if (usb_kbd_probe_dev(dev, ifnum) == 1)
|
||||
break;
|
||||
}
|
||||
if (ifnum >= max_ifnum)
|
||||
return -ENOENT;
|
||||
|
||||
/* Register the keyboard */
|
||||
debug("USB KBD: register.\n");
|
||||
memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
|
||||
strcpy(usb_kbd_dev.name, DEVNAME);
|
||||
if (usbkbd_count)
|
||||
sprintf(usb_kbd_dev.name, DEVNAME"%d", usbkbd_count);
|
||||
else
|
||||
strcpy(usb_kbd_dev.name, DEVNAME);
|
||||
usbkbd_count++;
|
||||
usb_kbd_dev.flags = DEV_FLAGS_INPUT;
|
||||
usb_kbd_dev.getc = usb_kbd_getc;
|
||||
usb_kbd_dev.tstc = usb_kbd_testc;
|
||||
usb_kbd_dev.priv = (void *)dev;
|
||||
error = stdio_register(&usb_kbd_dev);
|
||||
data = dev->privptr;
|
||||
error = stdio_register_dev(&usb_kbd_dev, &data->sdev);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
stdinname = env_get("stdin");
|
||||
#if CONFIG_IS_ENABLED(CONSOLE_MUX)
|
||||
if (strstr(stdinname, DEVNAME) != NULL) {
|
||||
if (strstr(stdinname, usb_kbd_dev.name) != NULL) {
|
||||
error = iomux_doenv(stdin, stdinname);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
#else
|
||||
/* Check if this is the standard input device. */
|
||||
if (!strcmp(stdinname, DEVNAME)) {
|
||||
if (!strcmp(stdinname, usb_kbd_dev.name)) {
|
||||
/* Reassign the console */
|
||||
if (overwrite_console())
|
||||
return 1;
|
||||
|
||||
error = console_assign(stdin, DEVNAME);
|
||||
error = console_assign(stdin, usb_kbd_dev.name);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
@ -681,14 +764,14 @@ static int usb_kbd_remove(struct udevice *dev)
|
|||
struct stdio_dev *sdev;
|
||||
int ret;
|
||||
|
||||
sdev = stdio_get_by_name(DEVNAME);
|
||||
data = udev->privptr;
|
||||
sdev = data->sdev;
|
||||
if (!sdev) {
|
||||
ret = -ENXIO;
|
||||
goto err;
|
||||
}
|
||||
data = udev->privptr;
|
||||
#if CONFIG_IS_ENABLED(CONSOLE_MUX)
|
||||
if (iomux_replace_device(stdin, DEVNAME, "nulldev")) {
|
||||
if (iomux_replace_device(stdin, data->sdev->name, "nulldev")) {
|
||||
ret = -ENOLINK;
|
||||
goto err;
|
||||
}
|
||||
|
@ -700,6 +783,7 @@ static int usb_kbd_remove(struct udevice *dev)
|
|||
#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
|
||||
destroy_int_queue(udev, data->intq);
|
||||
#endif
|
||||
usbkbd_count--;
|
||||
free(data->new);
|
||||
free(data);
|
||||
|
||||
|
@ -731,6 +815,18 @@ static const struct usb_device_id kbd_id_table[] = {
|
|||
.bInterfaceSubClass = USB_SUB_HID_BOOT,
|
||||
.bInterfaceProtocol = USB_PROT_HID_KEYBOARD,
|
||||
},
|
||||
{
|
||||
USB_DEVICE(USB_VENDOR_ID_APPLE,
|
||||
USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
|
||||
},
|
||||
{
|
||||
USB_DEVICE(USB_VENDOR_ID_APPLE,
|
||||
USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
|
||||
},
|
||||
{
|
||||
USB_DEVICE(USB_VENDOR_ID_APPLE,
|
||||
USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
|
||||
},
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
|
|
@ -118,8 +118,8 @@ CONFIG_JFFS2_PART_SIZE=0x100000
|
|||
CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_CMD_MTDPARTS_SPREAD=y
|
||||
CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y
|
||||
CONFIG_MTDIDS_DEFAULT="nor0=spi-nor"
|
||||
CONFIG_MTDPARTS_DEFAULT="spi-nor:64K@0(bootinfo),64K@64K(private),256K@128K(fsbl),64K@384K(env),192K@448K(opensbi),-@640K(uboot)"
|
||||
CONFIG_MTDIDS_DEFAULT="nor0=d420c000.spi-0"
|
||||
CONFIG_MTDPARTS_DEFAULT="d420c000.spi-0:64K@0(bootinfo),64K@64K(private),256K@128K(fsbl),64K@384K(env),192K@448K(opensbi),-@640K(uboot)"
|
||||
CONFIG_CMD_UBI=y
|
||||
CONFIG_SPACEMIT_FLASH=y
|
||||
CONFIG_SPL_FASTBOOT=y
|
||||
|
@ -129,17 +129,23 @@ CONFIG_MULTI_DTB_FIT=y
|
|||
CONFIG_ENV_OVERWRITE=y
|
||||
CONFIG_ENV_IS_NOWHERE=y
|
||||
CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_ENV_IS_IN_NFS=y
|
||||
CONFIG_ENV_IS_IN_SPI_FLASH=y
|
||||
CONFIG_SYS_MMC_ENV_DEV=1
|
||||
# CONFIG_SPL_ENV_IS_NOWHERE is not set
|
||||
CONFIG_ARP_TIMEOUT=200
|
||||
CONFIG_NET_RETRY_COUNT=50
|
||||
CONFIG_PROT_UDP=y
|
||||
CONFIG_NET_RANDOM_ETHADDR=y
|
||||
CONFIG_IP_DEFRAG=y
|
||||
CONFIG_NET_MAXDEFRAG=65535
|
||||
CONFIG_KEEP_SERVERADDR=y
|
||||
CONFIG_BOOTP_SERVERIP=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_DEVRES=y
|
||||
# CONFIG_SCSI_AHCI is not set
|
||||
CONFIG_BUTTON=y
|
||||
CONFIG_BUTTON_GPIO=y
|
||||
CONFIG_SPL_CLK=y
|
||||
CONFIG_SPL_CLK_CCF=y
|
||||
CONFIG_SPACEMIT_K1X_CCU=y
|
||||
|
@ -176,6 +182,7 @@ CONFIG_MISC=y
|
|||
CONFIG_I2C_EEPROM=y
|
||||
CONFIG_SPACEMIT_K1X_EFUSE=y
|
||||
CONFIG_SPL_SPACEMIT_K1X_EFUSE=y
|
||||
CONFIG_SPACEMIT_SHUTDOWN_CHARGE=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
CONFIG_MMC_HS400_ES_SUPPORT=y
|
||||
|
@ -211,6 +218,10 @@ CONFIG_PMIC_SPM8XX=y
|
|||
CONFIG_DM_REGULATOR=y
|
||||
CONFIG_DM_REGULATOR_SPM8XX=y
|
||||
CONFIG_DM_REGULATOR_SPACEMIT_HUB=y
|
||||
CONFIG_DM_BATTERY=y
|
||||
CONFIG_CW2015_BATTERY=y
|
||||
CONFIG_DM_CHARGER=y
|
||||
CONFIG_SGM41515_CHARGER=y
|
||||
CONFIG_SPL_SPACEMIT_POWER=y
|
||||
CONFIG_DM_PWM=y
|
||||
CONFIG_PWM_PXA=y
|
||||
|
@ -237,7 +248,7 @@ CONFIG_USB_DWC3=y
|
|||
CONFIG_USB_DWC3_GENERIC=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_KEYBOARD=y
|
||||
CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP=y
|
||||
CONFIG_SYS_USB_EVENT_POLL_COMPATIBLE=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_GADGET_VENDOR_NUM=0x361C
|
||||
CONFIG_USB_GADGET_PRODUCT_NUM=0x1001
|
||||
|
@ -265,9 +276,9 @@ CONFIG_JFFS2_NOR=y
|
|||
CONFIG_JFFS2_USE_MTD_READ=y
|
||||
CONFIG_UBIFS_SILENCE_MSG=y
|
||||
CONFIG_IMAGE_SPARSE_TRANSFER_BLK_NUM=0x3000
|
||||
CONFIG_PRINT_TIMESTAMP=y
|
||||
# CONFIG_SPL_USE_TINY_PRINTF is not set
|
||||
# CONFIG_RSA is not set
|
||||
# CONFIG_SPL_SHA1 is not set
|
||||
# CONFIG_SPL_SHA256 is not set
|
||||
CONFIG_ZSTD=y
|
||||
CONFIG_FDT_FIXUP_PARTITIONS=y
|
||||
|
|
33
debian/u-boot-spacemit.postinst
vendored
33
debian/u-boot-spacemit.postinst
vendored
|
@ -46,15 +46,27 @@ configure)
|
|||
fi
|
||||
;;
|
||||
"/dev/nvme0n1"*)
|
||||
BOOTINFO_FILE=bootinfo_spinor.bin
|
||||
BOOTINFO=/dev/mtdblock0
|
||||
FSBL=/dev/mtdblock0
|
||||
FSBL_SEEK=$((128 * 1024))
|
||||
ENV=/dev/mtdblock0
|
||||
ENV_SEEK=$((384 * 1024))
|
||||
UBOOT=/dev/mtdblock0
|
||||
# 以KB为单位
|
||||
UBOOT_SEEK=640
|
||||
if [ ! -e "/dev/mtdblock5" ]; then
|
||||
BOOTINFO_FILE=bootinfo_spinor.bin
|
||||
BOOTINFO=/dev/mtdblock0
|
||||
FSBL=/dev/mtdblock0
|
||||
FSBL_SEEK=$((128 * 1024))
|
||||
ENV=/dev/mtdblock0
|
||||
ENV_SEEK=$((384 * 1024))
|
||||
UBOOT=/dev/mtdblock0
|
||||
# 以KB为单位
|
||||
UBOOT_SEEK=640
|
||||
else
|
||||
BOOTINFO_FILE=bootinfo_spinor.bin
|
||||
BOOTINFO=/dev/mtdblock0
|
||||
FSBL=/dev/mtdblock2
|
||||
FSBL_SEEK=0
|
||||
ENV=/dev/mtdblock3
|
||||
ENV_SEEK=0
|
||||
UBOOT=/dev/mtdblock5
|
||||
# 以KB为单位
|
||||
UBOOT_SEEK=0
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported root=$ROOT"
|
||||
|
@ -78,11 +90,12 @@ configure)
|
|||
done
|
||||
|
||||
# 此前已经做了所有检查
|
||||
set -x
|
||||
dd if=/usr/lib/u-boot/$target/$BOOTINFO_FILE of=$BOOTINFO && sync
|
||||
dd if=/usr/lib/u-boot/$target/FSBL.bin of=$FSBL seek=$FSBL_SEEK bs=1 && sync
|
||||
dd if=/usr/lib/u-boot/$target/env.bin of=$ENV seek=$ENV_SEEK bs=1 && sync
|
||||
dd if=/usr/lib/u-boot/$target/u-boot.itb of=$UBOOT seek=$UBOOT_SEEK bs=1K && sync
|
||||
|
||||
set +x
|
||||
;;
|
||||
esac
|
||||
|
||||
|
|
|
@ -35,5 +35,13 @@ config SYS_SPD_BUS_NUM
|
|||
depends on DDR_SPD || SYS_I2C_LEGACY || SPL_SYS_I2C_LEGACY
|
||||
default 0
|
||||
|
||||
config DDR_QOS
|
||||
bool "DDR Quality of Service (QoS) support"
|
||||
help
|
||||
For memory controllers that support QoS, set different priority for
|
||||
different master, that ensure all on-chip data flows can concurrently
|
||||
meet latency and bandwidth requirements while sharing the finite
|
||||
bandwidth of DDR memory.
|
||||
|
||||
source "drivers/ddr/altera/Kconfig"
|
||||
source "drivers/ddr/imx/Kconfig"
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-y += ddr_init.o lpddr4_silicon_init.o ddr_freq.o
|
||||
obj-$(CONFIG_DDR_QOS) += ddr_qos.o
|
||||
else
|
||||
obj-$(CONFIG_DYNAMIC_DDR_CLK_FREQ) += ddr_freq.o
|
||||
endif
|
||||
|
|
|
@ -116,7 +116,7 @@ static u32 mode_register_read(u32 MR, u32 CH, u32 CS)
|
|||
read_data = readl((void __iomem*)DDR_MR_DATA);
|
||||
}
|
||||
|
||||
UI3 = readl((void __iomem*)(DDR_BASE + 0x234)) & 0xFF;
|
||||
UI3 = readl((void __iomem*)(DDR_BASE + 0x370)) & 0xFF;
|
||||
return UI3;
|
||||
}
|
||||
|
||||
|
@ -271,6 +271,12 @@ static struct dfc_level_config freq_levels[MAX_FREQ_LV] =
|
|||
{7, 3, DPLL_PLL2, DPLL_DIV1, DPLL_DIV1, 3200, 1, 3},
|
||||
};
|
||||
|
||||
#define KHZ 1000
|
||||
#define FREQ_MAX ~(0U)
|
||||
static int ddr_vmin_table[] = {
|
||||
0, 400000, 600000, FREQ_MAX
|
||||
};
|
||||
|
||||
|
||||
static int get_cur_freq_level(void)
|
||||
{
|
||||
|
@ -385,6 +391,25 @@ static int ddr_vftbl_cfg(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void set_vol_level(void)
|
||||
{
|
||||
int freq_lv, vmin_lv, cur_vol_lv = 0;
|
||||
u32 rate;
|
||||
|
||||
for (freq_lv = 0; freq_lv < MAX_FREQ_LV; freq_lv++) {
|
||||
rate = freq_levels[freq_lv].data_rate / DDR_CONS * KHZ;
|
||||
for (vmin_lv = cur_vol_lv; vmin_lv < ARRAY_SIZE(ddr_vmin_table); vmin_lv++) {
|
||||
if (rate <= ddr_vmin_table[vmin_lv]) {
|
||||
freq_levels[freq_lv].vol_lv = vmin_lv;
|
||||
cur_vol_lv = vmin_lv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pr_info("%d KHZ: %d; ", rate, vmin_lv);
|
||||
}
|
||||
pr_info("\n");
|
||||
}
|
||||
|
||||
static int config_core(void)
|
||||
{
|
||||
u32 val;
|
||||
|
@ -489,19 +514,20 @@ static int wait_freq_change_done(void)
|
|||
static int ddr_freq_init(void)
|
||||
{
|
||||
int ret;
|
||||
static bool ddr_freq_init_flag = false;
|
||||
static bool ddr_freq_init_flag = false;
|
||||
|
||||
if(ddr_freq_init_flag == true) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_K1_X_BOARD_ASIC
|
||||
#ifdef CONFIG_K1_X_BOARD_ASIC
|
||||
set_vol_level();
|
||||
ret = ddr_vftbl_cfg();
|
||||
if (ret < 0) {
|
||||
pr_err("%s failed!\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ddr_freq_init_flag = true;
|
||||
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
extern u32 ddr_cs_num;
|
||||
extern const char *ddr_type;
|
||||
extern int ddr_freq_change(u32 data_rate);
|
||||
extern void qos_set_default(void);
|
||||
|
||||
u32 ddr_datarate;
|
||||
|
||||
static int test_pattern(fdt_addr_t base, fdt_size_t size)
|
||||
{
|
||||
|
@ -126,7 +129,6 @@ static int spacemit_ddr_probe(struct udevice *dev)
|
|||
#ifdef CONFIG_K1_X_BOARD_FPGA
|
||||
void (*ddr_init)(void);
|
||||
#else
|
||||
uint32_t ddr_datarate;
|
||||
fdt_addr_t ddrc_base;
|
||||
|
||||
ddrc_base = dev_read_addr(dev);
|
||||
|
@ -137,16 +139,16 @@ static int spacemit_ddr_probe(struct udevice *dev)
|
|||
ddr_init();
|
||||
#else
|
||||
|
||||
/* check if dram data-rate is configued in dts */
|
||||
if(dev_read_u32u(dev, "datarate", &ddr_datarate)) {
|
||||
/* if dram data-rate is NOT configued in eeprom or in dts, use default value */
|
||||
if ((0 == ddr_datarate) && (dev_read_u32u(dev, "datarate", &ddr_datarate))) {
|
||||
pr_info("ddr data rate not configed in dts, use 1200 as default!\n");
|
||||
ddr_datarate = 1200;
|
||||
} else {
|
||||
pr_info("ddr data rate is %u configured in dts\n", ddr_datarate);
|
||||
pr_info("ddr data rate is configured as %dMT/s\n", ddr_datarate);
|
||||
}
|
||||
|
||||
/* if DDR cs number is NOT configued in eeprom or in dts, use default value */
|
||||
if((0 == ddr_cs_num) && dev_read_u32u(dev, "cs-num", &ddr_cs_num)) {
|
||||
if ((0 == ddr_cs_num) && dev_read_u32u(dev, "cs-num", &ddr_cs_num)) {
|
||||
pr_info("ddr cs number not configed in dts!\n");
|
||||
ddr_cs_num = DDR_CS_NUM;
|
||||
}
|
||||
|
@ -169,6 +171,9 @@ static int spacemit_ddr_probe(struct udevice *dev)
|
|||
pr_err("dram init failed!\n");
|
||||
return -EIO;
|
||||
}
|
||||
#ifdef CONFIG_DDR_QOS
|
||||
qos_set_default();
|
||||
#endif
|
||||
pr_info("dram init done\n");
|
||||
|
||||
return 0;
|
||||
|
|
157
drivers/ddr/spacemit/k1x/ddr_qos.c
Normal file
157
drivers/ddr/spacemit/k1x/ddr_qos.c
Normal file
|
@ -0,0 +1,157 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2022-2024 Spacemit
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <common.h>
|
||||
#include <dt-bindings/soc/spacemit-k1x.h>
|
||||
|
||||
#define DEBUG_QOS_DUMP
|
||||
|
||||
#define K1_DDRC_ADDR(base, offset) ((uintptr_t)(base) + (offset))
|
||||
#define MC_QOS_CTRL1 K1_DDRC_ADDR(K1X_CIU_BASE, 0x118)
|
||||
#define MC_QOS_CTRL2 K1_DDRC_ADDR(K1X_CIU_BASE, 0x11c)
|
||||
#define MC_QOS_CTRL3 K1_DDRC_ADDR(K1X_CIU_BASE, 0x120)
|
||||
#define MC_QOS_CTRL4 K1_DDRC_ADDR(K1X_CIU_BASE, 0x124)
|
||||
#define CCI_QOS_CTRL K1_DDRC_ADDR(K1X_PLAT_CIU_BASE, 0x98)
|
||||
#define ISP_QOS_CTRL K1_DDRC_ADDR(K1X_CIU_BASE, 0x1e0)
|
||||
#define GPU_QOS_CTRL K1_DDRC_ADDR(K1X_CIU_BASE, 0x100)
|
||||
#define GNSS_QOS_CTRL K1_DDRC_ADDR(K1X_CIU_BASE, 0x1c)
|
||||
#define REG32(x) (*((volatile uint32_t *)((uintptr_t)(x))))
|
||||
|
||||
/* DDR QoS master id */
|
||||
enum {
|
||||
/* port0 */
|
||||
DDR_MASTER_CORE = 0,
|
||||
DDR_MASTER_GPU,
|
||||
DDR_MASTER_GPU_H,
|
||||
/* port1 */
|
||||
DDR_MASTER_PDMA,
|
||||
DDR_MASTER_SDH,
|
||||
DDR_MASTER_USB_OTG,
|
||||
DDR_MASTER_USB2,
|
||||
DDR_MASTER_USB3,
|
||||
DDR_MASTER_EMAC0,
|
||||
DDR_MASTER_EMAC1,
|
||||
/* port2 */
|
||||
DDR_MASTER_VPU,
|
||||
DDR_MASTER_PCIE_A,
|
||||
DDR_MASTER_PCIE_B,
|
||||
DDR_MASTER_PCIE_C,
|
||||
/* port3 */
|
||||
DDR_MASTER_V2D,
|
||||
DDR_MASTER_CCIC,
|
||||
DDR_MASTER_JPEG,
|
||||
DDR_MASTER_CPP,
|
||||
DDR_MASTER_ISP,
|
||||
};
|
||||
|
||||
/* defined in ciu reg, bit width = 4 by default */
|
||||
struct ciu_qos_conf {
|
||||
const char *name;
|
||||
uint32_t qos_id;
|
||||
uint32_t reg;
|
||||
uint32_t aw_qos;
|
||||
uint32_t aw_offset;
|
||||
uint32_t ar_qos;
|
||||
uint32_t ar_offset;
|
||||
uint32_t mask;
|
||||
};
|
||||
|
||||
/* QoS on DDR port
|
||||
* lcd hdmi qos and v2d qos are in their drvier
|
||||
*/
|
||||
static struct ciu_qos_conf qos_conf[] = {
|
||||
/*name id reg wqos woffset rqos roffset mask */
|
||||
{"CORE", DDR_MASTER_CORE, CCI_QOS_CTRL, 0, 0, 0, 4, 0xff},
|
||||
{"GPU", DDR_MASTER_GPU, GPU_QOS_CTRL, 1, 8, 1, 12, 0xff},
|
||||
{"GPU_H", DDR_MASTER_GPU_H, GPU_QOS_CTRL, 1, 16, 1, 20, 0xff},
|
||||
|
||||
{"PDMA", DDR_MASTER_PDMA, MC_QOS_CTRL1, 0, 16, 0, 20, 0xff},
|
||||
{"USB3", DDR_MASTER_USB3, MC_QOS_CTRL1, 1, 8, 1, 12, 0xff},
|
||||
{"SDH", DDR_MASTER_SDH, MC_QOS_CTRL2, 1, 0, 1, 4, 0xff},
|
||||
{"USB_OTG", DDR_MASTER_USB_OTG, MC_QOS_CTRL2, 1, 8, 1, 12, 0xff},
|
||||
{"USB2", DDR_MASTER_USB2, MC_QOS_CTRL2, 1, 16, 1, 20, 0xff},
|
||||
{"EMAC0", DDR_MASTER_EMAC0, MC_QOS_CTRL3, 1, 0, 1, 0, 0xf},
|
||||
{"EMAC1", DDR_MASTER_EMAC1, MC_QOS_CTRL3, 1, 0, 1, 0, 0xf},
|
||||
|
||||
{"PCIE_A", DDR_MASTER_PCIE_A, MC_QOS_CTRL3, 2, 8, 2, 12, 0xff},
|
||||
{"PCIE_B", DDR_MASTER_PCIE_B, MC_QOS_CTRL3, 2, 16, 2, 20, 0xff},
|
||||
{"PCIE_C", DDR_MASTER_PCIE_C, MC_QOS_CTRL3, 2, 24, 2, 28, 0xff},
|
||||
{"VPU", DDR_MASTER_VPU, MC_QOS_CTRL4, 1, 24, 1, 28, 0xff},
|
||||
|
||||
{"CCIC", DDR_MASTER_CCIC, ISP_QOS_CTRL, 3, 24, 3, 28, 0xff},
|
||||
{"JPEG", DDR_MASTER_JPEG, ISP_QOS_CTRL, 2, 16, 2, 20, 0xff},
|
||||
{"CPP", DDR_MASTER_CPP, ISP_QOS_CTRL, 2, 8, 2, 12, 0xff},
|
||||
{"ISP", DDR_MASTER_ISP, ISP_QOS_CTRL, 3, 0, 2, 4, 0xff},
|
||||
};
|
||||
|
||||
static void qos_setup_one(struct ciu_qos_conf *qos_conf)
|
||||
{
|
||||
uint32_t reg, val, mask, shift, qos_val;
|
||||
|
||||
reg = qos_conf->reg;
|
||||
mask = qos_conf->mask;
|
||||
/* qos val = (aw_val<<aw_offset)|(ar_val<<(aw_offset+ar_offset)) */
|
||||
shift = qos_conf->ar_offset;
|
||||
qos_val = qos_conf->ar_qos << shift;
|
||||
shift = qos_conf->aw_offset;
|
||||
qos_val |= (qos_conf->aw_qos << shift);
|
||||
|
||||
val = REG32(reg);
|
||||
shift = min(qos_conf->ar_offset, qos_conf->aw_offset);
|
||||
val &= ~(mask << shift);
|
||||
val |= qos_val;
|
||||
REG32(reg) = val;
|
||||
}
|
||||
|
||||
static void qos_setup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
REG32(MC_QOS_CTRL2) &= ~(1 << 26);
|
||||
REG32(MC_QOS_CTRL2) |= (1 << 25);
|
||||
REG32(MC_QOS_CTRL2) |= (1 << 24);
|
||||
for (i = 0; i < ARRAY_SIZE(qos_conf); i++)
|
||||
qos_setup_one(&qos_conf[i]);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_QOS_DUMP
|
||||
static void qos_dump_one(struct ciu_qos_conf *qos_conf)
|
||||
{
|
||||
uint32_t reg, val, mask, shift;
|
||||
uint32_t rqos;
|
||||
uint32_t wqos;
|
||||
|
||||
reg = qos_conf->reg;
|
||||
mask = qos_conf->mask;
|
||||
shift = min(qos_conf->ar_offset, qos_conf->aw_offset);
|
||||
|
||||
val = REG32(reg);
|
||||
val &= (mask << shift);
|
||||
|
||||
shift = qos_conf->aw_offset;
|
||||
wqos = (val >> shift) & 0xf;
|
||||
shift = qos_conf->ar_offset;
|
||||
rqos = (val >> shift) & 0xf;
|
||||
|
||||
printf("%s: rd = %d wr = %d\n", qos_conf->name, rqos, wqos);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void qos_dump(void)
|
||||
{
|
||||
#ifdef DEBUG_QOS_DUMP
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qos_conf); i++)
|
||||
qos_dump_one(&qos_conf[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void qos_set_default(void)
|
||||
{
|
||||
qos_setup();
|
||||
qos_dump();
|
||||
}
|
|
@ -22,6 +22,7 @@
|
|||
#include <mapmem.h>
|
||||
#include <u-boot/crc.h>
|
||||
#include "ddr_freq.h"
|
||||
#include <linux/delay.h>
|
||||
|
||||
#define BOOT_PP 0
|
||||
#define PMUA_REG_BASE 0xd4282800
|
||||
|
@ -44,7 +45,7 @@ extern u32 ddr_cs_num;
|
|||
extern u32 ddr_get_mr8(void);
|
||||
extern uint32_t get_manufacture_id(void);
|
||||
extern uint32_t get_ddr_rev_id(void);
|
||||
|
||||
static uint32_t byte_mode_tag = 0;
|
||||
struct addrmap_info {
|
||||
u32 io_width_per_channel;
|
||||
u32 density_per_channel;
|
||||
|
@ -88,7 +89,7 @@ struct io_para_info {
|
|||
};
|
||||
|
||||
const struct io_para_info ddr_io_para_table[] = {
|
||||
{SK_HYNIX, LPDDR4X, 0x9D, R_40, R_40, R_60, 0x19, R_60, VOH_0P6, R_60, R_60, 0x55},
|
||||
{SK_HYNIX, LPDDR4X, 0x9D, R_40, R_40, R_80, 0x19, R_60, VOH_0P6, R_60, R_60, 0x55},
|
||||
{SK_HYNIX, LPDDR4, 0xB2, R_40, R_40, R_120, 0xA7, R_60, VOH_0P6, R_80, R_80, 0x33},
|
||||
// {SK_HYNIX, LPDDR4, 0xB2, R_40, R_40, R_60, 0xA7, R_48, VOH_0P6, R_48, R_48, 0x00},
|
||||
};
|
||||
|
@ -779,6 +780,25 @@ void ddr_dfc_table_init(unsigned int DDRC_BASE, unsigned int ddr_size_mb)
|
|||
REG32(DDRC_BASE + 0x70) = idx;
|
||||
}
|
||||
|
||||
void set_byte_mode_parameter(u32 DDRC_BASE)
|
||||
{
|
||||
REG32(DDRC_BASE + MC_CH0_BASE + 0x0104) = 0xF0800400;
|
||||
REG32(DDRC_BASE + MC_CH0_PHY_BASE + 0x03e4) = 0x19000A02;
|
||||
REG32(DDRC_BASE + MC_CH0_BASE + 0x01b4) = 0x08001400;
|
||||
|
||||
REG32(DDRC_BASE + MC_CH0_BASE + 0x0104) = 0xA0800400;
|
||||
REG32(DDRC_BASE + MC_CH0_PHY_BASE + 0x03e4) = 0x15000802;
|
||||
REG32(DDRC_BASE + MC_CH0_BASE + 0x01b4) = 0x08001000;
|
||||
|
||||
REG32(DDRC_BASE + MC_CH0_BASE + 0x0104) = 0x50800400;
|
||||
REG32(DDRC_BASE + MC_CH0_PHY_BASE + 0x03e4) = 0x0c000402;
|
||||
REG32(DDRC_BASE + MC_CH0_BASE + 0x01b4) = 0x08000A00;
|
||||
|
||||
REG32(DDRC_BASE + MC_CH0_BASE + 0x0104) = 0x00800400;
|
||||
REG32(DDRC_BASE + MC_CH0_PHY_BASE + 0x03e4) = 0x0c000402;
|
||||
REG32(DDRC_BASE + MC_CH0_BASE + 0x01b4) = 0x08000A00;
|
||||
}
|
||||
|
||||
void top_DDR_MC_init(unsigned DDRC_BASE, unsigned int fp)
|
||||
{
|
||||
u32 temp_data;
|
||||
|
@ -810,7 +830,12 @@ void top_DDR_MC_init(unsigned DDRC_BASE, unsigned int fp)
|
|||
|
||||
REG32(DDRC_BASE + MC_CH0_BASE + 0xcc) = 0x200;
|
||||
fp_timing_init(DDRC_BASE);
|
||||
|
||||
if(byte_mode_tag)
|
||||
set_byte_mode_parameter(DDRC_BASE);
|
||||
|
||||
fp_sel(DDRC_BASE, fp);
|
||||
|
||||
REG32(DDRC_BASE + MC_CH0_BASE + 0x0180) = 0x30D400;
|
||||
REG32(DDRC_BASE + MC_CH0_BASE + 0x0184) = 0x4E200;
|
||||
REG32(DDRC_BASE + MC_CH0_BASE + 0x0188) = 0xC800000;
|
||||
|
@ -857,7 +882,7 @@ void top_DDR_rx_ds_odt_vref(unsigned DPHY0_BASE,unsigned combination)
|
|||
case 2:
|
||||
data = REG32(DPHY0_BASE + COMMON_OFFSET + 0xc);
|
||||
data &= 0xFFC0FFFF;
|
||||
// d_reg3 = 0xE4;
|
||||
//d_reg3 = 0xE4;
|
||||
d_reg3 = (io_para_update->rx_odt << 3) | io_para_update->rx_odt;
|
||||
data |= (d_reg3 << 16);
|
||||
REG32(DPHY0_BASE + COMMON_OFFSET + 0xc) = data;
|
||||
|
@ -1217,8 +1242,22 @@ void lpddr4_silicon_init(u32 ddr_base, const char *ddr_type, u32 data_rate)
|
|||
|
||||
top_DDR_MC_Phy_Device_Init(ddr_base, cs_num, 0);
|
||||
|
||||
top_training_fp_all(ddr_base, cs_num, 0, info->para);
|
||||
|
||||
size_mb = ddr_get_density();
|
||||
mr8_value = ddr_get_mr8();
|
||||
byte_mode_tag = (mr8_value >> 6);
|
||||
|
||||
if (0 != byte_mode_tag) {
|
||||
//reset mc
|
||||
REG32(0xd4282800 + 0xb0) &= ~(0x1 << 21);
|
||||
udelay(100);
|
||||
REG32(0xd4282800 + 0xb0) |= (0x1 << 21);
|
||||
udelay(100);
|
||||
|
||||
top_DDR_MC_Phy_Device_Init(ddr_base, cs_num, 0);
|
||||
}
|
||||
|
||||
adjust_mapping(ddr_base, cs_num, size_mb, mr8_value);
|
||||
LogMsg(0,"ddr density: %u MB \n", size_mb);
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ static void write_raw_image(struct blk_desc *dev_desc,
|
|||
return;
|
||||
}
|
||||
|
||||
puts("Flashing Raw Image\n");
|
||||
printf("Flashing Raw Image\n");
|
||||
|
||||
blks = fb_blk_write(dev_desc, info->start, blkcnt, buffer);
|
||||
|
||||
|
@ -186,6 +186,8 @@ void fastboot_blk_flash_write(const char *cmd, void *download_buffer,
|
|||
static char __maybe_unused part_name_t[20] = "";
|
||||
unsigned long __maybe_unused src_len = ~0UL;
|
||||
bool gzip_image = false;
|
||||
bool is_hidden_part = false;
|
||||
int part_index = 0;
|
||||
|
||||
if (fdev == NULL){
|
||||
fdev = malloc(sizeof(struct flash_dev));
|
||||
|
@ -213,9 +215,42 @@ void fastboot_blk_flash_write(const char *cmd, void *download_buffer,
|
|||
response, fdev);
|
||||
return;
|
||||
}
|
||||
|
||||
for (part_index = 0; part_index < MAX_PARTITION_NUM; part_index++){
|
||||
if (fdev->parts_info[part_index].part_name != NULL
|
||||
&& strcmp(cmd, fdev->parts_info[part_index].part_name) == 0){
|
||||
if (fdev->parts_info[part_index].hidden)
|
||||
is_hidden_part = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_hidden_part){
|
||||
/*find available blk dev*/
|
||||
/* do_get_part_info(&dev_desc, cmd, &info); */
|
||||
|
||||
char *blk_dev;
|
||||
int blk_index = -1;
|
||||
if (get_available_blk_dev(&blk_dev, &blk_index) == 0) {
|
||||
dev_desc = blk_get_dev(blk_dev, blk_index);
|
||||
if (dev_desc == NULL){
|
||||
fastboot_fail("can not get available blk dev", response);
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
fastboot_fail("can not get available blk dev", response);
|
||||
return;
|
||||
}
|
||||
|
||||
strlcpy((char *)&info.name, cmd, sizeof(info.name));
|
||||
info.size = fdev->parts_info[part_index].part_size / dev_desc->blksz;
|
||||
info.start = fdev->parts_info[part_index].part_offset / dev_desc->blksz;
|
||||
info.blksz = dev_desc->blksz;
|
||||
printf("!!! flash image to hidden partition !!!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fastboot_blk_get_part_info(cmd, &dev_desc, &info, response) < 0)
|
||||
if (!is_hidden_part && fastboot_blk_get_part_info(cmd, &dev_desc, &info, response) < 0)
|
||||
return;
|
||||
|
||||
if (check_gzip_format((uchar *)download_buffer, src_len) >= 0) {
|
||||
|
|
|
@ -368,9 +368,9 @@ void fastboot_data_download(const void *fastboot_data,
|
|||
now_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
|
||||
|
||||
if (pre_dot_num != now_dot_num) {
|
||||
putc('.');
|
||||
printf(".");
|
||||
if (!(now_dot_num % 74))
|
||||
putc('\n');
|
||||
printf("\n");
|
||||
}
|
||||
*response = '\0';
|
||||
}
|
||||
|
@ -411,9 +411,9 @@ void fastboot_data_upload(const void *fastboot_data,
|
|||
now_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
|
||||
|
||||
if (pre_dot_num != now_dot_num) {
|
||||
putc('.');
|
||||
printf(".");
|
||||
if (!(now_dot_num % 74))
|
||||
putc('\n');
|
||||
printf("\n");
|
||||
}
|
||||
*response = '\0';
|
||||
}
|
||||
|
@ -430,7 +430,8 @@ void fastboot_data_complete(char *response)
|
|||
{
|
||||
/* Download complete. Respond with "OKAY" */
|
||||
fastboot_okay(NULL, response);
|
||||
pr_info("\ndownloading/uploading of %d bytes finished\n", fastboot_bytes_received);
|
||||
pr_info("\n");
|
||||
pr_info("downloading/uploading of %d bytes finished\n", fastboot_bytes_received);
|
||||
image_size = fastboot_bytes_received;
|
||||
env_set_hex("filesize", image_size);
|
||||
fastboot_bytes_expected = 0;
|
||||
|
|
|
@ -194,7 +194,7 @@ static void write_raw_image(struct blk_desc *dev_desc,
|
|||
return;
|
||||
}
|
||||
|
||||
puts("Flashing Raw Image\n");
|
||||
printf("Flashing Raw Image\n");
|
||||
|
||||
blks = fb_mmc_blk_write(dev_desc, info->start, blkcnt, buffer);
|
||||
|
||||
|
@ -359,7 +359,7 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
|
|||
struct disk_partition info;
|
||||
int res;
|
||||
|
||||
puts("Flashing zImage\n");
|
||||
printf("Flashing zImage\n");
|
||||
|
||||
/* Get boot partition info */
|
||||
res = part_get_info_by_name(dev_desc, BOOT_PARTITION_NAME, &info);
|
||||
|
@ -441,7 +441,7 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
|
|||
return -1;
|
||||
}
|
||||
|
||||
puts("........ zImage was updated in boot partition\n");
|
||||
printf("........ zImage was updated in boot partition\n");
|
||||
fastboot_okay(NULL, response);
|
||||
return 0;
|
||||
}
|
||||
|
@ -528,6 +528,8 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
|
|||
static char __maybe_unused part_name_t[20] = "";
|
||||
unsigned long __maybe_unused src_len = ~0UL;
|
||||
bool gzip_image = false;
|
||||
bool is_hidden_part = false;
|
||||
int part_index = 0;
|
||||
|
||||
if (fdev == NULL){
|
||||
fdev = malloc(sizeof(struct flash_dev));
|
||||
|
@ -659,6 +661,30 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPACEMIT_FLASH
|
||||
for (part_index = 0; part_index < MAX_PARTITION_NUM; part_index++){
|
||||
if (fdev->parts_info[part_index].part_name != NULL
|
||||
&& strcmp(cmd, fdev->parts_info[part_index].part_name) == 0){
|
||||
if (fdev->parts_info[part_index].hidden)
|
||||
is_hidden_part = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_hidden_part){
|
||||
/*find available blk dev*/
|
||||
dev_desc = fastboot_mmc_get_dev(response);
|
||||
if (!dev_desc)
|
||||
return;
|
||||
|
||||
strlcpy((char *)&info.name, cmd, sizeof(info.name));
|
||||
info.size = fdev->parts_info[part_index].part_size / dev_desc->blksz;
|
||||
info.start = fdev->parts_info[part_index].part_offset / dev_desc->blksz;
|
||||
info.blksz = dev_desc->blksz;
|
||||
printf("!!! flash image to hidden partition !!!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!info.name[0] &&
|
||||
fastboot_mmc_get_part_info(cmd, &dev_desc, &info, response) < 0)
|
||||
return;
|
||||
|
|
|
@ -110,12 +110,6 @@ int _clear_env_part(void *download_buffer, u32 download_bytes,
|
|||
{
|
||||
u32 boot_mode = get_boot_pin_select();
|
||||
|
||||
/* char cmdbuf[64] = {"\0"}; */
|
||||
/* sprintf(cmdbuf, "env export -c -s 0x%lx 0x%lx", (ulong)CONFIG_ENV_SIZE, (ulong)download_buffer); */
|
||||
/* if (run_command(cmdbuf, 0)){ */
|
||||
/* return -1; */
|
||||
/* } */
|
||||
|
||||
switch(boot_mode){
|
||||
#ifdef CONFIG_ENV_IS_IN_MMC
|
||||
case BOOT_MODE_EMMC:
|
||||
|
@ -147,12 +141,6 @@ int _clear_env_part(void *download_buffer, u32 download_bytes,
|
|||
ret = _fb_mtd_erase(mtd, CONFIG_ENV_SIZE);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
/*should not write env to env part*/
|
||||
/* ret = _fb_mtd_write(mtd, download_buffer, 0, CONFIG_ENV_SIZE, NULL); */
|
||||
/* if (ret){ */
|
||||
/* pr_err("can not write env to mtd flash\n"); */
|
||||
/* } */
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
@ -208,7 +196,7 @@ int _write_mtd_partition(struct flash_dev *fdev)
|
|||
* @brief transfer the string of size 'K' or 'M' to u32 type.
|
||||
*
|
||||
* @param reserve_size , the string of size
|
||||
* @return int , return the transfer result.
|
||||
* @return int , return the transfer result of KB.
|
||||
*/
|
||||
int transfer_string_to_ul(const char *reserve_size)
|
||||
{
|
||||
|
@ -303,6 +291,7 @@ int _parse_flash_config(struct flash_dev *fdev, void *load_flash_addr)
|
|||
const char *node_file = NULL;
|
||||
const char *node_offset = NULL;
|
||||
const char *node_size = NULL;
|
||||
fdev->parts_info[part_index].hidden = false;
|
||||
|
||||
cJSON *arraypart = cJSON_GetArrayItem(cj_parts, i);
|
||||
cJSON *cj_name = cJSON_GetObjectItem(arraypart, "name");
|
||||
|
@ -311,7 +300,7 @@ int _parse_flash_config(struct flash_dev *fdev, void *load_flash_addr)
|
|||
else
|
||||
node_part = "";
|
||||
|
||||
/*only blk dev would not add bootinfo partition*/
|
||||
/*bootinfo should be hidden as default in gpt partition*/
|
||||
if (!parse_mtd_partition){
|
||||
if (strlen(node_part) > 0 && !strncmp("bootinfo", node_part, 8)){
|
||||
pr_info("bootinfo would not add as partition\n");
|
||||
|
@ -319,6 +308,15 @@ int _parse_flash_config(struct flash_dev *fdev, void *load_flash_addr)
|
|||
}
|
||||
}
|
||||
|
||||
cJSON *cj_hidden = cJSON_GetObjectItem(arraypart, "hidden");
|
||||
if (cj_hidden){
|
||||
if ((cj_hidden->type == cJSON_String && strcmp("true", cj_hidden->valuestring) == 0)
|
||||
|| cj_hidden->type == cJSON_True){
|
||||
printf("!!!! patr name:%s would set to hidden part !!!!\n", node_part);
|
||||
fdev->parts_info[part_index].hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *cj_filename = cJSON_GetObjectItem(arraypart, "image");
|
||||
if (cj_filename && cj_filename->type == cJSON_String)
|
||||
node_file = cj_filename->valuestring;
|
||||
|
@ -374,19 +372,26 @@ int _parse_flash_config(struct flash_dev *fdev, void *load_flash_addr)
|
|||
if (off > 0)
|
||||
combine_size = off;
|
||||
|
||||
/*TODO: support hidden partition for mtd dev*/
|
||||
if (parse_mtd_partition){
|
||||
/*parse mtd partition*/
|
||||
if (strlen(combine_str) == 0)
|
||||
sprintf(combine_str, "%s%s@%dK(%s)", combine_str, node_size, combine_size, node_part);
|
||||
else
|
||||
sprintf(combine_str, "%s,%s@%dK(%s)", combine_str, node_size, combine_size, node_part);
|
||||
}else if (fdev->gptinfo.fastboot_flash_gpt){
|
||||
}else if (!fdev->parts_info[part_index].hidden && fdev->gptinfo.fastboot_flash_gpt){
|
||||
/*parse gpt partition*/
|
||||
if (strlen(node_offset) == 0)
|
||||
sprintf(combine_str, "%sname=%s,size=%s;", combine_str, node_part, node_size);
|
||||
else
|
||||
sprintf(combine_str, "%sname=%s,start=%s,size=%s;", combine_str, node_part, node_offset, node_size);
|
||||
}
|
||||
|
||||
/*save part offset and size to byte*/
|
||||
fdev->parts_info[part_index].part_offset = combine_size * 1024;
|
||||
fdev->parts_info[part_index].part_size = transfer_string_to_ul(node_size) * 1024;
|
||||
|
||||
/*save as the next part offset*/
|
||||
combine_size += transfer_string_to_ul(node_size);
|
||||
|
||||
/*after finish recovery, it would free the malloc paramenter at func recovery_show_result*/
|
||||
|
@ -742,7 +747,7 @@ int compare_blk_image_val(struct blk_desc *dev_desc, u64 compare_val, lbaint_t p
|
|||
}
|
||||
|
||||
for (int i = 0; i < div_times; i++) {
|
||||
pr_info("\ndownload and flash div %d\n", i);
|
||||
pr_info("download and flash div %d\n", i);
|
||||
download_bytes = byte_remain > RECOVERY_LOAD_IMG_SIZE ? RECOVERY_LOAD_IMG_SIZE : byte_remain;
|
||||
|
||||
blk_size = (download_bytes + (blksz - 1)) / blksz;
|
||||
|
@ -760,7 +765,7 @@ int compare_blk_image_val(struct blk_desc *dev_desc, u64 compare_val, lbaint_t p
|
|||
|
||||
pr_info("get calculate value:%llx, compare calculate:%llx\n", calculate, compare_val);
|
||||
time_start_flash = get_timer(time_start_flash);
|
||||
pr_info("\ncompare over, use time:%lu ms\n\n", time_start_flash);
|
||||
pr_info("compare over, use time:%lu ms\n", time_start_flash);
|
||||
return (calculate == compare_val) ? 0 : -1;
|
||||
}
|
||||
|
||||
|
@ -799,7 +804,7 @@ int compare_mtd_image_val(struct mtd_info *mtd, u64 compare_val, uint64_t image_
|
|||
|
||||
pr_info("get calculate value:%llx, compare calculate:%llx\n", calculate, compare_val);
|
||||
time_start_flash = get_timer(time_start_flash);
|
||||
pr_info("compare over, use time:%lu ms\n\n", time_start_flash);
|
||||
pr_info("compare over, use time:%lu ms\n", time_start_flash);
|
||||
return (calculate == compare_val) ? 0 : -1;
|
||||
}
|
||||
|
||||
|
@ -813,7 +818,7 @@ int compare_mtd_image_val(struct mtd_info *mtd, u64 compare_val, uint64_t image_
|
|||
* @param response
|
||||
* @param fdev
|
||||
*/
|
||||
void fastboot_oem_flash_bootinfo(const char *cmd, void *download_buffer,
|
||||
void fastboot_oem_flash_bootinfo(const char *cmd, void *download_buffer,
|
||||
u32 download_bytes, char *response, struct flash_dev *fdev)
|
||||
{
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC) || CONFIG_IS_ENABLED(FASTBOOT_MULTI_FLASH_OPTION_MMC)
|
||||
|
@ -885,6 +890,7 @@ const struct oem_config_info config_info[] = {
|
|||
{ "manufacturer", TLV_CODE_MANUF_NAME, 32, NULL },
|
||||
{ "sdk_version", TLV_CODE_SDK_VERSION, 3, NULL},
|
||||
{ "ddr_cs_num", TLV_CODE_DDR_CSNUM, 3, NULL},
|
||||
{ "ddr_datarate", TLV_CODE_DDR_DATARATE, 5, NULL},
|
||||
{ "ddr_type", TLV_CODE_DDR_TYPE, 32, NULL},
|
||||
{ "pmic_type", TLV_CODE_PMIC_TYPE, 3, NULL},
|
||||
{ "eeprom_i2c_index", TLV_CODE_EEPROM_I2C_INDEX, 3, NULL},
|
||||
|
|
|
@ -664,4 +664,15 @@ config SPL_SPACEMIT_K1X_EFUSE
|
|||
help
|
||||
This enable efuse read support in SPL, on Spacemit K1x SoCs.
|
||||
|
||||
config SPACEMIT_SHUTDOWN_CHARGE
|
||||
bool "Support charge battery in shutdown mode for k1x soc"
|
||||
depends on MISC
|
||||
help
|
||||
This enable the charge battery in system shutdown mode, on Spacemit K1x SoCs.
|
||||
|
||||
config SPL_SPACEMIT_SHUTDOWN_CHARGE
|
||||
bool "Support charge battery in shutdown mode for k1x soc in spl"
|
||||
depends on MISC
|
||||
help
|
||||
This enable the charge battery in system shutdown mode, on Spacemit K1x SoCs, in spl.
|
||||
endmenu
|
||||
|
|
|
@ -91,3 +91,4 @@ obj-$(CONFIG_ESM_PMIC) += esm_pmic.o
|
|||
obj-$(CONFIG_SL28CPLD) += sl28cpld.o
|
||||
obj-$(CONFIG_MCP4725) += mcp4725.o
|
||||
obj-$(CONFIG_$(SPL_)SPACEMIT_K1X_EFUSE) += spacemit_k1x_efuse.o
|
||||
obj-$(CONFIG_$(SPL_)SPACEMIT_SHUTDOWN_CHARGE) += spacemit_shutdown_charging.o
|
||||
|
|
519
drivers/misc/spacemit_shutdown_charging.c
Normal file
519
drivers/misc/spacemit_shutdown_charging.c
Normal file
|
@ -0,0 +1,519 @@
|
|||
#include <common.h>
|
||||
#include <fdt_support.h>
|
||||
#include <log.h>
|
||||
#include <irq.h>
|
||||
#include <dm.h>
|
||||
#include <dm/lists.h>
|
||||
#include <power-domain.h>
|
||||
#include <power/regulator.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <power/battery.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/io.h>
|
||||
#include <led.h>
|
||||
#include <asm-generic/gpio.h>
|
||||
#include <power/charger.h>
|
||||
#include <power/spacemit/spacemit_pmic.h>
|
||||
|
||||
#define SBI_HSM_SUSP_TOP_BIT 0x92000000
|
||||
|
||||
#define PLIC_PMIC_PRIO_REG 0xe0000100
|
||||
#define PLIC_PMIC_THRESH_REG 0xe0201000
|
||||
#define PLIC_PMIC_EN_REG 0xe0002088
|
||||
#define PLIC_PMIC_PENDING_REG 0xe0001008
|
||||
|
||||
#define RTC_CLK_SEL_EXTERNAL_OSC 0x8
|
||||
#define RTC_EN 0x4
|
||||
#define RTC_TICK_TYPE_1S 0x0
|
||||
#define RTC_TICK_TYPE_1MIN 0x1
|
||||
#define RTC_TICK_EN 0x40
|
||||
#define RTC_CRYSTAL_EN 0x1
|
||||
#define RTC_OUT_32K_EN 0x2
|
||||
#define RTC_TICK_IRQ 0x20
|
||||
|
||||
#define WAKEUP_SOURCE_POWER_KEY_EVENT 0x0
|
||||
#define WAKEUP_SOURCE_POWER_KEY_INTER 0x1
|
||||
#define WAKEUP_SOURCE_RTC_WAKEUP_CTRL 0x2
|
||||
#define WAKEUP_SOURCE_RTC_WAKEUP_EVENT 0x3
|
||||
#define WAKEUP_SOURCE_RTC_WAKEUP_IRQ 0x4
|
||||
#define SYS_SHUTDOWN 0x5
|
||||
#define SYS_REBOOT_FLAG 0x6
|
||||
|
||||
#define SYS_SHUTDOWN_BIT 0x4
|
||||
|
||||
#define BATTERY_RED_LIGHT_INDEX 0x0
|
||||
#define BATTERY_GREEN_LIGHT_INDEX 0x1
|
||||
#define DISABLE_BATTERY_LED 0x1
|
||||
|
||||
#define MAX_GPIO_COUNT 3
|
||||
#define MAX_REGULATOR_COUNT 7
|
||||
#define MAX_CHARGER_COUNT 2
|
||||
|
||||
#define CHARGER_LIGHT_FLASHES_CNT 10
|
||||
|
||||
#define VTHRESHOLD0 3000000
|
||||
#define VTHRESHOLD1 3500000
|
||||
#define VTHRESHOLD2 4350000
|
||||
|
||||
struct pt_regs {
|
||||
unsigned long long sepc;
|
||||
unsigned long long ra;
|
||||
unsigned long long sp;
|
||||
unsigned long long gp;
|
||||
unsigned long long tp;
|
||||
unsigned long long t0;
|
||||
unsigned long long t1;
|
||||
unsigned long long t2;
|
||||
unsigned long long s0;
|
||||
unsigned long long s1;
|
||||
unsigned long long a0;
|
||||
unsigned long long a1;
|
||||
unsigned long long a2;
|
||||
unsigned long long a3;
|
||||
unsigned long long a4;
|
||||
unsigned long long a5;
|
||||
unsigned long long a6;
|
||||
unsigned long long a7;
|
||||
unsigned long long s2;
|
||||
unsigned long long s3;
|
||||
unsigned long long s4;
|
||||
unsigned long long s5;
|
||||
unsigned long long s6;
|
||||
unsigned long long s7;
|
||||
unsigned long long s8;
|
||||
unsigned long long s9;
|
||||
unsigned long long s10;
|
||||
unsigned long long s11;
|
||||
unsigned long long t3;
|
||||
unsigned long long t4;
|
||||
unsigned long long t5;
|
||||
unsigned long long t6;
|
||||
/* Supervisor */
|
||||
unsigned long long sstatus;
|
||||
unsigned long long sbadaddr;
|
||||
unsigned long long scause;
|
||||
};
|
||||
|
||||
struct shutdown_charge {
|
||||
/* electricity meter */
|
||||
struct udevice *ele_meter;
|
||||
/* wakeup-source set
|
||||
* 0: wk_event
|
||||
* 1: wk_int
|
||||
* 2: rtc_tick_ctrl
|
||||
* 3: rtc_tick_event
|
||||
* 4: rtc_tick_irq
|
||||
* */
|
||||
struct udevice *wkup_set[MAX_REGULATOR_COUNT];
|
||||
const char **wkup_name;
|
||||
/* led charging indicator */
|
||||
struct gpio_desc led_indicators[MAX_GPIO_COUNT];
|
||||
int gpio_cnt;
|
||||
/* charget */
|
||||
struct udevice *charger[MAX_CHARGER_COUNT];
|
||||
const char **charger_name;
|
||||
int charger_cnt;
|
||||
/* power domain */
|
||||
struct power_domain pm_domain;
|
||||
};
|
||||
|
||||
struct suspend_context {
|
||||
/* Saved and restored by low-level functions */
|
||||
struct pt_regs regs;
|
||||
/* Saved and restored by high-level functions */
|
||||
unsigned long scratch;
|
||||
unsigned long tvec;
|
||||
unsigned long ie;
|
||||
} __aligned(64);
|
||||
|
||||
extern int __cpu_suspend_enter(void *context);
|
||||
extern int __cpu_resume_enter(void *context);
|
||||
|
||||
static struct suspend_context context = { 0 };
|
||||
|
||||
extern void flush_dcache_range(unsigned long start, unsigned long end);
|
||||
|
||||
static int sbi_suspend_finisher(unsigned long suspend_type,
|
||||
unsigned long resume_addr,
|
||||
unsigned long opaque)
|
||||
{
|
||||
struct sbiret ret;
|
||||
|
||||
flush_dcache_range((unsigned long)&context, (unsigned long)(&context) + sizeof(struct suspend_context));
|
||||
|
||||
ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_SUSPEND,
|
||||
suspend_type, resume_addr, opaque, 0, 0, 0);
|
||||
|
||||
return (ret.error) ? ret.error : 0;
|
||||
}
|
||||
|
||||
static void suspend_save_csrs(struct suspend_context *context)
|
||||
{
|
||||
context->scratch = csr_read(CSR_SSCRATCH);
|
||||
context->tvec = csr_read(CSR_STVEC);
|
||||
context->ie = csr_read(CSR_SIE);
|
||||
}
|
||||
|
||||
static void suspend_restore_csrs(struct suspend_context *context)
|
||||
{
|
||||
csr_write(CSR_SSCRATCH, context->scratch);
|
||||
csr_write(CSR_STVEC, context->tvec);
|
||||
csr_write(CSR_SIE, context->ie);
|
||||
}
|
||||
|
||||
int cpu_suspend(unsigned long arg,
|
||||
int (*finish)(unsigned long arg,
|
||||
unsigned long entry,
|
||||
unsigned long context))
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
/* Finisher should be non-NULL */
|
||||
if (!finish)
|
||||
return -EINVAL;
|
||||
|
||||
/* Save additional CSRs*/
|
||||
suspend_save_csrs(&context);
|
||||
|
||||
/* Save context on stack */
|
||||
if (__cpu_suspend_enter(&context)) {
|
||||
/* Call the finisher */
|
||||
rc = finish(arg, (unsigned long)__cpu_resume_enter,
|
||||
(ulong)&context);
|
||||
|
||||
/*
|
||||
* Should never reach here, unless the suspend finisher
|
||||
* fails. Successful cpu_suspend() should return from
|
||||
* __cpu_resume_entry()
|
||||
*/
|
||||
if (!rc)
|
||||
rc = -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* Restore additional CSRs */
|
||||
suspend_restore_csrs(&context);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int shutdown_charge_probe(struct udevice *dev)
|
||||
{
|
||||
int ret, status;
|
||||
unsigned int pwr_key_status = 0, reboot_flag;
|
||||
unsigned long long plugin_count = 0, plugout_count = 0, plugin_and_pwr_key_flag = 0;
|
||||
unsigned int uV, prio, thresh;
|
||||
struct shutdown_charge *priv = dev_get_priv(dev);
|
||||
|
||||
ret = uclass_get_device_by_phandle(UCLASS_BATTERY, dev,
|
||||
"electricity-meter", &priv->ele_meter);
|
||||
if (ret) {
|
||||
printf("%s:%d, get electrycity meter failed\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = power_domain_get(dev, &priv->pm_domain);
|
||||
if (ret) {
|
||||
printf("get pm domain failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = dev_read_string_list(dev, "wk-name", &priv->wkup_name);
|
||||
if (ret < 0) {
|
||||
printf("get wk source name failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (int i = 0; i < dev_read_string_count(dev, "wk-name"); ++i) {
|
||||
ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, priv->wkup_name[i],
|
||||
&priv->wkup_set[i]);
|
||||
if (ret) {
|
||||
printf("get wk source: %s faild\n", priv->wkup_name[i]);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
priv->charger_cnt = dev_read_string_count(dev, "charger-name");
|
||||
if (priv->charger_cnt < 0) {
|
||||
printf("get charger count failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = dev_read_string_list(dev, "charger-name", &priv->charger_name);
|
||||
if (ret < 0) {
|
||||
printf("get charger name failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (int i = 0; i < priv->charger_cnt; ++i) {
|
||||
ret = uclass_get_device_by_phandle(UCLASS_CHARGER, dev, priv->charger_name[i],
|
||||
&priv->charger[i]);
|
||||
if (ret) {
|
||||
printf("get charger: %s faild\n", priv->charger_name[i]);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
priv->gpio_cnt = gpio_request_list_by_name(dev, "charge-light", priv->led_indicators,
|
||||
MAX_GPIO_COUNT,
|
||||
GPIOD_IS_OUT);
|
||||
if (priv->gpio_cnt < 0) {
|
||||
printf("get charge-light failed\n");
|
||||
return priv->gpio_cnt;
|
||||
}
|
||||
|
||||
/* disable the battery led */
|
||||
for (int i = 0; i < priv->gpio_cnt; ++i) {
|
||||
dm_gpio_set_value(&priv->led_indicators[i], DISABLE_BATTERY_LED);
|
||||
}
|
||||
|
||||
pwr_key_status = regulator_get_value(priv->wkup_set[WAKEUP_SOURCE_POWER_KEY_EVENT]);
|
||||
|
||||
ret = battery_get_voltage(priv->ele_meter, &uV);
|
||||
if (ret) {
|
||||
printf("%s:%d, get battery volatge failed\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
for (int i = 0; i < priv->charger_cnt; ++i) {
|
||||
status |= charger_get_status(priv->charger[i]);
|
||||
}
|
||||
|
||||
/* reboot ??? */
|
||||
reboot_flag = regulator_get_value(priv->wkup_set[SYS_REBOOT_FLAG]);
|
||||
/* clear the reboot flag */
|
||||
reboot_flag &= ~(1 << SYS_REBOOT_FLAG_BIT);
|
||||
regulator_set_value_force(priv->wkup_set[SYS_REBOOT_FLAG], reboot_flag);
|
||||
|
||||
if ((reboot_flag & SYS_REBOOT_FLAG_BIT) && (uV >= VTHRESHOLD1)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* power-up system */
|
||||
if ((pwr_key_status & PWRKEY_RISING_EVENT) && !status && (uV >= VTHRESHOLD1)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* clear the power key pending */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_POWER_KEY_EVENT],
|
||||
PWRKEY_RISING_EVENT |
|
||||
PWRKEY_FAILING_EVENT |
|
||||
PWRKEY_LONG_PRESS_EVENT |
|
||||
PWRKEY_SHORT_PRESS_EVENT);
|
||||
|
||||
/* enable the rtc base function */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_CTRL],
|
||||
RTC_CLK_SEL_EXTERNAL_OSC |
|
||||
RTC_EN |
|
||||
RTC_OUT_32K_EN |
|
||||
RTC_CRYSTAL_EN);
|
||||
/* clear the rtc tick event */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_EVENT], 0xff);
|
||||
|
||||
/* set the priority */
|
||||
prio = readl((void __iomem *)PLIC_PMIC_PRIO_REG);
|
||||
writel(8, (void __iomem *)PLIC_PMIC_PRIO_REG);
|
||||
/* set the priority */
|
||||
thresh = readl((void __iomem *)PLIC_PMIC_THRESH_REG);
|
||||
writel(7, (void __iomem *)PLIC_PMIC_THRESH_REG);
|
||||
/* enable the IE: the interrupt number of pmic is 64 */
|
||||
writel(1, (void __iomem *)PLIC_PMIC_EN_REG);
|
||||
/* clear pending first */
|
||||
writel(0, (void __iomem *)PLIC_PMIC_PENDING_REG);
|
||||
|
||||
while (1) {
|
||||
ret = battery_get_voltage(priv->ele_meter, &uV);
|
||||
if (ret) {
|
||||
printf("%s:%d, get battery volatge failed\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
for (int i = 0; i < priv->charger_cnt; ++i) {
|
||||
status |= charger_get_status(priv->charger[i]);
|
||||
}
|
||||
|
||||
/* dp is not plugged */
|
||||
if (!status) {
|
||||
|
||||
++plugout_count;
|
||||
plugin_count = 0;
|
||||
plugin_and_pwr_key_flag = 0;
|
||||
|
||||
/* let the system power-down */
|
||||
if (plugout_count == CHARGER_LIGHT_FLASHES_CNT) {
|
||||
regulator_set_value_force(priv->wkup_set[SYS_SHUTDOWN], SYS_SHUTDOWN);
|
||||
}
|
||||
|
||||
if (uV >= VTHRESHOLD2) {
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_RED_LIGHT_INDEX], DISABLE_BATTERY_LED);
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_GREEN_LIGHT_INDEX], !DISABLE_BATTERY_LED);
|
||||
} else {
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_RED_LIGHT_INDEX], !!(plugout_count % 2));
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_GREEN_LIGHT_INDEX], DISABLE_BATTERY_LED);
|
||||
}
|
||||
|
||||
/* enable rtc tick modeule & 1s */
|
||||
ret = regulator_get_value(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_CTRL]);
|
||||
ret |= (RTC_TICK_EN | RTC_EN);
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_CTRL], ret);
|
||||
|
||||
/* enable rtc tick irq */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_IRQ], RTC_TICK_IRQ);
|
||||
|
||||
if (uV >= VTHRESHOLD0 && uV < VTHRESHOLD1) {
|
||||
/* the screen lights up to indicate low battery level */
|
||||
}
|
||||
|
||||
} else {
|
||||
/* the dp is plugged, we are charging now, so we can let the system enter low power mode */
|
||||
plugout_count = 0;
|
||||
++plugin_count;
|
||||
|
||||
/* enable rtc tick modeule & 1s */
|
||||
ret = regulator_get_value(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_CTRL]);
|
||||
ret |= (RTC_TICK_EN | RTC_EN);
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_CTRL], ret);
|
||||
|
||||
/* enable rtc tick irq */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_IRQ], RTC_TICK_IRQ);
|
||||
|
||||
if (uV < VTHRESHOLD2) {
|
||||
/* have the power-key event */
|
||||
if (pwr_key_status & PWRKEY_FAILING_EVENT || plugin_and_pwr_key_flag == 1) {
|
||||
|
||||
/* bring up the system */
|
||||
if (uV >= VTHRESHOLD1) {
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_RED_LIGHT_INDEX], !DISABLE_BATTERY_LED);
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_GREEN_LIGHT_INDEX], DISABLE_BATTERY_LED);
|
||||
plugin_and_pwr_key_flag = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (plugin_count < CHARGER_LIGHT_FLASHES_CNT) {
|
||||
|
||||
plugin_and_pwr_key_flag = 1;
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_RED_LIGHT_INDEX], !!(plugin_count % 2));
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_GREEN_LIGHT_INDEX], DISABLE_BATTERY_LED);
|
||||
|
||||
if (uV >= VTHRESHOLD0) {
|
||||
|
||||
/* screen displays chargin ircron and battery level */
|
||||
}
|
||||
|
||||
} else {
|
||||
plugin_and_pwr_key_flag = 0;
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_RED_LIGHT_INDEX], !DISABLE_BATTERY_LED);
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_GREEN_LIGHT_INDEX], DISABLE_BATTERY_LED);
|
||||
}
|
||||
} else {
|
||||
|
||||
plugin_and_pwr_key_flag = 0;
|
||||
|
||||
/* the led is alway on */
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_RED_LIGHT_INDEX], !DISABLE_BATTERY_LED);
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_GREEN_LIGHT_INDEX], DISABLE_BATTERY_LED);
|
||||
|
||||
if (uV >= VTHRESHOLD0) {
|
||||
if (plugin_count < CHARGER_LIGHT_FLASHES_CNT) {
|
||||
|
||||
/* screen displays chargin ircron and battery level */
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* the led is alway on */
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_RED_LIGHT_INDEX], DISABLE_BATTERY_LED);
|
||||
dm_gpio_set_value(&priv->led_indicators[BATTERY_GREEN_LIGHT_INDEX], !DISABLE_BATTERY_LED);
|
||||
|
||||
/* bringup the system */
|
||||
if (pwr_key_status & PWRKEY_FAILING_EVENT)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* enable the power-key */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_POWER_KEY_INTER], PWRKEY_FAILING_EVENT);
|
||||
|
||||
power_domain_on(&priv->pm_domain);
|
||||
|
||||
cpu_suspend(SBI_HSM_SUSP_TOP_BIT, sbi_suspend_finisher);
|
||||
|
||||
power_domain_off(&priv->pm_domain);
|
||||
|
||||
/* if we have the power-key event, so we reset the plugin counter */
|
||||
pwr_key_status = regulator_get_value(priv->wkup_set[WAKEUP_SOURCE_POWER_KEY_EVENT]);
|
||||
if (pwr_key_status & PWRKEY_FAILING_EVENT) {
|
||||
plugin_count = 0;
|
||||
plugin_and_pwr_key_flag = 0;
|
||||
plugout_count = 0;
|
||||
printf("%s:%d, pwr_key_status:%x\n", __func__, __LINE__, pwr_key_status);
|
||||
}
|
||||
|
||||
/* clean the event pending */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_POWER_KEY_EVENT],
|
||||
PWRKEY_RISING_EVENT |
|
||||
PWRKEY_FAILING_EVENT |
|
||||
PWRKEY_LONG_PRESS_EVENT |
|
||||
PWRKEY_SHORT_PRESS_EVENT);
|
||||
/* disable the irq of power-key */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_POWER_KEY_INTER], 0);
|
||||
|
||||
/* disable rtc tick first */
|
||||
ret = regulator_get_value(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_CTRL]);
|
||||
ret &= ~(RTC_TICK_EN | RTC_EN);
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_CTRL], ret);
|
||||
|
||||
/* clear the rtc tick event */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_EVENT], 0xff);
|
||||
|
||||
/* disable rtc tick irq */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_IRQ], 0);
|
||||
|
||||
/* clear pending */
|
||||
writel(0, (void __iomem *)PLIC_PMIC_PENDING_REG);
|
||||
}
|
||||
|
||||
out:
|
||||
/* disable PLIC */
|
||||
writel(0, (void __iomem *)PLIC_PMIC_PENDING_REG);
|
||||
writel(thresh, (void __iomem *)PLIC_PMIC_THRESH_REG);
|
||||
writel(prio, (void __iomem *)PLIC_PMIC_PRIO_REG);
|
||||
writel(0, (void __iomem *)PLIC_PMIC_EN_REG);
|
||||
|
||||
/* disable the event of power-key & clean the event pending */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_POWER_KEY_INTER], 0);
|
||||
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_POWER_KEY_EVENT],
|
||||
PWRKEY_RISING_EVENT |
|
||||
PWRKEY_FAILING_EVENT |
|
||||
PWRKEY_LONG_PRESS_EVENT |
|
||||
PWRKEY_SHORT_PRESS_EVENT);
|
||||
|
||||
/* disable rtc tick first */
|
||||
ret = regulator_get_value(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_CTRL]);
|
||||
ret &= ~(RTC_TICK_EN | RTC_EN);
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_CTRL], ret);
|
||||
/* clear the rtc tick event */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_EVENT], 0xff);
|
||||
/* disable rtc module */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_CTRL], 0);
|
||||
/* disable rtc tick irq */
|
||||
regulator_set_value_force(priv->wkup_set[WAKEUP_SOURCE_RTC_WAKEUP_IRQ], 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id shutdown_charging_ids[] = {
|
||||
{ .compatible = "k1,shutdown-charging" },
|
||||
{}
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(shutdown_charge) = {
|
||||
.name = "shutdown-charge",
|
||||
.of_match = shutdown_charging_ids,
|
||||
.id = UCLASS_MISC,
|
||||
.probe = shutdown_charge_probe,
|
||||
.priv_auto = sizeof(struct shutdown_charge),
|
||||
};
|
|
@ -14,6 +14,7 @@
|
|||
#include <asm/global_data.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include "sf_internal.h"
|
||||
#include <blk.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -104,9 +105,44 @@ static int spi_flash_post_bind(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPINOR_BLOCK_SUPPORT
|
||||
int spacemit_spinor_post_probe(struct udevice *dev)
|
||||
{
|
||||
struct blk_desc *bdesc;
|
||||
struct udevice *bdev;
|
||||
int ret;
|
||||
struct udevice *parent_dev = dev->parent;
|
||||
|
||||
// Create the block device interface for the SPI NOR device with the same parent as dev
|
||||
ret = blk_create_devicef(parent_dev, "nor_blk", "blk", IF_TYPE_NOR,
|
||||
dev_seq(dev), SPI_NOR_BLOCK_SIZE, 0, &bdev);
|
||||
if (ret) {
|
||||
pr_err("Cannot create block device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Obtain the block device descriptor
|
||||
bdesc = dev_get_uclass_plat(bdev);
|
||||
if (!bdesc) {
|
||||
pr_err("Failed to get block device descriptor\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
// Initialize block device descriptor
|
||||
bdesc->if_type = IF_TYPE_NOR;
|
||||
bdesc->removable = 0;
|
||||
|
||||
dev_set_priv(bdev, dev);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SPINOR_BLOCK_SUPPORT */
|
||||
|
||||
UCLASS_DRIVER(spi_flash) = {
|
||||
.id = UCLASS_SPI_FLASH,
|
||||
.name = "spi_flash",
|
||||
.post_bind = spi_flash_post_bind,
|
||||
#ifdef CONFIG_SPINOR_BLOCK_SUPPORT
|
||||
.post_probe = spacemit_spinor_post_probe,
|
||||
#endif /* CONFIG_SPINOR_BLOCK_SUPPORT */
|
||||
.per_device_auto = sizeof(struct spi_nor),
|
||||
};
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
#include <malloc.h>
|
||||
#include <spi.h>
|
||||
#include <spi_flash.h>
|
||||
#include <blk.h>
|
||||
#include <dm/device-internal.h>
|
||||
|
||||
#include "sf_internal.h"
|
||||
|
||||
|
@ -165,38 +163,6 @@ static int spi_flash_std_remove(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPINOR_BLOCK_SUPPORT
|
||||
int spacemit_spinor_bind(struct udevice *dev)
|
||||
{
|
||||
struct blk_desc *bdesc;
|
||||
struct udevice *bdev;
|
||||
int ret;
|
||||
struct udevice *parent_dev = dev->parent;
|
||||
|
||||
// Create the block device interface for the SPI NOR device with the same parent as dev
|
||||
ret = blk_create_devicef(parent_dev, "nor_blk", "blk", IF_TYPE_NOR,
|
||||
dev_seq(dev), SPI_NOR_BLOCK_SIZE, 0, &bdev);
|
||||
if (ret) {
|
||||
pr_err("Cannot create block device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Obtain the block device descriptor
|
||||
bdesc = dev_get_uclass_plat(bdev);
|
||||
if (!bdesc) {
|
||||
pr_err("Failed to get block device descriptor\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
// Initialize block device descriptor
|
||||
bdesc->if_type = IF_TYPE_NOR;
|
||||
bdesc->removable = 0;
|
||||
|
||||
dev_set_priv(bdev, dev);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SPINOR_BLOCK_SUPPORT */
|
||||
|
||||
static const struct dm_spi_flash_ops spi_flash_std_ops = {
|
||||
.read = spi_flash_std_read,
|
||||
.write = spi_flash_std_write,
|
||||
|
@ -217,9 +183,6 @@ U_BOOT_DRIVER(jedec_spi_nor) = {
|
|||
.remove = spi_flash_std_remove,
|
||||
.priv_auto = sizeof(struct spi_nor),
|
||||
.ops = &spi_flash_std_ops,
|
||||
#ifdef CONFIG_SPINOR_BLOCK_SUPPORT
|
||||
.bind = spacemit_spinor_bind,
|
||||
#endif /* CONFIG_SPINOR_BLOCK_SUPPORT */
|
||||
.flags = DM_FLAG_OS_PREPARE,
|
||||
};
|
||||
|
||||
|
|
|
@ -1125,7 +1125,7 @@ static int emac_probe(struct udevice *dev)
|
|||
|
||||
ret = emac_probe_resources_core(dev);
|
||||
if (ret < 0) {
|
||||
pr_err("emac_probe_resources_core() failed: %d", ret);
|
||||
pr_err("emac_probe_resources_core() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1145,7 +1145,7 @@ static int emac_probe(struct udevice *dev)
|
|||
|
||||
priv->mii = mdio_alloc();
|
||||
if (!priv->mii) {
|
||||
pr_err("mdio_alloc() failed");
|
||||
pr_err("mdio_alloc() failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_remove_resources_core;
|
||||
}
|
||||
|
@ -1156,7 +1156,7 @@ static int emac_probe(struct udevice *dev)
|
|||
|
||||
ret = mdio_register(priv->mii);
|
||||
if (ret < 0) {
|
||||
pr_err("mdio_register() failed: %d", ret);
|
||||
pr_err("mdio_register() failed: %d\n", ret);
|
||||
goto err_free_mdio;
|
||||
}
|
||||
|
||||
|
@ -1167,14 +1167,14 @@ static int emac_probe(struct udevice *dev)
|
|||
#ifdef CONFIG_GPIO /* gpio driver is not ready for fpga platform! */
|
||||
ret = gpio_request(priv->phy_reset_gpio, "phy-reset-pin");
|
||||
if (ret < 0) {
|
||||
pr_err("gpio_request_by_name(phy reset) failed: %d", ret);
|
||||
pr_err("gpio_request_by_name(phy reset) failed: %d\n", ret);
|
||||
goto err_free_mdio;
|
||||
}
|
||||
|
||||
if (priv->ldo_gpio >= 0) {
|
||||
ret = gpio_request(priv->ldo_gpio, "ldo-pwr-pin");
|
||||
if (ret < 0) {
|
||||
pr_err("gpio_request_by_name(ldo pwr) failed: %d", ret);
|
||||
pr_err("gpio_request_by_name(ldo pwr) failed: %d\n", ret);
|
||||
goto err_free_gpio;
|
||||
}
|
||||
gpio_direction_output(priv->ldo_gpio, 1);
|
||||
|
|
|
@ -894,6 +894,14 @@ int pci_bind_bus_devices(struct udevice *bus)
|
|||
PCI_SIZE_16);
|
||||
pci_bus_read_config(bus, bdf, PCI_CLASS_REVISION, &class,
|
||||
PCI_SIZE_32);
|
||||
|
||||
#if defined(CONFIG_TARGET_SPACEMIT_K1X)
|
||||
if(vendor == 0x144d && device == 0xa808) {
|
||||
debug("delay 2s for device 144d:a808\n");
|
||||
mdelay(2000);
|
||||
}
|
||||
#endif
|
||||
|
||||
class >>= 8;
|
||||
|
||||
/* Find this device in the device tree */
|
||||
|
|
|
@ -29,6 +29,8 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
|
||||
#define PCIE_VENDORID_MASK GENMASK(15, 0)
|
||||
#define PCIE_DEVICEID_SHIFT 16
|
||||
#define K1X_PCIE_VENDOR_ID 0x201F
|
||||
#define k1X_PCIE_DEVICE_ID 0x0001
|
||||
|
||||
#define PCIE_LINK_CAPABILITY 0x7c
|
||||
#define PCIE_LINK_CTL_2 0xa0
|
||||
|
@ -629,6 +631,16 @@ static int init_phy(struct pcie_dw_k1x *k1x)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pcie_dw_init_id(struct pcie_dw_k1x *pci)
|
||||
{
|
||||
dw_pcie_dbi_write_enable(&pci->dw, true);
|
||||
writew(K1X_PCIE_VENDOR_ID, pci->dw.dbi_base + PCI_VENDOR_ID);
|
||||
writew(k1X_PCIE_DEVICE_ID, pci->dw.dbi_base + PCI_DEVICE_ID);
|
||||
dw_pcie_dbi_write_enable(&pci->dw, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pcie_dw_k1x_probe() - Probe the PCIe bus for active link
|
||||
*
|
||||
|
@ -648,8 +660,6 @@ static int pcie_dw_k1x_probe(struct udevice *dev)
|
|||
int ret;
|
||||
u32 reg;
|
||||
|
||||
printf("%s, %d\n", __FUNCTION__, __LINE__);
|
||||
|
||||
/* enable pcie clk */
|
||||
clk_enable(&pci->clock);
|
||||
reset_deassert(&pci->reset);
|
||||
|
@ -667,7 +677,7 @@ static int pcie_dw_k1x_probe(struct udevice *dev)
|
|||
|
||||
ret = generic_phy_get_by_name(dev, "pcie-phy0", &phy0);
|
||||
if (ret) {
|
||||
dev_err(dev, "Unable to get phy0");
|
||||
dev_err(dev, "Unable to get phy0\n");
|
||||
} else {
|
||||
generic_phy_reset(&phy0);
|
||||
generic_phy_init(&phy0);
|
||||
|
@ -676,7 +686,7 @@ static int pcie_dw_k1x_probe(struct udevice *dev)
|
|||
|
||||
ret = generic_phy_get_by_name(dev, "pcie-phy1", &phy1);
|
||||
if (ret) {
|
||||
dev_err(dev, "Unable to get phy1");
|
||||
dev_err(dev, "Unable to get phy1\n");
|
||||
} else {
|
||||
generic_phy_reset(&phy1);
|
||||
generic_phy_init(&phy1);
|
||||
|
@ -690,6 +700,7 @@ static int pcie_dw_k1x_probe(struct udevice *dev)
|
|||
|
||||
k1x_pcie_host_init(pci);
|
||||
pcie_dw_setup_host(&pci->dw);
|
||||
pcie_dw_init_id(pci);
|
||||
|
||||
if (!pcie_dw_k1x_pcie_link_up(pci, LINK_SPEED_GEN_2)) {
|
||||
printf("PCIE-%d: Link down\n", dev_seq(dev));
|
||||
|
|
|
@ -51,6 +51,10 @@ source "drivers/power/pmic/Kconfig"
|
|||
|
||||
source "drivers/power/regulator/Kconfig"
|
||||
|
||||
source "drivers/power/battery/Kconfig"
|
||||
|
||||
source "drivers/power/charger/Kconfig"
|
||||
|
||||
choice
|
||||
prompt "Select Sunxi PMIC Variant"
|
||||
depends on ARCH_SUNXI
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
obj-$(CONFIG_$(SPL_TPL_)ACPI_PMC) += acpi_pmc/
|
||||
obj-y += battery/
|
||||
obj-y += charger/
|
||||
obj-$(CONFIG_$(SPL_TPL_)POWER_DOMAIN) += domain/
|
||||
obj-y += fuel_gauge/
|
||||
obj-y += mfd/
|
||||
|
|
11
drivers/power/battery/Kconfig
Normal file
11
drivers/power/battery/Kconfig
Normal file
|
@ -0,0 +1,11 @@
|
|||
config DM_BATTERY
|
||||
bool "Enable Driver Model for BATTERY drivers (UCLASS_BATTERY)"
|
||||
depends on DM
|
||||
---help---
|
||||
This config enables driver model battery support.
|
||||
|
||||
config CW2015_BATTERY
|
||||
bool "Enable Driver Model for SPACEMIT CW2015 battery"
|
||||
depends on DM_BATTERY
|
||||
help
|
||||
This config enables driver model for cw2015 battery
|
|
@ -5,3 +5,5 @@
|
|||
|
||||
obj-$(CONFIG_POWER_BATTERY_TRATS) += bat_trats.o
|
||||
obj-$(CONFIG_POWER_BATTERY_TRATS2) += bat_trats2.o
|
||||
obj-$(CONFIG_DM_BATTERY) += battery-uclass.o
|
||||
obj-$(CONFIG_$(SPL_)CW2015_BATTERY) += spacemit_cw2015.o
|
||||
|
|
53
drivers/power/battery/battery-uclass.c
Normal file
53
drivers/power/battery/battery-uclass.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2018 Simon Shields <simon@lineageos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <power/battery.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int battery_get(const char *devname, struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_name(UCLASS_BATTERY, devname, devp);
|
||||
}
|
||||
|
||||
int battery_get_voltage(struct udevice *dev, unsigned int *uV)
|
||||
{
|
||||
const struct dm_battery_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->get_voltage)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_voltage(dev, uV);
|
||||
}
|
||||
|
||||
int battery_get_status(struct udevice *dev)
|
||||
{
|
||||
const struct dm_battery_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->get_status)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_status(dev);
|
||||
}
|
||||
|
||||
int battery_get_soc(struct udevice *dev)
|
||||
{
|
||||
const struct dm_battery_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->get_soc)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_soc(dev);
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(battery) = {
|
||||
.id = UCLASS_BATTERY,
|
||||
.name = "battery",
|
||||
};
|
324
drivers/power/battery/spacemit_cw2015.c
Normal file
324
drivers/power/battery/spacemit_cw2015.c
Normal file
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Spacemit
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <power/battery.h>
|
||||
#include <power/pmic.h>
|
||||
#include <linux/delay.h>
|
||||
#include <dm/lists.h>
|
||||
#include <log.h>
|
||||
|
||||
#define REG_VERSION 0x0
|
||||
#define REG_VCELL 0x2
|
||||
#define REG_SOC 0x4
|
||||
#define REG_RRT_ALERT 0x6
|
||||
#define REG_CONFIG 0x8
|
||||
#define REG_MODE 0xA
|
||||
#define REG_VTEMPL 0xC
|
||||
#define REG_VTEMPH 0xD
|
||||
#define REG_BATINFO 0x10
|
||||
|
||||
#define MODE_SLEEP_MASK (0x3<<6)
|
||||
#define MODE_SLEEP (0x3<<6)
|
||||
#define MODE_NORMAL (0x0<<6)
|
||||
#define MODE_QUICK_START (0x3<<4)
|
||||
#define MODE_RESTART (0xf<<0)
|
||||
|
||||
#define CONFIG_UPDATE_FLG (0x1<<1)
|
||||
#define ATHD (0x0<<3) // ATHD = 0%
|
||||
#define MASK_ATHD GENMASK(7, 3)
|
||||
#define MASK_SOC GENMASK(12, 0)
|
||||
|
||||
#define BATTERY_CAPACITY_ERROR 40*1000
|
||||
#define BATTERY_CHARGING_ZERO 1800*1000
|
||||
|
||||
#define UI_FULL 100
|
||||
#define DECIMAL_MAX 80
|
||||
#define DECIMAL_MIN 20
|
||||
|
||||
#define CHARGING_ON 1
|
||||
#define NO_CHARGING 0
|
||||
|
||||
#define SIZE_BATINFO 64
|
||||
static unsigned char config_info[SIZE_BATINFO] = {};
|
||||
|
||||
/*struct cw_battery {
|
||||
struct udevice *dev;
|
||||
int charger_mode;
|
||||
int capacity;
|
||||
int voltage;
|
||||
int status;
|
||||
int change;
|
||||
int raw_soc;
|
||||
int time_to_empty;
|
||||
};*/
|
||||
|
||||
static int cw2015_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_read(dev, reg, buff, len);
|
||||
if(ret) {
|
||||
debug("read error from device: %p register: %#x!\n", dev, reg);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cw2015_write(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_write(dev, reg, buff, len);
|
||||
if(ret) {
|
||||
debug("write error to device: %p register: %#x!\n", dev, reg);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cw_get_voltage(struct udevice *dev, unsigned int *uV)
|
||||
{
|
||||
int ret;
|
||||
unsigned char reg_val[2];
|
||||
u16 value16, value16_1, value16_2, value16_3;
|
||||
|
||||
ret = cw2015_read(dev, REG_VCELL, reg_val, 2);
|
||||
if(ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
value16 = (reg_val[0] << 8) + reg_val[1];
|
||||
|
||||
ret = cw2015_read(dev, REG_VCELL, reg_val, 2);
|
||||
if(ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
value16_1 = (reg_val[0] << 8) + reg_val[1];
|
||||
|
||||
ret = cw2015_read(dev, REG_VCELL, reg_val, 2);
|
||||
if(ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
value16_2 = (reg_val[0] << 8) + reg_val[1];
|
||||
|
||||
if(value16 > value16_1) {
|
||||
value16_3 = value16;
|
||||
value16 = value16_1;
|
||||
value16_1 = value16_3;
|
||||
}
|
||||
|
||||
if(value16_1 > value16_2) {
|
||||
value16_3 =value16_1;
|
||||
value16_1 =value16_2;
|
||||
value16_2 =value16_3;
|
||||
}
|
||||
|
||||
if(value16 >value16_1) {
|
||||
value16_3 =value16;
|
||||
value16 =value16_1;
|
||||
value16_1 =value16_3;
|
||||
}
|
||||
|
||||
*uV = value16_1 * 625 / 2048 * 1000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cw_update_config_info(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
unsigned char reg_val;
|
||||
int i;
|
||||
unsigned char reset_val;
|
||||
|
||||
// make sure no in sleep mode
|
||||
ret = cw2015_read(dev, REG_MODE, ®_val, 1);
|
||||
if(ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
reset_val = reg_val;
|
||||
if((reg_val & MODE_SLEEP_MASK) == MODE_SLEEP) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// update new battery info
|
||||
for (i = 0; i < SIZE_BATINFO; i++) {
|
||||
ret = cw2015_write(dev, REG_BATINFO + i, &config_info[i], 1);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
reg_val = 0x00;
|
||||
reg_val |= CONFIG_UPDATE_FLG; // set UPDATE_FLAG
|
||||
reg_val &= 0x07; // clear ATHD
|
||||
reg_val |= ATHD; // set ATHD
|
||||
ret = cw2015_write(dev, REG_CONFIG, ®_val, 1);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
|
||||
mdelay(50);
|
||||
// reset
|
||||
reg_val = 0x00;
|
||||
reset_val &= ~(MODE_RESTART);
|
||||
reg_val = reset_val | MODE_RESTART;
|
||||
ret = cw2015_write(dev, REG_MODE, ®_val, 1);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
|
||||
mdelay(10);
|
||||
|
||||
ret = cw2015_write(dev, REG_MODE, &reset_val, 1);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
|
||||
mdelay(100);
|
||||
printf("cw2015 update config success!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cw_init(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
unsigned char reg_val = MODE_NORMAL;
|
||||
|
||||
ret = cw2015_write(dev, REG_MODE, ®_val, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = cw2015_read(dev, REG_CONFIG, ®_val, 1);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
if (!(reg_val & CONFIG_UPDATE_FLG)) {
|
||||
debug("update config flg is true, need update config\n");
|
||||
ret = cw_update_config_info(dev);
|
||||
if (ret < 0) {
|
||||
printf("%s : update config fail\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
for(i = 0; i < SIZE_BATINFO; i++) {
|
||||
ret = cw2015_read(dev, (REG_BATINFO + i), ®_val, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
debug("%X\n", reg_val);
|
||||
if (config_info[i] != reg_val)
|
||||
break;
|
||||
}
|
||||
if (i != SIZE_BATINFO) {
|
||||
reg_val = MODE_SLEEP;
|
||||
ret = cw2015_write(dev, REG_MODE, ®_val, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mdelay(30);
|
||||
reg_val = MODE_NORMAL;
|
||||
ret = cw2015_write(dev, REG_MODE, ®_val, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
printf("config didn't match, need update config\n");
|
||||
ret = cw_update_config_info(dev);
|
||||
if (ret < 0){
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mdelay(10);
|
||||
for (i = 0; i < 30; i++) {
|
||||
ret = cw2015_read(dev, REG_SOC, ®_val, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (reg_val <= 0x64)
|
||||
break;
|
||||
mdelay(120);
|
||||
}
|
||||
|
||||
if (i >= 30 ){
|
||||
reg_val = MODE_SLEEP;
|
||||
ret = cw2015_write(dev, REG_MODE, ®_val, 1);
|
||||
printf("cw2015 input unvalid power error, cw2015 join sleep mode\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("cw2015 init success!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cw_get_capacity(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
unsigned char reg_val[2];
|
||||
|
||||
ret = cw2015_read(dev, REG_SOC, reg_val, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return reg_val[0];
|
||||
}
|
||||
|
||||
static int cw_get_status(struct udevice *dev)
|
||||
{
|
||||
int voltage;
|
||||
int ret = cw_get_voltage(dev, &voltage);
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
if(voltage <= 3400000)
|
||||
ret = BAT_STATE_NEED_CHARGING;
|
||||
else if(voltage > 3400000 && voltage <= 4350000)
|
||||
ret = BAT_STATE_NORMAL;
|
||||
else
|
||||
ret = BAT_STATE_NOT_PRESENT;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct dm_battery_ops cw2015_battery_ops = {
|
||||
.get_voltage = cw_get_voltage,
|
||||
.get_status = cw_get_status,
|
||||
.get_soc = cw_get_capacity,
|
||||
};
|
||||
|
||||
static int cw2015_probe(struct udevice *dev)
|
||||
{
|
||||
int ret, i;
|
||||
int loop = 0;
|
||||
const char *data;
|
||||
|
||||
data = dev_read_u8_array_ptr(dev, "cellwise,battery-profile", SIZE_BATINFO);
|
||||
if (!data)
|
||||
return -1;
|
||||
for(i = 0; i < SIZE_BATINFO; i++)
|
||||
config_info[i] = *(data + i);
|
||||
ret = cw_init(dev);
|
||||
while ((loop++ < 3) && (ret != 0)) {
|
||||
mdelay(200);
|
||||
ret = cw_init(dev);
|
||||
}
|
||||
if (ret) {
|
||||
printf("%s : cw2015 init fail!\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id cw2015_ids[] = {
|
||||
{ .compatible = "spacemit,cw2015", .data = 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(cw_battery) = {
|
||||
.name = "cw-bat",
|
||||
.id = UCLASS_BATTERY,
|
||||
.of_match = cw2015_ids,
|
||||
.ops = &cw2015_battery_ops,
|
||||
.probe = cw2015_probe,
|
||||
//.priv_auto = sizeof(struct cw_battery),
|
||||
};
|
11
drivers/power/charger/Kconfig
Normal file
11
drivers/power/charger/Kconfig
Normal file
|
@ -0,0 +1,11 @@
|
|||
config DM_CHARGER
|
||||
bool "Enable Driver Model for charger drivers (UCLASS_CHARGER)"
|
||||
depends on DM
|
||||
---help---
|
||||
This config enables driver model charger support.
|
||||
|
||||
config SGM41515_CHARGER
|
||||
bool "Enable Driver Model for SPACEMIT sgm41515 charger"
|
||||
depends on DM_CHARGER
|
||||
help
|
||||
This config enables driver model for sgm41515 charger.
|
2
drivers/power/charger/Makefile
Normal file
2
drivers/power/charger/Makefile
Normal file
|
@ -0,0 +1,2 @@
|
|||
obj-$(CONFIG_DM_CHARGER) += charger-uclass.o
|
||||
obj-$(CONFIG_$(SPL_)SGM41515_CHARGER) += sgm41515.o
|
54
drivers/power/charger/charger-uclass.c
Normal file
54
drivers/power/charger/charger-uclass.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2018 Simon Shields <simon@lineageos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <power/charger.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int charger_get(const char *devname, struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_name(UCLASS_CHARGER, devname, devp);
|
||||
}
|
||||
|
||||
int charger_set_current(struct udevice *dev, unsigned int microamps)
|
||||
{
|
||||
const struct dm_charger_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->set_current)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->set_current(dev, microamps);
|
||||
}
|
||||
|
||||
int charger_get_current(struct udevice *dev)
|
||||
{
|
||||
const struct dm_charger_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->get_current)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_current(dev);
|
||||
}
|
||||
|
||||
int charger_get_status(struct udevice *dev)
|
||||
{
|
||||
const struct dm_charger_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->get_status)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_status(dev);
|
||||
}
|
||||
|
||||
|
||||
UCLASS_DRIVER(charger) = {
|
||||
.id = UCLASS_CHARGER,
|
||||
.name = "charger",
|
||||
};
|
395
drivers/power/charger/sgm41515.c
Normal file
395
drivers/power/charger/sgm41515.c
Normal file
|
@ -0,0 +1,395 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Spacemit
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <power/charger.h>
|
||||
#include <power/pmic.h>
|
||||
#include <linux/delay.h>
|
||||
#include <dm/lists.h>
|
||||
#include <log.h>
|
||||
#include <asm-generic/gpio.h>
|
||||
|
||||
#define SGM41515_CHRG_CTRL_0 0x00
|
||||
#define SGM41515_CHRG_CTRL_1 0x01
|
||||
#define SGM41515_CHRG_CTRL_2 0x02
|
||||
#define SGM41515_CHRG_CTRL_3 0x03
|
||||
#define SGM41515_CHRG_CTRL_4 0x04
|
||||
#define SGM41515_CHRG_CTRL_5 0x05
|
||||
#define SGM41515_CHRG_CTRL_6 0x06
|
||||
#define SGM41515_CHRG_CTRL_7 0x07
|
||||
#define SGM41515_CHRG_STAT 0x08
|
||||
#define SGM41515_CHRG_FAULT 0x09
|
||||
#define SGM41515_CHRG_CTRL_a 0x0a
|
||||
#define SGM41515_CHRG_CTRL_b 0x0b
|
||||
#define SGM41515_CHRG_CTRL_c 0x0c
|
||||
#define SGM41515_CHRG_CTRL_d 0x0d
|
||||
#define SGM41515_INPUT_DET 0x0e
|
||||
#define SGM41515_CHRG_CTRL_f 0x0f
|
||||
|
||||
#define SGM41515_CHRG_EN BIT(4)
|
||||
#define SGM41515_HIZ_EN BIT(7)
|
||||
#define SGM41515_TERM_EN BIT(7)
|
||||
#define SGM41515_VAC_OVP_MASK GENMASK(7, 6)
|
||||
#define SGM41515_DPDM_ONGOING BIT(7)
|
||||
#define SGM41515_VBUS_GOOD BIT(7)
|
||||
|
||||
#define SGM41515_VREG_V_MASK GENMASK(7, 3)
|
||||
#define SGM41515_VREG_V_MAX_uV 4624000
|
||||
#define SGM41515_VREG_V_MIN_uV 3856000
|
||||
#define SGM41515_VREG_V_DEF_uV 4208000
|
||||
#define SGM41515_VREG_V_STEP_uV 32000
|
||||
|
||||
#define SGM41515_IINDPM_I_MASK GENMASK(4, 0)
|
||||
#define SGM41515_IINDPM_I_MIN_uA 100000
|
||||
#define SGM41515_IINDPM_I_MAX_uA 3200000
|
||||
#define SGM41515_IINDPM_STEP_uA 100000
|
||||
#define SGM41515_IINDPM_DEF_uA 2400000
|
||||
|
||||
#define SGM41515_ICHRG_CUR_MASK GENMASK(5, 0)
|
||||
#define SGM41515_PG_STAT BIT(2)
|
||||
|
||||
/* WDT TIMER SET */
|
||||
#define SGM41515_WDT_TIMER_MASK GENMASK(5, 4)
|
||||
#define SGM41515_WDT_TIMER_DISABLE 0
|
||||
#define SGM41515_WDT_TIMER_40S BIT(4)
|
||||
#define SGM41515_WDT_TIMER_80S BIT(5)
|
||||
#define SGM41515_WDT_TIMER_160S (BIT(4)| BIT(5))
|
||||
|
||||
#define SGM41515_BOOSTV (BIT(4)| BIT(5))
|
||||
#define SGM41515_BOOST_LIM BIT(7)
|
||||
#define SGM41515_OTG_EN BIT(5)
|
||||
|
||||
#define SGM41515_PRECHRG_CUR_MASK GENMASK(7, 4)
|
||||
#define SGM41515_TERMCHRG_CUR_MASK GENMASK(3, 0)
|
||||
#define SGM41515_PRECHRG_I_DEF_uA 120000
|
||||
#define SGM41515_TERMCHRG_I_DEF_uA 120000
|
||||
static const unsigned int IPRECHG_CURRENT_STABLE[] = {
|
||||
5000, 10000, 15000, 20000, 30000, 40000, 50000, 60000,
|
||||
80000, 100000, 120000, 140000, 160000, 180000, 200000, 240000
|
||||
};
|
||||
|
||||
static const unsigned int ITERM_CURRENT_STABLE[] = {
|
||||
5000, 10000, 15000, 20000, 30000, 40000, 50000, 60000,
|
||||
80000, 100000, 120000, 140000, 160000, 180000, 200000, 240000
|
||||
};
|
||||
|
||||
static const unsigned int BOOST_VOLT_LIMIT[] = {
|
||||
4850000, 5000000, 5150000, 5300000
|
||||
};
|
||||
|
||||
struct sgm41515_charger {
|
||||
struct gpio_desc nqon;
|
||||
struct gpio_desc charge_en;
|
||||
u32 ichg; /* charge current */
|
||||
u32 ilim; /* input current */
|
||||
u32 vreg; /* regulation voltage */
|
||||
u32 iterm; /* termination current */
|
||||
u32 iprechg; /* precharge current */
|
||||
u32 vlim; /* minimum system voltage limit */
|
||||
u32 max_ichg;
|
||||
u32 max_vreg;
|
||||
|
||||
};
|
||||
|
||||
static int sgm41515_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_read(dev, reg, buff, len);
|
||||
if(ret) {
|
||||
debug("read error from device: %p register: %#x!\n", dev, reg);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sgm41515_write(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_write(dev, reg, buff, len);
|
||||
if(ret) {
|
||||
debug("write error to device: %p register: %#x!\n", dev, reg);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sgm41515_set_input_curr_lim(struct udevice *dev, int iindpm)
|
||||
{
|
||||
int ret;
|
||||
unsigned char reg, reg_val;
|
||||
|
||||
if (iindpm < SGM41515_IINDPM_I_MIN_uA ||
|
||||
iindpm > SGM41515_IINDPM_I_MAX_uA)
|
||||
return -EINVAL;
|
||||
reg_val = (iindpm-SGM41515_IINDPM_I_MIN_uA) / SGM41515_IINDPM_STEP_uA;
|
||||
|
||||
ret = sgm41515_read(dev, SGM41515_CHRG_CTRL_0, ®, 1);
|
||||
reg &= ~SGM41515_IINDPM_I_MASK;
|
||||
reg_val |= reg;
|
||||
ret = sgm41515_write(dev, SGM41515_CHRG_CTRL_0, ®_val, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sgm41515_set_chrg_curr(struct udevice *dev, int uA)
|
||||
{
|
||||
int ret;
|
||||
unsigned char reg, reg_val;
|
||||
|
||||
if (uA <= 40000)
|
||||
reg_val = uA / 5000;
|
||||
else if (uA <= 110000)
|
||||
reg_val = 0x08 + (uA -40000) / 10000;
|
||||
else if (uA <= 270000)
|
||||
reg_val = 0x0F + (uA -110000) / 20000;
|
||||
else if (uA <= 540000)
|
||||
reg_val = 0x17 + (uA -270000) / 30000;
|
||||
else if (uA <= 1500000)
|
||||
reg_val = 0x20 + (uA -540000) / 60000;
|
||||
else if (uA <= 2940000)
|
||||
reg_val = 0x30 + (uA -1500000) / 120000;
|
||||
else
|
||||
reg_val = 0x3d;
|
||||
|
||||
ret = sgm41515_read(dev, SGM41515_CHRG_CTRL_2, ®, 1);
|
||||
reg &= ~SGM41515_ICHRG_CUR_MASK;
|
||||
reg_val |= reg;
|
||||
ret = sgm41515_write(dev, SGM41515_CHRG_CTRL_2, ®_val, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sgm41515_set_chrg_volt(struct udevice *dev, int chrg_volt)
|
||||
{
|
||||
int ret;
|
||||
unsigned char reg, reg_val;
|
||||
struct sgm41515_charger *priv = dev_get_priv(dev);
|
||||
|
||||
if (chrg_volt < SGM41515_VREG_V_MIN_uV)
|
||||
chrg_volt = SGM41515_VREG_V_MIN_uV;
|
||||
else if (chrg_volt > priv->max_vreg)
|
||||
chrg_volt = priv->max_vreg;
|
||||
|
||||
reg_val = (chrg_volt-SGM41515_VREG_V_MIN_uV) / SGM41515_VREG_V_STEP_uV;
|
||||
reg_val = reg_val<<3;
|
||||
|
||||
ret = sgm41515_read(dev, SGM41515_CHRG_CTRL_4, ®, 1);
|
||||
reg &= ~SGM41515_VREG_V_MASK;
|
||||
reg_val |= reg;
|
||||
ret = sgm41515_write(dev, SGM41515_CHRG_CTRL_4, ®_val, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sgm41515_set_watchdog_timer(struct udevice *dev, int time)
|
||||
{
|
||||
int ret;
|
||||
unsigned char reg, reg_val;
|
||||
|
||||
if (time == 0)
|
||||
reg_val = SGM41515_WDT_TIMER_DISABLE;
|
||||
else if (time == 40)
|
||||
reg_val = SGM41515_WDT_TIMER_40S;
|
||||
else if (time == 80)
|
||||
reg_val = SGM41515_WDT_TIMER_80S;
|
||||
else
|
||||
reg_val = SGM41515_WDT_TIMER_160S;
|
||||
|
||||
ret = sgm41515_read(dev, SGM41515_CHRG_CTRL_5, ®, 1);
|
||||
reg &= ~SGM41515_WDT_TIMER_MASK;
|
||||
reg_val |= reg;
|
||||
ret = sgm41515_write(dev, SGM41515_CHRG_CTRL_5, ®_val, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sgm41515_set_output_volt(struct udevice *dev, int uV)
|
||||
{
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
unsigned char reg, reg_val;
|
||||
while(i < 4){
|
||||
if (uV == BOOST_VOLT_LIMIT[i]){
|
||||
reg_val = (unsigned char)i;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (reg_val < 0)
|
||||
return reg_val;
|
||||
reg_val = reg_val << 4;
|
||||
ret = sgm41515_read(dev, SGM41515_CHRG_CTRL_6, ®, 1);
|
||||
reg &= ~SGM41515_BOOSTV;
|
||||
reg_val |= reg;
|
||||
ret = sgm41515_write(dev, SGM41515_CHRG_CTRL_6, ®_val, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sgm41515_set_term_curr(struct udevice *dev, int uA)
|
||||
{
|
||||
unsigned char reg, reg_val;
|
||||
|
||||
for(reg_val = 1; reg_val < 16 && uA >= ITERM_CURRENT_STABLE[reg_val]; reg_val++)
|
||||
;
|
||||
reg_val--;
|
||||
sgm41515_read(dev, SGM41515_CHRG_CTRL_3, ®, 1);
|
||||
reg &= ~SGM41515_TERMCHRG_CUR_MASK;
|
||||
reg_val |= reg;
|
||||
|
||||
return sgm41515_write(dev, SGM41515_CHRG_CTRL_3, ®_val, 1);
|
||||
}
|
||||
|
||||
static int sgm41515_set_prechrg_curr(struct udevice *dev, int uA)
|
||||
{
|
||||
unsigned char reg, reg_val;
|
||||
|
||||
for(reg_val = 1; reg_val < 16 && uA >= IPRECHG_CURRENT_STABLE[reg_val]; reg_val++)
|
||||
;
|
||||
reg_val--;
|
||||
reg_val = reg_val << 4;
|
||||
sgm41515_read(dev, SGM41515_CHRG_CTRL_3, ®, 1);
|
||||
reg &= ~SGM41515_PRECHRG_CUR_MASK;
|
||||
reg_val |= reg;
|
||||
|
||||
return sgm41515_write(dev, SGM41515_CHRG_CTRL_3, ®_val, 1);
|
||||
}
|
||||
|
||||
static int sgm41515_hw_init(struct udevice *dev)
|
||||
{
|
||||
int ret, val;
|
||||
struct sgm41515_charger *priv = dev_get_priv(dev);
|
||||
/* set input current limit */
|
||||
ret = sgm41515_set_input_curr_lim(dev, priv->ilim);
|
||||
if(ret) {
|
||||
printf("set input current failed\n");
|
||||
return ret;
|
||||
}
|
||||
/* set charge current and voltage limit */
|
||||
ret = sgm41515_set_chrg_curr(dev, priv->ichg);
|
||||
if(ret) {
|
||||
printf("set charge current failed\n");
|
||||
return ret;
|
||||
}
|
||||
ret = sgm41515_set_chrg_volt(dev, priv->max_vreg);
|
||||
if(ret) {
|
||||
printf("set charge voltage failed\n");
|
||||
return ret;
|
||||
}
|
||||
sgm41515_set_watchdog_timer(dev, 0);
|
||||
sgm41515_set_output_volt(dev, 5000000);
|
||||
val = dev_read_u32_default(dev, "sgm41515-prechrg-uA", SGM41515_PRECHRG_I_DEF_uA);
|
||||
sgm41515_set_prechrg_curr(dev, val);
|
||||
val = dev_read_u32_default(dev, "sgm41515-termchrg-uA", SGM41515_TERMCHRG_I_DEF_uA);
|
||||
sgm41515_set_term_curr(dev, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sgm41515_enable_charge(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
unsigned char reg, reg_val;
|
||||
struct sgm41515_charger *priv = dev_get_priv(dev);
|
||||
ret = gpio_request_by_name(dev, "ch-en-gpios", 0, &priv->charge_en,
|
||||
GPIOD_IS_OUT);
|
||||
if (ret) {
|
||||
printf("%s: Warning: cannot get enable GPIO: ret=%d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
/* enable charge */
|
||||
dm_gpio_set_value(&priv->charge_en, 0);
|
||||
|
||||
ret = gpio_request_by_name(dev, "nqon-gpios", 0, &priv->nqon,
|
||||
GPIOD_IS_OUT);
|
||||
if (ret) {
|
||||
printf("%s: Warning: cannot get enable GPIO: ret=%d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
/* enable charge */
|
||||
dm_gpio_set_value(&priv->nqon, 1);
|
||||
|
||||
reg_val = SGM41515_CHRG_EN;
|
||||
ret = sgm41515_read(dev, SGM41515_CHRG_CTRL_1, ®, 1);
|
||||
reg &= ~SGM41515_CHRG_EN;
|
||||
reg_val |= reg;
|
||||
ret = sgm41515_write(dev, SGM41515_CHRG_CTRL_1, ®_val, 1);
|
||||
if(ret)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sgm41515_get_status(struct udevice *dev)
|
||||
{
|
||||
unsigned char reg;
|
||||
int ret;
|
||||
bool online;
|
||||
struct sgm41515_charger *priv = dev_get_priv(dev);
|
||||
|
||||
ret = sgm41515_read(dev, SGM41515_CHRG_STAT, ®, 1);
|
||||
if(ret) {
|
||||
printf("failed to get charger status\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
online = !!(reg & SGM41515_PG_STAT);
|
||||
if(online) {
|
||||
printf("vbus is attached\n");
|
||||
ret = sgm41515_set_input_curr_lim(dev, priv->ilim);
|
||||
if(ret) {
|
||||
printf("set input current failed\n");
|
||||
return ret;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
printf("vbus is not attached\n");
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sgm41515_probe(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
int input_current, ichrg_limit, vchrg_limit;
|
||||
struct sgm41515_charger *priv = dev_get_priv(dev);
|
||||
|
||||
input_current = dev_read_u32_default(dev, "sgm41515-cur-input-uA", 2000000);
|
||||
ichrg_limit = dev_read_u32_default(dev, "sgm41515-ichrg-uA", 2000000);
|
||||
vchrg_limit = dev_read_u32_default(dev, "sgm41515-vchrg-uV", 4350000);
|
||||
priv->max_vreg = vchrg_limit;
|
||||
priv->ichg = ichrg_limit;
|
||||
priv->ilim = input_current;
|
||||
|
||||
ret = sgm41515_hw_init(dev);
|
||||
if(ret)
|
||||
return ret;
|
||||
/* enable charger */
|
||||
sgm41515_enable_charge(dev);
|
||||
printf("sgm41515 charger register successfully!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id sgm41515_ids[] = {
|
||||
{ .compatible = "spacemit,sgm41515", .data = 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct dm_charger_ops sgm41515_chg_ops = {
|
||||
.get_status = sgm41515_get_status,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sgm41515_charger) = {
|
||||
.name = "sgm41515-charger",
|
||||
.id = UCLASS_CHARGER,
|
||||
.of_match = sgm41515_ids,
|
||||
.ops = &sgm41515_chg_ops,
|
||||
.probe = sgm41515_probe,
|
||||
.priv_auto = sizeof(struct sgm41515_charger),
|
||||
};
|
|
@ -12,6 +12,20 @@
|
|||
#define APMU_REGMAP_INDEX 1
|
||||
|
||||
#define APMU_POWER_STATUS_REG 0xf0
|
||||
#define MPMU_APCR_PER_REG 0x1098
|
||||
#define MPMU_AWUCRM_REG 0x104c
|
||||
|
||||
#define PM_QOS_AXISDD_OFFSET 31
|
||||
#define PM_QOS_DDRCORSD_OFFSET 27
|
||||
#define PM_QOS_APBSD_OFFSET 26
|
||||
#define PM_QOS_VCTCXOSD_OFFSET 19
|
||||
#define PM_QOS_STBYEN_OFFSET 13
|
||||
#define PM_QOS_PE_VOTE_AP_SLPEN_OFFSET 3
|
||||
|
||||
/* pmic */
|
||||
#define WAKEUP_SOURCE_WAKEUP_7 7
|
||||
|
||||
static unsigned int g_acpr_per;
|
||||
|
||||
enum pm_domain_id {
|
||||
K1X_PMU_VPU_PWR_DOMAIN,
|
||||
|
@ -21,6 +35,7 @@ enum pm_domain_id {
|
|||
K1X_PMU_AUD_PWR_DOMAIN,
|
||||
K1X_PMU_GNSS_PWR_DOMAIN,
|
||||
K1X_PMU_HDMI_PWR_DOMAIN,
|
||||
K1X_PMU_WKUP_EVENT_PWR_DOMAIN,
|
||||
};
|
||||
|
||||
struct pm_domain_desc {
|
||||
|
@ -131,6 +146,10 @@ static struct pm_domain_desc k1x_pm_domain_desc[] = {
|
|||
.use_hw = 1,
|
||||
.pm_index = K1X_PMU_HDMI_PWR_DOMAIN,
|
||||
},
|
||||
|
||||
[K1X_PMU_WKUP_EVENT_PWR_DOMAIN] = {
|
||||
.pm_index = K1X_PMU_WKUP_EVENT_PWR_DOMAIN,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct udevice_id spacemit_power_domain_of_match[] = {
|
||||
|
@ -159,6 +178,17 @@ static int k1x_pd_power_off(struct spacemit_k1x_pd_platdata *skp, struct pm_doma
|
|||
{
|
||||
unsigned int val;
|
||||
int loop;
|
||||
unsigned int apcr_per;
|
||||
|
||||
if (desc->pm_index == K1X_PMU_WKUP_EVENT_PWR_DOMAIN) {
|
||||
regmap_write(skp->regmap[MPMU_REGMAP_INDEX], MPMU_APCR_PER_REG, g_acpr_per);
|
||||
|
||||
/* disable pmic wakeup */
|
||||
regmap_read(skp->regmap[MPMU_REGMAP_INDEX], MPMU_AWUCRM_REG, &apcr_per);
|
||||
apcr_per &= ~(1 << WAKEUP_SOURCE_WAKEUP_7);
|
||||
regmap_write(skp->regmap[MPMU_REGMAP_INDEX], MPMU_AWUCRM_REG, apcr_per);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!desc->use_hw) {
|
||||
/* this is the sw type */
|
||||
|
@ -210,6 +240,29 @@ static int k1x_pd_power_on(struct spacemit_k1x_pd_platdata *skp, struct pm_domai
|
|||
{
|
||||
int loop;
|
||||
unsigned int val;
|
||||
unsigned int apcr_per;
|
||||
unsigned int apcr_clear = 0, apcr_set = (1 << PM_QOS_PE_VOTE_AP_SLPEN_OFFSET);
|
||||
|
||||
if (desc->pm_index == K1X_PMU_WKUP_EVENT_PWR_DOMAIN) {
|
||||
/* vote the per, and enable some wakeup source */
|
||||
apcr_set |= (1 << PM_QOS_AXISDD_OFFSET);
|
||||
apcr_set |= (1 << PM_QOS_DDRCORSD_OFFSET);
|
||||
apcr_set |= (1 << PM_QOS_APBSD_OFFSET);
|
||||
apcr_set |= (1 << PM_QOS_VCTCXOSD_OFFSET);
|
||||
apcr_set |= (1 << PM_QOS_STBYEN_OFFSET);
|
||||
|
||||
regmap_read(skp->regmap[MPMU_REGMAP_INDEX], MPMU_APCR_PER_REG, &apcr_per);
|
||||
g_acpr_per = apcr_per;
|
||||
apcr_per &= ~(apcr_clear);
|
||||
apcr_per |= apcr_set;
|
||||
regmap_write(skp->regmap[MPMU_REGMAP_INDEX], MPMU_APCR_PER_REG, apcr_per);
|
||||
|
||||
/* enable pmic wakeup */
|
||||
regmap_read(skp->regmap[MPMU_REGMAP_INDEX], MPMU_AWUCRM_REG, &apcr_per);
|
||||
apcr_per |= (1 << WAKEUP_SOURCE_WAKEUP_7);
|
||||
regmap_write(skp->regmap[MPMU_REGMAP_INDEX], MPMU_AWUCRM_REG, apcr_per);
|
||||
return 0;
|
||||
}
|
||||
|
||||
regmap_read(skp->regmap[APMU_REGMAP_INDEX], APMU_POWER_STATUS_REG, &val);
|
||||
if (val & (1 << desc->bit_pwr_stat))
|
||||
|
|
|
@ -330,12 +330,12 @@ static void regulator_show(struct udevice *dev, int ret)
|
|||
|
||||
uc_pdata = dev_get_uclass_plat(dev);
|
||||
|
||||
pr_info("%s@%s: ", dev->name, uc_pdata->name);
|
||||
pr_info("%s@%s:", dev->name, uc_pdata->name);
|
||||
if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
|
||||
pr_info("set %d uV", uc_pdata->min_uV);
|
||||
pr_info(" set %d uV;", uc_pdata->min_uV);
|
||||
if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)
|
||||
pr_info("; set %d uA", uc_pdata->min_uA);
|
||||
pr_info("; enabling");
|
||||
pr_info(" set %d uA;", uc_pdata->min_uA);
|
||||
pr_info(" enabling");
|
||||
if (ret)
|
||||
pr_info(" (ret: %d)", ret);
|
||||
pr_info("\n");
|
||||
|
|
|
@ -248,49 +248,43 @@ static int buck_set_value(struct udevice *dev, int uvolt)
|
|||
static int buck_set_suspend_value(struct udevice *dev, int uvolt)
|
||||
{
|
||||
/* the hardware has already support the function */
|
||||
/**
|
||||
* int sel, ret = -EINVAL;
|
||||
* int buck = dev->driver_data - 1;
|
||||
* const struct pm8xx_buck_desc *info = get_buck_reg(dev->parent, buck);
|
||||
*
|
||||
* if (info == NULL)
|
||||
* return -ENOSYS;
|
||||
*
|
||||
* sel = regulator_map_voltage_linear_range(info, uvolt, uvolt);
|
||||
* if (sel >=0) {
|
||||
* // has get the selctor
|
||||
* sel <<= ffs(info->vsel_sleep_msk) - 1;
|
||||
* ret = pmic_clrsetbits(dev->parent, info->vsel_sleep_reg, info->vsel_sleep_msk, sel);
|
||||
* }
|
||||
*
|
||||
* return ret;
|
||||
*/
|
||||
return 0;
|
||||
int sel, ret = -EINVAL;
|
||||
int buck = dev->driver_data - 1;
|
||||
const struct pm8xx_buck_desc *info = get_buck_reg(dev->parent, buck);
|
||||
|
||||
if (info == NULL)
|
||||
return -ENOSYS;
|
||||
|
||||
sel = regulator_map_voltage_linear_range(info, uvolt, uvolt);
|
||||
if (sel >=0) {
|
||||
// has get the selctor
|
||||
sel <<= ffs(info->vsel_sleep_msk) - 1;
|
||||
ret = pmic_clrsetbits(dev->parent, info->vsel_sleep_reg, info->vsel_sleep_msk, sel);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int buck_get_suspend_value(struct udevice *dev)
|
||||
{
|
||||
/* the hardware has already support the function */
|
||||
/**
|
||||
* int buck = dev->driver_data - 1;
|
||||
* const struct pm8xx_buck_desc *info = get_buck_reg(dev->parent, buck);
|
||||
* int mask = info->vsel_sleep_msk;
|
||||
* int ret;
|
||||
* unsigned int val;
|
||||
*
|
||||
* if (info == NULL)
|
||||
* return -ENOSYS;
|
||||
*
|
||||
* ret = pmic_reg_read(dev->parent, info->vsel_sleep_reg);
|
||||
* if (ret < 0)
|
||||
* return ret;
|
||||
* val = ret & mask;
|
||||
*
|
||||
* val >>= ffs(mask) - 1;
|
||||
*
|
||||
* return regulator_desc_list_voltage_linear_range(info, val);
|
||||
*/
|
||||
return 0;
|
||||
int buck = dev->driver_data - 1;
|
||||
const struct pm8xx_buck_desc *info = get_buck_reg(dev->parent, buck);
|
||||
int mask = info->vsel_sleep_msk;
|
||||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
if (info == NULL)
|
||||
return -ENOSYS;
|
||||
|
||||
ret = pmic_reg_read(dev->parent, info->vsel_sleep_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
val = ret & mask;
|
||||
|
||||
val >>= ffs(mask) - 1;
|
||||
|
||||
return regulator_desc_list_voltage_linear_range(info, val);
|
||||
}
|
||||
|
||||
static int buck_get_enable(struct udevice *dev)
|
||||
|
@ -437,48 +431,42 @@ static int ldo_set_value(struct udevice *dev, int uvolt)
|
|||
|
||||
static int ldo_set_suspend_value(struct udevice *dev, int uvolt)
|
||||
{
|
||||
/**
|
||||
* int sel, ret = -EINVAL;
|
||||
* int buck = dev->driver_data - 1;
|
||||
* const struct pm8xx_buck_desc *info = get_ldo_reg(dev->parent, buck);
|
||||
*
|
||||
* if (info == NULL)
|
||||
* return -ENOSYS;
|
||||
*
|
||||
* sel = regulator_map_voltage_linear_range(info, uvolt, uvolt);
|
||||
* if (sel >=0) {
|
||||
*
|
||||
* sel <<= ffs(info->vsel_sleep_msk) - 1;
|
||||
* ret = pmic_clrsetbits(dev->parent, info->vsel_sleep_reg, info->vsel_sleep_msk, sel);
|
||||
* }
|
||||
*
|
||||
* return ret;
|
||||
*/
|
||||
return 0;
|
||||
int sel, ret = -EINVAL;
|
||||
int buck = dev->driver_data - 1;
|
||||
const struct pm8xx_buck_desc *info = get_ldo_reg(dev->parent, buck);
|
||||
|
||||
if (info == NULL)
|
||||
return -ENOSYS;
|
||||
|
||||
sel = regulator_map_voltage_linear_range(info, uvolt, uvolt);
|
||||
if (sel >=0) {
|
||||
sel <<= ffs(info->vsel_sleep_msk) - 1;
|
||||
ret = pmic_clrsetbits(dev->parent, info->vsel_sleep_reg, info->vsel_sleep_msk, sel);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ldo_get_suspend_value(struct udevice *dev)
|
||||
{
|
||||
/**
|
||||
* int buck = dev->driver_data - 1;
|
||||
* const struct pm8xx_buck_desc *info = get_ldo_reg(dev->parent, buck);
|
||||
* int mask = info->vsel_sleep_msk;
|
||||
* int ret;
|
||||
* unsigned int val;
|
||||
*
|
||||
* if (info == NULL)
|
||||
* return -ENOSYS;
|
||||
*
|
||||
* ret = pmic_reg_read(dev->parent, info->vsel_sleep_reg);
|
||||
* if (ret < 0)
|
||||
* return ret;
|
||||
* val = ret & mask;
|
||||
*
|
||||
* val >>= ffs(mask) - 1;
|
||||
*
|
||||
* return regulator_desc_list_voltage_linear_range(info, val);
|
||||
*/
|
||||
return 0;
|
||||
|
||||
int buck = dev->driver_data - 1;
|
||||
const struct pm8xx_buck_desc *info = get_ldo_reg(dev->parent, buck);
|
||||
int mask = info->vsel_sleep_msk;
|
||||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
if (info == NULL)
|
||||
return -ENOSYS;
|
||||
|
||||
ret = pmic_reg_read(dev->parent, info->vsel_sleep_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
val = ret & mask;
|
||||
|
||||
val >>= ffs(mask) - 1;
|
||||
|
||||
return regulator_desc_list_voltage_linear_range(info, val);
|
||||
}
|
||||
|
||||
static int ldo_get_enable(struct udevice *dev)
|
||||
|
@ -585,11 +573,51 @@ static const struct pm8xx_buck_desc *get_switch_reg(struct udevice *pmic, int nu
|
|||
|
||||
static int switch_get_value(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
int ret;
|
||||
unsigned int val;
|
||||
int buck = dev->driver_data - 1;
|
||||
const struct pm8xx_buck_desc *info = get_switch_reg(dev->parent, buck);
|
||||
int mask = info->enable_msk;
|
||||
|
||||
if (info == NULL)
|
||||
return -ENOSYS;
|
||||
|
||||
ret = pmic_reg_read(dev->parent, info->enable_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
val = ret & mask;
|
||||
|
||||
val >>= ffs(mask) - 1;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int switch_set_value(struct udevice *dev, int uvolt)
|
||||
{
|
||||
int ret;
|
||||
unsigned int val = 0;
|
||||
int buck = dev->driver_data - 1;
|
||||
const struct pm8xx_buck_desc *info = get_switch_reg(dev->parent, buck);
|
||||
int mask = info->enable_msk;
|
||||
|
||||
ret = pmic_reg_read(dev->parent, info->enable_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
val = (unsigned int)ret;
|
||||
val &= mask;
|
||||
val >>= ffs(mask) - 1;
|
||||
|
||||
if (uvolt == val)
|
||||
return 0;
|
||||
|
||||
val = uvolt << (ffs(mask) - 1);
|
||||
|
||||
ret = pmic_clrsetbits(dev->parent, info->enable_reg, info->enable_msk, val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,6 @@ static int pxa_pwm_set_enable(struct udevice *dev, uint channel, bool enable)
|
|||
struct pxa_pwm_priv *priv = dev_get_priv(dev);
|
||||
|
||||
if (enable) {
|
||||
printf("!!!!!!!!!!!!!!!!!!\n");
|
||||
return clk_enable(&priv->clk);
|
||||
}
|
||||
else
|
||||
|
@ -146,7 +145,7 @@ static const struct udevice_id pxa_pwm_ids[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_pwm) = {
|
||||
U_BOOT_DRIVER(spacemit_pwm) = {
|
||||
.name = "pxa_pwm",
|
||||
.id = UCLASS_PWM,
|
||||
.of_match = pxa_pwm_ids,
|
||||
|
|
|
@ -458,7 +458,7 @@ static int spacemit_reset_deassert(struct reset_ctl *rst)
|
|||
static int spacemit_k1x_reset_probe(struct udevice *dev)
|
||||
{
|
||||
struct spacemit_reset *reset = dev_get_priv(dev);
|
||||
pr_info("[RESET]probe start \r\n");
|
||||
pr_info("reset driver probe start \n");
|
||||
|
||||
reset->mpmu_base = (void __iomem *)dev_remap_addr_index(dev, 0);
|
||||
if (!reset->mpmu_base) {
|
||||
|
@ -508,7 +508,7 @@ static int spacemit_k1x_reset_probe(struct udevice *dev)
|
|||
goto out;
|
||||
}
|
||||
reset->signals = k1x_reset_signals;
|
||||
pr_info("[RESET]probe finish \r\n");
|
||||
pr_info("reset driver probe finish \n");
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -127,6 +127,12 @@ config SYS_USB_EVENT_POLL
|
|||
config SYS_USB_EVENT_POLL_VIA_INT_QUEUE
|
||||
bool "Poll via interrupt queue"
|
||||
|
||||
config SYS_USB_EVENT_POLL_COMPATIBLE
|
||||
bool "Interrupt polling compatible mode"
|
||||
---help---
|
||||
Select to poll via interrupt queue if controller supported,
|
||||
this allow using different mechanisms for different controllers.
|
||||
|
||||
config SYS_USB_EVENT_POLL_VIA_CONTROL_EP
|
||||
bool "Poll via control EP"
|
||||
|
||||
|
|
|
@ -64,8 +64,9 @@ void xhci_inval_cache(uintptr_t addr, u32 len)
|
|||
* @param ptr pointer to "segement" to be freed
|
||||
* Return: none
|
||||
*/
|
||||
static void xhci_segment_free(struct xhci_segment *seg)
|
||||
static void xhci_segment_free(struct xhci_ctrl *ctrl, struct xhci_segment *seg)
|
||||
{
|
||||
xhci_dma_unmap(ctrl, seg->dma, SEGMENT_SIZE);
|
||||
free(seg->trbs);
|
||||
seg->trbs = NULL;
|
||||
|
||||
|
@ -78,7 +79,7 @@ static void xhci_segment_free(struct xhci_segment *seg)
|
|||
* @param ptr pointer to "ring" to be freed
|
||||
* Return: none
|
||||
*/
|
||||
static void xhci_ring_free(struct xhci_ring *ring)
|
||||
static void xhci_ring_free(struct xhci_ctrl *ctrl, struct xhci_ring *ring)
|
||||
{
|
||||
struct xhci_segment *seg;
|
||||
struct xhci_segment *first_seg;
|
||||
|
@ -89,10 +90,10 @@ static void xhci_ring_free(struct xhci_ring *ring)
|
|||
seg = first_seg->next;
|
||||
while (seg != first_seg) {
|
||||
struct xhci_segment *next = seg->next;
|
||||
xhci_segment_free(seg);
|
||||
xhci_segment_free(ctrl, seg);
|
||||
seg = next;
|
||||
}
|
||||
xhci_segment_free(first_seg);
|
||||
xhci_segment_free(ctrl, first_seg);
|
||||
|
||||
free(ring);
|
||||
}
|
||||
|
@ -105,12 +106,20 @@ static void xhci_ring_free(struct xhci_ring *ring)
|
|||
*/
|
||||
static void xhci_scratchpad_free(struct xhci_ctrl *ctrl)
|
||||
{
|
||||
struct xhci_hccr *hccr = ctrl->hccr;
|
||||
int num_sp;
|
||||
|
||||
if (!ctrl->scratchpad)
|
||||
return;
|
||||
|
||||
num_sp = HCS_MAX_SCRATCHPAD(xhci_readl(&hccr->cr_hcsparams2));
|
||||
xhci_dma_unmap(ctrl, ctrl->scratchpad->sp_array[0],
|
||||
num_sp * ctrl->page_size);
|
||||
xhci_dma_unmap(ctrl, ctrl->dcbaa->dev_context_ptrs[0],
|
||||
num_sp * sizeof(u64));
|
||||
ctrl->dcbaa->dev_context_ptrs[0] = 0;
|
||||
|
||||
free(xhci_bus_to_virt(ctrl, le64_to_cpu(ctrl->scratchpad->sp_array[0])));
|
||||
free(ctrl->scratchpad->scratchpad);
|
||||
free(ctrl->scratchpad->sp_array);
|
||||
free(ctrl->scratchpad);
|
||||
ctrl->scratchpad = NULL;
|
||||
|
@ -122,8 +131,10 @@ static void xhci_scratchpad_free(struct xhci_ctrl *ctrl)
|
|||
* @param ptr pointer to "xhci_container_ctx" to be freed
|
||||
* Return: none
|
||||
*/
|
||||
static void xhci_free_container_ctx(struct xhci_container_ctx *ctx)
|
||||
static void xhci_free_container_ctx(struct xhci_ctrl *ctrl,
|
||||
struct xhci_container_ctx *ctx)
|
||||
{
|
||||
xhci_dma_unmap(ctrl, ctx->dma, ctx->size);
|
||||
free(ctx->bytes);
|
||||
free(ctx);
|
||||
}
|
||||
|
@ -153,12 +164,12 @@ static void xhci_free_virt_devices(struct xhci_ctrl *ctrl)
|
|||
|
||||
for (i = 0; i < 31; ++i)
|
||||
if (virt_dev->eps[i].ring)
|
||||
xhci_ring_free(virt_dev->eps[i].ring);
|
||||
xhci_ring_free(ctrl, virt_dev->eps[i].ring);
|
||||
|
||||
if (virt_dev->in_ctx)
|
||||
xhci_free_container_ctx(virt_dev->in_ctx);
|
||||
xhci_free_container_ctx(ctrl, virt_dev->in_ctx);
|
||||
if (virt_dev->out_ctx)
|
||||
xhci_free_container_ctx(virt_dev->out_ctx);
|
||||
xhci_free_container_ctx(ctrl, virt_dev->out_ctx);
|
||||
|
||||
free(virt_dev);
|
||||
/* make sure we are pointing to NULL */
|
||||
|
@ -174,11 +185,15 @@ static void xhci_free_virt_devices(struct xhci_ctrl *ctrl)
|
|||
*/
|
||||
void xhci_cleanup(struct xhci_ctrl *ctrl)
|
||||
{
|
||||
xhci_ring_free(ctrl->event_ring);
|
||||
xhci_ring_free(ctrl->cmd_ring);
|
||||
xhci_ring_free(ctrl, ctrl->event_ring);
|
||||
xhci_ring_free(ctrl, ctrl->cmd_ring);
|
||||
xhci_scratchpad_free(ctrl);
|
||||
xhci_free_virt_devices(ctrl);
|
||||
xhci_dma_unmap(ctrl, ctrl->erst.erst_dma_addr,
|
||||
sizeof(struct xhci_erst_entry) * ERST_NUM_SEGS);
|
||||
free(ctrl->erst.entries);
|
||||
xhci_dma_unmap(ctrl, ctrl->dcbaa->dma,
|
||||
sizeof(struct xhci_device_context_array));
|
||||
free(ctrl->dcbaa);
|
||||
memset(ctrl, '\0', sizeof(struct xhci_ctrl));
|
||||
}
|
||||
|
@ -218,15 +233,13 @@ static void xhci_link_segments(struct xhci_ctrl *ctrl, struct xhci_segment *prev
|
|||
struct xhci_segment *next, bool link_trbs)
|
||||
{
|
||||
u32 val;
|
||||
u64 val_64 = 0;
|
||||
|
||||
if (!prev || !next)
|
||||
return;
|
||||
prev->next = next;
|
||||
if (link_trbs) {
|
||||
val_64 = xhci_virt_to_bus(ctrl, next->trbs);
|
||||
prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
|
||||
cpu_to_le64(val_64);
|
||||
cpu_to_le64(next->dma);
|
||||
|
||||
/*
|
||||
* Set the last TRB in the segment to
|
||||
|
@ -273,7 +286,7 @@ static void xhci_initialize_ring_info(struct xhci_ring *ring)
|
|||
* @param none
|
||||
* Return: pointer to the newly allocated SEGMENT
|
||||
*/
|
||||
static struct xhci_segment *xhci_segment_alloc(void)
|
||||
static struct xhci_segment *xhci_segment_alloc(struct xhci_ctrl *ctrl)
|
||||
{
|
||||
struct xhci_segment *seg;
|
||||
|
||||
|
@ -281,6 +294,7 @@ static struct xhci_segment *xhci_segment_alloc(void)
|
|||
BUG_ON(!seg);
|
||||
|
||||
seg->trbs = xhci_malloc(SEGMENT_SIZE);
|
||||
seg->dma = xhci_dma_map(ctrl, seg->trbs, SEGMENT_SIZE);
|
||||
|
||||
seg->next = NULL;
|
||||
|
||||
|
@ -314,7 +328,7 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_ctrl *ctrl, unsigned int num_segs,
|
|||
if (num_segs == 0)
|
||||
return ring;
|
||||
|
||||
ring->first_seg = xhci_segment_alloc();
|
||||
ring->first_seg = xhci_segment_alloc(ctrl);
|
||||
BUG_ON(!ring->first_seg);
|
||||
|
||||
num_segs--;
|
||||
|
@ -323,7 +337,7 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_ctrl *ctrl, unsigned int num_segs,
|
|||
while (num_segs > 0) {
|
||||
struct xhci_segment *next;
|
||||
|
||||
next = xhci_segment_alloc();
|
||||
next = xhci_segment_alloc(ctrl);
|
||||
BUG_ON(!next);
|
||||
|
||||
xhci_link_segments(ctrl, prev, next, link_trbs);
|
||||
|
@ -372,7 +386,8 @@ static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl)
|
|||
if (!scratchpad->sp_array)
|
||||
goto fail_sp2;
|
||||
|
||||
val_64 = xhci_virt_to_bus(ctrl, scratchpad->sp_array);
|
||||
val_64 = xhci_dma_map(ctrl, scratchpad->sp_array,
|
||||
num_sp * sizeof(u64));
|
||||
ctrl->dcbaa->dev_context_ptrs[0] = cpu_to_le64(val_64);
|
||||
|
||||
xhci_flush_cache((uintptr_t)&ctrl->dcbaa->dev_context_ptrs[0],
|
||||
|
@ -386,16 +401,18 @@ static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl)
|
|||
}
|
||||
BUG_ON(i == 16);
|
||||
|
||||
page_size = 1 << (i + 12);
|
||||
buf = memalign(page_size, num_sp * page_size);
|
||||
ctrl->page_size = 1 << (i + 12);
|
||||
buf = memalign(ctrl->page_size, num_sp * ctrl->page_size);
|
||||
if (!buf)
|
||||
goto fail_sp3;
|
||||
memset(buf, '\0', num_sp * page_size);
|
||||
xhci_flush_cache((uintptr_t)buf, num_sp * page_size);
|
||||
memset(buf, '\0', num_sp * ctrl->page_size);
|
||||
xhci_flush_cache((uintptr_t)buf, num_sp * ctrl->page_size);
|
||||
|
||||
scratchpad->scratchpad = buf;
|
||||
val_64 = xhci_dma_map(ctrl, buf, num_sp * ctrl->page_size);
|
||||
for (i = 0; i < num_sp; i++) {
|
||||
val_64 = xhci_virt_to_bus(ctrl, buf + i * page_size);
|
||||
scratchpad->sp_array[i] = cpu_to_le64(val_64);
|
||||
val_64 += ctrl->page_size;
|
||||
}
|
||||
|
||||
xhci_flush_cache((uintptr_t)scratchpad->sp_array,
|
||||
|
@ -437,6 +454,7 @@ static struct xhci_container_ctx
|
|||
ctx->size += CTX_SIZE(xhci_readl(&ctrl->hccr->cr_hccparams));
|
||||
|
||||
ctx->bytes = xhci_malloc(ctx->size);
|
||||
ctx->dma = xhci_dma_map(ctrl, ctx->bytes, ctx->size);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
@ -487,7 +505,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id)
|
|||
/* Allocate endpoint 0 ring */
|
||||
virt_dev->eps[0].ring = xhci_ring_alloc(ctrl, 1, true);
|
||||
|
||||
byte_64 = xhci_virt_to_bus(ctrl, virt_dev->out_ctx->bytes);
|
||||
byte_64 = virt_dev->out_ctx->dma;
|
||||
|
||||
/* Point to output device context in dcbaa. */
|
||||
ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64);
|
||||
|
@ -497,6 +515,30 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_ctrl *ctrl,
|
||||
struct usb_device *udev)
|
||||
{
|
||||
struct xhci_virt_device *virt_dev;
|
||||
struct xhci_ep_ctx *ep0_ctx;
|
||||
struct xhci_ring *ep_ring;
|
||||
|
||||
virt_dev = ctrl->devs[udev->slot_id];
|
||||
ep0_ctx = xhci_get_ep_ctx(ctrl, virt_dev->in_ctx, 0);
|
||||
ep_ring = virt_dev->eps[0].ring;
|
||||
/*
|
||||
* FIXME we don't keep track of the dequeue pointer very well after a
|
||||
* Set TR dequeue pointer, so we're setting the dequeue pointer of the
|
||||
* host to our enqueue pointer. This should only be called after a
|
||||
* configured device has reset, so all control transfers should have
|
||||
* been completed or cancelled before the reset.
|
||||
*/
|
||||
ep0_ctx->deq = cpu_to_le64(xhci_trb_virt_to_dma(ep_ring->enq_seg,
|
||||
ep_ring->enqueue)
|
||||
| ep_ring->cycle_state);
|
||||
/* uboot should flush the cache here while kernel do elsewhere */
|
||||
xhci_flush_cache((uintptr_t)ep0_ctx, sizeof(struct xhci_ep_ctx));
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates the necessary data structures
|
||||
* for XHCI host controller
|
||||
|
@ -523,15 +565,16 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
val_64 = xhci_virt_to_bus(ctrl, ctrl->dcbaa);
|
||||
ctrl->dcbaa->dma = xhci_dma_map(ctrl, ctrl->dcbaa,
|
||||
sizeof(struct xhci_device_context_array));
|
||||
/* Set the pointer in DCBAA register */
|
||||
xhci_writeq(&hcor->or_dcbaap, val_64);
|
||||
xhci_writeq(&hcor->or_dcbaap, ctrl->dcbaa->dma);
|
||||
|
||||
/* Command ring control pointer register initialization */
|
||||
ctrl->cmd_ring = xhci_ring_alloc(ctrl, 1, true);
|
||||
|
||||
/* Set the address in the Command Ring Control register */
|
||||
trb_64 = xhci_virt_to_bus(ctrl, ctrl->cmd_ring->first_seg->trbs);
|
||||
trb_64 = ctrl->cmd_ring->first_seg->dma;
|
||||
val_64 = xhci_readq(&hcor->or_crcr);
|
||||
val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
|
||||
(trb_64 & (u64) ~CMD_RING_RSVD_BITS) |
|
||||
|
@ -555,6 +598,8 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
|
|||
ctrl->event_ring = xhci_ring_alloc(ctrl, ERST_NUM_SEGS, false);
|
||||
ctrl->erst.entries = xhci_malloc(sizeof(struct xhci_erst_entry) *
|
||||
ERST_NUM_SEGS);
|
||||
ctrl->erst.erst_dma_addr = xhci_dma_map(ctrl, ctrl->erst.entries,
|
||||
sizeof(struct xhci_erst_entry) * ERST_NUM_SEGS);
|
||||
|
||||
ctrl->erst.num_entries = ERST_NUM_SEGS;
|
||||
|
||||
|
@ -562,7 +607,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
|
|||
val < ERST_NUM_SEGS;
|
||||
val++) {
|
||||
struct xhci_erst_entry *entry = &ctrl->erst.entries[val];
|
||||
trb_64 = xhci_virt_to_bus(ctrl, seg->trbs);
|
||||
trb_64 = seg->dma;
|
||||
entry->seg_addr = cpu_to_le64(trb_64);
|
||||
entry->seg_size = cpu_to_le32(TRBS_PER_SEGMENT);
|
||||
entry->rsvd = 0;
|
||||
|
@ -571,7 +616,8 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
|
|||
xhci_flush_cache((uintptr_t)ctrl->erst.entries,
|
||||
ERST_NUM_SEGS * sizeof(struct xhci_erst_entry));
|
||||
|
||||
deq = xhci_virt_to_bus(ctrl, ctrl->event_ring->dequeue);
|
||||
deq = xhci_trb_virt_to_dma(ctrl->event_ring->deq_seg,
|
||||
ctrl->event_ring->dequeue);
|
||||
|
||||
/* Update HC event ring dequeue pointer */
|
||||
xhci_writeq(&ctrl->ir_set->erst_dequeue,
|
||||
|
@ -586,7 +632,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
|
|||
/* this is the event ring segment table pointer */
|
||||
val_64 = xhci_readq(&ctrl->ir_set->erst_base);
|
||||
val_64 &= ERST_PTR_MASK;
|
||||
val_64 |= xhci_virt_to_bus(ctrl, ctrl->erst.entries) & ~ERST_PTR_MASK;
|
||||
val_64 |= ctrl->erst.erst_dma_addr & ~ERST_PTR_MASK;
|
||||
|
||||
xhci_writeq(&ctrl->ir_set->erst_base, val_64);
|
||||
|
||||
|
@ -849,7 +895,7 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
|
|||
/* EP 0 can handle "burst" sizes of 1, so Max Burst Size field is 0 */
|
||||
ep0_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(0) | ERROR_COUNT(3));
|
||||
|
||||
trb_64 = xhci_virt_to_bus(ctrl, virt_dev->eps[0].ring->first_seg->trbs);
|
||||
trb_64 = virt_dev->eps[0].ring->first_seg->dma;
|
||||
ep0_ctx->deq = cpu_to_le64(trb_64 | virt_dev->eps[0].ring->cycle_state);
|
||||
|
||||
/*
|
||||
|
|
|
@ -24,6 +24,24 @@
|
|||
|
||||
#include <usb/xhci.h>
|
||||
|
||||
/*
|
||||
* Returns zero if the TRB isn't in this segment, otherwise it returns the DMA
|
||||
* address of the TRB.
|
||||
*/
|
||||
dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg,
|
||||
union xhci_trb *trb)
|
||||
{
|
||||
unsigned long segment_offset;
|
||||
|
||||
if (!seg || !trb || trb < seg->trbs)
|
||||
return 0;
|
||||
/* offset in TRBs */
|
||||
segment_offset = trb - seg->trbs;
|
||||
if (segment_offset >= TRBS_PER_SEGMENT)
|
||||
return 0;
|
||||
return seg->dma + (segment_offset * sizeof(*trb));
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this TRB a link TRB or was the last TRB the last TRB in this event ring
|
||||
* segment? I.e. would the updated event TRB pointer step off the end of the
|
||||
|
@ -180,12 +198,11 @@ static void inc_deq(struct xhci_ctrl *ctrl, struct xhci_ring *ring)
|
|||
* @param trb_fields pointer to trb field array containing TRB contents
|
||||
* Return: pointer to the enqueued trb
|
||||
*/
|
||||
static struct xhci_generic_trb *queue_trb(struct xhci_ctrl *ctrl,
|
||||
struct xhci_ring *ring,
|
||||
bool more_trbs_coming,
|
||||
unsigned int *trb_fields)
|
||||
static dma_addr_t queue_trb(struct xhci_ctrl *ctrl, struct xhci_ring *ring,
|
||||
bool more_trbs_coming, unsigned int *trb_fields)
|
||||
{
|
||||
struct xhci_generic_trb *trb;
|
||||
dma_addr_t addr;
|
||||
int i;
|
||||
|
||||
trb = &ring->enqueue->generic;
|
||||
|
@ -195,9 +212,11 @@ static struct xhci_generic_trb *queue_trb(struct xhci_ctrl *ctrl,
|
|||
|
||||
xhci_flush_cache((uintptr_t)trb, sizeof(struct xhci_generic_trb));
|
||||
|
||||
addr = xhci_trb_virt_to_dma(ring->enq_seg, (union xhci_trb *)trb);
|
||||
|
||||
inc_enq(ctrl, ring, more_trbs_coming);
|
||||
|
||||
return trb;
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -227,7 +246,8 @@ static int prepare_ring(struct xhci_ctrl *ctrl, struct xhci_ring *ep_ring,
|
|||
puts("WARN waiting for error on ep to be cleared\n");
|
||||
return -EINVAL;
|
||||
case EP_STATE_HALTED:
|
||||
puts("WARN halted endpoint, queueing URB anyway.\n");
|
||||
puts("WARN endpoint is halted\n");
|
||||
return -EINVAL;
|
||||
case EP_STATE_STOPPED:
|
||||
case EP_STATE_RUNNING:
|
||||
debug("EP STATE RUNNING.\n");
|
||||
|
@ -271,22 +291,24 @@ static int prepare_ring(struct xhci_ctrl *ctrl, struct xhci_ring *ep_ring,
|
|||
* @param cmd Command type to enqueue
|
||||
* Return: none
|
||||
*/
|
||||
void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr, u32 slot_id,
|
||||
void xhci_queue_command(struct xhci_ctrl *ctrl, dma_addr_t addr, u32 slot_id,
|
||||
u32 ep_index, trb_type cmd)
|
||||
{
|
||||
return xhci_queue_command_extra_flags(ctrl, addr, slot_id, ep_index, cmd, 0);
|
||||
}
|
||||
|
||||
void xhci_queue_command_extra_flags(struct xhci_ctrl *ctrl, dma_addr_t addr, u32 slot_id,
|
||||
u32 ep_index, trb_type cmd, u32 extra_flags)
|
||||
{
|
||||
u32 fields[4];
|
||||
u64 val_64 = 0;
|
||||
|
||||
BUG_ON(prepare_ring(ctrl, ctrl->cmd_ring, EP_STATE_RUNNING));
|
||||
|
||||
if (ptr)
|
||||
val_64 = xhci_virt_to_bus(ctrl, ptr);
|
||||
|
||||
fields[0] = lower_32_bits(val_64);
|
||||
fields[1] = upper_32_bits(val_64);
|
||||
fields[0] = lower_32_bits(addr);
|
||||
fields[1] = upper_32_bits(addr);
|
||||
fields[2] = 0;
|
||||
fields[3] = TRB_TYPE(cmd) | SLOT_ID_FOR_TRB(slot_id) |
|
||||
ctrl->cmd_ring->cycle_state;
|
||||
ctrl->cmd_ring->cycle_state | extra_flags;
|
||||
|
||||
/*
|
||||
* Only 'reset endpoint', 'stop endpoint' and 'set TR dequeue pointer'
|
||||
|
@ -399,12 +421,15 @@ static void giveback_first_trb(struct usb_device *udev, int ep_index,
|
|||
*/
|
||||
void xhci_acknowledge_event(struct xhci_ctrl *ctrl)
|
||||
{
|
||||
dma_addr_t deq;
|
||||
|
||||
/* Advance our dequeue pointer to the next event */
|
||||
inc_deq(ctrl, ctrl->event_ring);
|
||||
|
||||
/* Inform the hardware */
|
||||
xhci_writeq(&ctrl->ir_set->erst_dequeue,
|
||||
xhci_virt_to_bus(ctrl, ctrl->event_ring->dequeue) | ERST_EHB);
|
||||
deq = xhci_trb_virt_to_dma(ctrl->event_ring->deq_seg,
|
||||
ctrl->event_ring->dequeue);
|
||||
xhci_writeq(&ctrl->ir_set->erst_dequeue, deq | ERST_EHB);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -440,6 +465,12 @@ static int event_ready(struct xhci_ctrl *ctrl)
|
|||
* Return: pointer to event trb
|
||||
*/
|
||||
union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected)
|
||||
{
|
||||
return xhci_wait_for_event_timeout(ctrl, expected, XHCI_TIMEOUT);
|
||||
}
|
||||
|
||||
union xhci_trb *xhci_wait_for_event_timeout(struct xhci_ctrl *ctrl, trb_type expected,
|
||||
unsigned long timeout)
|
||||
{
|
||||
trb_type type;
|
||||
unsigned long ts = get_timer(0);
|
||||
|
@ -451,7 +482,8 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected)
|
|||
continue;
|
||||
|
||||
type = TRB_FIELD_TO_TYPE(le32_to_cpu(event->event_cmd.flags));
|
||||
if (type == expected)
|
||||
if (type == expected ||
|
||||
(expected == TRB_NONE && type != TRB_PORT_STATUS))
|
||||
return event;
|
||||
|
||||
if (type == TRB_PORT_STATUS)
|
||||
|
@ -472,13 +504,15 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected)
|
|||
le32_to_cpu(event->generic.field[3]));
|
||||
|
||||
xhci_acknowledge_event(ctrl);
|
||||
} while (get_timer(ts) < XHCI_TIMEOUT);
|
||||
} while (get_timer(ts) < timeout);
|
||||
|
||||
if (expected == TRB_TRANSFER)
|
||||
return NULL;
|
||||
|
||||
printf("XHCI timeout on event type %d... cannot recover.\n", expected);
|
||||
BUG();
|
||||
/* Don't spam msgs for some keyboards who always timeout when no inputs */
|
||||
debug("XHCI timeout on event type %d...\n", expected);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -490,18 +524,26 @@ static void reset_ep(struct usb_device *udev, int ep_index)
|
|||
struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
|
||||
struct xhci_ring *ring = ctrl->devs[udev->slot_id]->eps[ep_index].ring;
|
||||
union xhci_trb *event;
|
||||
u64 addr;
|
||||
u32 field;
|
||||
|
||||
printf("Resetting EP %d...\n", ep_index);
|
||||
xhci_queue_command(ctrl, NULL, udev->slot_id, ep_index, TRB_RESET_EP);
|
||||
xhci_queue_command(ctrl, 0, udev->slot_id, ep_index, TRB_RESET_EP);
|
||||
event = xhci_wait_for_event(ctrl, TRB_COMPLETION);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
field = le32_to_cpu(event->trans_event.flags);
|
||||
BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id);
|
||||
xhci_acknowledge_event(ctrl);
|
||||
|
||||
xhci_queue_command(ctrl, (void *)((uintptr_t)ring->enqueue |
|
||||
ring->cycle_state), udev->slot_id, ep_index, TRB_SET_DEQ);
|
||||
addr = xhci_trb_virt_to_dma(ring->enq_seg,
|
||||
(void *)((uintptr_t)ring->enqueue | ring->cycle_state));
|
||||
xhci_queue_command(ctrl, addr, udev->slot_id, ep_index, TRB_SET_DEQ);
|
||||
event = xhci_wait_for_event(ctrl, TRB_COMPLETION);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags))
|
||||
!= udev->slot_id || GET_COMP_CODE(le32_to_cpu(
|
||||
event->event_cmd.status)) != COMP_SUCCESS);
|
||||
|
@ -521,27 +563,49 @@ static void abort_td(struct usb_device *udev, int ep_index)
|
|||
struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
|
||||
struct xhci_ring *ring = ctrl->devs[udev->slot_id]->eps[ep_index].ring;
|
||||
union xhci_trb *event;
|
||||
xhci_comp_code comp;
|
||||
trb_type type;
|
||||
u64 addr;
|
||||
u32 field;
|
||||
|
||||
xhci_queue_command(ctrl, NULL, udev->slot_id, ep_index, TRB_STOP_RING);
|
||||
xhci_queue_command(ctrl, 0, udev->slot_id, ep_index, TRB_STOP_RING);
|
||||
|
||||
event = xhci_wait_for_event(ctrl, TRB_TRANSFER);
|
||||
field = le32_to_cpu(event->trans_event.flags);
|
||||
BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id);
|
||||
BUG_ON(TRB_TO_EP_INDEX(field) != ep_index);
|
||||
BUG_ON(GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len
|
||||
!= COMP_STOP)));
|
||||
event = xhci_wait_for_event(ctrl, TRB_NONE);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
type = TRB_FIELD_TO_TYPE(le32_to_cpu(event->event_cmd.flags));
|
||||
if (type == TRB_TRANSFER) {
|
||||
field = le32_to_cpu(event->trans_event.flags);
|
||||
BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id);
|
||||
BUG_ON(TRB_TO_EP_INDEX(field) != ep_index);
|
||||
BUG_ON(GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len
|
||||
!= COMP_STOP)));
|
||||
xhci_acknowledge_event(ctrl);
|
||||
|
||||
event = xhci_wait_for_event(ctrl, TRB_COMPLETION);
|
||||
if (!event)
|
||||
return;
|
||||
type = TRB_FIELD_TO_TYPE(le32_to_cpu(event->event_cmd.flags));
|
||||
|
||||
} else {
|
||||
printf("abort_td: Expected a TRB_TRANSFER TRB first\n");
|
||||
}
|
||||
|
||||
comp = GET_COMP_CODE(le32_to_cpu(event->event_cmd.status));
|
||||
BUG_ON(type != TRB_COMPLETION ||
|
||||
TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags))
|
||||
!= udev->slot_id || (comp != COMP_SUCCESS && comp
|
||||
!= COMP_CTX_STATE));
|
||||
xhci_acknowledge_event(ctrl);
|
||||
|
||||
addr = xhci_trb_virt_to_dma(ring->enq_seg,
|
||||
(void *)((uintptr_t)ring->enqueue | ring->cycle_state));
|
||||
xhci_queue_command(ctrl, addr, udev->slot_id, ep_index, TRB_SET_DEQ);
|
||||
event = xhci_wait_for_event(ctrl, TRB_COMPLETION);
|
||||
BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags))
|
||||
!= udev->slot_id || GET_COMP_CODE(le32_to_cpu(
|
||||
event->event_cmd.status)) != COMP_SUCCESS);
|
||||
xhci_acknowledge_event(ctrl);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
xhci_queue_command(ctrl, (void *)((uintptr_t)ring->enqueue |
|
||||
ring->cycle_state), udev->slot_id, ep_index, TRB_SET_DEQ);
|
||||
event = xhci_wait_for_event(ctrl, TRB_COMPLETION);
|
||||
BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags))
|
||||
!= udev->slot_id || GET_COMP_CODE(le32_to_cpu(
|
||||
event->event_cmd.status)) != COMP_SUCCESS);
|
||||
|
@ -576,18 +640,8 @@ static void record_transfer_result(struct usb_device *udev,
|
|||
}
|
||||
}
|
||||
|
||||
/**** Bulk and Control transfer methods ****/
|
||||
/**
|
||||
* Queues up the BULK Request
|
||||
*
|
||||
* @param udev pointer to the USB device structure
|
||||
* @param pipe contains the DIR_IN or OUT , devnum
|
||||
* @param length length of the buffer
|
||||
* @param buffer buffer to be read/written based on the request
|
||||
* Return: returns 0 if successful else -1 on failure
|
||||
*/
|
||||
int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
|
||||
int length, void *buffer)
|
||||
static int xhci_normal_tx_internal(struct usb_device *udev, unsigned long pipe,
|
||||
int length, void *buffer, unsigned long timeout)
|
||||
{
|
||||
int num_trbs = 0;
|
||||
struct xhci_generic_trb *start_trb;
|
||||
|
@ -609,8 +663,8 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
|
|||
u64 addr;
|
||||
int ret;
|
||||
u32 trb_fields[4];
|
||||
u64 val_64 = xhci_virt_to_bus(ctrl, buffer);
|
||||
void *last_transfer_trb_addr;
|
||||
u64 buf_64 = xhci_dma_map(ctrl, buffer, length);
|
||||
dma_addr_t last_transfer_trb_addr;
|
||||
int available_length;
|
||||
|
||||
debug("dev=%p, pipe=%lx, buffer=%p, length=%d\n",
|
||||
|
@ -625,7 +679,18 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
|
|||
|
||||
ep_ctx = xhci_get_ep_ctx(ctrl, virt_dev->out_ctx, ep_index);
|
||||
|
||||
/*
|
||||
* If the endpoint was halted due to a prior error, resume it before
|
||||
* the next transfer. It is the responsibility of the upper layer to
|
||||
* have dealt with whatever caused the error.
|
||||
*/
|
||||
if ((le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK) == EP_STATE_HALTED)
|
||||
reset_ep(udev, ep_index);
|
||||
|
||||
ring = virt_dev->eps[ep_index].ring;
|
||||
if (!ring)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* How much data is (potentially) left before the 64KB boundary?
|
||||
* XHCI Spec puts restriction( TABLE 49 and 6.4.1 section of XHCI Spec)
|
||||
|
@ -633,7 +698,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
|
|||
* we send request in more than 1 TRB by chaining them.
|
||||
*/
|
||||
running_total = TRB_MAX_BUFF_SIZE -
|
||||
(lower_32_bits(val_64) & (TRB_MAX_BUFF_SIZE - 1));
|
||||
(lower_32_bits(buf_64) & (TRB_MAX_BUFF_SIZE - 1));
|
||||
trb_buff_len = running_total;
|
||||
running_total &= TRB_MAX_BUFF_SIZE - 1;
|
||||
|
||||
|
@ -678,7 +743,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
|
|||
* that the buffer should not span 64KB boundary. if so
|
||||
* we send request in more than 1 TRB by chaining them.
|
||||
*/
|
||||
addr = val_64;
|
||||
addr = buf_64;
|
||||
|
||||
if (trb_buff_len > length)
|
||||
trb_buff_len = length;
|
||||
|
@ -744,7 +809,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
|
|||
giveback_first_trb(udev, ep_index, start_cycle, start_trb);
|
||||
|
||||
again:
|
||||
event = xhci_wait_for_event(ctrl, TRB_TRANSFER);
|
||||
event = xhci_wait_for_event_timeout(ctrl, TRB_TRANSFER, timeout);
|
||||
if (!event) {
|
||||
debug("XHCI bulk transfer timed out, aborting...\n");
|
||||
abort_td(udev, ep_index);
|
||||
|
@ -754,7 +819,7 @@ again:
|
|||
}
|
||||
|
||||
if ((uintptr_t)(le64_to_cpu(event->trans_event.buffer)) !=
|
||||
(uintptr_t)xhci_virt_to_bus(ctrl, last_transfer_trb_addr)) {
|
||||
(uintptr_t)last_transfer_trb_addr) {
|
||||
available_length -=
|
||||
(int)EVENT_TRB_LEN(le32_to_cpu(event->trans_event.transfer_len));
|
||||
xhci_acknowledge_event(ctrl);
|
||||
|
@ -768,10 +833,45 @@ again:
|
|||
record_transfer_result(udev, event, available_length);
|
||||
xhci_acknowledge_event(ctrl);
|
||||
xhci_inval_cache((uintptr_t)buffer, length);
|
||||
xhci_dma_unmap(ctrl, buf_64, length);
|
||||
|
||||
return (udev->status != USB_ST_NOT_PROC) ? 0 : -1;
|
||||
}
|
||||
|
||||
/**** Bulk, Interrupt and Control transfer methods ****/
|
||||
/**
|
||||
* Queues up the BULK Request
|
||||
*
|
||||
* @param udev pointer to the USB device structure
|
||||
* @param pipe contains the DIR_IN or OUT , devnum
|
||||
* @param length length of the buffer
|
||||
* @param buffer buffer to be read/written based on the request
|
||||
* Return: returns 0 if successful else -1 on failure
|
||||
*/
|
||||
int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
|
||||
int length, void *buffer)
|
||||
{
|
||||
return xhci_normal_tx_internal(udev, pipe, length, buffer, XHCI_TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues up the INTR Request
|
||||
*
|
||||
* @param udev pointer to the USB device structure
|
||||
* @param pipe contains the DIR_IN or OUT , devnum
|
||||
* @param length length of the buffer
|
||||
* @param buffer buffer to be read/written based on the request
|
||||
* @param nonblock non-blocking flag, useful for keyboard intrupt
|
||||
* Return: returns 0 if successful else -1 on failure
|
||||
*/
|
||||
int xhci_intr_tx(struct usb_device *udev, unsigned long pipe,
|
||||
int length, void *buffer, bool nonblock)
|
||||
{
|
||||
unsigned long timeout;
|
||||
timeout = nonblock ? XHCI_NONBLOCK_INTR_TIMEOUT : USB_TIMEOUT_MS(pipe);
|
||||
return xhci_normal_tx_internal(udev, pipe, length, buffer, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues up the Control Transfer Request
|
||||
*
|
||||
|
@ -811,6 +911,8 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
|
|||
ep_index = usb_pipe_ep_index(pipe);
|
||||
|
||||
ep_ring = virt_dev->eps[ep_index].ring;
|
||||
if (!ep_ring)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Check to see if the max packet size for the default control
|
||||
|
@ -911,7 +1013,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
|
|||
if (length > 0) {
|
||||
if (req->requesttype & USB_DIR_IN)
|
||||
field |= TRB_DIR_IN;
|
||||
buf_64 = xhci_virt_to_bus(ctrl, buffer);
|
||||
buf_64 = xhci_dma_map(ctrl, buffer, length);
|
||||
|
||||
trb_fields[0] = lower_32_bits(buf_64);
|
||||
trb_fields[1] = upper_32_bits(buf_64);
|
||||
|
@ -961,8 +1063,10 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
|
|||
}
|
||||
|
||||
/* Invalidate buffer to make it available to usb-core */
|
||||
if (length > 0)
|
||||
if (length > 0) {
|
||||
xhci_inval_cache((uintptr_t)buffer, length);
|
||||
xhci_dma_unmap(ctrl, buf_64, length);
|
||||
}
|
||||
|
||||
if (GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len))
|
||||
== COMP_SHORT_TX) {
|
||||
|
|
|
@ -448,9 +448,12 @@ static int xhci_configure_endpoints(struct usb_device *udev, bool ctx_change)
|
|||
in_ctx = virt_dev->in_ctx;
|
||||
|
||||
xhci_flush_cache((uintptr_t)in_ctx->bytes, in_ctx->size);
|
||||
xhci_queue_command(ctrl, in_ctx->bytes, udev->slot_id, 0,
|
||||
xhci_queue_command(ctrl, in_ctx->dma, udev->slot_id, 0,
|
||||
ctx_change ? TRB_EVAL_CONTEXT : TRB_CONFIG_EP);
|
||||
event = xhci_wait_for_event(ctrl, TRB_COMPLETION);
|
||||
if (!event)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags))
|
||||
!= udev->slot_id);
|
||||
|
||||
|
@ -472,67 +475,34 @@ static int xhci_configure_endpoints(struct usb_device *udev, bool ctx_change)
|
|||
}
|
||||
|
||||
/**
|
||||
* Configure the endpoint, programming the device contexts.
|
||||
* Fill endpoint contexts for interface descriptor ifdesc.
|
||||
*
|
||||
* @param udev pointer to the USB device structure
|
||||
* Return: returns the status of the xhci_configure_endpoints
|
||||
* @param udev pointer to the USB device structure
|
||||
* @param ctrl pointer to the xhci pravte device structure
|
||||
* @param virt_dev pointer to the xhci virtual device structure
|
||||
* @param ifdesc pointer to the USB interface config descriptor
|
||||
* Return: returns the status of xhci_init_ep_contexts_if
|
||||
*/
|
||||
static int xhci_set_configuration(struct usb_device *udev)
|
||||
static int xhci_init_ep_contexts_if(struct usb_device *udev,
|
||||
struct xhci_ctrl *ctrl,
|
||||
struct xhci_virt_device *virt_dev,
|
||||
struct usb_interface *ifdesc
|
||||
)
|
||||
{
|
||||
struct xhci_container_ctx *in_ctx;
|
||||
struct xhci_container_ctx *out_ctx;
|
||||
struct xhci_input_control_ctx *ctrl_ctx;
|
||||
struct xhci_slot_ctx *slot_ctx;
|
||||
struct xhci_ep_ctx *ep_ctx[MAX_EP_CTX_NUM];
|
||||
int cur_ep;
|
||||
int max_ep_flag = 0;
|
||||
int ep_index;
|
||||
unsigned int dir;
|
||||
unsigned int ep_type;
|
||||
struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
|
||||
int num_of_ep;
|
||||
int ep_flag = 0;
|
||||
u64 trb_64 = 0;
|
||||
int slot_id = udev->slot_id;
|
||||
struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
|
||||
struct usb_interface *ifdesc;
|
||||
u32 max_esit_payload;
|
||||
unsigned int interval;
|
||||
unsigned int mult;
|
||||
unsigned int max_burst;
|
||||
unsigned int avg_trb_len;
|
||||
unsigned int err_count = 0;
|
||||
int num_of_ep = ifdesc->no_of_ep;
|
||||
|
||||
out_ctx = virt_dev->out_ctx;
|
||||
in_ctx = virt_dev->in_ctx;
|
||||
|
||||
num_of_ep = udev->config.if_desc[0].no_of_ep;
|
||||
ifdesc = &udev->config.if_desc[0];
|
||||
|
||||
ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
|
||||
/* Initialize the input context control */
|
||||
ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
|
||||
ctrl_ctx->drop_flags = 0;
|
||||
|
||||
/* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
|
||||
for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
|
||||
ep_flag = xhci_get_ep_index(&ifdesc->ep_desc[cur_ep]);
|
||||
ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
|
||||
if (max_ep_flag < ep_flag)
|
||||
max_ep_flag = ep_flag;
|
||||
}
|
||||
|
||||
xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
|
||||
|
||||
/* slot context */
|
||||
xhci_slot_copy(ctrl, in_ctx, out_ctx);
|
||||
slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx);
|
||||
slot_ctx->dev_info &= ~(cpu_to_le32(LAST_CTX_MASK));
|
||||
slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(max_ep_flag + 1) | 0);
|
||||
|
||||
xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
|
||||
|
||||
/* filling up ep contexts */
|
||||
for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
|
||||
struct usb_endpoint_descriptor *endpt_desc = NULL;
|
||||
struct usb_ss_ep_comp_descriptor *ss_ep_comp_desc = NULL;
|
||||
|
@ -558,7 +528,8 @@ static int xhci_set_configuration(struct usb_device *udev)
|
|||
avg_trb_len = max_esit_payload;
|
||||
|
||||
ep_index = xhci_get_ep_index(endpt_desc);
|
||||
ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, in_ctx, ep_index);
|
||||
ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, virt_dev->in_ctx,
|
||||
ep_index);
|
||||
|
||||
/* Allocate the ep rings */
|
||||
virt_dev->eps[ep_index].ring = xhci_ring_alloc(ctrl, 1, true);
|
||||
|
@ -585,7 +556,8 @@ static int xhci_set_configuration(struct usb_device *udev)
|
|||
cpu_to_le32(MAX_BURST(max_burst) |
|
||||
ERROR_COUNT(err_count));
|
||||
|
||||
trb_64 = xhci_virt_to_bus(ctrl, virt_dev->eps[ep_index].ring->enqueue);
|
||||
trb_64 = xhci_trb_virt_to_dma(virt_dev->eps[ep_index].ring->enq_seg,
|
||||
virt_dev->eps[ep_index].ring->enqueue);
|
||||
ep_ctx[ep_index]->deq = cpu_to_le64(trb_64 |
|
||||
virt_dev->eps[ep_index].ring->cycle_state);
|
||||
|
||||
|
@ -610,6 +582,72 @@ static int xhci_set_configuration(struct usb_device *udev)
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the endpoint, programming the device contexts.
|
||||
*
|
||||
* @param udev pointer to the USB device structure
|
||||
* Return: returns the status of the xhci_configure_endpoints
|
||||
*/
|
||||
static int xhci_set_configuration(struct usb_device *udev)
|
||||
{
|
||||
struct xhci_container_ctx *out_ctx;
|
||||
struct xhci_container_ctx *in_ctx;
|
||||
struct xhci_input_control_ctx *ctrl_ctx;
|
||||
struct xhci_slot_ctx *slot_ctx;
|
||||
int err;
|
||||
int cur_ep;
|
||||
int max_ep_flag = 0;
|
||||
struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
|
||||
int num_of_ep;
|
||||
int ep_flag = 0;
|
||||
int slot_id = udev->slot_id;
|
||||
struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
|
||||
struct usb_interface *ifdesc;
|
||||
unsigned int ifnum;
|
||||
unsigned int max_ifnum = min((unsigned int)USB_MAX_ACTIVE_INTERFACES,
|
||||
(unsigned int)udev->config.no_of_if);
|
||||
|
||||
out_ctx = virt_dev->out_ctx;
|
||||
in_ctx = virt_dev->in_ctx;
|
||||
|
||||
ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
|
||||
/* Initialize the input context control */
|
||||
ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
|
||||
ctrl_ctx->drop_flags = 0;
|
||||
|
||||
for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
|
||||
ifdesc = &udev->config.if_desc[ifnum];
|
||||
num_of_ep = ifdesc->no_of_ep;
|
||||
/* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
|
||||
for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
|
||||
ep_flag = xhci_get_ep_index(&ifdesc->ep_desc[cur_ep]);
|
||||
ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
|
||||
if (max_ep_flag < ep_flag)
|
||||
max_ep_flag = ep_flag;
|
||||
}
|
||||
}
|
||||
|
||||
xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
|
||||
|
||||
/* slot context */
|
||||
xhci_slot_copy(ctrl, in_ctx, out_ctx);
|
||||
slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx);
|
||||
slot_ctx->dev_info &= ~(cpu_to_le32(LAST_CTX_MASK));
|
||||
slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(max_ep_flag + 1) | 0);
|
||||
|
||||
xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
|
||||
|
||||
/* filling up ep contexts */
|
||||
for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
|
||||
ifdesc = &udev->config.if_desc[ifnum];
|
||||
err = xhci_init_ep_contexts_if(udev, ctrl, virt_dev, ifdesc);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
return xhci_configure_endpoints(udev, false);
|
||||
}
|
||||
|
||||
|
@ -620,7 +658,7 @@ static int xhci_set_configuration(struct usb_device *udev)
|
|||
* @param udev pointer to the Device Data Structure
|
||||
* Return: 0 if successful else error code on failure
|
||||
*/
|
||||
static int xhci_address_device(struct usb_device *udev, int root_portnr)
|
||||
static int xhci_address_device(struct usb_device *udev, int root_portnr, bool do_address)
|
||||
{
|
||||
int ret = 0;
|
||||
struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
|
||||
|
@ -636,15 +674,32 @@ static int xhci_address_device(struct usb_device *udev, int root_portnr)
|
|||
* This is the first Set Address since device plug-in
|
||||
* so setting up the slot context.
|
||||
*/
|
||||
debug("Setting up addressable devices %p\n", ctrl->dcbaa);
|
||||
xhci_setup_addressable_virt_dev(ctrl, udev, root_portnr);
|
||||
debug("Setting up addressable devices %p, BSR: %d\n", ctrl->dcbaa, !do_address);
|
||||
slot_ctx = xhci_get_slot_ctx(ctrl, virt_dev->in_ctx);
|
||||
/*
|
||||
* If this is the first Set Address since device plug-in or
|
||||
* virt_device realloaction after a resume with an xHCI power loss,
|
||||
* then set up the slot context.
|
||||
*/
|
||||
if (!slot_ctx->dev_info)
|
||||
xhci_setup_addressable_virt_dev(ctrl, udev, root_portnr);
|
||||
/* Otherwise, update the control endpoint ring enqueue pointer. */
|
||||
else
|
||||
xhci_copy_ep0_dequeue_into_input_ctx(ctrl, udev);
|
||||
|
||||
ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx);
|
||||
ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
|
||||
ctrl_ctx->drop_flags = 0;
|
||||
|
||||
xhci_queue_command(ctrl, (void *)ctrl_ctx, slot_id, 0, TRB_ADDR_DEV);
|
||||
if (!do_address)
|
||||
xhci_queue_command_extra_flags(ctrl, virt_dev->in_ctx->dma,
|
||||
slot_id, 0, TRB_ADDR_DEV, TRB_BSR);
|
||||
else
|
||||
xhci_queue_command(ctrl, virt_dev->in_ctx->dma,
|
||||
slot_id, 0, TRB_ADDR_DEV);
|
||||
event = xhci_wait_for_event(ctrl, TRB_COMPLETION);
|
||||
if (!event)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != slot_id);
|
||||
|
||||
switch (GET_COMP_CODE(le32_to_cpu(event->event_cmd.status))) {
|
||||
|
@ -707,6 +762,9 @@ static int _xhci_alloc_device(struct usb_device *udev)
|
|||
struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
|
||||
union xhci_trb *event;
|
||||
int ret;
|
||||
struct usb_device *uhop;
|
||||
struct udevice *hub;
|
||||
int root_portnr = 0;
|
||||
|
||||
/*
|
||||
* Root hub will be first device to be initailized.
|
||||
|
@ -718,8 +776,11 @@ static int _xhci_alloc_device(struct usb_device *udev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
xhci_queue_command(ctrl, NULL, 0, 0, TRB_ENABLE_SLOT);
|
||||
xhci_queue_command(ctrl, 0, 0, 0, TRB_ENABLE_SLOT);
|
||||
event = xhci_wait_for_event(ctrl, TRB_COMPLETION);
|
||||
if (!event)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
BUG_ON(GET_COMP_CODE(le32_to_cpu(event->event_cmd.status))
|
||||
!= COMP_SUCCESS);
|
||||
|
||||
|
@ -737,6 +798,21 @@ static int _xhci_alloc_device(struct usb_device *udev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hub = udev->dev;
|
||||
if (device_get_uclass_id(hub) == UCLASS_USB_HUB) {
|
||||
/* Figure out our port number on the root hub */
|
||||
if (usb_hub_is_root_hub(hub)) {
|
||||
root_portnr = udev->portnr;
|
||||
} else {
|
||||
while (!usb_hub_is_root_hub(hub->parent))
|
||||
hub = hub->parent;
|
||||
uhop = dev_get_parent_priv(hub);
|
||||
root_portnr = uhop->portnr;
|
||||
}
|
||||
}
|
||||
|
||||
xhci_address_device(udev, root_portnr, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1114,7 +1190,7 @@ static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe,
|
|||
* (at most) one TD. A TD (comprised of sg list entries) can
|
||||
* take several service intervals to transmit.
|
||||
*/
|
||||
return xhci_bulk_tx(udev, pipe, length, buffer);
|
||||
return xhci_intr_tx(udev, pipe, length, buffer, nonblock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1165,7 +1241,7 @@ static int _xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe,
|
|||
|
||||
if (setup->request == USB_REQ_SET_ADDRESS &&
|
||||
(setup->requesttype & USB_TYPE_MASK) == USB_TYPE_STANDARD)
|
||||
return xhci_address_device(udev, root_portnr);
|
||||
return xhci_address_device(udev, root_portnr, true);
|
||||
|
||||
if (setup->request == USB_REQ_SET_CONFIGURATION &&
|
||||
(setup->requesttype & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
|
||||
|
@ -1396,12 +1472,12 @@ int xhci_register(struct udevice *dev, struct xhci_hccr *hccr,
|
|||
ctrl->dev = dev;
|
||||
|
||||
/*
|
||||
* XHCI needs to issue a Address device command to setup
|
||||
* proper device context structures, before it can interact
|
||||
* with the device. So a get_descriptor will fail before any
|
||||
* of that is done for XHCI unlike EHCI.
|
||||
* XHCI support get_descriptor before Address device command after
|
||||
* we support send Address device command with BSR to setup proper
|
||||
* device context structures without actually sending Set Address to
|
||||
* device, so enable it.
|
||||
*/
|
||||
priv->desc_before_addr = false;
|
||||
priv->desc_before_addr = true;
|
||||
|
||||
ret = xhci_reset(hcor);
|
||||
if (ret)
|
||||
|
|
|
@ -8,6 +8,7 @@ obj-y += video/spacemit_video_tx.o \
|
|||
|
||||
obj-y += video/lcd/lcd_icnl9911c.o
|
||||
obj-y += video/lcd/lcd_icnl9951r.o
|
||||
obj-y += video/lcd/lcd_jd9365dah3.o
|
||||
obj-y += video/lcd/lcd_gx09inx101.o
|
||||
obj-y += video/lcd/lcd_lt8911ext_edp_1080p.o
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ int lcd_mipi_probe(void);
|
|||
int lcd_icnl9911c_init(void);
|
||||
int lcd_icnl9951r_init(void);
|
||||
int lcd_gx09inx101_init(void);
|
||||
int lcd_jd9365dah3_init(void);
|
||||
int lcd_lt8911ext_edp_1080p_init(void);
|
||||
|
||||
#endif /*_SPACEMIT_DSI_COMMON_H_*/
|
||||
|
|
|
@ -160,6 +160,7 @@ struct spacemit_panel_priv {
|
|||
struct gpio_desc bl;
|
||||
struct gpio_desc enable;
|
||||
struct gpio_desc reset;
|
||||
struct udevice *backlight;
|
||||
bool dcp_valid;
|
||||
bool dcn_valid;
|
||||
bool avee_valid;
|
||||
|
|
341
drivers/video/spacemit/dsi/video/lcd/lcd_jd9365dah3.c
Normal file
341
drivers/video/spacemit/dsi/video/lcd/lcd_jd9365dah3.c
Normal file
|
@ -0,0 +1,341 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2023 Spacemit Co., Ltd.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include "../../include/spacemit_dsi_common.h"
|
||||
#include "../../include/spacemit_video_tx.h"
|
||||
#include <linux/delay.h>
|
||||
|
||||
#define UNLOCK_DELAY 0
|
||||
|
||||
struct spacemit_mode_modeinfo jd9365dah3_spacemit_modelist[] = {
|
||||
{
|
||||
.name = "800x1280-60",
|
||||
.refresh = 60,
|
||||
.xres = 800,
|
||||
.yres = 1280,
|
||||
.real_xres = 800,
|
||||
.real_yres = 1280,
|
||||
.left_margin = 20,
|
||||
.right_margin = 40,
|
||||
.hsync_len = 20,
|
||||
.upper_margin = 8,
|
||||
.lower_margin = 20,
|
||||
.vsync_len = 4,
|
||||
.hsync_invert = 0,
|
||||
.vsync_invert = 0,
|
||||
.invert_pixclock = 0,
|
||||
.pixclock_freq = 87*1000,
|
||||
.pix_fmt_out = OUTFMT_RGB888,
|
||||
.width = 108,
|
||||
.height = 172,
|
||||
},
|
||||
};
|
||||
|
||||
struct spacemit_mipi_info jd9365dah3_mipi_info = {
|
||||
.height = 1280,
|
||||
.width = 800,
|
||||
.hfp = 40, /* unit: pixel */
|
||||
.hbp = 20,
|
||||
.hsync = 20,
|
||||
.vfp = 20, /* unit: line */
|
||||
.vbp = 8,
|
||||
.vsync = 4,
|
||||
.fps = 60,
|
||||
|
||||
.work_mode = SPACEMIT_DSI_MODE_VIDEO, /*command_mode, video_mode*/
|
||||
.rgb_mode = DSI_INPUT_DATA_RGB_MODE_888,
|
||||
.lane_number = 4,
|
||||
.phy_bit_clock = 614400000,
|
||||
.phy_esc_clock = 51200000,
|
||||
.split_enable = 0,
|
||||
.eotp_enable = 0,
|
||||
|
||||
.burst_mode = DSI_BURST_MODE_BURST,
|
||||
};
|
||||
|
||||
static struct spacemit_dsi_cmd_desc jd9365dah3_set_id_cmds[] = {
|
||||
{SPACEMIT_DSI_SET_MAX_PKT_SIZE, SPACEMIT_DSI_LP_MODE, UNLOCK_DELAY, 1, {0x01}},
|
||||
};
|
||||
|
||||
static struct spacemit_dsi_cmd_desc jd9365dah3_read_id_cmds[] = {
|
||||
{SPACEMIT_DSI_GENERIC_READ1, SPACEMIT_DSI_LP_MODE, UNLOCK_DELAY, 1, {0x04}},
|
||||
};
|
||||
|
||||
static struct spacemit_dsi_cmd_desc jd9365dah3_set_power_cmds[] = {
|
||||
{SPACEMIT_DSI_SET_MAX_PKT_SIZE, SPACEMIT_DSI_HS_MODE, UNLOCK_DELAY, 1, {0x1}},
|
||||
};
|
||||
|
||||
static struct spacemit_dsi_cmd_desc jd9365dah3_read_power_cmds[] = {
|
||||
{SPACEMIT_DSI_GENERIC_READ1, SPACEMIT_DSI_HS_MODE, UNLOCK_DELAY, 1, {0xA}},
|
||||
};
|
||||
|
||||
static struct spacemit_dsi_cmd_desc jd9365dah3_init_cmds[] = {
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0xE0, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0xE1, 0x93}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0xE2, 0x65}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0xE3, 0xF8}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x80, 0x03}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0xE0, 0x01}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x00, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x01, 0x40}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x03, 0x10}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x04, 0x47}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x0C, 0x74}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x17, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x18, 0xD7}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x19, 0x01}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x1A, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x1B, 0xD7}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x1C, 0x01}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x24, 0xFE}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x25, 0x40}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x35, 0x28}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x37, 0x69}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x38, 0x05}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x39, 0x08}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x3A, 0x0A}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x3C, 0x78}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x3D, 0xFF}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x3E, 0xFF}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x3F, 0xFF}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x40, 0x06}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x41, 0xA0}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x43, 0x14}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x44, 0x08}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x45, 0x20}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x4B, 0x04}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x55, 0x02}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x57, 0xA9}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x59, 0x0A}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x5A, 0x2D}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x5B, 0x19}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x5C, 0x15}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x5D, 0x7C}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x5E, 0x6C}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x5F, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x60, 0x54}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x61, 0x50}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x62, 0x43}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x63, 0x46}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x64, 0x2F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x65, 0x48}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x66, 0x46}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x67, 0x44}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x68, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x69, 0x49}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x6A, 0x4C}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x6B, 0x3D}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x6C, 0x36}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x6D, 0x29}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x6E, 0x18}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x6F, 0x0C}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x70, 0x7C}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x71, 0x6C}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x72, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x73, 0x54}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x74, 0x50}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x75, 0x43}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x76, 0x46}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x77, 0x2F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x78, 0x48}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x79, 0x46}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x7A, 0x44}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x7B, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x7C, 0x49}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x7D, 0x4C}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x7E, 0x3D}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x7F, 0x36}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x80, 0x29}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x81, 0x18}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x82, 0x0C}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0xE0, 0x02}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x00, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x01, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x02, 0x52}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x03, 0x51}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x04, 0x50}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x05, 0x4B}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x06, 0x4A}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x07, 0x49}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x08, 0x48}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x09, 0x47}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x0A, 0x46}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x0B, 0x45}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x0C, 0x44}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x0D, 0x40}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x0E, 0x41}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x0F, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x10, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x11, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x12, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x13, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x14, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x15, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x16, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x17, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x18, 0x52}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x19, 0x51}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x1A, 0x50}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x1B, 0x4B}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x1C, 0x4A}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x1D, 0x49}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x1E, 0x48}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x1F, 0x47}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x20, 0x46}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x21, 0x45}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x22, 0x44}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x23, 0x40}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x24, 0x41}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x25, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x26, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x27, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x28, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x29, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x2A, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x2B, 0x5F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x2C, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x2D, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x2E, 0x12}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x2F, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x30, 0x01}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x31, 0x08}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x32, 0x09}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x33, 0x0A}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x34, 0x0B}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x35, 0x04}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x36, 0x05}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x37, 0x06}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x38, 0x07}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x39, 0x11}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x3A, 0x10}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x3B, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x3C, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x3D, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x3E, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x3F, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x40, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x41, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x42, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x43, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x44, 0x12}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x45, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x46, 0x01}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x47, 0x08}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x48, 0x09}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x49, 0x0A}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x4A, 0x0B}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x4B, 0x04}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x4C, 0x05}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x4D, 0x06}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x4E, 0x07}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x4F, 0x11}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x50, 0x10}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x51, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x52, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x53, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x54, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x55, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x56, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x57, 0x1F}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x58, 0x40}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x59, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x5A, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x5B, 0x10}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x5C, 0x02}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x5D, 0x50}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x5E, 0x01}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x5F, 0x02}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x60, 0x50}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x61, 0x05}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x62, 0x02}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x63, 0x04}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x64, 0x64}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x65, 0x65}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x66, 0x08}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x67, 0x73}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x68, 0x04}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x69, 0x04}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x6A, 0x64}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x6B, 0x08}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x6C, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x6D, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x6E, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x6F, 0x88}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x70, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x71, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x72, 0x06}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x73, 0x7B}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x74, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x75, 0x0C}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x76, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x77, 0x5D}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x78, 0x17}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x79, 0x10}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x7A, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x7B, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x7C, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x7D, 0x03}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x7E, 0x7B}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0xE0, 0x04}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x2C, 0x6B}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x35, 0x0A}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0xE0, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 120, 2, {0x11, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 5, 2, {0x29, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_LWRITE, SPACEMIT_DSI_LP_MODE, 0, 2, {0x35, 0x00}},
|
||||
};
|
||||
|
||||
static struct spacemit_dsi_cmd_desc jd9365dah3_sleep_out_cmds[] = {
|
||||
{SPACEMIT_DSI_DCS_SWRITE,SPACEMIT_DSI_LP_MODE,120,2,{0x11, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_SWRITE,SPACEMIT_DSI_LP_MODE,50,2,{0x29, 0x00}},
|
||||
};
|
||||
|
||||
static struct spacemit_dsi_cmd_desc jd9365dah3_sleep_in_cmds[] = {
|
||||
{SPACEMIT_DSI_DCS_SWRITE,SPACEMIT_DSI_LP_MODE,50,2,{0x28, 0x00}},
|
||||
{SPACEMIT_DSI_DCS_SWRITE,SPACEMIT_DSI_LP_MODE,120,2,{0x10, 0x00}},
|
||||
};
|
||||
|
||||
|
||||
struct lcd_mipi_panel_info lcd_jd9365dah3 = {
|
||||
.lcd_name = "jd9365dah3",
|
||||
.lcd_id = 0x9365,
|
||||
.panel_id0 = 0x93,
|
||||
.power_value = 0x18,
|
||||
.panel_type = LCD_MIPI,
|
||||
.width_mm = 108,
|
||||
.height_mm = 172,
|
||||
.dft_pwm_bl = 128,
|
||||
.set_id_cmds_num = ARRAY_SIZE(jd9365dah3_set_id_cmds),
|
||||
.read_id_cmds_num = ARRAY_SIZE(jd9365dah3_read_id_cmds),
|
||||
.init_cmds_num = ARRAY_SIZE(jd9365dah3_init_cmds),
|
||||
.set_power_cmds_num = ARRAY_SIZE(jd9365dah3_set_power_cmds),
|
||||
.read_power_cmds_num = ARRAY_SIZE(jd9365dah3_read_power_cmds),
|
||||
.sleep_out_cmds_num = ARRAY_SIZE(jd9365dah3_sleep_out_cmds),
|
||||
.sleep_in_cmds_num = ARRAY_SIZE(jd9365dah3_sleep_in_cmds),
|
||||
//.drm_modeinfo = jd9365dah3_modelist,
|
||||
.spacemit_modeinfo = jd9365dah3_spacemit_modelist,
|
||||
.mipi_info = &jd9365dah3_mipi_info,
|
||||
.set_id_cmds = jd9365dah3_set_id_cmds,
|
||||
.read_id_cmds = jd9365dah3_read_id_cmds,
|
||||
.set_power_cmds = jd9365dah3_set_power_cmds,
|
||||
.read_power_cmds = jd9365dah3_read_power_cmds,
|
||||
.init_cmds = jd9365dah3_init_cmds,
|
||||
.sleep_out_cmds = jd9365dah3_sleep_out_cmds,
|
||||
.sleep_in_cmds = jd9365dah3_sleep_in_cmds,
|
||||
.bitclk_sel = 3,
|
||||
.bitclk_div = 1,
|
||||
.pxclk_sel = 2,
|
||||
.pxclk_div = 6,
|
||||
};
|
||||
|
||||
int lcd_jd9365dah3_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lcd_mipi_register_panel(&lcd_jd9365dah3);
|
||||
return ret;
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
#include <asm/global_data.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <backlight.h>
|
||||
|
||||
#define PANEL_NUM_MAX 5
|
||||
|
||||
|
@ -354,13 +354,24 @@ static int lcd_bl_enable(struct video_tx_device *dev, bool enable)
|
|||
struct lcd_mipi_tx_data *video_tx_client =
|
||||
video_tx_get_drvdata(dev);
|
||||
struct spacemit_panel_priv *priv = video_tx_client->priv;
|
||||
int ret;
|
||||
|
||||
if (priv->bl_valid) {
|
||||
|
||||
if (enable)
|
||||
dm_gpio_set_value(&priv->bl, 1);
|
||||
else
|
||||
dm_gpio_set_value(&priv->bl, 0);
|
||||
if (enable) {
|
||||
ret = backlight_set_brightness(priv->backlight, BACKLIGHT_DEFAULT);
|
||||
pr_debug("%s: set brightness done, ret = %d\n", __func__, ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = backlight_enable(priv->backlight);
|
||||
pr_debug("%s: enable backlight done, ret = %d\n", __func__, ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
ret = backlight_set_brightness(priv->backlight, BACKLIGHT_OFF);
|
||||
pr_debug("%s: shutdown backlight done, ret = %d\n", __func__, ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -444,6 +455,10 @@ int lcd_mipi_probe(void)
|
|||
tx_device_client.panel_type = LCD_MIPI;
|
||||
tx_device.panel_type = tx_device_client.panel_type;
|
||||
lcd_icnl9951r_init();
|
||||
} else if(strcmp("jd9365dah3", priv->panel_name) == 0) {
|
||||
tx_device_client.panel_type = LCD_MIPI;
|
||||
tx_device.panel_type = tx_device_client.panel_type;
|
||||
lcd_jd9365dah3_init();
|
||||
} else {
|
||||
// lcd_icnl9911c_init();
|
||||
lcd_gx09inx101_init();
|
||||
|
@ -513,13 +528,14 @@ static int spacemit_panel_of_to_plat(struct udevice *dev)
|
|||
}
|
||||
|
||||
|
||||
ret = gpio_request_by_name(dev, "bl-gpios", 0, &priv->bl,
|
||||
GPIOD_IS_OUT);
|
||||
ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
|
||||
"backlight", &priv->backlight);
|
||||
if (ret) {
|
||||
pr_debug("%s: Warning: cannot get bl GPIO: ret=%d\n",
|
||||
__func__, ret);
|
||||
pr_debug("%s: Warning: cannot get backlight pwm: ret = %d\n",
|
||||
__func__, ret);
|
||||
priv->bl_valid = false;
|
||||
} else {
|
||||
pr_debug("apply for pwm successfully\n");
|
||||
priv->bl_valid = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <display.h>
|
||||
#include <cpu_func.h>
|
||||
#include <dm.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <dm/device.h>
|
||||
|
@ -306,12 +307,15 @@ static int spacemit_display_init(struct udevice *dev, ulong fbbase, ofnode ep_no
|
|||
return ret;
|
||||
}
|
||||
|
||||
hdmi_dpu_init(&hdmi_1080p_modeinfo, fbbase);
|
||||
|
||||
uc_priv->xsize = 1920;
|
||||
uc_priv->ysize = 1080;
|
||||
|
||||
pr_info("fb=%lx, size=%d %d\n", fbbase, uc_priv->xsize, uc_priv->ysize);
|
||||
pr_info("fb=%lx, size=%dx%d\n", fbbase, uc_priv->xsize, uc_priv->ysize);
|
||||
|
||||
memset((void *)fbbase, 0, uc_priv->xsize * uc_priv->ysize * VNBYTES(uc_priv->bpix));
|
||||
flush_cache(fbbase, uc_priv->xsize * uc_priv->ysize * VNBYTES(uc_priv->bpix));
|
||||
|
||||
hdmi_dpu_init(&hdmi_1080p_modeinfo, fbbase);
|
||||
|
||||
return 0;
|
||||
} else if (dpu_id == DPU_MODE_MIPI) {
|
||||
|
@ -356,6 +360,11 @@ static int spacemit_display_init(struct udevice *dev, ulong fbbase, ofnode ep_no
|
|||
uc_priv->xsize = spacemit_mode->xres;
|
||||
uc_priv->ysize = spacemit_mode->yres;
|
||||
|
||||
pr_info("fb=%lx, size=%dx%d\n", fbbase, uc_priv->xsize, uc_priv->ysize);
|
||||
|
||||
memset((void *)fbbase, 0, uc_priv->xsize * uc_priv->ysize * VNBYTES(uc_priv->bpix));
|
||||
flush_cache(fbbase, uc_priv->xsize * uc_priv->ysize * VNBYTES(uc_priv->bpix));
|
||||
|
||||
pr_debug("%s: panel type %d\n", __func__, fbi.tx->panel_type);
|
||||
|
||||
if (fbi.tx->panel_type == LCD_MIPI) {
|
||||
|
@ -393,8 +402,6 @@ static int spacemit_display_init(struct udevice *dev, ulong fbbase, ofnode ep_no
|
|||
pr_info("%s: Failed to find panel\n", __func__);
|
||||
}
|
||||
|
||||
pr_info("fb=%lx, size=%d %d\n", fbbase, uc_priv->xsize, uc_priv->ysize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ struct pmic_wdt_priv {
|
|||
fdt_addr_t base;
|
||||
fdt_addr_t pwr_ctrl0;
|
||||
fdt_addr_t pwr_ctrl2;
|
||||
fdt_addr_t alive_reg;
|
||||
enum pmic_model model;
|
||||
};
|
||||
|
||||
|
@ -199,6 +200,14 @@ static int pmic_wdt_expire_now(struct udevice *dev, ulong flags)
|
|||
|
||||
switch (priv->model) {
|
||||
case PMIC_MODEL_SPM8821:
|
||||
|
||||
/* set the reset flag for shutdown charging or not */
|
||||
ret = pmic_reg_read(priv->pmic_dev, priv->alive_reg);
|
||||
if (ret < 0) return ret;
|
||||
reg_val = ret | (1 << SYS_REBOOT_FLAG_BIT);
|
||||
ret = pmic_reg_write(priv->pmic_dev, priv->alive_reg, reg_val);
|
||||
if (ret) return ret;
|
||||
|
||||
/* Set SW_RST bit of PWR_CTRL2 */
|
||||
ret = pmic_reg_read(priv->pmic_dev, priv->pwr_ctrl2);
|
||||
if (ret < 0) return ret;
|
||||
|
@ -234,6 +243,7 @@ static int pmic_wdt_probe(struct udevice *dev)
|
|||
priv->base = SPM8821_WDT_CTRL;
|
||||
priv->pwr_ctrl0 = SPM8821_PWR_CTRL0;
|
||||
priv->pwr_ctrl2 = SPM8821_PWR_CTRL2;
|
||||
priv->alive_reg = SPM8821_ALIVE_REGISTER;
|
||||
} else {
|
||||
priv->model = PMIC_MODEL_UNKNOWN;
|
||||
pr_err("Device is not compatible: %s\n", wdt_name);
|
||||
|
|
7
env/Kconfig
vendored
7
env/Kconfig
vendored
|
@ -272,6 +272,13 @@ config ENV_IS_IN_NAND
|
|||
Currently, CONFIG_ENV_OFFSET_REDUND is not supported when
|
||||
using CONFIG_ENV_OFFSET_OOB.
|
||||
|
||||
config ENV_IS_IN_NFS
|
||||
bool "Environment is in NFS"
|
||||
depends on NET
|
||||
help
|
||||
This option allows loading the environment from an NFS server
|
||||
when local bootfs is not available.
|
||||
|
||||
config ENV_RANGE
|
||||
hex "Length of the region in which the environment can be written"
|
||||
depends on ENV_IS_IN_NAND
|
||||
|
|
6
fs/fs.c
6
fs/fs.c
|
@ -812,11 +812,11 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[],
|
|||
|
||||
printf("%llu bytes read in %lu ms", len_read, time);
|
||||
if (time > 0) {
|
||||
puts(" (");
|
||||
printf(" (");
|
||||
print_size(div_u64(len_read, time) * 1000, "/s");
|
||||
puts(")");
|
||||
printf(")");
|
||||
}
|
||||
puts("\n");
|
||||
printf("\n");
|
||||
|
||||
env_set_hex("fileaddr", addr);
|
||||
env_set_hex("filesize", len_read);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#define RISCV_MMODE_TIMER_FREQ 24000000
|
||||
#define RISCV_SMODE_TIMER_FREQ 24000000
|
||||
#define RISCV_TIMER_FREQ (RISCV_SMODE_TIMER_FREQ)
|
||||
|
||||
#define CONFIG_IPADDR 10.0.92.253
|
||||
#define CONFIG_SERVERIP 10.0.92.134
|
||||
|
@ -77,6 +78,7 @@
|
|||
#define TLV_CODE_SDK_VERSION 0x40
|
||||
#define TLV_CODE_DDR_CSNUM 0x41
|
||||
#define TLV_CODE_DDR_TYPE 0x42
|
||||
#define TLV_CODE_DDR_DATARATE 0x43
|
||||
|
||||
#define TLV_CODE_PMIC_TYPE 0x80
|
||||
#define TLV_CODE_EEPROM_I2C_INDEX 0x81
|
||||
|
@ -172,11 +174,6 @@ struct boot_storage_op
|
|||
"dtb_addr=" __stringify(DTB_LOAD_ADDR) "\0" \
|
||||
"scriptaddr=0x2c100000\0" \
|
||||
"pxefile_addr_r=0x0c200000\0" \
|
||||
"ipaddr=192.168.1.15\0" \
|
||||
"netmask=255.255.255.0\0" \
|
||||
"serverip=10.0.92.134\0" \
|
||||
"gatewayip=192.168.1.1\0" \
|
||||
"net_data_path=spacemit_flash_file/net_flash_file/\0" \
|
||||
"splashimage=" __stringify(CONFIG_FASTBOOT_BUF_ADDR) "\0" \
|
||||
"splashpos=m,m\0" \
|
||||
"splashfile=bianbu.bmp\0" \
|
||||
|
|
|
@ -37,6 +37,8 @@ enum uclass_id {
|
|||
UCLASS_AUDIO_CODEC, /* Audio codec with control and data path */
|
||||
UCLASS_AXI, /* AXI bus */
|
||||
UCLASS_BLK, /* Block device */
|
||||
UCLASS_BATTERY, /* Battery */
|
||||
UCLASS_CHARGER, /* Charger */
|
||||
UCLASS_BOOTCOUNT, /* Bootcount backing store */
|
||||
UCLASS_BOOTDEV, /* Boot device for locating an OS to boot */
|
||||
UCLASS_BOOTMETH, /* Bootmethod for booting an OS */
|
||||
|
|
|
@ -10,5 +10,6 @@
|
|||
#define K1X_PMU_AUD_PWR_DOMAIN 4
|
||||
#define K1X_PMU_GNSS_PWR_DOMAIN 5
|
||||
#define K1X_PMU_HDMI_PWR_DOMAIN 6
|
||||
#define K1X_PMU_WKUP_EVENT_PWR_DOMAIN 7
|
||||
|
||||
#endif /* __DT_BINDINGS_POWER_DOMAIN_K1X_H */
|
||||
|
|
|
@ -721,6 +721,9 @@ efi_status_t efi_allocate_pool(enum efi_memory_type pool_type,
|
|||
efi_uintn_t size, void **buffer);
|
||||
/* EFI pool memory free function. */
|
||||
efi_status_t efi_free_pool(void *buffer);
|
||||
/* Allocate and retrieve EFI memory map */
|
||||
efi_status_t efi_get_memory_map_alloc(efi_uintn_t *map_size,
|
||||
struct efi_mem_desc **memory_map);
|
||||
/* Returns the EFI memory map */
|
||||
efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
|
||||
struct efi_mem_desc *memory_map,
|
||||
|
|
|
@ -58,8 +58,16 @@ struct flash_volume_image {
|
|||
struct flash_parts_info {
|
||||
char *part_name;
|
||||
char *file_name;
|
||||
/*partition size info, such as 128MiB*/
|
||||
|
||||
/*partition offset info*/
|
||||
u64 part_offset;
|
||||
|
||||
/*partition size info*/
|
||||
u64 part_size;
|
||||
|
||||
/*save partition size to string*/
|
||||
char *size;
|
||||
|
||||
/*use for fsbl, if hidden that gpt would reserve a raw memeory
|
||||
for fsbl and the partition is not available.
|
||||
*/
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef __POWER_BATTERY_H_
|
||||
#define __POWER_BATTERY_H_
|
||||
|
||||
#ifndef CONFIG_DM_BATTERY
|
||||
/* TODO: remove this once all users have been moved over to DM */
|
||||
struct battery {
|
||||
unsigned int version;
|
||||
unsigned int state_of_chrg;
|
||||
|
@ -18,4 +20,41 @@ struct battery {
|
|||
};
|
||||
|
||||
int power_bat_init(unsigned char bus);
|
||||
#else
|
||||
|
||||
enum dm_battery_state {
|
||||
BAT_STATE_UNUSED = 0, /* never used */
|
||||
BAT_STATE_NOT_PRESENT, /* battery is not present */
|
||||
BAT_STATE_NEED_CHARGING, /* battery needs charging (i.e. low SOC or voltage) */
|
||||
BAT_STATE_NORMAL, /* battery is OK */
|
||||
};
|
||||
|
||||
/* Battery device operations */
|
||||
struct dm_battery_ops {
|
||||
/**
|
||||
* Get the current voltage of the battery.
|
||||
* @dev - battery device
|
||||
* @uV - pointer to place to store voltage, in microvolts
|
||||
* @return 0 if success, -errno otherwise.
|
||||
*/
|
||||
int (*get_voltage)(struct udevice *dev, unsigned int *uV);
|
||||
/**
|
||||
* Get the current battery status
|
||||
* @dev - battery device
|
||||
* @return -errno on error, enum dm_battery_state otherwise
|
||||
*/
|
||||
int (*get_status)(struct udevice *dev);
|
||||
/**
|
||||
* Get the battery's State Of Charge (SOC)
|
||||
* @dev - battery device
|
||||
* @return 0-100 value representing current battery charge percentage, -errno on error
|
||||
*/
|
||||
int (*get_soc)(struct udevice *dev);
|
||||
};
|
||||
|
||||
int battery_get(const char *devname, struct udevice **devp);
|
||||
int battery_get_voltage(struct udevice *dev, unsigned int *uV);
|
||||
int battery_get_status(struct udevice *dev);
|
||||
int battery_get_soc(struct udevice *dev);
|
||||
#endif /* CONFIG_DM_BATTERY */
|
||||
#endif /* __POWER_BATTERY_H_ */
|
||||
|
|
40
include/power/charger.h
Normal file
40
include/power/charger.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2018 Simon Shields <simon@lineageos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
enum charger_state {
|
||||
CHARGE_STATE_UNKNOWN = 0,
|
||||
CHARGE_STATE_CHARGING = 1, /* charging normally */
|
||||
CHARGE_STATE_FULL = 2, /* not charging - battery full */
|
||||
CHARGE_STATE_NOT_CHARGING = 3, /* not charging - some other reason */
|
||||
CHARGE_STATE_DISCHARGING = 4, /* discharging */
|
||||
};
|
||||
|
||||
struct dm_charger_ops {
|
||||
/**
|
||||
* Get the charge current of the charger.
|
||||
* Some devices may return the maximum charge current rather than the current charge current.
|
||||
* @dev - charger device.
|
||||
* @return -errno on error, charge current in uA.
|
||||
*/
|
||||
int (*get_current)(struct udevice *dev);
|
||||
/**
|
||||
* Set the maximum charge current for the charger. A current of zero will disable charging.
|
||||
* @dev - charger device
|
||||
* @return -errno on error, 0 otherwise.
|
||||
*/
|
||||
int (*set_current)(struct udevice *dev, unsigned int microamps);
|
||||
/**
|
||||
* Get current charging state.
|
||||
* @dev - charger device
|
||||
* @return -errno on error, enum charger_state otherwise.
|
||||
*/
|
||||
int (*get_status)(struct udevice *dev);
|
||||
};
|
||||
|
||||
int charger_get(const char *devname, struct udevice **devp);
|
||||
int charger_get_current(struct udevice *dev);
|
||||
int charger_set_current(struct udevice *dev, unsigned int microamps);
|
||||
int charger_get_status(struct udevice *dev);
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue