Merge git://git.denx.de/u-boot-rockchip

This adds a new firefly-rk3399 board, MIPI support for rk3399 and
rk3288, rk818 pmic support, mkimage improvements for rockchip and a few
other things.
This commit is contained in:
Tom Rini 2017-05-10 17:40:11 -04:00
commit 1f5541c881
78 changed files with 5917 additions and 613 deletions

View file

@ -42,6 +42,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3288-veyron-minnie.dtb \ rk3288-veyron-minnie.dtb \
rk3328-evb.dtb \ rk3328-evb.dtb \
rk3399-evb.dtb \ rk3399-evb.dtb \
rk3399-firefly.dtb \
rk3399-puma.dtb rk3399-puma.dtb
dtb-$(CONFIG_ARCH_MESON) += \ dtb-$(CONFIG_ARCH_MESON) += \
meson-gxbb-odroidc2.dtb meson-gxbb-odroidc2.dtb

View file

@ -85,6 +85,59 @@
regulator-always-on; regulator-always-on;
vin-supply = <&vcc_5v>; vin-supply = <&vcc_5v>;
}; };
backlight: backlight {
compatible = "pwm-backlight";
power-supply = <&vcc_sys>;
enable-gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>;
brightness-levels = <
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63
64 65 66 67 68 69 70 71
72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87
88 89 90 91 92 93 94 95
96 97 98 99 100 101 102 103
104 105 106 107 108 109 110 111
112 113 114 115 116 117 118 119
120 121 122 123 124 125 126 127
128 129 130 131 132 133 134 135
136 137 138 139 140 141 142 143
144 145 146 147 148 149 150 151
152 153 154 155 156 157 158 159
160 161 162 163 164 165 166 167
168 169 170 171 172 173 174 175
176 177 178 179 180 181 182 183
184 185 186 187 188 189 190 191
192 193 194 195 196 197 198 199
200 201 202 203 204 205 206 207
208 209 210 211 212 213 214 215
216 217 218 219 220 221 222 223
224 225 226 227 228 229 230 231
232 233 234 235 236 237 238 239
240 241 242 243 244 245 246 247
248 249 250 251 252 253 254 255>;
default-brightness-level = <50>;
pwms = <&pwm0 0 25000 0>;
pinctrl-names = "default";
pinctrl-0 = <&pwm0_pin>;
pwm-delay-us = <10000>;
status = "disabled";
};
panel: panel {
compatible = "simple-panel";
power-supply = <&vcc_io>;
backlight = <&backlight>;
enable-gpios = <&gpio7 3 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
}; };
&cpu0 { &cpu0 {
@ -318,6 +371,10 @@
}; };
}; };
&pwm0 {
status = "okay";
};
&saradc { &saradc {
vref-supply = <&vcc_18>; vref-supply = <&vcc_18>;
status = "okay"; status = "okay";
@ -396,6 +453,29 @@
status = "okay"; status = "okay";
}; };
&mipi_dsi0 {
status = "disabled";
rockchip,panel = <&panel>;
display-timings {
timing0 {
bits-per-pixel = <24>;
clock-frequency = <160000000>;
hfront-porch = <120>;
hsync-len = <20>;
hback-porch = <21>;
hactive = <1200>;
vfront-porch = <21>;
vsync-len = <3>;
vback-porch = <18>;
vactive = <1920>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
&wdt { &wdt {
status = "okay"; status = "okay";
}; };

View file

@ -67,3 +67,10 @@
&gpio8 { &gpio8 {
u-boot,dm-pre-reloc; u-boot,dm-pre-reloc;
}; };
&i2c2 {
m24c08@50 {
compatible = "at,24c08", "i2c-eeprom";
reg = <0x50>;
};
};

View file

@ -664,6 +664,7 @@
}; };
vopb: vop@ff930000 { vopb: vop@ff930000 {
u-boot,dm-pre-reloc;
compatible = "rockchip,rk3288-vop"; compatible = "rockchip,rk3288-vop";
reg = <0xff930000 0x19c>; reg = <0xff930000 0x19c>;
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
@ -689,6 +690,11 @@
reg = <2>; reg = <2>;
remote-endpoint = <&lvds_in_vopb>; remote-endpoint = <&lvds_in_vopb>;
}; };
vopb_out_mipi: endpoint@3 {
reg = <3>;
remote-endpoint = <&mipi_in_vopb>;
};
}; };
}; };
@ -729,6 +735,11 @@
reg = <2>; reg = <2>;
remote-endpoint = <&lvds_in_vopl>; remote-endpoint = <&lvds_in_vopl>;
}; };
vopl_out_mipi: endpoint@3 {
reg = <3>;
remote-endpoint = <&mipi_in_vopl>;
};
}; };
}; };
@ -823,6 +834,36 @@
}; };
}; };
mipi_dsi0: mipi@ff960000 {
compatible = "rockchip,rk3288_mipi_dsi";
reg = <0xff960000 0x4000>;
clocks = <&cru PCLK_MIPI_DSI0>;
clock-names = "pclk_mipi";
/*pinctrl-names = "default";
pinctrl-0 = <&lcdc0_ctl>;*/
rockchip,grf = <&grf>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
mipi_in: port {
#address-cells = <1>;
#size-cells = <0>;
mipi_in_vopb: endpoint@0 {
reg = <0>;
remote-endpoint = <&vopb_out_mipi>;
};
mipi_in_vopl: endpoint@1 {
reg = <1>;
remote-endpoint = <&vopl_out_mipi>;
};
};
};
};
hdmi_audio: hdmi_audio { hdmi_audio: hdmi_audio {
compatible = "rockchip,rk3288-hdmi-audio"; compatible = "rockchip,rk3288-hdmi-audio";
i2s-controller = <&i2s>; i2s-controller = <&i2s>;

View file

@ -6,6 +6,7 @@
/dts-v1/; /dts-v1/;
#include <dt-bindings/pwm/pwm.h> #include <dt-bindings/pwm/pwm.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include "rk3399.dtsi" #include "rk3399.dtsi"
#include "rk3399-sdram-lpddr3-4GB-1600.dtsi" #include "rk3399-sdram-lpddr3-4GB-1600.dtsi"
@ -20,7 +21,7 @@
vdd_center: vdd-center { vdd_center: vdd-center {
compatible = "pwm-regulator"; compatible = "pwm-regulator";
pwms = <&pwm3 0 25000 0>; pwms = <&pwm3 0 25000 1>;
regulator-name = "vdd_center"; regulator-name = "vdd_center";
regulator-min-microvolt = <800000>; regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1400000>; regulator-max-microvolt = <1400000>;
@ -59,6 +60,65 @@
gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>; gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
}; };
clkin_gmac: external-gmac-clock {
compatible = "fixed-clock";
clock-frequency = <125000000>;
clock-output-names = "clkin_gmac";
#clock-cells = <0>;
};
backlight: backlight {
compatible = "pwm-backlight";
power-supply = <&vccsys>;
enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
brightness-levels = <
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63
64 65 66 67 68 69 70 71
72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87
88 89 90 91 92 93 94 95
96 97 98 99 100 101 102 103
104 105 106 107 108 109 110 111
112 113 114 115 116 117 118 119
120 121 122 123 124 125 126 127
128 129 130 131 132 133 134 135
136 137 138 139 140 141 142 143
144 145 146 147 148 149 150 151
152 153 154 155 156 157 158 159
160 161 162 163 164 165 166 167
168 169 170 171 172 173 174 175
176 177 178 179 180 181 182 183
184 185 186 187 188 189 190 191
192 193 194 195 196 197 198 199
200 201 202 203 204 205 206 207
208 209 210 211 212 213 214 215
216 217 218 219 220 221 222 223
224 225 226 227 228 229 230 231
232 233 234 235 236 237 238 239
240 241 242 243 244 245 246 247
248 249 250 251 252 253 254 255>;
default-brightness-level = <200>;
pwms = <&pwm0 0 25000 0>;
pinctrl-names = "default";
pinctrl-0 = <&pwm0_pin>;
pwm-delay-us = <10000>;
status = "disabled";
};
panel:panel {
compatible = "simple-panel";
power-supply = <&vcc33_lcd>;
backlight = <&backlight>;
/*enable-gpios = <&gpio4 18 GPIO_ACTIVE_HIGH>;*/
status = "disabled";
};
}; };
&emmc_phy { &emmc_phy {
@ -141,6 +201,7 @@
status = "okay"; status = "okay";
vcc12-supply = <&vcc3v3_sys>; vcc12-supply = <&vcc3v3_sys>;
regulators { regulators {
vcc33_lcd: SWITCH_REG2 { vcc33_lcd: SWITCH_REG2 {
regulator-always-on; regulator-always-on;
@ -151,6 +212,29 @@
}; };
}; };
&mipi_dsi {
status = "disabled";
rockchip,panel = <&panel>;
display-timings {
timing0 {
bits-per-pixel = <24>;
clock-frequency = <160000000>;
hfront-porch = <120>;
hsync-len = <20>;
hback-porch = <21>;
hactive = <1200>;
vfront-porch = <21>;
vsync-len = <3>;
vback-porch = <18>;
vactive = <1920>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
&pinctrl { &pinctrl {
pmic { pmic {
pmic_int_l: pmic-int-l { pmic_int_l: pmic-int-l {
@ -164,3 +248,35 @@
}; };
}; };
}; };
&gmac {
phy-supply = <&vcc_phy>;
phy-mode = "rgmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 10000 50000>;
assigned-clocks = <&cru SCLK_RMII_SRC>;
assigned-clock-parents = <&clkin_gmac>;
pinctrl-names = "default";
pinctrl-0 = <&rgmii_pins>;
tx_delay = <0x10>;
rx_delay = <0x10>;
status = "okay";
};
&gmac {
phy-supply = <&vcc_phy>;
phy-mode = "rgmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 10000 50000>;
assigned-clocks = <&cru SCLK_RMII_SRC>;
assigned-clock-parents = <&clkin_gmac>;
pinctrl-names = "default";
pinctrl-0 = <&rgmii_pins>;
tx_delay = <0x10>;
rx_delay = <0x10>;
status = "okay";
};

View file

@ -0,0 +1,660 @@
/*
* Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/dts-v1/;
#include <dt-bindings/pwm/pwm.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include "rk3399.dtsi"
#include "rk3399-sdram-ddr3-1333.dtsi"
/ {
model = "Firefly-RK3399 Board";
compatible = "firefly,firefly-rk3399", "rockchip,rk3399";
chosen {
stdout-path = &uart2;
};
backlight: backlight {
compatible = "pwm-backlight";
enable-gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>;
pwms = <&pwm0 0 25000 0>;
brightness-levels = <
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63
64 65 66 67 68 69 70 71
72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87
88 89 90 91 92 93 94 95
96 97 98 99 100 101 102 103
104 105 106 107 108 109 110 111
112 113 114 115 116 117 118 119
120 121 122 123 124 125 126 127
128 129 130 131 132 133 134 135
136 137 138 139 140 141 142 143
144 145 146 147 148 149 150 151
152 153 154 155 156 157 158 159
160 161 162 163 164 165 166 167
168 169 170 171 172 173 174 175
176 177 178 179 180 181 182 183
184 185 186 187 188 189 190 191
192 193 194 195 196 197 198 199
200 201 202 203 204 205 206 207
208 209 210 211 212 213 214 215
216 217 218 219 220 221 222 223
224 225 226 227 228 229 230 231
232 233 234 235 236 237 238 239
240 241 242 243 244 245 246 247
248 249 250 251 252 253 254 255>;
default-brightness-level = <200>;
};
clkin_gmac: external-gmac-clock {
compatible = "fixed-clock";
clock-frequency = <125000000>;
clock-output-names = "clkin_gmac";
#clock-cells = <0>;
};
rt5640-sound {
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,rt5640-codec";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,widgets =
"Microphone", "Mic Jack",
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"Mic Jack", "MICBIAS1",
"IN1P", "Mic Jack",
"Headphone Jack", "HPOL",
"Headphone Jack", "HPOR";
simple-audio-card,cpu {
sound-dai = <&i2s1>;
};
simple-audio-card,codec {
sound-dai = <&rt5640>;
};
};
sdio_pwrseq: sdio-pwrseq {
compatible = "mmc-pwrseq-simple";
clocks = <&rk808 1>;
clock-names = "ext_clock";
pinctrl-names = "default";
pinctrl-0 = <&wifi_enable_h>;
/*
* On the module itself this is one of these (depending
* on the actual card populated):
* - SDIO_RESET_L_WL_REG_ON
* - PDN (power down when low)
*/
reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
};
vcc3v3_pcie: vcc3v3-pcie-regulator {
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pcie_drv>;
regulator-name = "vcc3v3_pcie";
regulator-always-on;
regulator-boot-on;
};
vcc3v3_sys: vcc3v3-sys {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_sys";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
vcc5v0_host: vcc5v0-host-regulator {
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&host_vbus_drv>;
regulator-name = "vcc5v0_host";
regulator-always-on;
};
vcc5v0_sys: vcc5v0-sys {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_sys";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
vcc_phy: vcc-phy-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc_phy";
regulator-always-on;
regulator-boot-on;
};
vdd_log: vdd-log {
compatible = "pwm-regulator";
pwms = <&pwm2 0 25000 1>;
regulator-name = "vdd_log";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1400000>;
};
vccadc_ref: vccadc-ref {
compatible = "regulator-fixed";
regulator-name = "vcc1v8_sys";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
};
&cpu_l0 {
cpu-supply = <&vdd_cpu_l>;
};
&cpu_l1 {
cpu-supply = <&vdd_cpu_l>;
};
&cpu_l2 {
cpu-supply = <&vdd_cpu_l>;
};
&cpu_l3 {
cpu-supply = <&vdd_cpu_l>;
};
&cpu_b0 {
cpu-supply = <&vdd_cpu_b>;
};
&cpu_b1 {
cpu-supply = <&vdd_cpu_b>;
};
&emmc_phy {
status = "okay";
};
&gmac {
assigned-clocks = <&cru SCLK_RMII_SRC>;
assigned-clock-parents = <&clkin_gmac>;
clock_in_out = "input";
phy-supply = <&vcc_phy>;
phy-mode = "rgmii";
pinctrl-names = "default";
pinctrl-0 = <&rgmii_pins>;
snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 10000 50000>;
tx_delay = <0x28>;
rx_delay = <0x11>;
status = "okay";
};
&i2c0 {
clock-frequency = <400000>;
i2c-scl-rising-time-ns = <168>;
i2c-scl-falling-time-ns = <4>;
status = "okay";
rk808: pmic@1b {
compatible = "rockchip,rk808";
reg = <0x1b>;
interrupt-parent = <&gpio1>;
interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
#clock-cells = <1>;
clock-output-names = "xin32k", "rk808-clkout2";
pinctrl-names = "default";
pinctrl-0 = <&pmic_int_l>;
rockchip,system-power-controller;
wakeup-source;
vcc1-supply = <&vcc3v3_sys>;
vcc2-supply = <&vcc3v3_sys>;
vcc3-supply = <&vcc3v3_sys>;
vcc4-supply = <&vcc3v3_sys>;
vcc6-supply = <&vcc3v3_sys>;
vcc7-supply = <&vcc3v3_sys>;
vcc8-supply = <&vcc3v3_sys>;
vcc9-supply = <&vcc3v3_sys>;
vcc10-supply = <&vcc3v3_sys>;
vcc11-supply = <&vcc3v3_sys>;
vcc12-supply = <&vcc3v3_sys>;
vddio-supply = <&vcc1v8_pmu>;
regulators {
vdd_center: DCDC_REG1 {
regulator-name = "vdd_center";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <6001>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
vdd_cpu_l: DCDC_REG2 {
regulator-name = "vdd_cpu_l";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <6001>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc_ddr: DCDC_REG3 {
regulator-name = "vcc_ddr";
regulator-always-on;
regulator-boot-on;
regulator-state-mem {
regulator-on-in-suspend;
};
};
vcc_1v8: DCDC_REG4 {
regulator-name = "vcc_1v8";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
vcc1v8_dvp: LDO_REG1 {
regulator-name = "vcc1v8_dvp";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc3v0_tp: LDO_REG2 {
regulator-name = "vcc3v0_tp";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc1v8_pmu: LDO_REG3 {
regulator-name = "vcc1v8_pmu";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
vcc_sd: LDO_REG4 {
regulator-name = "vcc_sd";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
vcca3v0_codec: LDO_REG5 {
regulator-name = "vcca3v0_codec";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc_1v5: LDO_REG6 {
regulator-name = "vcc_1v5";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1500000>;
};
};
vcca1v8_codec: LDO_REG7 {
regulator-name = "vcca1v8_codec";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc_3v0: LDO_REG8 {
regulator-name = "vcc_3v0";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3000000>;
};
};
vcc3v3_s3: SWITCH_REG1 {
regulator-name = "vcc3v3_s3";
regulator-always-on;
regulator-boot-on;
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc3v3_s0: SWITCH_REG2 {
regulator-name = "vcc3v3_s0";
regulator-always-on;
regulator-boot-on;
regulator-state-mem {
regulator-off-in-suspend;
};
};
};
};
vdd_cpu_b: regulator@40 {
compatible = "silergy,syr827";
reg = <0x40>;
fcs,suspend-voltage-selector = <0>;
regulator-name = "vdd_cpu_b";
regulator-min-microvolt = <712500>;
regulator-max-microvolt = <1500000>;
regulator-ramp-delay = <1000>;
regulator-always-on;
regulator-boot-on;
vin-supply = <&vcc5v0_sys>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
vdd_gpu: regulator@41 {
compatible = "silergy,syr828";
reg = <0x41>;
fcs,suspend-voltage-selector = <1>;
regulator-name = "vdd_gpu";
regulator-min-microvolt = <712500>;
regulator-max-microvolt = <1500000>;
regulator-ramp-delay = <1000>;
regulator-always-on;
regulator-boot-on;
vin-supply = <&vcc5v0_sys>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
};
&i2c1 {
i2c-scl-rising-time-ns = <300>;
i2c-scl-falling-time-ns = <15>;
status = "okay";
rt5640: rt5640@1c {
compatible = "realtek,rt5640";
reg = <0x1c>;
clocks = <&cru SCLK_I2S_8CH_OUT>;
clock-names = "mclk";
realtek,in1-differential;
#sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&rt5640_hpcon>;
};
};
&i2c3 {
i2c-scl-rising-time-ns = <450>;
i2c-scl-falling-time-ns = <15>;
status = "okay";
};
&i2c4 {
i2c-scl-rising-time-ns = <600>;
i2c-scl-falling-time-ns = <20>;
status = "okay";
accelerometer@68 {
compatible = "invensense,mpu6500";
reg = <0x68>;
interrupt-parent = <&gpio1>;
interrupts = <RK_PC6 IRQ_TYPE_EDGE_RISING>;
};
};
&i2s0 {
rockchip,playback-channels = <8>;
rockchip,capture-channels = <8>;
#sound-dai-cells = <0>;
status = "okay";
};
&i2s1 {
rockchip,playback-channels = <2>;
rockchip,capture-channels = <2>;
#sound-dai-cells = <0>;
status = "okay";
};
&i2s2 {
#sound-dai-cells = <0>;
status = "okay";
};
&io_domains {
status = "okay";
bt656-supply = <&vcc1v8_dvp>;
audio-supply = <&vcca1v8_codec>;
sdmmc-supply = <&vcc_sd>;
gpio1830-supply = <&vcc_3v0>;
};
&pcie_phy {
status = "okay";
};
&pcie0 {
ep-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_HIGH>;
num-lanes = <4>;
pinctrl-names = "default";
pinctrl-0 = <&pcie_clkreqn>;
status = "okay";
};
&pmu_io_domains {
pmu1830-supply = <&vcc_3v0>;
status = "okay";
};
&pinctrl {
buttons {
pwrbtn: pwrbtn {
rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
lcd-panel {
lcd_panel_reset: lcd-panel-reset {
rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
pcie {
pcie_drv: pcie-drv {
rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
};
pcie_3g_drv: pcie-3g-drv {
rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
pmic {
vsel1_gpio: vsel1-gpio {
rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>;
};
vsel2_gpio: vsel2-gpio {
rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
};
};
sdio-pwrseq {
wifi_enable_h: wifi-enable-h {
rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
rt5640 {
rt5640_hpcon: rt5640-hpcon {
rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
pmic {
pmic_int_l: pmic-int-l {
rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
usb2 {
host_vbus_drv: host-vbus-drv {
rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
&pwm0 {
status = "okay";
};
&pwm2 {
status = "okay";
};
&saradc {
vref-supply = <&vccadc_ref>;
status = "okay";
};
&sdhci {
bus-width = <8>;
keep-power-in-suspend;
mmc-hs400-1_8v;
mmc-hs400-enhanced-strobe;
non-removable;
status = "okay";
};
&tsadc {
/* tshut mode 0:CRU 1:GPIO */
rockchip,hw-tshut-mode = <1>;
/* tshut polarity 0:LOW 1:HIGH */
rockchip,hw-tshut-polarity = <1>;
status = "okay";
};
&u2phy0 {
status = "okay";
u2phy0_otg: otg-port {
status = "okay";
};
u2phy0_host: host-port {
phy-supply = <&vcc5v0_host>;
status = "okay";
};
};
&u2phy1 {
status = "okay";
u2phy1_otg: otg-port {
status = "okay";
};
u2phy1_host: host-port {
phy-supply = <&vcc5v0_host>;
status = "okay";
};
};
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_xfer &uart0_cts>;
status = "okay";
};
&uart2 {
status = "okay";
};
&usb_host0_ehci {
status = "okay";
};
&usb_host0_ohci {
status = "okay";
};
&usb_host1_ehci {
status = "okay";
};
&usb_host1_ohci {
status = "okay";
};

View file

@ -7,12 +7,16 @@
/dts-v1/; /dts-v1/;
#include <dt-bindings/pwm/pwm.h> #include <dt-bindings/pwm/pwm.h>
#include "rk3399.dtsi" #include "rk3399.dtsi"
#include "rk3399-sdram-ddr3-1333.dtsi" #include "rk3399-sdram-ddr3-1600.dtsi"
/ { / {
model = "Theobroma Systems RK3399-Q7 SoM"; model = "Theobroma Systems RK3399-Q7 SoM";
compatible = "tsd,puma", "rockchip,rk3399"; compatible = "tsd,puma", "rockchip,rk3399";
config {
u-boot,spl-payload-offset = <204800>;
};
chosen { chosen {
stdout-path = "serial0:115200n8"; stdout-path = "serial0:115200n8";
u-boot,spl-boot-order = &spiflash, &sdhci, &sdmmc; u-boot,spl-boot-order = &spiflash, &sdhci, &sdmmc;

View file

@ -39,22 +39,22 @@
666 666
3 3
2 2
/* 13 */ 9 9
1 1
0x00000600 0x00000600
0x00000000 0x00000000
0x00000000 0x00000000
0x00000000 0x00000000
0x00000000 0x00000000
/* 0xaae60 */ 7 0x00000007
0x00000000 0x00000000
0x00000000 0x00000000
0x00000000 0x00000000
/* 0xaae60 */ 7 0x00000007
0x00000000 0x00000000
0x00000000 0x00000000
0x00000000 0x00000000
/* 0xaae60 */ 7 0x00000007
0x00000000 0x00000000
0x00000000 0x00000000
0x01000000 0x01000000

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -16,3 +16,7 @@
.space 0x4 /* space for the 'RK33' */ .space 0x4 /* space for the 'RK33' */
#endif #endif
b reset b reset
#if defined(CONFIG_ROCKCHIP_RK3399) && defined(CONFIG_SPL_BUILD)
.space CONFIG_ROCKCHIP_SPL_RESERVE_IRAM /* space for the ATF data */
#endif

View file

@ -824,4 +824,66 @@ enum {
(0x7f << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT), (0x7f << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT),
}; };
/* GRF_SOC_CON6 */
enum GRF_SOC_CON6 {
RK3288_HDMI_EDP_SEL_SHIFT = 0xf,
RK3288_HDMI_EDP_SEL_MASK =
1 << RK3288_HDMI_EDP_SEL_SHIFT,
RK3288_HDMI_EDP_SEL_EDP = 0,
RK3288_HDMI_EDP_SEL_HDMI,
RK3288_DSI0_DPICOLORM_SHIFT = 0x8,
RK3288_DSI0_DPICOLORM_MASK =
1 << RK3288_DSI0_DPICOLORM_SHIFT,
RK3288_DSI0_DPISHUTDN_SHIFT = 0x7,
RK3288_DSI0_DPISHUTDN_MASK =
1 << RK3288_DSI0_DPISHUTDN_SHIFT,
RK3288_DSI0_LCDC_SEL_SHIFT = 0x6,
RK3288_DSI0_LCDC_SEL_MASK =
1 << RK3288_DSI0_LCDC_SEL_SHIFT,
RK3288_DSI0_LCDC_SEL_BIG = 0,
RK3288_DSI0_LCDC_SEL_LIT = 1,
RK3288_EDP_LCDC_SEL_SHIFT = 0x5,
RK3288_EDP_LCDC_SEL_MASK =
1 << RK3288_EDP_LCDC_SEL_SHIFT,
RK3288_EDP_LCDC_SEL_BIG = 0,
RK3288_EDP_LCDC_SEL_LIT = 1,
RK3288_HDMI_LCDC_SEL_SHIFT = 0x4,
RK3288_HDMI_LCDC_SEL_MASK =
1 << RK3288_HDMI_LCDC_SEL_SHIFT,
RK3288_HDMI_LCDC_SEL_BIG = 0,
RK3288_HDMI_LCDC_SEL_LIT = 1,
RK3288_LVDS_LCDC_SEL_SHIFT = 0x3,
RK3288_LVDS_LCDC_SEL_MASK =
1 << RK3288_LVDS_LCDC_SEL_SHIFT,
RK3288_LVDS_LCDC_SEL_BIG = 0,
RK3288_LVDS_LCDC_SEL_LIT = 1,
};
/* RK3288_SOC_CON8 */
enum GRF_SOC_CON8 {
RK3288_DPHY_TX0_RXMODE_SHIFT = 4,
RK3288_DPHY_TX0_RXMODE_MASK =
0xf << RK3288_DPHY_TX0_RXMODE_SHIFT,
RK3288_DPHY_TX0_RXMODE_EN = 0xf,
RK3288_DPHY_TX0_RXMODE_DIS = 0,
RK3288_DPHY_TX0_TXSTOPMODE_SHIFT = 0x8,
RK3288_DPHY_TX0_TXSTOPMODE_MASK =
0xf << RK3288_DPHY_TX0_TXSTOPMODE_SHIFT,
RK3288_DPHY_TX0_TXSTOPMODE_EN = 0xf,
RK3288_DPHY_TX0_TXSTOPMODE_DIS = 0,
RK3288_DPHY_TX0_TURNREQUEST_SHIFT = 0,
RK3288_DPHY_TX0_TURNREQUEST_MASK =
0xf << RK3288_DPHY_TX0_TURNREQUEST_SHIFT,
RK3288_DPHY_TX0_TURNREQUEST_EN = 0xf,
RK3288_DPHY_TX0_TURNREQUEST_DIS = 0,
};
#endif #endif

View file

@ -151,10 +151,11 @@ struct rk3399_grf_regs {
u32 gpio2_sr[3][4]; u32 gpio2_sr[3][4];
u32 reserved23[4]; u32 reserved23[4];
u32 gpio2_smt[3][4]; u32 gpio2_smt[3][4];
u32 reserved24[(0xe130 - 0xe0ec)/4 - 1]; u32 reserved24[(0xe100 - 0xe0ec)/4 - 1];
u32 gpio4b_e01; u32 gpio2_e[4];
u32 gpio4b_e2; u32 gpio3_e[7];
u32 reserved24a[(0xe200 - 0xe134)/4 - 1]; u32 gpio4_e[5];
u32 reserved24a[(0xe200 - 0xe13c)/4 - 1];
u32 soc_con0; u32 soc_con0;
u32 soc_con1; u32 soc_con1;
u32 soc_con2; u32 soc_con2;
@ -344,6 +345,18 @@ enum {
GRF_GPIO2C1_SEL_SHIFT = 2, GRF_GPIO2C1_SEL_SHIFT = 2,
GRF_GPIO2C1_SEL_MASK = 3 << GRF_GPIO2C1_SEL_SHIFT, GRF_GPIO2C1_SEL_MASK = 3 << GRF_GPIO2C1_SEL_SHIFT,
GRF_UART0BT_SOUT = 1, GRF_UART0BT_SOUT = 1,
GRF_GPIO2C4_SEL_SHIFT = 8,
GRF_GPIO2C4_SEL_MASK = 3 << GRF_GPIO2C4_SEL_SHIFT,
GRF_SPI5EXPPLUS_RXD = 2,
GRF_GPIO2C5_SEL_SHIFT = 10,
GRF_GPIO2C5_SEL_MASK = 3 << GRF_GPIO2C5_SEL_SHIFT,
GRF_SPI5EXPPLUS_TXD = 2,
GRF_GPIO2C6_SEL_SHIFT = 12,
GRF_GPIO2C6_SEL_MASK = 3 << GRF_GPIO2C6_SEL_SHIFT,
GRF_SPI5EXPPLUS_CLK = 2,
GRF_GPIO2C7_SEL_SHIFT = 14,
GRF_GPIO2C7_SEL_MASK = 3 << GRF_GPIO2C7_SEL_SHIFT,
GRF_SPI5EXPPLUS_CSN0 = 2,
/* GRF_GPIO3A_IOMUX */ /* GRF_GPIO3A_IOMUX */
GRF_GPIO3A0_SEL_SHIFT = 0, GRF_GPIO3A0_SEL_SHIFT = 0,
@ -427,9 +440,11 @@ enum {
GRF_GPIO4C0_SEL_SHIFT = 0, GRF_GPIO4C0_SEL_SHIFT = 0,
GRF_GPIO4C0_SEL_MASK = 3 << GRF_GPIO4C0_SEL_SHIFT, GRF_GPIO4C0_SEL_MASK = 3 << GRF_GPIO4C0_SEL_SHIFT,
GRF_UART2DGBB_SIN = 2, GRF_UART2DGBB_SIN = 2,
GRF_HDMII2C_SCL = 3,
GRF_GPIO4C1_SEL_SHIFT = 2, GRF_GPIO4C1_SEL_SHIFT = 2,
GRF_GPIO4C1_SEL_MASK = 3 << GRF_GPIO4C1_SEL_SHIFT, GRF_GPIO4C1_SEL_MASK = 3 << GRF_GPIO4C1_SEL_SHIFT,
GRF_UART2DGBB_SOUT = 2, GRF_UART2DGBB_SOUT = 2,
GRF_HDMII2C_SDA = 3,
GRF_GPIO4C2_SEL_SHIFT = 4, GRF_GPIO4C2_SEL_SHIFT = 4,
GRF_GPIO4C2_SEL_MASK = 3 << GRF_GPIO4C2_SEL_SHIFT, GRF_GPIO4C2_SEL_MASK = 3 << GRF_GPIO4C2_SEL_SHIFT,
GRF_PWM_0 = 1, GRF_PWM_0 = 1,
@ -443,10 +458,99 @@ enum {
GRF_GPIO4C6_SEL_MASK = 3 << GRF_GPIO4C6_SEL_SHIFT, GRF_GPIO4C6_SEL_MASK = 3 << GRF_GPIO4C6_SEL_SHIFT,
GRF_PWM_1 = 1, GRF_PWM_1 = 1,
/* GRF_GPIO3A_E01 */
GRF_GPIO3A0_E_SHIFT = 0,
GRF_GPIO3A0_E_MASK = 7 << GRF_GPIO3A0_E_SHIFT,
GRF_GPIO3A1_E_SHIFT = 3,
GRF_GPIO3A1_E_MASK = 7 << GRF_GPIO3A1_E_SHIFT,
GRF_GPIO3A2_E_SHIFT = 6,
GRF_GPIO3A2_E_MASK = 7 << GRF_GPIO3A2_E_SHIFT,
GRF_GPIO3A3_E_SHIFT = 9,
GRF_GPIO3A3_E_MASK = 7 << GRF_GPIO3A3_E_SHIFT,
GRF_GPIO3A4_E_SHIFT = 12,
GRF_GPIO3A4_E_MASK = 7 << GRF_GPIO3A4_E_SHIFT,
GRF_GPIO3A5_E0_SHIFT = 15,
GRF_GPIO3A5_E0_MASK = 1 << GRF_GPIO3A5_E0_SHIFT,
/* GRF_GPIO3A_E2 */
GRF_GPIO3A5_E12_SHIFT = 0,
GRF_GPIO3A5_E12_MASK = 3 << GRF_GPIO3A5_E12_SHIFT,
GRF_GPIO3A6_E_SHIFT = 2,
GRF_GPIO3A6_E_MASK = 7 << GRF_GPIO3A6_E_SHIFT,
GRF_GPIO3A7_E_SHIFT = 5,
GRF_GPIO3A7_E_MASK = 7 << GRF_GPIO3A7_E_SHIFT,
/* GRF_GPIO3B_E01 */
GRF_GPIO3B0_E_SHIFT = 0,
GRF_GPIO3B0_E_MASK = 7 << GRF_GPIO3B0_E_SHIFT,
GRF_GPIO3B1_E_SHIFT = 3,
GRF_GPIO3B1_E_MASK = 7 << GRF_GPIO3B1_E_SHIFT,
GRF_GPIO3B2_E_SHIFT = 6,
GRF_GPIO3B2_E_MASK = 7 << GRF_GPIO3B2_E_SHIFT,
GRF_GPIO3B3_E_SHIFT = 9,
GRF_GPIO3B3_E_MASK = 7 << GRF_GPIO3B3_E_SHIFT,
GRF_GPIO3B4_E_SHIFT = 12,
GRF_GPIO3B4_E_MASK = 7 << GRF_GPIO3B4_E_SHIFT,
GRF_GPIO3B5_E0_SHIFT = 15,
GRF_GPIO3B5_E0_MASK = 1 << GRF_GPIO3B5_E0_SHIFT,
/* GRF_GPIO3A_E2 */
GRF_GPIO3B5_E12_SHIFT = 0,
GRF_GPIO3B5_E12_MASK = 3 << GRF_GPIO3B5_E12_SHIFT,
GRF_GPIO3B6_E_SHIFT = 2,
GRF_GPIO3B6_E_MASK = 7 << GRF_GPIO3B6_E_SHIFT,
GRF_GPIO3B7_E_SHIFT = 5,
GRF_GPIO3B7_E_MASK = 7 << GRF_GPIO3B7_E_SHIFT,
/* GRF_GPIO3C_E01 */
GRF_GPIO3C0_E_SHIFT = 0,
GRF_GPIO3C0_E_MASK = 7 << GRF_GPIO3C0_E_SHIFT,
GRF_GPIO3C1_E_SHIFT = 3,
GRF_GPIO3C1_E_MASK = 7 << GRF_GPIO3C1_E_SHIFT,
GRF_GPIO3C2_E_SHIFT = 6,
GRF_GPIO3C2_E_MASK = 7 << GRF_GPIO3C2_E_SHIFT,
GRF_GPIO3C3_E_SHIFT = 9,
GRF_GPIO3C3_E_MASK = 7 << GRF_GPIO3C3_E_SHIFT,
GRF_GPIO3C4_E_SHIFT = 12,
GRF_GPIO3C4_E_MASK = 7 << GRF_GPIO3C4_E_SHIFT,
GRF_GPIO3C5_E0_SHIFT = 15,
GRF_GPIO3C5_E0_MASK = 1 << GRF_GPIO3C5_E0_SHIFT,
/* GRF_GPIO3C_E2 */
GRF_GPIO3C5_E12_SHIFT = 0,
GRF_GPIO3C5_E12_MASK = 3 << GRF_GPIO3C5_E12_SHIFT,
GRF_GPIO3C6_E_SHIFT = 2,
GRF_GPIO3C6_E_MASK = 7 << GRF_GPIO3C6_E_SHIFT,
GRF_GPIO3C7_E_SHIFT = 5,
GRF_GPIO3C7_E_MASK = 7 << GRF_GPIO3C7_E_SHIFT,
/* GRF_SOC_CON7 */ /* GRF_SOC_CON7 */
GRF_UART_DBG_SEL_SHIFT = 10, GRF_UART_DBG_SEL_SHIFT = 10,
GRF_UART_DBG_SEL_MASK = 3 << GRF_UART_DBG_SEL_SHIFT, GRF_UART_DBG_SEL_MASK = 3 << GRF_UART_DBG_SEL_SHIFT,
GRF_UART_DBG_SEL_C = 2, GRF_UART_DBG_SEL_C = 2,
/* GRF_SOC_CON20 */
GRF_DSI0_VOP_SEL_SHIFT = 0,
GRF_DSI0_VOP_SEL_MASK = 1 << GRF_DSI0_VOP_SEL_SHIFT,
GRF_DSI0_VOP_SEL_B = 0,
GRF_DSI0_VOP_SEL_L = 1,
/* GRF_SOC_CON22 */
GRF_DPHY_TX0_RXMODE_SHIFT = 0,
GRF_DPHY_TX0_RXMODE_MASK = 0xf << GRF_DPHY_TX0_RXMODE_SHIFT,
GRF_DPHY_TX0_RXMODE_EN = 0xb,
GRF_DPHY_TX0_RXMODE_DIS = 0,
GRF_DPHY_TX0_TXSTOPMODE_SHIFT = 4,
GRF_DPHY_TX0_TXSTOPMODE_MASK = 0xf0 << GRF_DPHY_TX0_TXSTOPMODE_SHIFT,
GRF_DPHY_TX0_TXSTOPMODE_EN = 0xc,
GRF_DPHY_TX0_TXSTOPMODE_DIS = 0,
GRF_DPHY_TX0_TURNREQUEST_SHIFT = 12,
GRF_DPHY_TX0_TURNREQUEST_MASK =
0xf000 << GRF_DPHY_TX0_TURNREQUEST_SHIFT,
GRF_DPHY_TX0_TURNREQUEST_EN = 0x1,
GRF_DPHY_TX0_TURNREQUEST_DIS = 0,
/* PMUGRF_GPIO0A_IOMUX */ /* PMUGRF_GPIO0A_IOMUX */
PMUGRF_GPIO0A6_SEL_SHIFT = 12, PMUGRF_GPIO0A6_SEL_SHIFT = 12,

View file

@ -27,6 +27,9 @@ enum periph_id {
PERIPH_ID_SPI0, PERIPH_ID_SPI0,
PERIPH_ID_SPI1, PERIPH_ID_SPI1,
PERIPH_ID_SPI2, PERIPH_ID_SPI2,
PERIPH_ID_SPI3,
PERIPH_ID_SPI4,
PERIPH_ID_SPI5,
PERIPH_ID_UART0, PERIPH_ID_UART0,
PERIPH_ID_UART1, PERIPH_ID_UART1,
PERIPH_ID_UART2, PERIPH_ID_UART2,

View file

@ -0,0 +1,195 @@
/*
* Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd
* author: Eric Gao <eric.gao@rock-chips.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef ROCKCHIP_MIPI_DSI_H
#define ROCKCHIP_MIPI_DSI_H
/*
* All these mipi controller register declaration provide reg address offset,
* bits width, bit offset for a specified register bits. With these message, we
* can set or clear every bits individually for a 32bit widthregister. We use
* DSI_HOST_BITS macro definition to combinat these message using the following
* format: val(32bit) = addr(16bit) | width(8bit) | offest(8bit)
* For example:
* #define SHUTDOWNZ DSI_HOST_BITS(0x004, 1, 0)
* means SHUTDOWNZ is a signal reg bit with bit offset qual 0,and it's reg addr
* offset is 0x004.The conbinat result = (0x004 << 16) | (1 << 8) | 0
*/
#define ADDR_SHIFT 16
#define BITS_SHIFT 8
#define OFFSET_SHIFT 0
#define DSI_HOST_BITS(addr, bits, bit_offset) \
((addr << ADDR_SHIFT) | (bits << BITS_SHIFT) | (bit_offset << OFFSET_SHIFT))
/* DWC_DSI_VERSION_0x3133302A */
#define VERSION DSI_HOST_BITS(0x000, 32, 0)
#define SHUTDOWNZ DSI_HOST_BITS(0x004, 1, 0)
#define TO_CLK_DIVISION DSI_HOST_BITS(0x008, 8, 8)
#define TX_ESC_CLK_DIVISION DSI_HOST_BITS(0x008, 8, 0)
#define DPI_VCID DSI_HOST_BITS(0x00c, 2, 0)
#define EN18_LOOSELY DSI_HOST_BITS(0x010, 1, 8)
#define DPI_COLOR_CODING DSI_HOST_BITS(0x010, 4, 0)
#define COLORM_ACTIVE_LOW DSI_HOST_BITS(0x014, 1, 4)
#define SHUTD_ACTIVE_LOW DSI_HOST_BITS(0x014, 1, 3)
#define HSYNC_ACTIVE_LOW DSI_HOST_BITS(0x014, 1, 2)
#define VSYNC_ACTIVE_LOW DSI_HOST_BITS(0x014, 1, 1)
#define DATAEN_ACTIVE_LOW DSI_HOST_BITS(0x014, 1, 0)
#define OUTVACT_LPCMD_TIME DSI_HOST_BITS(0x018, 8, 16)
#define INVACT_LPCMD_TIME DSI_HOST_BITS(0x018, 8, 0)
#define CRC_RX_EN DSI_HOST_BITS(0x02c, 1, 4)
#define ECC_RX_EN DSI_HOST_BITS(0x02c, 1, 3)
#define BTA_EN DSI_HOST_BITS(0x02c, 1, 2)
#define EOTP_RX_EN DSI_HOST_BITS(0x02c, 1, 1)
#define EOTP_TX_EN DSI_HOST_BITS(0x02c, 1, 0)
#define GEN_VID_RX DSI_HOST_BITS(0x030, 2, 0)
#define CMD_VIDEO_MODE DSI_HOST_BITS(0x034, 1, 0)
#define VPG_ORIENTATION DSI_HOST_BITS(0x038, 1, 24)
#define VPG_MODE DSI_HOST_BITS(0x038, 1, 20)
#define VPG_EN DSI_HOST_BITS(0x038, 1, 16)
#define LP_CMD_EN DSI_HOST_BITS(0x038, 1, 15)
#define FRAME_BTA_ACK_EN DSI_HOST_BITS(0x038, 1, 14)
#define LP_HFP_EN DSI_HOST_BITS(0x038, 1, 13)
#define LP_HBP_EN DSI_HOST_BITS(0x038, 1, 12)
#define LP_VACT_EN DSI_HOST_BITS(0x038, 1, 11)
#define LP_VFP_EN DSI_HOST_BITS(0x038, 1, 10)
#define LP_VBP_EN DSI_HOST_BITS(0x038, 1, 9)
#define LP_VSA_EN DSI_HOST_BITS(0x038, 1, 8)
#define VID_MODE_TYPE DSI_HOST_BITS(0x038, 2, 0)
#define VID_PKT_SIZE DSI_HOST_BITS(0x03c, 14, 0)
#define NUM_CHUNKS DSI_HOST_BITS(0x040, 13, 0)
#define NULL_PKT_SIZE DSI_HOST_BITS(0x044, 13, 0)
#define VID_HSA_TIME DSI_HOST_BITS(0x048, 12, 0)
#define VID_HBP_TIME DSI_HOST_BITS(0x04c, 12, 0)
#define VID_HLINE_TIME DSI_HOST_BITS(0x050, 15, 0)
#define VID_VSA_LINES DSI_HOST_BITS(0x054, 10, 0)
#define VID_VBP_LINES DSI_HOST_BITS(0x058, 10, 0)
#define VID_VFP_LINES DSI_HOST_BITS(0x05c, 10, 0)
#define VID_ACTIVE_LINES DSI_HOST_BITS(0x060, 14, 0)
#define EDPI_CMD_SIZE DSI_HOST_BITS(0x064, 16, 0)
#define MAX_RD_PKT_SIZE DSI_HOST_BITS(0x068, 1, 24)
#define DCS_LW_TX DSI_HOST_BITS(0x068, 1, 19)
#define DCS_SR_0P_TX DSI_HOST_BITS(0x068, 1, 18)
#define DCS_SW_1P_TX DSI_HOST_BITS(0x068, 1, 17)
#define DCS_SW_0P_TX DSI_HOST_BITS(0x068, 1, 16)
#define GEN_LW_TX DSI_HOST_BITS(0x068, 1, 14)
#define GEN_SR_2P_TX DSI_HOST_BITS(0x068, 1, 13)
#define GEN_SR_1P_TX DSI_HOST_BITS(0x068, 1, 12)
#define GEN_SR_0P_TX DSI_HOST_BITS(0x068, 1, 11)
#define GEN_SW_2P_TX DSI_HOST_BITS(0x068, 1, 10)
#define GEN_SW_1P_TX DSI_HOST_BITS(0x068, 1, 9)
#define GEN_SW_0P_TX DSI_HOST_BITS(0x068, 1, 8)
#define ACK_RQST_EN DSI_HOST_BITS(0x068, 1, 1)
#define TEAR_FX_EN DSI_HOST_BITS(0x068, 1, 0)
#define GEN_WC_MSBYTE DSI_HOST_BITS(0x06c, 14, 16)
#define GEN_WC_LSBYTE DSI_HOST_BITS(0x06c, 8, 8)
#define GEN_VC DSI_HOST_BITS(0x06c, 2, 6)
#define GEN_DT DSI_HOST_BITS(0x06c, 6, 0)
#define GEN_PLD_DATA DSI_HOST_BITS(0x070, 32, 0)
#define GEN_RD_CMD_BUSY DSI_HOST_BITS(0x074, 1, 6)
#define GEN_PLD_R_FULL DSI_HOST_BITS(0x074, 1, 5)
#define GEN_PLD_R_EMPTY DSI_HOST_BITS(0x074, 1, 4)
#define GEN_PLD_W_FULL DSI_HOST_BITS(0x074, 1, 3)
#define GEN_PLD_W_EMPTY DSI_HOST_BITS(0x074, 1, 2)
#define GEN_CMD_FULL DSI_HOST_BITS(0x074, 1, 1)
#define GEN_CMD_EMPTY DSI_HOST_BITS(0x074, 1, 0)
#define HSTX_TO_CNT DSI_HOST_BITS(0x078, 16, 16)
#define LPRX_TO_CNT DSI_HOST_BITS(0x078, 16, 0)
#define HS_RD_TO_CNT DSI_HOST_BITS(0x07c, 16, 0)
#define LP_RD_TO_CNT DSI_HOST_BITS(0x080, 16, 0)
#define PRESP_TO_MODE DSI_HOST_BITS(0x084, 1, 24)
#define HS_WR_TO_CNT DSI_HOST_BITS(0x084, 16, 0)
#define LP_WR_TO_CNT DSI_HOST_BITS(0x088, 16, 0)
#define BTA_TO_CNT DSI_HOST_BITS(0x08c, 16, 0)
#define AUTO_CLKLANE_CTRL DSI_HOST_BITS(0x094, 1, 1)
#define PHY_TXREQUESTCLKHS DSI_HOST_BITS(0x094, 1, 0)
#define PHY_HS2LP_TIME_CLK_LANE DSI_HOST_BITS(0x098, 10, 16)
#define PHY_HS2HS_TIME_CLK_LANE DSI_HOST_BITS(0x098, 10, 0)
#define PHY_HS2LP_TIME DSI_HOST_BITS(0x09c, 8, 24)
#define PHY_LP2HS_TIME DSI_HOST_BITS(0x09c, 8, 16)
#define MAX_RD_TIME DSI_HOST_BITS(0x09c, 15, 0)
#define PHY_FORCEPLL DSI_HOST_BITS(0x0a0, 1, 3)
#define PHY_ENABLECLK DSI_HOST_BITS(0x0a0, 1, 2)
#define PHY_RSTZ DSI_HOST_BITS(0x0a0, 1, 1)
#define PHY_SHUTDOWNZ DSI_HOST_BITS(0x0a0, 1, 0)
#define PHY_STOP_WAIT_TIME DSI_HOST_BITS(0x0a4, 8, 8)
#define N_LANES DSI_HOST_BITS(0x0a4, 2, 0)
#define PHY_TXEXITULPSLAN DSI_HOST_BITS(0x0a8, 1, 3)
#define PHY_TXREQULPSLAN DSI_HOST_BITS(0x0a8, 1, 2)
#define PHY_TXEXITULPSCLK DSI_HOST_BITS(0x0a8, 1, 1)
#define PHY_TXREQULPSCLK DSI_HOST_BITS(0x0a8, 1, 0)
#define PHY_TX_TRIGGERS DSI_HOST_BITS(0x0ac, 4, 0)
#define PHYSTOPSTATECLKLANE DSI_HOST_BITS(0x0b0, 1, 2)
#define PHYLOCK DSI_HOST_BITS(0x0b0, 1, 0)
#define PHY_TESTCLK DSI_HOST_BITS(0x0b4, 1, 1)
#define PHY_TESTCLR DSI_HOST_BITS(0x0b4, 1, 0)
#define PHY_TESTEN DSI_HOST_BITS(0x0b8, 1, 16)
#define PHY_TESTDOUT DSI_HOST_BITS(0x0b8, 8, 8)
#define PHY_TESTDIN DSI_HOST_BITS(0x0b8, 8, 0)
#define PHY_TEST_CTRL1 DSI_HOST_BITS(0x0b8, 17, 0)
#define PHY_TEST_CTRL0 DSI_HOST_BITS(0x0b4, 2, 0)
#define INT_ST0 DSI_HOST_BITS(0x0bc, 21, 0)
#define INT_ST1 DSI_HOST_BITS(0x0c0, 18, 0)
#define INT_MKS0 DSI_HOST_BITS(0x0c4, 21, 0)
#define INT_MKS1 DSI_HOST_BITS(0x0c8, 18, 0)
#define INT_FORCE0 DSI_HOST_BITS(0x0d8, 21, 0)
#define INT_FORCE1 DSI_HOST_BITS(0x0dc, 18, 0)
#define CODE_HS_RX_CLOCK 0x34
#define CODE_HS_RX_LANE0 0x44
#define CODE_HS_RX_LANE1 0x54
#define CODE_HS_RX_LANE2 0x84
#define CODE_HS_RX_LANE3 0x94
#define CODE_PLL_VCORANGE_VCOCAP 0x10
#define CODE_PLL_CPCTRL 0x11
#define CODE_PLL_LPF_CP 0x12
#define CODE_PLL_INPUT_DIV_RAT 0x17
#define CODE_PLL_LOOP_DIV_RAT 0x18
#define CODE_PLL_INPUT_LOOP_DIV_RAT 0x19
#define CODE_BANDGAP_BIAS_CTRL 0x20
#define CODE_TERMINATION_CTRL 0x21
#define CODE_AFE_BIAS_BANDGAP_ANOLOG 0x22
#define CODE_HSTXDATALANEREQUSETSTATETIME 0x70
#define CODE_HSTXDATALANEPREPARESTATETIME 0x71
#define CODE_HSTXDATALANEHSZEROSTATETIME 0x72
/* Transmission mode between vop and MIPI controller */
enum vid_mode_type_t {
NON_BURST_SYNC_PLUSE = 0,
NON_BURST_SYNC_EVENT,
BURST_MODE,
};
enum cmd_video_mode {
VIDEO_MODE = 0,
CMD_MODE,
};
/* Indicate MIPI DSI color mode */
enum dpi_color_coding {
DPI_16BIT_CFG_1 = 0,
DPI_16BIT_CFG_2,
DPI_16BIT_CFG_3,
DPI_18BIT_CFG_1,
DPI_18BIT_CFG_2,
DPI_24BIT,
DPI_20BIT_YCBCR_422_LP,
DPI_24BIT_YCBCR_422,
DPI_16BIT_YCBCR_422,
DPI_30BIT,
DPI_36BIT,
DPI_12BIT_YCBCR_420,
};
/* Indicate which VOP the MIPI DSI use, bit or little one */
enum vop_id {
VOP_B = 0,
VOP_L,
};
#endif /* end of ROCKCHIP_MIPI_DSI_H */

View file

@ -90,6 +90,7 @@ enum vop_modes {
VOP_MODE_EDP = 0, VOP_MODE_EDP = 0,
VOP_MODE_HDMI, VOP_MODE_HDMI,
VOP_MODE_LVDS, VOP_MODE_LVDS,
VOP_MODE_MIPI,
VOP_MODE_NONE, VOP_MODE_NONE,
VOP_MODE_AUTO_DETECT, VOP_MODE_AUTO_DETECT,
VOP_MODE_UNKNOWN, VOP_MODE_UNKNOWN,

View file

@ -74,6 +74,14 @@ config ROCKCHIP_SPL_BACK_TO_BROM
SPL will return to the boot rom, which will then load the U-Boot SPL will return to the boot rom, which will then load the U-Boot
binary to keep going on. binary to keep going on.
config ROCKCHIP_SPL_RESERVE_IRAM
hex "Size of IRAM reserved in SPL"
default 0x4000
help
SPL may need reserve memory for firmware loaded by SPL, whose load
address is in IRAM and may overlay with SPL text area if not
reserved.
config ROCKCHIP_BROM_HELPER config ROCKCHIP_BROM_HELPER
bool bool

View file

@ -164,7 +164,6 @@ void board_init_f(ulong dummy)
int ret; int ret;
/* Example code showing how to enable the debug UART on RK3288 */ /* Example code showing how to enable the debug UART on RK3288 */
#ifdef EARLY_UART
#include <asm/arch/grf_rk3288.h> #include <asm/arch/grf_rk3288.h>
/* Enable early UART on the RK3288 */ /* Enable early UART on the RK3288 */
#define GRF_BASE 0xff770000 #define GRF_BASE 0xff770000
@ -183,8 +182,7 @@ void board_init_f(ulong dummy)
* printascii("string"); * printascii("string");
*/ */
debug_uart_init(); debug_uart_init();
#endif debug("\nspl:debug uart enabled in %s\n", __func__);
ret = spl_early_init(); ret = spl_early_init();
if (ret) { if (ret) {
debug("spl_early_init() failed: %d\n", ret); debug("spl_early_init() failed: %d\n", ret);
@ -205,7 +203,7 @@ void board_init_f(ulong dummy)
debug("Pinctrl init failed: %d\n", ret); debug("Pinctrl init failed: %d\n", ret);
return; return;
} }
debug("\nspl:init dram\n");
ret = uclass_get_device(UCLASS_RAM, 0, &dev); ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret) { if (ret) {
debug("DRAM init failed: %d\n", ret); debug("DRAM init failed: %d\n", ret);

View file

@ -24,7 +24,7 @@
#include <asm/arch/sdram.h> #include <asm/arch/sdram.h>
#include <linux/err.h> #include <linux/err.h>
#include <power/regulator.h> #include <power/regulator.h>
#include <power/rk808_pmic.h> #include <power/rk8xx_pmic.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
@ -981,11 +981,11 @@ static int veyron_init(struct dram_info *priv)
return ret; return ret;
/* Slowly raise to max CPU voltage to prevent overshoot */ /* Slowly raise to max CPU voltage to prevent overshoot */
ret = rk808_spl_configure_buck(pmic, 1, 1200000); ret = rk8xx_spl_configure_buck(pmic, 1, 1200000);
if (ret) if (ret)
return ret; return ret;
udelay(175);/* Must wait for voltage to stabilize, 2mV/us */ udelay(175);/* Must wait for voltage to stabilize, 2mV/us */
ret = rk808_spl_configure_buck(pmic, 1, 1400000); ret = rk8xx_spl_configure_buck(pmic, 1, 1400000);
if (ret) if (ret)
return ret; return ret;
udelay(100);/* Must wait for voltage to stabilize, 2mV/us */ udelay(100);/* Must wait for voltage to stabilize, 2mV/us */

View file

@ -15,13 +15,13 @@ static struct mm_region rk3399_mem_map[] = {
{ {
.virt = 0x0UL, .virt = 0x0UL,
.phys = 0x0UL, .phys = 0x0UL,
.size = 0x80000000UL, .size = 0xf8000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE
}, { }, {
.virt = 0xf0000000UL, .virt = 0xf8000000UL,
.phys = 0xf0000000UL, .phys = 0xf8000000UL,
.size = 0x10000000UL, .size = 0x08000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN PTE_BLOCK_PXN | PTE_BLOCK_UXN

View file

@ -1280,6 +1280,8 @@ static int rk3399_dmc_probe(struct udevice *dev)
priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF); priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
debug("%s: pmugrf=%p\n", __func__, priv->pmugrf); debug("%s: pmugrf=%p\n", __func__, priv->pmugrf);
priv->info.base = 0;
priv->info.size = sdram_size_mb(priv) << 20;
#endif #endif
return 0; return 0;
} }
@ -1288,9 +1290,7 @@ static int rk3399_dmc_get_info(struct udevice *dev, struct ram_info *info)
{ {
struct dram_info *priv = dev_get_priv(dev); struct dram_info *priv = dev_get_priv(dev);
info = &priv->info; *info = priv->info;
priv->info.base = 0;
priv->info.size = sdram_size_mb(priv) << 20;
return 0; return 0;
} }
@ -1314,8 +1314,8 @@ U_BOOT_DRIVER(dmc_rk3399) = {
.ofdata_to_platdata = rk3399_dmc_ofdata_to_platdata, .ofdata_to_platdata = rk3399_dmc_ofdata_to_platdata,
#endif #endif
.probe = rk3399_dmc_probe, .probe = rk3399_dmc_probe,
#ifdef CONFIG_SPL_BUILD
.priv_auto_alloc_size = sizeof(struct dram_info), .priv_auto_alloc_size = sizeof(struct dram_info),
#ifdef CONFIG_SPL_BUILD
.platdata_auto_alloc_size = sizeof(struct rockchip_dmc_plat), .platdata_auto_alloc_size = sizeof(struct rockchip_dmc_plat),
#endif #endif
}; };

View file

@ -5,6 +5,7 @@
*/ */
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <ram.h>
#include <dm/pinctrl.h> #include <dm/pinctrl.h>
#include <dm/uclass-internal.h> #include <dm/uclass-internal.h>
#include <asm/arch/periph.h> #include <asm/arch/periph.h>
@ -28,6 +29,13 @@ int board_init(void)
goto out; goto out;
} }
/* Enable pwm0 for panel backlight */
ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_PWM0);
if (ret) {
debug("%s PWM0 pinctrl init fail! (ret=%d)\n", __func__, ret);
goto out;
}
ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_PWM2); ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_PWM2);
if (ret) { if (ret) {
debug("%s PWM2 pinctrl init fail!\n", __func__); debug("%s PWM2 pinctrl init fail!\n", __func__);
@ -40,10 +48,9 @@ int board_init(void)
goto out; goto out;
} }
/* rk3399 need init vdd_center to get correct output voltage */ ret = regulators_enable_boot_on(false);
ret = regulator_get_by_platname("vdd_center", &regulator);
if (ret) if (ret)
debug("%s: Cannot get vdd_center regulator\n", __func__); debug("%s: Cannot enable boot on regulator\n", __func__);
ret = regulator_get_by_platname("vcc5v0_host", &regulator); ret = regulator_get_by_platname("vcc5v0_host", &regulator);
if (ret) { if (ret) {
@ -63,7 +70,23 @@ out:
int dram_init(void) int dram_init(void)
{ {
gd->ram_size = 0x80000000; struct ram_info ram;
struct udevice *dev;
int ret;
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret) {
debug("DRAM init failed: %d\n", ret);
return ret;
}
ret = ram_get_info(dev, &ram);
if (ret) {
debug("Cannot get DRAM size: %d\n", ret);
return ret;
}
debug("SDRAM base=%llx, size=%x\n", ram.base, (unsigned int)ram.size);
gd->ram_size = ram.size;
return 0; return 0;
} }

View file

@ -5,3 +5,31 @@
*/ */
#include <common.h> #include <common.h>
#include <dm.h>
#include <i2c_eeprom.h>
#include <netdev.h>
static int get_ethaddr_from_eeprom(u8 *addr)
{
int ret;
struct udevice *dev;
ret = uclass_first_device_err(UCLASS_I2C_EEPROM, &dev);
if (ret)
return ret;
return i2c_eeprom_read(dev, 0, addr, 6);
}
int rk_board_late_init(void)
{
u8 ethaddr[6];
if (get_ethaddr_from_eeprom(ethaddr))
return 0;
if (is_valid_ethaddr(ethaddr))
eth_setenv_enetaddr("ethaddr", ethaddr);
return 0;
}

View file

@ -5,10 +5,18 @@
*/ */
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <misc.h>
#include <ram.h>
#include <dm/pinctrl.h> #include <dm/pinctrl.h>
#include <dm/uclass-internal.h> #include <dm/uclass-internal.h>
#include <asm/arch/periph.h> #include <asm/arch/periph.h>
#include <power/regulator.h> #include <power/regulator.h>
#include <u-boot/sha256.h>
DECLARE_GLOBAL_DATA_PTR;
#define RK3399_CPUID_OFF 0x7
#define RK3399_CPUID_LEN 0x10
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
@ -57,7 +65,23 @@ out:
int dram_init(void) int dram_init(void)
{ {
gd->ram_size = 0x80000000; struct ram_info ram;
struct udevice *dev;
int ret;
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret) {
debug("DRAM init failed: %d\n", ret);
return ret;
}
ret = ram_get_info(dev, &ram);
if (ret) {
debug("Cannot get DRAM size: %d\n", ret);
return ret;
}
debug("SDRAM base=%llx, size=%x\n", ram.base, (unsigned int)ram.size);
gd->ram_size = ram.size;
return 0; return 0;
} }

View file

@ -54,10 +54,10 @@ CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_PINCTRL_ROCKCHIP_RK3288=y
CONFIG_DM_PMIC=y CONFIG_DM_PMIC=y
# CONFIG_SPL_PMIC_CHILDREN is not set # CONFIG_SPL_PMIC_CHILDREN is not set
CONFIG_PMIC_RK808=y CONFIG_PMIC_RK8XX=y
CONFIG_SPL_DM_REGULATOR=y CONFIG_SPL_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y CONFIG_RAM=y
CONFIG_SPL_RAM=y CONFIG_SPL_RAM=y
@ -72,6 +72,7 @@ CONFIG_SYSRESET=y
CONFIG_DM_VIDEO=y CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y CONFIG_DISPLAY=y
CONFIG_VIDEO_ROCKCHIP=y CONFIG_VIDEO_ROCKCHIP=y
CONFIG_DISPLAY_ROCKCHIP_HDMI=y
CONFIG_USE_TINY_PRINTF=y CONFIG_USE_TINY_PRINTF=y
CONFIG_CMD_DHRYSTONE=y CONFIG_CMD_DHRYSTONE=y
CONFIG_ERRNO_STR=y CONFIG_ERRNO_STR=y

View file

@ -55,9 +55,9 @@ CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_PINCTRL_ROCKCHIP_RK3288=y
CONFIG_DM_PMIC=y CONFIG_DM_PMIC=y
# CONFIG_SPL_PMIC_CHILDREN is not set # CONFIG_SPL_PMIC_CHILDREN is not set
CONFIG_PMIC_RK808=y CONFIG_PMIC_RK8XX=y
CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y CONFIG_RAM=y
CONFIG_SPL_RAM=y CONFIG_SPL_RAM=y
@ -72,6 +72,8 @@ CONFIG_SYSRESET=y
CONFIG_DM_VIDEO=y CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y CONFIG_DISPLAY=y
CONFIG_VIDEO_ROCKCHIP=y CONFIG_VIDEO_ROCKCHIP=y
CONFIG_DISPLAY_ROCKCHIP_EDP=y
CONFIG_DISPLAY_ROCKCHIP_HDMI=y
CONFIG_CONSOLE_SCROLL_LINES=10 CONFIG_CONSOLE_SCROLL_LINES=10
CONFIG_USE_TINY_PRINTF=y CONFIG_USE_TINY_PRINTF=y
CONFIG_CMD_DHRYSTONE=y CONFIG_CMD_DHRYSTONE=y

View file

@ -55,9 +55,9 @@ CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_PINCTRL_ROCKCHIP_RK3288=y
CONFIG_DM_PMIC=y CONFIG_DM_PMIC=y
# CONFIG_SPL_PMIC_CHILDREN is not set # CONFIG_SPL_PMIC_CHILDREN is not set
CONFIG_PMIC_RK808=y CONFIG_PMIC_RK8XX=y
CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y CONFIG_RAM=y
CONFIG_SPL_RAM=y CONFIG_SPL_RAM=y
@ -72,6 +72,8 @@ CONFIG_SYSRESET=y
CONFIG_DM_VIDEO=y CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y CONFIG_DISPLAY=y
CONFIG_VIDEO_ROCKCHIP=y CONFIG_VIDEO_ROCKCHIP=y
CONFIG_DISPLAY_ROCKCHIP_HDMI=y
CONFIG_DISPLAY_ROCKCHIP_EDP=y
CONFIG_CONSOLE_SCROLL_LINES=10 CONFIG_CONSOLE_SCROLL_LINES=10
CONFIG_USE_TINY_PRINTF=y CONFIG_USE_TINY_PRINTF=y
CONFIG_CMD_DHRYSTONE=y CONFIG_CMD_DHRYSTONE=y

View file

@ -34,14 +34,21 @@ CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y CONFIG_MMC_DW=y
CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ROCKCHIP=y CONFIG_MMC_SDHCI_ROCKCHIP=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_RK808=y
CONFIG_REGULATOR_RK808=y
CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_GMAC_ROCKCHIP=y
CONFIG_PINCTRL=y CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_ROCKCHIP_RK3399=y CONFIG_PINCTRL_ROCKCHIP_RK3399=y
CONFIG_DM_PMIC=y CONFIG_DM_PMIC=y
CONFIG_PMIC_RK808=y CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_PWM=y
CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y CONFIG_RAM=y
CONFIG_SPL_RAM=y CONFIG_SPL_RAM=y
@ -58,5 +65,9 @@ CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE=y
CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y
CONFIG_VIDEO_ROCKCHIP=y
CONFIG_DISPLAY_ROCKCHIP_MIPI=y
CONFIG_USE_TINY_PRINTF=y CONFIG_USE_TINY_PRINTF=y
CONFIG_ERRNO_STR=y CONFIG_ERRNO_STR=y

View file

@ -49,9 +49,9 @@ CONFIG_SPL_PINCTRL=y
# CONFIG_SPL_PINCTRL_FULL is not set # CONFIG_SPL_PINCTRL_FULL is not set
CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_PINCTRL_ROCKCHIP_RK3288=y
CONFIG_DM_PMIC=y CONFIG_DM_PMIC=y
CONFIG_PMIC_RK808=y CONFIG_PMIC_RK8XX=y
CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y CONFIG_RAM=y
CONFIG_SPL_RAM=y CONFIG_SPL_RAM=y

View file

@ -69,6 +69,7 @@ CONFIG_USB_STORAGE=y
CONFIG_DM_VIDEO=y CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y CONFIG_DISPLAY=y
CONFIG_VIDEO_ROCKCHIP=y CONFIG_VIDEO_ROCKCHIP=y
CONFIG_DISPLAY_ROCKCHIP_HDMI=y
CONFIG_CONSOLE_SCROLL_LINES=10 CONFIG_CONSOLE_SCROLL_LINES=10
CONFIG_USE_TINY_PRINTF=y CONFIG_USE_TINY_PRINTF=y
CONFIG_CMD_DHRYSTONE=y CONFIG_CMD_DHRYSTONE=y

View file

@ -0,0 +1,65 @@
CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SYS_MALLOC_F_LEN=0x4000
CONFIG_ROCKCHIP_RK3399=y
CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEFAULT_DEVICE_TREE="rk3399-firefly"
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x4000
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_IMLS is not set
CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIME=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
CONFIG_SPL_OF_PLATDATA=y
CONFIG_REGMAP=y
CONFIG_SPL_REGMAP=y
CONFIG_SYSCON=y
CONFIG_SPL_SYSCON=y
CONFIG_CLK=y
CONFIG_SPL_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ROCKCHIP=y
CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_GMAC_ROCKCHIP=y
CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y
CONFIG_ROCKCHIP_RK3399_PINCTRL=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y
CONFIG_SPL_RAM=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_STORAGE=y
CONFIG_USE_TINY_PRINTF=y
CONFIG_ERRNO_STR=y

View file

@ -66,6 +66,7 @@ CONFIG_USB_STORAGE=y
CONFIG_DM_VIDEO=y CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y CONFIG_DISPLAY=y
CONFIG_VIDEO_ROCKCHIP=y CONFIG_VIDEO_ROCKCHIP=y
CONFIG_DISPLAY_ROCKCHIP_HDMI=y
CONFIG_CONSOLE_SCROLL_LINES=10 CONFIG_CONSOLE_SCROLL_LINES=10
CONFIG_USE_TINY_PRINTF=y CONFIG_USE_TINY_PRINTF=y
CONFIG_CMD_DHRYSTONE=y CONFIG_CMD_DHRYSTONE=y

View file

@ -49,9 +49,9 @@ CONFIG_SPL_PINCTRL=y
# CONFIG_SPL_PINCTRL_FULL is not set # CONFIG_SPL_PINCTRL_FULL is not set
CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_PINCTRL_ROCKCHIP_RK3288=y
CONFIG_DM_PMIC=y CONFIG_DM_PMIC=y
CONFIG_PMIC_RK808=y CONFIG_PMIC_RK8XX=y
CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y CONFIG_RAM=y
CONFIG_SPL_RAM=y CONFIG_SPL_RAM=y

View file

@ -64,6 +64,7 @@ CONFIG_SYSRESET=y
CONFIG_DM_VIDEO=y CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y CONFIG_DISPLAY=y
CONFIG_VIDEO_ROCKCHIP=y CONFIG_VIDEO_ROCKCHIP=y
CONFIG_DISPLAY_ROCKCHIP_HDMI=y
CONFIG_CONSOLE_SCROLL_LINES=10 CONFIG_CONSOLE_SCROLL_LINES=10
CONFIG_USE_TINY_PRINTF=y CONFIG_USE_TINY_PRINTF=y
CONFIG_CMD_DHRYSTONE=y CONFIG_CMD_DHRYSTONE=y

View file

@ -127,7 +127,7 @@ CONFIG_PMIC_ACT8846=y
CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_PFUZE100=y
CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MAX77686=y
CONFIG_PMIC_PM8916=y CONFIG_PMIC_PM8916=y
CONFIG_PMIC_RK808=y CONFIG_PMIC_RK8XX=y
CONFIG_PMIC_S2MPS11=y CONFIG_PMIC_S2MPS11=y
CONFIG_DM_PMIC_SANDBOX=y CONFIG_DM_PMIC_SANDBOX=y
CONFIG_PMIC_S5M8767=y CONFIG_PMIC_S5M8767=y
@ -137,7 +137,7 @@ CONFIG_REGULATOR_ACT8846=y
CONFIG_DM_REGULATOR_PFUZE100=y CONFIG_DM_REGULATOR_PFUZE100=y
CONFIG_DM_REGULATOR_MAX77686=y CONFIG_DM_REGULATOR_MAX77686=y
CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RK8XX=y
CONFIG_REGULATOR_S5M8767=y CONFIG_REGULATOR_S5M8767=y
CONFIG_DM_REGULATOR_SANDBOX=y CONFIG_DM_REGULATOR_SANDBOX=y
CONFIG_REGULATOR_TPS65090=y CONFIG_REGULATOR_TPS65090=y

View file

@ -131,7 +131,7 @@ CONFIG_PMIC_ACT8846=y
CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_PFUZE100=y
CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MAX77686=y
CONFIG_PMIC_PM8916=y CONFIG_PMIC_PM8916=y
CONFIG_PMIC_RK808=y CONFIG_PMIC_RK8XX=y
CONFIG_PMIC_S2MPS11=y CONFIG_PMIC_S2MPS11=y
CONFIG_DM_PMIC_SANDBOX=y CONFIG_DM_PMIC_SANDBOX=y
CONFIG_PMIC_S5M8767=y CONFIG_PMIC_S5M8767=y
@ -141,7 +141,7 @@ CONFIG_REGULATOR_ACT8846=y
CONFIG_DM_REGULATOR_PFUZE100=y CONFIG_DM_REGULATOR_PFUZE100=y
CONFIG_DM_REGULATOR_MAX77686=y CONFIG_DM_REGULATOR_MAX77686=y
CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RK8XX=y
CONFIG_REGULATOR_S5M8767=y CONFIG_REGULATOR_S5M8767=y
CONFIG_DM_REGULATOR_SANDBOX=y CONFIG_DM_REGULATOR_SANDBOX=y
CONFIG_REGULATOR_TPS65090=y CONFIG_REGULATOR_TPS65090=y

View file

@ -133,7 +133,7 @@ CONFIG_PMIC_ACT8846=y
CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_PFUZE100=y
CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MAX77686=y
CONFIG_PMIC_PM8916=y CONFIG_PMIC_PM8916=y
CONFIG_PMIC_RK808=y CONFIG_PMIC_RK8XX=y
CONFIG_PMIC_S2MPS11=y CONFIG_PMIC_S2MPS11=y
CONFIG_DM_PMIC_SANDBOX=y CONFIG_DM_PMIC_SANDBOX=y
CONFIG_PMIC_S5M8767=y CONFIG_PMIC_S5M8767=y
@ -143,7 +143,7 @@ CONFIG_REGULATOR_ACT8846=y
CONFIG_DM_REGULATOR_PFUZE100=y CONFIG_DM_REGULATOR_PFUZE100=y
CONFIG_DM_REGULATOR_MAX77686=y CONFIG_DM_REGULATOR_MAX77686=y
CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RK8XX=y
CONFIG_REGULATOR_S5M8767=y CONFIG_REGULATOR_S5M8767=y
CONFIG_DM_REGULATOR_SANDBOX=y CONFIG_DM_REGULATOR_SANDBOX=y
CONFIG_REGULATOR_TPS65090=y CONFIG_REGULATOR_TPS65090=y

View file

@ -11,6 +11,7 @@ CONFIG_CONSOLE_MUX=y
# CONFIG_DISPLAY_CPUINFO is not set # CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
CONFIG_SPL_I2C_SUPPORT=y
# CONFIG_CMD_IMLS is not set # CONFIG_CMD_IMLS is not set
CONFIG_CMD_GPT=y CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y CONFIG_CMD_MMC=y
@ -39,6 +40,8 @@ CONFIG_CLK=y
CONFIG_SPL_CLK=y CONFIG_SPL_CLK=y
CONFIG_ROCKCHIP_GPIO=y CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MISC=y
CONFIG_I2C_EEPROM=y
CONFIG_MMC_DW=y CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_DM_ETH=y CONFIG_DM_ETH=y
@ -49,9 +52,9 @@ CONFIG_SPL_PINCTRL=y
# CONFIG_SPL_PINCTRL_FULL is not set # CONFIG_SPL_PINCTRL_FULL is not set
CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_PINCTRL_ROCKCHIP_RK3288=y
CONFIG_DM_PMIC=y CONFIG_DM_PMIC=y
CONFIG_PMIC_RK808=y CONFIG_PMIC_RK8XX=y
CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y CONFIG_RAM=y
CONFIG_SPL_RAM=y CONFIG_SPL_RAM=y

View file

@ -0,0 +1,69 @@
Specifying PWM information for devices
======================================
1) PWM user nodes
-----------------
PWM users should specify a list of PWM devices that they want to use
with a property containing a 'pwm-list':
pwm-list ::= <single-pwm> [pwm-list]
single-pwm ::= <pwm-phandle> <pwm-specifier>
pwm-phandle : phandle to PWM controller node
pwm-specifier : array of #pwm-cells specifying the given PWM
(controller specific)
PWM properties should be named "pwms". The exact meaning of each pwms
property must be documented in the device tree binding for each device.
An optional property "pwm-names" may contain a list of strings to label
each of the PWM devices listed in the "pwms" property. If no "pwm-names"
property is given, the name of the user node will be used as fallback.
Drivers for devices that use more than a single PWM device can use the
"pwm-names" property to map the name of the PWM device requested by the
pwm_get() call to an index into the list given by the "pwms" property.
The following example could be used to describe a PWM-based backlight
device:
pwm: pwm {
#pwm-cells = <2>;
};
[...]
bl: backlight {
pwms = <&pwm 0 5000000>;
pwm-names = "backlight";
};
Note that in the example above, specifying the "pwm-names" is redundant
because the name "backlight" would be used as fallback anyway.
pwm-specifier typically encodes the chip-relative PWM number and the PWM
period in nanoseconds.
Optionally, the pwm-specifier can encode a number of flags (defined in
<dt-bindings/pwm/pwm.h>) in a third cell:
- PWM_POLARITY_INVERTED: invert the PWM signal polarity
Example with optional PWM specifier for inverse polarity
bl: backlight {
pwms = <&pwm 0 5000000 PWM_POLARITY_INVERTED>;
pwm-names = "backlight";
};
2) PWM controller nodes
-----------------------
PWM controller nodes must specify the number of cells used for the
specifier using the '#pwm-cells' property.
An example PWM controller might look like this:
pwm: pwm@7000a000 {
compatible = "nvidia,tegra20-pwm";
reg = <0x7000a000 0x100>;
#pwm-cells = <2>;
};

View file

@ -228,11 +228,13 @@ static ulong rockchip_mmc_get_clk(struct rk3036_cru *cru, uint clk_general_rate,
switch (periph) { switch (periph) {
case HCLK_EMMC: case HCLK_EMMC:
case SCLK_EMMC:
con = readl(&cru->cru_clksel_con[12]); con = readl(&cru->cru_clksel_con[12]);
mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK; mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK;
div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK; div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
break; break;
case HCLK_SDIO: case HCLK_SDIO:
case SCLK_SDIO:
con = readl(&cru->cru_clksel_con[12]); con = readl(&cru->cru_clksel_con[12]);
mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK; mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK;
div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK; div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
@ -265,6 +267,7 @@ static ulong rockchip_mmc_set_clk(struct rk3036_cru *cru, uint clk_general_rate,
switch (periph) { switch (periph) {
case HCLK_EMMC: case HCLK_EMMC:
case SCLK_EMMC:
rk_clrsetreg(&cru->cru_clksel_con[12], rk_clrsetreg(&cru->cru_clksel_con[12],
EMMC_PLL_MASK << EMMC_PLL_SHIFT | EMMC_PLL_MASK << EMMC_PLL_SHIFT |
EMMC_DIV_MASK << EMMC_DIV_SHIFT, EMMC_DIV_MASK << EMMC_DIV_SHIFT,
@ -272,6 +275,7 @@ static ulong rockchip_mmc_set_clk(struct rk3036_cru *cru, uint clk_general_rate,
(src_clk_div - 1) << EMMC_DIV_SHIFT); (src_clk_div - 1) << EMMC_DIV_SHIFT);
break; break;
case HCLK_SDIO: case HCLK_SDIO:
case SCLK_SDIO:
rk_clrsetreg(&cru->cru_clksel_con[11], rk_clrsetreg(&cru->cru_clksel_con[11],
MMC0_PLL_MASK << MMC0_PLL_SHIFT | MMC0_PLL_MASK << MMC0_PLL_SHIFT |
MMC0_DIV_MASK << MMC0_DIV_SHIFT, MMC0_DIV_MASK << MMC0_DIV_SHIFT,
@ -307,6 +311,7 @@ static ulong rk3036_clk_set_rate(struct clk *clk, ulong rate)
case 0 ... 63: case 0 ... 63:
return 0; return 0;
case HCLK_EMMC: case HCLK_EMMC:
case SCLK_EMMC:
new_rate = rockchip_mmc_set_clk(priv->cru, gclk_rate, new_rate = rockchip_mmc_set_clk(priv->cru, gclk_rate,
clk->id, rate); clk->id, rate);
break; break;

View file

@ -269,14 +269,17 @@ static ulong rockchip_mmc_get_clk(struct rk3188_cru *cru, uint gclk_rate,
switch (periph) { switch (periph) {
case HCLK_EMMC: case HCLK_EMMC:
case SCLK_EMMC:
con = readl(&cru->cru_clksel_con[12]); con = readl(&cru->cru_clksel_con[12]);
div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK; div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
break; break;
case HCLK_SDMMC: case HCLK_SDMMC:
case SCLK_SDMMC:
con = readl(&cru->cru_clksel_con[11]); con = readl(&cru->cru_clksel_con[11]);
div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK; div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
break; break;
case HCLK_SDIO: case HCLK_SDIO:
case SCLK_SDIO:
con = readl(&cru->cru_clksel_con[12]); con = readl(&cru->cru_clksel_con[12]);
div = (con >> SDIO_DIV_SHIFT) & SDIO_DIV_MASK; div = (con >> SDIO_DIV_SHIFT) & SDIO_DIV_MASK;
break; break;
@ -298,16 +301,19 @@ static ulong rockchip_mmc_set_clk(struct rk3188_cru *cru, uint gclk_rate,
switch (periph) { switch (periph) {
case HCLK_EMMC: case HCLK_EMMC:
case SCLK_EMMC:
rk_clrsetreg(&cru->cru_clksel_con[12], rk_clrsetreg(&cru->cru_clksel_con[12],
EMMC_DIV_MASK << EMMC_DIV_SHIFT, EMMC_DIV_MASK << EMMC_DIV_SHIFT,
src_clk_div << EMMC_DIV_SHIFT); src_clk_div << EMMC_DIV_SHIFT);
break; break;
case HCLK_SDMMC: case HCLK_SDMMC:
case SCLK_SDMMC:
rk_clrsetreg(&cru->cru_clksel_con[11], rk_clrsetreg(&cru->cru_clksel_con[11],
MMC0_DIV_MASK << MMC0_DIV_SHIFT, MMC0_DIV_MASK << MMC0_DIV_SHIFT,
src_clk_div << MMC0_DIV_SHIFT); src_clk_div << MMC0_DIV_SHIFT);
break; break;
case HCLK_SDIO: case HCLK_SDIO:
case SCLK_SDIO:
rk_clrsetreg(&cru->cru_clksel_con[12], rk_clrsetreg(&cru->cru_clksel_con[12],
SDIO_DIV_MASK << SDIO_DIV_SHIFT, SDIO_DIV_MASK << SDIO_DIV_SHIFT,
src_clk_div << SDIO_DIV_SHIFT); src_clk_div << SDIO_DIV_SHIFT);
@ -466,6 +472,9 @@ static ulong rk3188_clk_get_rate(struct clk *clk)
case HCLK_EMMC: case HCLK_EMMC:
case HCLK_SDMMC: case HCLK_SDMMC:
case HCLK_SDIO: case HCLK_SDIO:
case SCLK_EMMC:
case SCLK_SDMMC:
case SCLK_SDIO:
new_rate = rockchip_mmc_get_clk(priv->cru, PERI_HCLK_HZ, new_rate = rockchip_mmc_get_clk(priv->cru, PERI_HCLK_HZ,
clk->id); clk->id);
break; break;
@ -505,6 +514,9 @@ static ulong rk3188_clk_set_rate(struct clk *clk, ulong rate)
case HCLK_EMMC: case HCLK_EMMC:
case HCLK_SDMMC: case HCLK_SDMMC:
case HCLK_SDIO: case HCLK_SDIO:
case SCLK_EMMC:
case SCLK_SDMMC:
case SCLK_SDIO:
new_rate = rockchip_mmc_set_clk(cru, PERI_HCLK_HZ, new_rate = rockchip_mmc_set_clk(cru, PERI_HCLK_HZ,
clk->id, rate); clk->id, rate);
break; break;

View file

@ -513,16 +513,19 @@ static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint gclk_rate,
switch (periph) { switch (periph) {
case HCLK_EMMC: case HCLK_EMMC:
case SCLK_EMMC:
con = readl(&cru->cru_clksel_con[12]); con = readl(&cru->cru_clksel_con[12]);
mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK; mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK;
div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK; div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
break; break;
case HCLK_SDMMC: case HCLK_SDMMC:
case SCLK_SDMMC:
con = readl(&cru->cru_clksel_con[11]); con = readl(&cru->cru_clksel_con[11]);
mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK; mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK;
div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK; div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
break; break;
case HCLK_SDIO0: case HCLK_SDIO0:
case SCLK_SDIO0:
con = readl(&cru->cru_clksel_con[12]); con = readl(&cru->cru_clksel_con[12]);
mux = (con >> SDIO0_PLL_SHIFT) & SDIO0_PLL_MASK; mux = (con >> SDIO0_PLL_SHIFT) & SDIO0_PLL_MASK;
div = (con >> SDIO0_DIV_SHIFT) & SDIO0_DIV_MASK; div = (con >> SDIO0_DIV_SHIFT) & SDIO0_DIV_MASK;
@ -556,6 +559,7 @@ static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint gclk_rate,
} }
switch (periph) { switch (periph) {
case HCLK_EMMC: case HCLK_EMMC:
case SCLK_EMMC:
rk_clrsetreg(&cru->cru_clksel_con[12], rk_clrsetreg(&cru->cru_clksel_con[12],
EMMC_PLL_MASK << EMMC_PLL_SHIFT | EMMC_PLL_MASK << EMMC_PLL_SHIFT |
EMMC_DIV_MASK << EMMC_DIV_SHIFT, EMMC_DIV_MASK << EMMC_DIV_SHIFT,
@ -563,6 +567,7 @@ static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint gclk_rate,
(src_clk_div - 1) << EMMC_DIV_SHIFT); (src_clk_div - 1) << EMMC_DIV_SHIFT);
break; break;
case HCLK_SDMMC: case HCLK_SDMMC:
case SCLK_SDMMC:
rk_clrsetreg(&cru->cru_clksel_con[11], rk_clrsetreg(&cru->cru_clksel_con[11],
MMC0_PLL_MASK << MMC0_PLL_SHIFT | MMC0_PLL_MASK << MMC0_PLL_SHIFT |
MMC0_DIV_MASK << MMC0_DIV_SHIFT, MMC0_DIV_MASK << MMC0_DIV_SHIFT,
@ -570,6 +575,7 @@ static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint gclk_rate,
(src_clk_div - 1) << MMC0_DIV_SHIFT); (src_clk_div - 1) << MMC0_DIV_SHIFT);
break; break;
case HCLK_SDIO0: case HCLK_SDIO0:
case SCLK_SDIO0:
rk_clrsetreg(&cru->cru_clksel_con[12], rk_clrsetreg(&cru->cru_clksel_con[12],
SDIO0_PLL_MASK << SDIO0_PLL_SHIFT | SDIO0_PLL_MASK << SDIO0_PLL_SHIFT |
SDIO0_DIV_MASK << SDIO0_DIV_SHIFT, SDIO0_DIV_MASK << SDIO0_DIV_SHIFT,
@ -662,6 +668,9 @@ static ulong rk3288_clk_get_rate(struct clk *clk)
case HCLK_EMMC: case HCLK_EMMC:
case HCLK_SDMMC: case HCLK_SDMMC:
case HCLK_SDIO0: case HCLK_SDIO0:
case SCLK_EMMC:
case SCLK_SDMMC:
case SCLK_SDIO0:
new_rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, clk->id); new_rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, clk->id);
break; break;
case SCLK_SPI0: case SCLK_SPI0:
@ -706,6 +715,9 @@ static ulong rk3288_clk_set_rate(struct clk *clk, ulong rate)
case HCLK_EMMC: case HCLK_EMMC:
case HCLK_SDMMC: case HCLK_SDMMC:
case HCLK_SDIO0: case HCLK_SDIO0:
case SCLK_EMMC:
case SCLK_SDMMC:
case SCLK_SDIO0:
new_rate = rockchip_mmc_set_clk(cru, gclk_rate, clk->id, rate); new_rate = rockchip_mmc_set_clk(cru, gclk_rate, clk->id, rate);
break; break;
case SCLK_SPI0: case SCLK_SPI0:

View file

@ -397,9 +397,11 @@ static ulong rk3328_mmc_get_clk(struct rk3328_cru *cru, uint clk_id)
switch (clk_id) { switch (clk_id) {
case HCLK_SDMMC: case HCLK_SDMMC:
case SCLK_SDMMC:
con_id = 30; con_id = 30;
break; break;
case HCLK_EMMC: case HCLK_EMMC:
case SCLK_EMMC:
con_id = 32; con_id = 32;
break; break;
default: default:
@ -423,9 +425,11 @@ static ulong rk3328_mmc_set_clk(struct rk3328_cru *cru,
switch (clk_id) { switch (clk_id) {
case HCLK_SDMMC: case HCLK_SDMMC:
case SCLK_SDMMC:
con_id = 30; con_id = 30;
break; break;
case HCLK_EMMC: case HCLK_EMMC:
case SCLK_EMMC:
con_id = 32; con_id = 32;
break; break;
default: default:
@ -483,6 +487,8 @@ static ulong rk3328_clk_get_rate(struct clk *clk)
return 0; return 0;
case HCLK_SDMMC: case HCLK_SDMMC:
case HCLK_EMMC: case HCLK_EMMC:
case SCLK_SDMMC:
case SCLK_EMMC:
rate = rk3328_mmc_get_clk(priv->cru, clk->id); rate = rk3328_mmc_get_clk(priv->cru, clk->id);
break; break;
case SCLK_I2C0: case SCLK_I2C0:
@ -511,6 +517,8 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate)
return 0; return 0;
case HCLK_SDMMC: case HCLK_SDMMC:
case HCLK_EMMC: case HCLK_EMMC:
case SCLK_SDMMC:
case SCLK_EMMC:
ret = rk3328_mmc_set_clk(priv->cru, clk->id, rate); ret = rk3328_mmc_set_clk(priv->cru, clk->id, rate);
break; break;
case SCLK_I2C0: case SCLK_I2C0:

View file

@ -1,5 +1,6 @@
/* /*
* (C) Copyright 2015 Google, Inc * (C) Copyright 2015 Google, Inc
* (C) 2017 Theobroma Systems Design und Consulting GmbH
* *
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
*/ */
@ -207,12 +208,15 @@ enum {
DCLK_VOP_DIV_CON_SHIFT = 0, DCLK_VOP_DIV_CON_SHIFT = 0,
/* CLKSEL_CON58 */ /* CLKSEL_CON58 */
CLK_SPI_PLL_SEL_MASK = 1, CLK_SPI_PLL_SEL_WIDTH = 1,
CLK_SPI_PLL_SEL_CPLL = 0, CLK_SPI_PLL_SEL_MASK = ((1 < CLK_SPI_PLL_SEL_WIDTH) - 1),
CLK_SPI_PLL_SEL_GPLL = 1, CLK_SPI_PLL_SEL_CPLL = 0,
CLK_SPI_PLL_DIV_CON_MASK = 0x7f, CLK_SPI_PLL_SEL_GPLL = 1,
CLK_SPI5_PLL_DIV_CON_SHIFT = 8, CLK_SPI_PLL_DIV_CON_WIDTH = 7,
CLK_SPI5_PLL_SEL_SHIFT = 15, CLK_SPI_PLL_DIV_CON_MASK = ((1 << CLK_SPI_PLL_DIV_CON_WIDTH) - 1),
CLK_SPI5_PLL_DIV_CON_SHIFT = 8,
CLK_SPI5_PLL_SEL_SHIFT = 15,
/* CLKSEL_CON59 */ /* CLKSEL_CON59 */
CLK_SPI1_PLL_SEL_SHIFT = 15, CLK_SPI1_PLL_SEL_SHIFT = 15,
@ -602,7 +606,96 @@ static ulong rk3399_i2c_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz)
return -EINVAL; return -EINVAL;
} }
return DIV_TO_RATE(GPLL_HZ, src_clk_div); return rk3399_i2c_get_clk(cru, clk_id);
}
/*
* RK3399 SPI clocks have a common divider-width (7 bits) and a single bit
* to select either CPLL or GPLL as the clock-parent. The location within
* the enclosing CLKSEL_CON (i.e. div_shift and sel_shift) are variable.
*/
struct spi_clkreg {
uint8_t reg; /* CLKSEL_CON[reg] register in CRU */
uint8_t div_shift;
uint8_t sel_shift;
};
/*
* The entries are numbered relative to their offset from SCLK_SPI0.
*
* Note that SCLK_SPI3 (which is configured via PMUCRU and requires different
* logic is not supported).
*/
static const struct spi_clkreg spi_clkregs[] = {
[0] = { .reg = 59,
.div_shift = CLK_SPI0_PLL_DIV_CON_SHIFT,
.sel_shift = CLK_SPI0_PLL_SEL_SHIFT, },
[1] = { .reg = 59,
.div_shift = CLK_SPI1_PLL_DIV_CON_SHIFT,
.sel_shift = CLK_SPI1_PLL_SEL_SHIFT, },
[2] = { .reg = 60,
.div_shift = CLK_SPI2_PLL_DIV_CON_SHIFT,
.sel_shift = CLK_SPI2_PLL_SEL_SHIFT, },
[3] = { .reg = 60,
.div_shift = CLK_SPI4_PLL_DIV_CON_SHIFT,
.sel_shift = CLK_SPI4_PLL_SEL_SHIFT, },
[4] = { .reg = 58,
.div_shift = CLK_SPI5_PLL_DIV_CON_SHIFT,
.sel_shift = CLK_SPI5_PLL_SEL_SHIFT, },
};
static inline u32 extract_bits(u32 val, unsigned width, unsigned shift)
{
return (val >> shift) & ((1 << width) - 1);
}
static ulong rk3399_spi_get_clk(struct rk3399_cru *cru, ulong clk_id)
{
const struct spi_clkreg *spiclk = NULL;
u32 div, val;
switch (clk_id) {
case SCLK_SPI0 ... SCLK_SPI5:
spiclk = &spi_clkregs[clk_id - SCLK_SPI0];
break;
default:
error("%s: SPI clk-id %ld not supported\n", __func__, clk_id);
return -EINVAL;
}
val = readl(&cru->clksel_con[spiclk->reg]);
div = extract_bits(val, CLK_SPI_PLL_DIV_CON_WIDTH, spiclk->div_shift);
return DIV_TO_RATE(GPLL_HZ, div);
}
static ulong rk3399_spi_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz)
{
const struct spi_clkreg *spiclk = NULL;
int src_clk_div;
src_clk_div = RATE_TO_DIV(GPLL_HZ, hz);
assert(src_clk_div < 127);
switch (clk_id) {
case SCLK_SPI1 ... SCLK_SPI5:
spiclk = &spi_clkregs[clk_id - SCLK_SPI0];
break;
default:
error("%s: SPI clk-id %ld not supported\n", __func__, clk_id);
return -EINVAL;
}
rk_clrsetreg(&cru->clksel_con[spiclk->reg],
((CLK_SPI_PLL_DIV_CON_MASK << spiclk->div_shift) |
(CLK_SPI_PLL_SEL_GPLL << spiclk->sel_shift)),
((src_clk_div << spiclk->div_shift) |
(CLK_SPI_PLL_SEL_GPLL << spiclk->sel_shift)));
return rk3399_spi_get_clk(cru, clk_id);
} }
static ulong rk3399_vop_set_clk(struct rk3399_cru *cru, ulong clk_id, u32 hz) static ulong rk3399_vop_set_clk(struct rk3399_cru *cru, ulong clk_id, u32 hz)
@ -654,6 +747,7 @@ static ulong rk3399_mmc_get_clk(struct rk3399_cru *cru, uint clk_id)
u32 div, con; u32 div, con;
switch (clk_id) { switch (clk_id) {
case HCLK_SDMMC:
case SCLK_SDMMC: case SCLK_SDMMC:
con = readl(&cru->clksel_con[16]); con = readl(&cru->clksel_con[16]);
break; break;
@ -679,6 +773,7 @@ static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
int aclk_emmc = 198*MHz; int aclk_emmc = 198*MHz;
switch (clk_id) { switch (clk_id) {
case HCLK_SDMMC:
case SCLK_SDMMC: case SCLK_SDMMC:
/* Select clk_sdmmc source from GPLL by default */ /* Select clk_sdmmc source from GPLL by default */
src_clk_div = GPLL_HZ / set_rate; src_clk_div = GPLL_HZ / set_rate;
@ -768,6 +863,7 @@ static ulong rk3399_clk_get_rate(struct clk *clk)
switch (clk->id) { switch (clk->id) {
case 0 ... 63: case 0 ... 63:
return 0; return 0;
case HCLK_SDMMC:
case SCLK_SDMMC: case SCLK_SDMMC:
case SCLK_EMMC: case SCLK_EMMC:
rate = rk3399_mmc_get_clk(priv->cru, clk->id); rate = rk3399_mmc_get_clk(priv->cru, clk->id);
@ -780,9 +876,20 @@ static ulong rk3399_clk_get_rate(struct clk *clk)
case SCLK_I2C7: case SCLK_I2C7:
rate = rk3399_i2c_get_clk(priv->cru, clk->id); rate = rk3399_i2c_get_clk(priv->cru, clk->id);
break; break;
case SCLK_SPI0...SCLK_SPI5:
rate = rk3399_spi_get_clk(priv->cru, clk->id);
break;
case SCLK_UART0:
case SCLK_UART2:
return 24000000;
break;
case PCLK_HDMI_CTRL:
break;
case DCLK_VOP0: case DCLK_VOP0:
case DCLK_VOP1: case DCLK_VOP1:
break; break;
case PCLK_EFUSE1024NS:
break;
default: default:
return -ENOENT; return -ENOENT;
} }
@ -798,6 +905,7 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
switch (clk->id) { switch (clk->id) {
case 0 ... 63: case 0 ... 63:
return 0; return 0;
case HCLK_SDMMC:
case SCLK_SDMMC: case SCLK_SDMMC:
case SCLK_EMMC: case SCLK_EMMC:
ret = rk3399_mmc_set_clk(priv->cru, clk->id, rate); ret = rk3399_mmc_set_clk(priv->cru, clk->id, rate);
@ -814,6 +922,13 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
case SCLK_I2C7: case SCLK_I2C7:
ret = rk3399_i2c_set_clk(priv->cru, clk->id, rate); ret = rk3399_i2c_set_clk(priv->cru, clk->id, rate);
break; break;
case SCLK_SPI0...SCLK_SPI5:
ret = rk3399_spi_set_clk(priv->cru, clk->id, rate);
break;
case PCLK_HDMI_CTRL:
case PCLK_VIO_GRF:
/* the PCLK gates for video are enabled by default */
break;
case DCLK_VOP0: case DCLK_VOP0:
case DCLK_VOP1: case DCLK_VOP1:
ret = rk3399_vop_set_clk(priv->cru, clk->id, rate); ret = rk3399_vop_set_clk(priv->cru, clk->id, rate);
@ -821,6 +936,8 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
case SCLK_DDRCLK: case SCLK_DDRCLK:
ret = rk3399_ddr_set_clk(priv->cru, rate); ret = rk3399_ddr_set_clk(priv->cru, rate);
break; break;
case PCLK_EFUSE1024NS:
break;
default: default:
return -ENOENT; return -ENOENT;
} }

View file

@ -10,21 +10,41 @@
#include <i2c.h> #include <i2c.h>
#include <i2c_eeprom.h> #include <i2c_eeprom.h>
static int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size)
int size) {
const struct i2c_eeprom_ops *ops = device_get_ops(dev);
if (!ops->read)
return -ENOSYS;
return ops->read(dev, offset, buf, size);
}
int i2c_eeprom_write(struct udevice *dev, int offset, uint8_t *buf, int size)
{
const struct i2c_eeprom_ops *ops = device_get_ops(dev);
if (!ops->write)
return -ENOSYS;
return ops->write(dev, offset, buf, size);
}
static int i2c_eeprom_std_read(struct udevice *dev, int offset, uint8_t *buf,
int size)
{ {
return dm_i2c_read(dev, offset, buf, size); return dm_i2c_read(dev, offset, buf, size);
} }
static int i2c_eeprom_write(struct udevice *dev, int offset, static int i2c_eeprom_std_write(struct udevice *dev, int offset,
const uint8_t *buf, int size) const uint8_t *buf, int size)
{ {
return -ENODEV; return -ENODEV;
} }
struct i2c_eeprom_ops i2c_eeprom_std_ops = { struct i2c_eeprom_ops i2c_eeprom_std_ops = {
.read = i2c_eeprom_read, .read = i2c_eeprom_std_read,
.write = i2c_eeprom_write, .write = i2c_eeprom_std_write,
}; };
static int i2c_eeprom_std_ofdata_to_platdata(struct udevice *dev) static int i2c_eeprom_std_ofdata_to_platdata(struct udevice *dev)

View file

@ -44,7 +44,7 @@ static uint rockchip_dwmmc_get_mmc_clk(struct dwmci_host *host, uint freq)
ret = clk_set_rate(&priv->clk, freq); ret = clk_set_rate(&priv->clk, freq);
if (ret < 0) { if (ret < 0) {
debug("%s: err=%d\n", __func__, ret); printf("%s: err=%d\n", __func__, ret);
return ret; return ret;
} }
@ -76,9 +76,25 @@ static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
return -EINVAL; return -EINVAL;
priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev), priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
"fifo-mode"); "fifo-mode");
/*
* 'clock-freq-min-max' is deprecated
* (see https://github.com/torvalds/linux/commit/b023030f10573de738bbe8df63d43acab64c9f7b)
*/
if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
"clock-freq-min-max", priv->minmax, 2)) "clock-freq-min-max", priv->minmax, 2)) {
return -EINVAL; int val = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"max-frequency", -EINVAL);
if (val < 0)
return val;
priv->minmax[0] = 400000; /* 400 kHz */
priv->minmax[1] = val;
} else {
debug("%s: 'clock-freq-min-max' property was deprecated.\n",
__func__);
}
#endif #endif
return 0; return 0;
} }
@ -109,7 +125,7 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
if (ret < 0) if (ret < 0)
return ret; return ret;
#else #else
ret = clk_get_by_index(dev, 0, &priv->clk); ret = clk_get_by_name(dev, "ciu", &priv->clk);
if (ret < 0) if (ret < 0)
return ret; return ret;
#endif #endif

View file

@ -145,7 +145,19 @@ static int pinctrl_rk3399_spi_config(struct rk3399_grf_regs *grf,
| GRF_SPI2TPM_CLK << GRF_GPIO2B3_SEL_SHIFT | GRF_SPI2TPM_CLK << GRF_GPIO2B3_SEL_SHIFT
| GRF_SPI2TPM_CSN0 << GRF_GPIO2B4_SEL_SHIFT); | GRF_SPI2TPM_CSN0 << GRF_GPIO2B4_SEL_SHIFT);
break; break;
case PERIPH_ID_SPI5:
if (cs != 0)
goto err;
rk_clrsetreg(&grf->gpio2c_iomux,
GRF_GPIO2C4_SEL_MASK | GRF_GPIO2C5_SEL_MASK
| GRF_GPIO2C6_SEL_MASK | GRF_GPIO2C7_SEL_MASK,
GRF_SPI5EXPPLUS_RXD << GRF_GPIO2C4_SEL_SHIFT
| GRF_SPI5EXPPLUS_TXD << GRF_GPIO2C5_SEL_SHIFT
| GRF_SPI5EXPPLUS_CLK << GRF_GPIO2C6_SEL_SHIFT
| GRF_SPI5EXPPLUS_CSN0 << GRF_GPIO2C7_SEL_SHIFT);
break;
default: default:
printf("%s: spi_id %d is not supported.\n", __func__, spi_id);
goto err; goto err;
} }
@ -232,6 +244,41 @@ static void pinctrl_rk3399_gmac_config(struct rk3399_grf_regs *grf, int mmc_id)
rk_clrsetreg(&grf->gpio3c_iomux, rk_clrsetreg(&grf->gpio3c_iomux,
GRF_GPIO3C1_SEL_MASK, GRF_GPIO3C1_SEL_MASK,
GRF_MAC_TXCLK << GRF_GPIO3C1_SEL_SHIFT); GRF_MAC_TXCLK << GRF_GPIO3C1_SEL_SHIFT);
/* Set drive strength for GMAC tx io, value 3 means 13mA */
rk_clrsetreg(&grf->gpio3_e[0],
GRF_GPIO3A0_E_MASK | GRF_GPIO3A1_E_MASK |
GRF_GPIO3A4_E_MASK | GRF_GPIO3A5_E0_MASK,
3 << GRF_GPIO3A0_E_SHIFT |
3 << GRF_GPIO3A1_E_SHIFT |
3 << GRF_GPIO3A4_E_SHIFT |
1 << GRF_GPIO3A5_E0_SHIFT);
rk_clrsetreg(&grf->gpio3_e[1],
GRF_GPIO3A5_E12_MASK,
1 << GRF_GPIO3A5_E12_SHIFT);
rk_clrsetreg(&grf->gpio3_e[2],
GRF_GPIO3B4_E_MASK,
3 << GRF_GPIO3B4_E_SHIFT);
rk_clrsetreg(&grf->gpio3_e[4],
GRF_GPIO3C1_E_MASK,
3 << GRF_GPIO3C1_E_SHIFT);
}
#endif
#if !defined(CONFIG_SPL_BUILD)
static void pinctrl_rk3399_hdmi_config(struct rk3399_grf_regs *grf, int hdmi_id)
{
switch (hdmi_id) {
case PERIPH_ID_HDMI:
rk_clrsetreg(&grf->gpio4c_iomux,
GRF_GPIO4C0_SEL_MASK | GRF_GPIO4C1_SEL_MASK,
(GRF_HDMII2C_SCL << GRF_GPIO4C0_SEL_SHIFT) |
(GRF_HDMII2C_SDA << GRF_GPIO4C1_SEL_SHIFT));
break;
default:
debug("%s: hdmi_id = %d unsupported\n", __func__, hdmi_id);
break;
}
} }
#endif #endif
@ -259,6 +306,9 @@ static int rk3399_pinctrl_request(struct udevice *dev, int func, int flags)
case PERIPH_ID_SPI0: case PERIPH_ID_SPI0:
case PERIPH_ID_SPI1: case PERIPH_ID_SPI1:
case PERIPH_ID_SPI2: case PERIPH_ID_SPI2:
case PERIPH_ID_SPI3:
case PERIPH_ID_SPI4:
case PERIPH_ID_SPI5:
pinctrl_rk3399_spi_config(priv->grf, priv->pmugrf, func, flags); pinctrl_rk3399_spi_config(priv->grf, priv->pmugrf, func, flags);
break; break;
case PERIPH_ID_UART0: case PERIPH_ID_UART0:
@ -280,6 +330,11 @@ static int rk3399_pinctrl_request(struct udevice *dev, int func, int flags)
case PERIPH_ID_GMAC: case PERIPH_ID_GMAC:
pinctrl_rk3399_gmac_config(priv->grf, func); pinctrl_rk3399_gmac_config(priv->grf, func);
break; break;
#endif
#if !defined(CONFIG_SPL_BUILD)
case PERIPH_ID_HDMI:
pinctrl_rk3399_hdmi_config(priv->grf, func);
break;
#endif #endif
default: default:
return -EINVAL; return -EINVAL;
@ -307,6 +362,8 @@ static int rk3399_pinctrl_get_periph_id(struct udevice *dev,
return PERIPH_ID_SPI1; return PERIPH_ID_SPI1;
case 52: case 52:
return PERIPH_ID_SPI2; return PERIPH_ID_SPI2;
case 132:
return PERIPH_ID_SPI5;
case 57: case 57:
return PERIPH_ID_I2C0; return PERIPH_ID_I2C0;
case 59: /* Note strange order */ case 59: /* Note strange order */
@ -324,6 +381,10 @@ static int rk3399_pinctrl_get_periph_id(struct udevice *dev,
#if CONFIG_IS_ENABLED(GMAC_ROCKCHIP) #if CONFIG_IS_ENABLED(GMAC_ROCKCHIP)
case 12: case 12:
return PERIPH_ID_GMAC; return PERIPH_ID_GMAC;
#endif
#if !defined(CONFIG_SPL_BUILD)
case 23:
return PERIPH_ID_HDMI;
#endif #endif
} }
#endif #endif

View file

@ -28,7 +28,7 @@ config SPL_PMIC_CHILDREN
This allows PMICs to support child devices (such as regulators) in This allows PMICs to support child devices (such as regulators) in
SPL. This adds quite a bit of code so if you are not using this SPL. This adds quite a bit of code so if you are not using this
feature you can turn it off. In this case you may need a 'back door' feature you can turn it off. In this case you may need a 'back door'
to call your regulator code (e.g. see rk808.c for direct functions to call your regulator code (e.g. see rk8xx.c for direct functions
for use in SPL). for use in SPL).
config PMIC_ACT8846 config PMIC_ACT8846
@ -100,8 +100,8 @@ config PMIC_PM8916
Driver binding info: doc/device-tree-bindings/pmic/pm8916.txt Driver binding info: doc/device-tree-bindings/pmic/pm8916.txt
config PMIC_RK808 config PMIC_RK8XX
bool "Enable support for Rockchip PMIC RK808" bool "Enable support for Rockchip PMIC RK8XX"
depends on DM_PMIC depends on DM_PMIC
---help--- ---help---
The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs, The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs,

View file

@ -15,7 +15,7 @@ obj-$(CONFIG_PMIC_ACT8846) += act8846.o
obj-$(CONFIG_PMIC_AS3722) += as3722.o obj-$(CONFIG_PMIC_AS3722) += as3722.o
obj-$(CONFIG_PMIC_MAX8997) += max8997.o obj-$(CONFIG_PMIC_MAX8997) += max8997.o
obj-$(CONFIG_PMIC_PM8916) += pm8916.o obj-$(CONFIG_PMIC_PM8916) += pm8916.o
obj-$(CONFIG_PMIC_RK808) += rk808.o obj-$(CONFIG_PMIC_RK8XX) += rk8xx.o
obj-$(CONFIG_PMIC_RN5T567) += rn5t567.o obj-$(CONFIG_PMIC_RN5T567) += rn5t567.o
obj-$(CONFIG_PMIC_TPS65090) += tps65090.o obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o

View file

@ -10,24 +10,24 @@
#include <errno.h> #include <errno.h>
#include <fdtdec.h> #include <fdtdec.h>
#include <libfdt.h> #include <libfdt.h>
#include <power/rk808_pmic.h> #include <power/rk8xx_pmic.h>
#include <power/pmic.h> #include <power/pmic.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
static const struct pmic_child_info pmic_children_info[] = { static const struct pmic_child_info pmic_children_info[] = {
{ .prefix = "DCDC_REG", .driver = "rk808_buck"}, { .prefix = "DCDC_REG", .driver = "rk8xx_buck"},
{ .prefix = "LDO_REG", .driver = "rk808_ldo"}, { .prefix = "LDO_REG", .driver = "rk8xx_ldo"},
{ .prefix = "SWITCH_REG", .driver = "rk808_switch"}, { .prefix = "SWITCH_REG", .driver = "rk8xx_switch"},
{ }, { },
}; };
static int rk808_reg_count(struct udevice *dev) static int rk8xx_reg_count(struct udevice *dev)
{ {
return RK808_NUM_OF_REGS; return RK808_NUM_OF_REGS;
} }
static int rk808_write(struct udevice *dev, uint reg, const uint8_t *buff, static int rk8xx_write(struct udevice *dev, uint reg, const uint8_t *buff,
int len) int len)
{ {
int ret; int ret;
@ -41,7 +41,7 @@ static int rk808_write(struct udevice *dev, uint reg, const uint8_t *buff,
return 0; return 0;
} }
static int rk808_read(struct udevice *dev, uint reg, uint8_t *buff, int len) static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
{ {
int ret; int ret;
@ -55,7 +55,7 @@ static int rk808_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
} }
#if CONFIG_IS_ENABLED(PMIC_CHILDREN) #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
static int rk808_bind(struct udevice *dev) static int rk8xx_bind(struct udevice *dev)
{ {
const void *blob = gd->fdt_blob; const void *blob = gd->fdt_blob;
int regulators_node; int regulators_node;
@ -80,23 +80,39 @@ static int rk808_bind(struct udevice *dev)
} }
#endif #endif
static struct dm_pmic_ops rk808_ops = { static int rk8xx_probe(struct udevice *dev)
.reg_count = rk808_reg_count, {
.read = rk808_read, struct rk8xx_priv *priv = dev_get_priv(dev);
.write = rk808_write, uint8_t msb, lsb;
/* read Chip variant */
rk8xx_read(dev, ID_MSB, &msb, 1);
rk8xx_read(dev, ID_LSB, &lsb, 1);
priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
return 0;
}
static struct dm_pmic_ops rk8xx_ops = {
.reg_count = rk8xx_reg_count,
.read = rk8xx_read,
.write = rk8xx_write,
}; };
static const struct udevice_id rk808_ids[] = { static const struct udevice_id rk8xx_ids[] = {
{ .compatible = "rockchip,rk808" }, { .compatible = "rockchip,rk808" },
{ .compatible = "rockchip,rk818" },
{ } { }
}; };
U_BOOT_DRIVER(pmic_rk808) = { U_BOOT_DRIVER(pmic_rk8xx) = {
.name = "rk808 pmic", .name = "rk8xx pmic",
.id = UCLASS_PMIC, .id = UCLASS_PMIC,
.of_match = rk808_ids, .of_match = rk8xx_ids,
#if CONFIG_IS_ENABLED(PMIC_CHILDREN) #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
.bind = rk808_bind, .bind = rk8xx_bind,
#endif #endif
.ops = &rk808_ops, .probe = rk8xx_probe,
.ops = &rk8xx_ops,
}; };

View file

@ -76,11 +76,11 @@ config DM_REGULATOR_GPIO
features for gpio regulators. The driver implements get/set for features for gpio regulators. The driver implements get/set for
voltage value. voltage value.
config REGULATOR_RK808 config REGULATOR_RK8XX
bool "Enable driver for RK808 regulators" bool "Enable driver for RK8XX regulators"
depends on DM_REGULATOR && PMIC_RK808 depends on DM_REGULATOR && PMIC_RK8XX
---help--- ---help---
Enable support for the regulator functions of the RK808 PMIC. The Enable support for the regulator functions of the RK8XX PMIC. The
driver implements get/set api for the various BUCKS and LDOs supported driver implements get/set api for the various BUCKS and LDOs supported
by the PMIC device. This driver is controlled by a device tree node by the PMIC device. This driver is controlled by a device tree node
which includes voltage limits. which includes voltage limits.

View file

@ -12,7 +12,7 @@ obj-$(CONFIG_DM_REGULATOR_PFUZE100) += pfuze100.o
obj-$(CONFIG_REGULATOR_PWM) += pwm_regulator.o obj-$(CONFIG_REGULATOR_PWM) += pwm_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_FIXED) += fixed.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_FIXED) += fixed.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_GPIO) += gpio-regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_GPIO) += gpio-regulator.o
obj-$(CONFIG_REGULATOR_RK808) += rk808.o obj-$(CONFIG_REGULATOR_RK8XX) += rk8xx.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o
obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o

View file

@ -24,6 +24,12 @@ struct pwm_regulator_info {
int pwm_id; int pwm_id;
/* the period of one PWM cycle */ /* the period of one PWM cycle */
int period_ns; int period_ns;
/*
* the polarity of one PWM
* 0: normal polarity
* 1: inverted polarity
*/
bool polarity;
struct udevice *pwm; struct udevice *pwm;
/* initialize voltage of regulator */ /* initialize voltage of regulator */
unsigned int init_voltage; unsigned int init_voltage;
@ -49,7 +55,7 @@ static int pwm_voltage_to_duty_cycle_percentage(struct udevice *dev, int req_uV)
int max_uV = priv->max_voltage; int max_uV = priv->max_voltage;
int diff = max_uV - min_uV; int diff = max_uV - min_uV;
return 100 - (((req_uV * 100) - (min_uV * 100)) / diff); return ((req_uV * 100) - (min_uV * 100)) / diff;
} }
static int pwm_regulator_get_voltage(struct udevice *dev) static int pwm_regulator_get_voltage(struct udevice *dev)
@ -67,6 +73,12 @@ static int pwm_regulator_set_voltage(struct udevice *dev, int uvolt)
duty_cycle = pwm_voltage_to_duty_cycle_percentage(dev, uvolt); duty_cycle = pwm_voltage_to_duty_cycle_percentage(dev, uvolt);
ret = pwm_set_invert(priv->pwm, priv->pwm_id, priv->polarity);
if (ret) {
dev_err(dev, "Failed to init PWM\n");
return ret;
}
ret = pwm_set_config(priv->pwm, priv->pwm_id, ret = pwm_set_config(priv->pwm, priv->pwm_id,
(priv->period_ns / 100) * duty_cycle, priv->period_ns); (priv->period_ns / 100) * duty_cycle, priv->period_ns);
if (ret) { if (ret) {
@ -97,9 +109,9 @@ static int pwm_regulator_ofdata_to_platdata(struct udevice *dev)
debug("%s: Cannot get PWM phandle: ret=%d\n", __func__, ret); debug("%s: Cannot get PWM phandle: ret=%d\n", __func__, ret);
return ret; return ret;
} }
/* TODO: pwm_id here from device tree if needed */
priv->period_ns = args.args[1]; priv->period_ns = args.args[1];
priv->polarity = args.args[2];
priv->init_voltage = fdtdec_get_int(blob, node, priv->init_voltage = fdtdec_get_int(blob, node,
"regulator-init-microvolt", -1); "regulator-init-microvolt", -1);

View file

@ -12,7 +12,7 @@
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <errno.h> #include <errno.h>
#include <power/rk808_pmic.h> #include <power/rk8xx_pmic.h>
#include <power/pmic.h> #include <power/pmic.h>
#include <power/regulator.h> #include <power/regulator.h>
@ -20,36 +20,88 @@
#define ENABLE_DRIVER #define ENABLE_DRIVER
#endif #endif
struct rk808_reg_info { /* Field Definitions */
#define RK808_BUCK_VSEL_MASK 0x3f
#define RK808_BUCK4_VSEL_MASK 0xf
#define RK808_LDO_VSEL_MASK 0x1f
#define RK818_BUCK_VSEL_MASK 0x3f
#define RK818_BUCK4_VSEL_MASK 0x1f
#define RK818_LDO_VSEL_MASK 0x1f
#define RK818_LDO3_ON_VSEL_MASK 0xf
#define RK818_BOOST_ON_VSEL_MASK 0xe0
struct rk8xx_reg_info {
uint min_uv; uint min_uv;
uint step_uv; uint step_uv;
s8 vsel_reg; s8 vsel_reg;
u8 vsel_bits; u8 vsel_mask;
}; };
static const struct rk808_reg_info rk808_buck[] = { static const struct rk8xx_reg_info rk808_buck[] = {
{ 712500, 12500, REG_BUCK1_ON_VSEL, 6, }, { 712500, 12500, REG_BUCK1_ON_VSEL, RK808_BUCK_VSEL_MASK, },
{ 712500, 12500, REG_BUCK2_ON_VSEL, 6, }, { 712500, 12500, REG_BUCK2_ON_VSEL, RK808_BUCK_VSEL_MASK, },
{ 712500, 12500, -1, 6, }, { 712500, 12500, -1, RK808_BUCK_VSEL_MASK, },
{ 1800000, 100000, REG_BUCK4_ON_VSEL, 4, }, { 1800000, 100000, REG_BUCK4_ON_VSEL, RK808_BUCK4_VSEL_MASK, },
}; };
static const struct rk808_reg_info rk808_ldo[] = { static const struct rk8xx_reg_info rk808_ldo[] = {
{ 1800000, 100000, LDO1_ON_VSEL, 5, }, { 1800000, 100000, REG_LDO1_ON_VSEL, RK808_LDO_VSEL_MASK, },
{ 1800000, 100000, LDO2_ON_VSEL, 5, }, { 1800000, 100000, REG_LDO2_ON_VSEL, RK808_LDO_VSEL_MASK, },
{ 800000, 100000, LDO3_ON_VSEL, 4, }, { 800000, 100000, REG_LDO3_ON_VSEL, RK808_BUCK4_VSEL_MASK, },
{ 1800000, 100000, LDO4_ON_VSEL, 5, }, { 1800000, 100000, REG_LDO4_ON_VSEL, RK808_LDO_VSEL_MASK, },
{ 1800000, 100000, LDO5_ON_VSEL, 5, }, { 1800000, 100000, REG_LDO5_ON_VSEL, RK808_LDO_VSEL_MASK, },
{ 800000, 100000, LDO6_ON_VSEL, 5, }, { 800000, 100000, REG_LDO6_ON_VSEL, RK808_LDO_VSEL_MASK, },
{ 800000, 100000, LDO7_ON_VSEL, 5, }, { 800000, 100000, REG_LDO7_ON_VSEL, RK808_LDO_VSEL_MASK, },
{ 1800000, 100000, LDO8_ON_VSEL, 5, }, { 1800000, 100000, REG_LDO8_ON_VSEL, RK808_LDO_VSEL_MASK, },
}; };
static const struct rk8xx_reg_info rk818_buck[] = {
{ 712500, 12500, REG_BUCK1_ON_VSEL, RK818_BUCK_VSEL_MASK, },
{ 712500, 12500, REG_BUCK2_ON_VSEL, RK818_BUCK_VSEL_MASK, },
{ 712500, 12500, -1, RK818_BUCK_VSEL_MASK, },
{ 1800000, 100000, REG_BUCK4_ON_VSEL, RK818_BUCK4_VSEL_MASK, },
};
static const struct rk8xx_reg_info rk818_ldo[] = {
{ 1800000, 100000, REG_LDO1_ON_VSEL, RK818_LDO_VSEL_MASK, },
{ 1800000, 100000, REG_LDO2_ON_VSEL, RK818_LDO_VSEL_MASK, },
{ 800000, 100000, REG_LDO3_ON_VSEL, RK818_LDO3_ON_VSEL_MASK, },
{ 1800000, 100000, REG_LDO4_ON_VSEL, RK818_LDO_VSEL_MASK, },
{ 1800000, 100000, REG_LDO5_ON_VSEL, RK818_LDO_VSEL_MASK, },
{ 800000, 100000, REG_LDO6_ON_VSEL, RK818_LDO_VSEL_MASK, },
{ 800000, 100000, REG_LDO7_ON_VSEL, RK818_LDO_VSEL_MASK, },
{ 1800000, 100000, REG_LDO8_ON_VSEL, RK818_LDO_VSEL_MASK, },
};
static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
int num)
{
struct rk8xx_priv *priv = dev_get_priv(pmic);
switch (priv->variant) {
case RK818_ID:
return &rk818_buck[num];
default:
return &rk808_buck[num];
}
}
static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
int num)
{
struct rk8xx_priv *priv = dev_get_priv(pmic);
switch (priv->variant) {
case RK818_ID:
return &rk818_ldo[num - 1];
default:
return &rk808_ldo[num - 1];
}
}
static int _buck_set_value(struct udevice *pmic, int buck, int uvolt) static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
{ {
const struct rk808_reg_info *info = &rk808_buck[buck - 1]; const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck - 1);
int mask = (1 << info->vsel_bits) - 1; int mask = info->vsel_mask;
int val; int val;
if (info->vsel_reg == -1) if (info->vsel_reg == -1)
@ -69,7 +121,7 @@ static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
buck--; buck--;
mask = 1 << buck; mask = 1 << buck;
if (enable) { if (enable) {
ret = pmic_clrsetbits(pmic, DCDC_ILMAX, 0, 3 << (buck * 2)); ret = pmic_clrsetbits(pmic, REG_DCDC_ILMAX, 0, 3 << (buck * 2));
if (ret) if (ret)
return ret; return ret;
ret = pmic_clrsetbits(pmic, REG_DCDC_UV_ACT, 1 << buck, 0); ret = pmic_clrsetbits(pmic, REG_DCDC_UV_ACT, 1 << buck, 0);
@ -84,8 +136,8 @@ static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
static int buck_get_value(struct udevice *dev) static int buck_get_value(struct udevice *dev)
{ {
int buck = dev->driver_data - 1; int buck = dev->driver_data - 1;
const struct rk808_reg_info *info = &rk808_buck[buck]; const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck);
int mask = (1 << info->vsel_bits) - 1; int mask = info->vsel_mask;
int ret, val; int ret, val;
if (info->vsel_reg == -1) if (info->vsel_reg == -1)
@ -130,8 +182,8 @@ static bool buck_get_enable(struct udevice *dev)
static int ldo_get_value(struct udevice *dev) static int ldo_get_value(struct udevice *dev)
{ {
int ldo = dev->driver_data - 1; int ldo = dev->driver_data - 1;
const struct rk808_reg_info *info = &rk808_ldo[ldo]; const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
int mask = (1 << info->vsel_bits) - 1; int mask = info->vsel_mask;
int ret, val; int ret, val;
if (info->vsel_reg == -1) if (info->vsel_reg == -1)
@ -147,8 +199,8 @@ static int ldo_get_value(struct udevice *dev)
static int ldo_set_value(struct udevice *dev, int uvolt) static int ldo_set_value(struct udevice *dev, int uvolt)
{ {
int ldo = dev->driver_data - 1; int ldo = dev->driver_data - 1;
const struct rk808_reg_info *info = &rk808_ldo[ldo]; const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
int mask = (1 << info->vsel_bits) - 1; int mask = info->vsel_mask;
int val; int val;
if (info->vsel_reg == -1) if (info->vsel_reg == -1)
@ -212,7 +264,7 @@ static bool switch_get_enable(struct udevice *dev)
return ret & mask ? true : false; return ret & mask ? true : false;
} }
static int rk808_buck_probe(struct udevice *dev) static int rk8xx_buck_probe(struct udevice *dev)
{ {
struct dm_regulator_uclass_platdata *uc_pdata; struct dm_regulator_uclass_platdata *uc_pdata;
@ -224,7 +276,7 @@ static int rk808_buck_probe(struct udevice *dev)
return 0; return 0;
} }
static int rk808_ldo_probe(struct udevice *dev) static int rk8xx_ldo_probe(struct udevice *dev)
{ {
struct dm_regulator_uclass_platdata *uc_pdata; struct dm_regulator_uclass_platdata *uc_pdata;
@ -236,7 +288,7 @@ static int rk808_ldo_probe(struct udevice *dev)
return 0; return 0;
} }
static int rk808_switch_probe(struct udevice *dev) static int rk8xx_switch_probe(struct udevice *dev)
{ {
struct dm_regulator_uclass_platdata *uc_pdata; struct dm_regulator_uclass_platdata *uc_pdata;
@ -248,48 +300,48 @@ static int rk808_switch_probe(struct udevice *dev)
return 0; return 0;
} }
static const struct dm_regulator_ops rk808_buck_ops = { static const struct dm_regulator_ops rk8xx_buck_ops = {
.get_value = buck_get_value, .get_value = buck_get_value,
.set_value = buck_set_value, .set_value = buck_set_value,
.get_enable = buck_get_enable, .get_enable = buck_get_enable,
.set_enable = buck_set_enable, .set_enable = buck_set_enable,
}; };
static const struct dm_regulator_ops rk808_ldo_ops = { static const struct dm_regulator_ops rk8xx_ldo_ops = {
.get_value = ldo_get_value, .get_value = ldo_get_value,
.set_value = ldo_set_value, .set_value = ldo_set_value,
.get_enable = ldo_get_enable, .get_enable = ldo_get_enable,
.set_enable = ldo_set_enable, .set_enable = ldo_set_enable,
}; };
static const struct dm_regulator_ops rk808_switch_ops = { static const struct dm_regulator_ops rk8xx_switch_ops = {
.get_enable = switch_get_enable, .get_enable = switch_get_enable,
.set_enable = switch_set_enable, .set_enable = switch_set_enable,
}; };
U_BOOT_DRIVER(rk808_buck) = { U_BOOT_DRIVER(rk8xx_buck) = {
.name = "rk808_buck", .name = "rk8xx_buck",
.id = UCLASS_REGULATOR, .id = UCLASS_REGULATOR,
.ops = &rk808_buck_ops, .ops = &rk8xx_buck_ops,
.probe = rk808_buck_probe, .probe = rk8xx_buck_probe,
}; };
U_BOOT_DRIVER(rk808_ldo) = { U_BOOT_DRIVER(rk8xx_ldo) = {
.name = "rk808_ldo", .name = "rk8xx_ldo",
.id = UCLASS_REGULATOR, .id = UCLASS_REGULATOR,
.ops = &rk808_ldo_ops, .ops = &rk8xx_ldo_ops,
.probe = rk808_ldo_probe, .probe = rk8xx_ldo_probe,
}; };
U_BOOT_DRIVER(rk808_switch) = { U_BOOT_DRIVER(rk8xx_switch) = {
.name = "rk808_switch", .name = "rk8xx_switch",
.id = UCLASS_REGULATOR, .id = UCLASS_REGULATOR,
.ops = &rk808_switch_ops, .ops = &rk8xx_switch_ops,
.probe = rk808_switch_probe, .probe = rk8xx_switch_probe,
}; };
#endif #endif
int rk808_spl_configure_buck(struct udevice *pmic, int buck, int uvolt) int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt)
{ {
int ret; int ret;

View file

@ -9,6 +9,16 @@
#include <dm.h> #include <dm.h>
#include <pwm.h> #include <pwm.h>
int pwm_set_invert(struct udevice *dev, uint channel, bool polarity)
{
struct pwm_ops *ops = pwm_get_ops(dev);
if (!ops->set_invert)
return -ENOSYS;
return ops->set_invert(dev, channel, polarity);
}
int pwm_set_config(struct udevice *dev, uint channel, uint period_ns, int pwm_set_config(struct udevice *dev, uint channel, uint period_ns,
uint duty_ns) uint duty_ns)
{ {

View file

@ -21,8 +21,22 @@ DECLARE_GLOBAL_DATA_PTR;
struct rk_pwm_priv { struct rk_pwm_priv {
struct rk3288_pwm *regs; struct rk3288_pwm *regs;
ulong freq; ulong freq;
uint enable_conf;
}; };
static int rk_pwm_set_invert(struct udevice *dev, uint channel, bool polarity)
{
struct rk_pwm_priv *priv = dev_get_priv(dev);
debug("%s: polarity=%u\n", __func__, polarity);
if (polarity)
priv->enable_conf |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSTIVE;
else
priv->enable_conf |= PWM_DUTY_POSTIVE | PWM_INACTIVE_NEGATIVE;
return 0;
}
static int rk_pwm_set_config(struct udevice *dev, uint channel, uint period_ns, static int rk_pwm_set_config(struct udevice *dev, uint channel, uint period_ns,
uint duty_ns) uint duty_ns)
{ {
@ -32,7 +46,7 @@ static int rk_pwm_set_config(struct udevice *dev, uint channel, uint period_ns,
debug("%s: period_ns=%u, duty_ns=%u\n", __func__, period_ns, duty_ns); debug("%s: period_ns=%u, duty_ns=%u\n", __func__, period_ns, duty_ns);
writel(PWM_SEL_SRC_CLK | PWM_OUTPUT_LEFT | PWM_LP_DISABLE | writel(PWM_SEL_SRC_CLK | PWM_OUTPUT_LEFT | PWM_LP_DISABLE |
PWM_CONTINUOUS | PWM_DUTY_POSTIVE | PWM_INACTIVE_POSTIVE | PWM_CONTINUOUS | priv->enable_conf |
RK_PWM_DISABLE, RK_PWM_DISABLE,
&regs->ctrl); &regs->ctrl);
@ -83,6 +97,7 @@ static int rk_pwm_probe(struct udevice *dev)
} }
static const struct pwm_ops rk_pwm_ops = { static const struct pwm_ops rk_pwm_ops = {
.set_invert = rk_pwm_set_invert,
.set_config = rk_pwm_set_config, .set_config = rk_pwm_set_config,
.set_enable = rk_pwm_set_enable, .set_enable = rk_pwm_set_enable,
}; };

View file

@ -21,6 +21,7 @@ struct sandbox_pwm_chan {
uint period_ns; uint period_ns;
uint duty_ns; uint duty_ns;
bool enable; bool enable;
bool polarity;
}; };
struct sandbox_pwm_priv { struct sandbox_pwm_priv {
@ -56,9 +57,24 @@ static int sandbox_pwm_set_enable(struct udevice *dev, uint channel,
return 0; return 0;
} }
static int sandbox_pwm_set_invert(struct udevice *dev, uint channel,
bool polarity)
{
struct sandbox_pwm_priv *priv = dev_get_priv(dev);
struct sandbox_pwm_chan *chan;
if (channel >= NUM_CHANNELS)
return -ENOSPC;
chan = &priv->chan[channel];
chan->polarity = polarity;
return 0;
}
static const struct pwm_ops sandbox_pwm_ops = { static const struct pwm_ops sandbox_pwm_ops = {
.set_config = sandbox_pwm_set_config, .set_config = sandbox_pwm_set_config,
.set_enable = sandbox_pwm_set_enable, .set_enable = sandbox_pwm_set_enable,
.set_invert = sandbox_pwm_set_invert,
}; };
static const struct udevice_id sandbox_pwm_ids[] = { static const struct udevice_id sandbox_pwm_ids[] = {

View file

@ -79,12 +79,31 @@ static void rkspi_enable_chip(struct rockchip_spi *regs, bool enable)
static void rkspi_set_clk(struct rockchip_spi_priv *priv, uint speed) static void rkspi_set_clk(struct rockchip_spi_priv *priv, uint speed)
{ {
uint clk_div; /*
* We should try not to exceed the speed requested by the caller:
* when selecting a divider, we need to make sure we round up.
*/
uint clk_div = DIV_ROUND_UP(priv->input_rate, speed);
/* The baudrate register (BAUDR) is defined as a 32bit register where
* the upper 16bit are reserved and having 'Fsclk_out' in the lower
* 16bits with 'Fsclk_out' defined as follows:
*
* Fsclk_out = Fspi_clk/ SCKDV
* Where SCKDV is any even value between 2 and 65534.
*/
if (clk_div > 0xfffe) {
clk_div = 0xfffe;
debug("%s: can't divide down to %d hz (actual will be %d hz)\n",
__func__, speed, priv->input_rate / clk_div);
}
/* Round up to the next even 16bit number */
clk_div = (clk_div + 1) & 0xfffe;
clk_div = clk_get_divisor(priv->input_rate, speed);
debug("spi speed %u, div %u\n", speed, clk_div); debug("spi speed %u, div %u\n", speed, clk_div);
writel(clk_div, &priv->regs->baudr); clrsetbits_le32(&priv->regs->baudr, 0xffff, clk_div);
priv->last_speed_hz = speed; priv->last_speed_hz = speed;
} }
@ -190,6 +209,26 @@ static int rockchip_spi_ofdata_to_platdata(struct udevice *bus)
return 0; return 0;
} }
static int rockchip_spi_calc_modclk(ulong max_freq)
{
unsigned div;
const unsigned long gpll_hz = 594000000UL;
/*
* We need to find an input clock that provides at least twice
* the maximum frequency and can be generated from the assumed
* speed of GPLL (594MHz) using an integer divider.
*
* To give us more achievable bitrates at higher speeds (these
* are generated by dividing by an even 16-bit integer from
* this frequency), we try to have an input frequency of at
* least 4x our max_freq.
*/
div = DIV_ROUND_UP(gpll_hz, max_freq * 4);
return gpll_hz / div;
}
static int rockchip_spi_probe(struct udevice *bus) static int rockchip_spi_probe(struct udevice *bus)
{ {
struct rockchip_spi_platdata *plat = dev_get_platdata(bus); struct rockchip_spi_platdata *plat = dev_get_platdata(bus);
@ -207,11 +246,13 @@ static int rockchip_spi_probe(struct udevice *bus)
priv->last_transaction_us = timer_get_us(); priv->last_transaction_us = timer_get_us();
priv->max_freq = plat->frequency; priv->max_freq = plat->frequency;
/* /* Clamp the value from the DTS against any hardware limits */
* Use 99 MHz as our clock since it divides nicely into 594 MHz which if (priv->max_freq > ROCKCHIP_SPI_MAX_RATE)
* is the assumed speed for CLK_GENERAL. priv->max_freq = ROCKCHIP_SPI_MAX_RATE;
*/
ret = clk_set_rate(&priv->clk, 99000000); /* Find a module-input clock that fits with the max_freq setting */
ret = clk_set_rate(&priv->clk,
rockchip_spi_calc_modclk(priv->max_freq));
if (ret < 0) { if (ret < 0) {
debug("%s: Failed to set clock: %d\n", __func__, ret); debug("%s: Failed to set clock: %d\n", __func__, ret);
return ret; return ret;
@ -371,10 +412,10 @@ static int rockchip_spi_set_speed(struct udevice *bus, uint speed)
{ {
struct rockchip_spi_priv *priv = dev_get_priv(bus); struct rockchip_spi_priv *priv = dev_get_priv(bus);
if (speed > ROCKCHIP_SPI_MAX_RATE) /* Clamp to the maximum frequency specified in the DTS */
return -EINVAL;
if (speed > priv->max_freq) if (speed > priv->max_freq)
speed = priv->max_freq; speed = priv->max_freq;
priv->speed_hz = speed; priv->speed_hz = speed;
return 0; return 0;
@ -403,6 +444,7 @@ static const struct dm_spi_ops rockchip_spi_ops = {
static const struct udevice_id rockchip_spi_ids[] = { static const struct udevice_id rockchip_spi_ids[] = {
{ .compatible = "rockchip,rk3288-spi" }, { .compatible = "rockchip,rk3288-spi" },
{ .compatible = "rockchip,rk3399-spi" },
{ } { }
}; };

View file

@ -119,6 +119,13 @@ enum {
}; };
#define ROCKCHIP_SPI_TIMEOUT_MS 1000 #define ROCKCHIP_SPI_TIMEOUT_MS 1000
#define ROCKCHIP_SPI_MAX_RATE 48000000
/*
* We limit the maximum bitrate to 50MBit/s (50MHz) due to an assumed
* hardware limitation... the Linux kernel source has the following
* comment:
* "sclk_out: spi master internal logic in rk3x can support 50Mhz"
*/
#define ROCKCHIP_SPI_MAX_RATE 50000000
#endif /* __RK_SPI_H */ #endif /* __RK_SPI_H */

View file

@ -425,15 +425,7 @@ config VIDEO_FSL_DCU_MAX_FB_SIZE_MB
Set maximum framebuffer size to be used for Freescale Display Set maximum framebuffer size to be used for Freescale Display
Controller Unit (DCU4). Controller Unit (DCU4).
config VIDEO_ROCKCHIP source "drivers/video/rockchip/Kconfig"
bool "Enable Rockchip video support"
depends on DM_VIDEO
help
Rockchip SoCs provide video output capabilities for High-Definition
Multimedia Interface (HDMI), Low-voltage Differential Signalling
(LVDS), embedded DisplayPort (eDP) and Display Serial Interface
(DSI). This driver supports the on-chip video output device, and
targets the Rockchip RK3288.
config VIDEO_SANDBOX_SDL config VIDEO_SANDBOX_SDL
bool "Enable sandbox video console using SDL" bool "Enable sandbox video console using SDL"

View file

@ -0,0 +1,50 @@
#
# Video drivers selection for rockchip soc. These configs only impact the
# compile process. You can surely check all the options. In this case, all the
# display driver will be compiled, but which drivers finally will be used is
# decided by device tree configuration. What's more, enable needed power for
# display by configure the device tree, and the vop driver will do the rest.
#
# Author: Eric Gao <eric.gao@rock-chips.com>
#
menuconfig VIDEO_ROCKCHIP
bool "Enable Rockchip Video Support"
depends on DM_VIDEO
help
Rockchip SoCs provide video output capabilities for High-Definition
Multimedia Interface (HDMI), Low-voltage Differential Signalling
(LVDS), embedded DisplayPort (eDP) and Display Serial Interface
(DSI). This driver supports the on-chip video output device, and
targets the Rockchip RK3288 and RK3399.
if VIDEO_ROCKCHIP
config DISPLAY_ROCKCHIP_EDP
bool "EDP Port"
depends on VIDEO_ROCKCHIP
help
This enables Embedded DisplayPort(EDP) display support.
config DISPLAY_ROCKCHIP_LVDS
bool "LVDS Port"
depends on VIDEO_ROCKCHIP
help
This enables Low-voltage Differential Signaling(LVDS) display
support.
config DISPLAY_ROCKCHIP_HDMI
bool "HDMI port"
depends on VIDEO_ROCKCHIP
help
This enables High-Definition Multimedia Interface display support.
config DISPLAY_ROCKCHIP_MIPI
bool "MIPI Port"
depends on VIDEO_ROCKCHIP
help
This enables Mobile Industry Processor Interface(MIPI) display
support. The mipi controller and dphy on rk3288& rk3399 support
16,18, 24 bits per pixel with upto 2k resolution ratio.
endif

View file

@ -5,4 +5,10 @@
# SPDX-License-Identifier: GPL-2.0+ # SPDX-License-Identifier: GPL-2.0+
# #
obj-y += rk_edp.o rk_hdmi.o rk_vop.o rk_lvds.o ../dw_hdmi.o ifdef CONFIG_VIDEO_ROCKCHIP
obj-y += rk_vop.o
obj-$(CONFIG_DISPLAY_ROCKCHIP_EDP) += rk_edp.o
obj-$(CONFIG_DISPLAY_ROCKCHIP_LVDS) += rk_lvds.o
obj-$(CONFIG_DISPLAY_ROCKCHIP_HDMI) += rk_hdmi.o ../dw_hdmi.o
obj-$(CONFIG_DISPLAY_ROCKCHIP_MIPI) += rk_mipi.o
endif

View file

@ -0,0 +1,491 @@
/*
* Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
* Author: Eric Gao <eric.gao@rock-chips.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <clk.h>
#include <display.h>
#include <dm.h>
#include <fdtdec.h>
#include <panel.h>
#include <regmap.h>
#include <syscon.h>
#include <asm/gpio.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <dm/uclass-internal.h>
#include <linux/kernel.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3399.h>
#include <asm/arch/grf_rk3399.h>
#include <asm/arch/rockchip_mipi_dsi.h>
#include <dt-bindings/clock/rk3288-cru.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* Private information for rk mipi
*
* @regs: mipi controller address
* @grf: GRF register
* @panel: panel assined by device tree
* @ref_clk: reference clock for mipi dsi pll
* @sysclk: config clock for mipi dsi register
* @pix_clk: pixel clock for vop->dsi data transmission
* @phy_clk: mipi dphy output clock
* @txbyte_clk: clock for dsi->dphy high speed data transmission
* @txesc_clk: clock for tx esc mode
*/
struct rk_mipi_priv {
void __iomem *regs;
struct rk3399_grf_regs *grf;
struct udevice *panel;
struct mipi_dsi *dsi;
u32 ref_clk;
u32 sys_clk;
u32 pix_clk;
u32 phy_clk;
u32 txbyte_clk;
u32 txesc_clk;
};
static int rk_mipi_read_timing(struct udevice *dev,
struct display_timing *timing)
{
int ret;
ret = fdtdec_decode_display_timing(gd->fdt_blob, dev_of_offset(dev),
0, timing);
if (ret) {
debug("%s: Failed to decode display timing (ret=%d)\n",
__func__, ret);
return -EINVAL;
}
return 0;
}
/*
* Register write function used only for mipi dsi controller.
* Parameter:
* @regs: mipi controller address
* @reg: combination of regaddr(16bit)|bitswidth(8bit)|offset(8bit) you can
* use define in rk_mipi.h directly for this parameter
* @val: value that will be write to specified bits of register
*/
static void rk_mipi_dsi_write(u32 regs, u32 reg, u32 val)
{
u32 dat;
u32 mask;
u32 offset = (reg >> OFFSET_SHIFT) & 0xff;
u32 bits = (reg >> BITS_SHIFT) & 0xff;
u64 addr = (reg >> ADDR_SHIFT) + regs;
/* Mask for specifiled bits,the corresponding bits will be clear */
mask = ~((0xffffffff << offset) & (0xffffffff >> (32 - offset - bits)));
/* Make sure val in the available range */
val &= ~(0xffffffff << bits);
/* Get register's original val */
dat = readl(addr);
/* Clear specified bits */
dat &= mask;
/* Fill specified bits */
dat |= val << offset;
writel(dat, addr);
}
static int rk_mipi_dsi_enable(struct udevice *dev,
const struct display_timing *timing)
{
int node, timing_node;
int val;
struct rk_mipi_priv *priv = dev_get_priv(dev);
u64 regs = (u64)priv->regs;
struct display_plat *disp_uc_plat = dev_get_uclass_platdata(dev);
u32 txbyte_clk = priv->txbyte_clk;
u32 txesc_clk = priv->txesc_clk;
txesc_clk = txbyte_clk/(txbyte_clk/txesc_clk + 1);
/* Select the video source */
switch (disp_uc_plat->source_id) {
case VOP_B:
rk_clrsetreg(&priv->grf->soc_con20, GRF_DSI0_VOP_SEL_MASK,
GRF_DSI0_VOP_SEL_B << GRF_DSI0_VOP_SEL_SHIFT);
break;
case VOP_L:
rk_clrsetreg(&priv->grf->soc_con20, GRF_DSI0_VOP_SEL_MASK,
GRF_DSI0_VOP_SEL_L << GRF_DSI0_VOP_SEL_SHIFT);
break;
default:
debug("%s: Invalid VOP id\n", __func__);
return -EINVAL;
}
/* Set Controller as TX mode */
val = GRF_DPHY_TX0_RXMODE_DIS << GRF_DPHY_TX0_RXMODE_SHIFT;
rk_clrsetreg(&priv->grf->soc_con22, GRF_DPHY_TX0_RXMODE_MASK, val);
/* Exit tx stop mode */
val |= GRF_DPHY_TX0_TXSTOPMODE_DIS << GRF_DPHY_TX0_TXSTOPMODE_SHIFT;
rk_clrsetreg(&priv->grf->soc_con22, GRF_DPHY_TX0_TXSTOPMODE_MASK, val);
/* Disable turnequest */
val |= GRF_DPHY_TX0_TURNREQUEST_DIS << GRF_DPHY_TX0_TURNREQUEST_SHIFT;
rk_clrsetreg(&priv->grf->soc_con22, GRF_DPHY_TX0_TURNREQUEST_MASK, val);
/* Set Display timing parameter */
rk_mipi_dsi_write(regs, VID_HSA_TIME, timing->hsync_len.typ);
rk_mipi_dsi_write(regs, VID_HBP_TIME, timing->hback_porch.typ);
rk_mipi_dsi_write(regs, VID_HLINE_TIME, (timing->hsync_len.typ
+ timing->hback_porch.typ + timing->hactive.typ
+ timing->hfront_porch.typ));
rk_mipi_dsi_write(regs, VID_VSA_LINES, timing->vsync_len.typ);
rk_mipi_dsi_write(regs, VID_VBP_LINES, timing->vback_porch.typ);
rk_mipi_dsi_write(regs, VID_VFP_LINES, timing->vfront_porch.typ);
rk_mipi_dsi_write(regs, VID_ACTIVE_LINES, timing->vactive.typ);
/* Set Signal Polarity */
val = (timing->flags & DISPLAY_FLAGS_HSYNC_LOW) ? 1 : 0;
rk_mipi_dsi_write(regs, HSYNC_ACTIVE_LOW, val);
val = (timing->flags & DISPLAY_FLAGS_VSYNC_LOW) ? 1 : 0;
rk_mipi_dsi_write(regs, VSYNC_ACTIVE_LOW, val);
val = (timing->flags & DISPLAY_FLAGS_DE_LOW) ? 1 : 0;
rk_mipi_dsi_write(regs, DISPLAY_FLAGS_DE_LOW, val);
val = (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) ? 1 : 0;
rk_mipi_dsi_write(regs, COLORM_ACTIVE_LOW, val);
/* Set video mode */
rk_mipi_dsi_write(regs, CMD_VIDEO_MODE, VIDEO_MODE);
/* Set video mode transmission type as burst mode */
rk_mipi_dsi_write(regs, VID_MODE_TYPE, BURST_MODE);
/* Set pix num in a video package */
rk_mipi_dsi_write(regs, VID_PKT_SIZE, 0x4b0);
/* Set dpi color coding depth 24 bit */
timing_node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(dev),
"display-timings");
node = fdt_first_subnode(gd->fdt_blob, timing_node);
val = fdtdec_get_int(gd->fdt_blob, node, "bits-per-pixel", -1);
switch (val) {
case 16:
rk_mipi_dsi_write(regs, DPI_COLOR_CODING, DPI_16BIT_CFG_1);
break;
case 24:
rk_mipi_dsi_write(regs, DPI_COLOR_CODING, DPI_24BIT);
break;
case 30:
rk_mipi_dsi_write(regs, DPI_COLOR_CODING, DPI_30BIT);
break;
default:
rk_mipi_dsi_write(regs, DPI_COLOR_CODING, DPI_24BIT);
}
/* Enable low power mode */
rk_mipi_dsi_write(regs, LP_CMD_EN, 1);
rk_mipi_dsi_write(regs, LP_HFP_EN, 1);
rk_mipi_dsi_write(regs, LP_VACT_EN, 1);
rk_mipi_dsi_write(regs, LP_VFP_EN, 1);
rk_mipi_dsi_write(regs, LP_VBP_EN, 1);
rk_mipi_dsi_write(regs, LP_VSA_EN, 1);
/* Division for timeout counter clk */
rk_mipi_dsi_write(regs, TO_CLK_DIVISION, 0x0a);
/* Tx esc clk division from txbyte clk */
rk_mipi_dsi_write(regs, TX_ESC_CLK_DIVISION, txbyte_clk/txesc_clk);
/* Timeout count for hs<->lp transation between Line period */
rk_mipi_dsi_write(regs, HSTX_TO_CNT, 0x3e8);
/* Phy State transfer timing */
rk_mipi_dsi_write(regs, PHY_STOP_WAIT_TIME, 32);
rk_mipi_dsi_write(regs, PHY_TXREQUESTCLKHS, 1);
rk_mipi_dsi_write(regs, PHY_HS2LP_TIME, 0x14);
rk_mipi_dsi_write(regs, PHY_LP2HS_TIME, 0x10);
rk_mipi_dsi_write(regs, MAX_RD_TIME, 0x2710);
/* Power on */
rk_mipi_dsi_write(regs, SHUTDOWNZ, 1);
return 0;
}
/* rk mipi dphy write function. It is used to write test data to dphy */
static void rk_mipi_phy_write(u32 regs, unsigned char test_code,
unsigned char *test_data, unsigned char size)
{
int i = 0;
/* Write Test code */
rk_mipi_dsi_write(regs, PHY_TESTCLK, 1);
rk_mipi_dsi_write(regs, PHY_TESTDIN, test_code);
rk_mipi_dsi_write(regs, PHY_TESTEN, 1);
rk_mipi_dsi_write(regs, PHY_TESTCLK, 0);
rk_mipi_dsi_write(regs, PHY_TESTEN, 0);
/* Write Test data */
for (i = 0; i < size; i++) {
rk_mipi_dsi_write(regs, PHY_TESTCLK, 0);
rk_mipi_dsi_write(regs, PHY_TESTDIN, test_data[i]);
rk_mipi_dsi_write(regs, PHY_TESTCLK, 1);
}
}
/*
* Mipi dphy config function. Calculate the suitable prediv, feedback div,
* fsfreqrang value ,cap ,lpf and so on according to the given pix clk rate,
* and then enable phy.
*/
static int rk_mipi_phy_enable(struct udevice *dev)
{
int i;
struct rk_mipi_priv *priv = dev_get_priv(dev);
u64 regs = (u64)priv->regs;
u64 fbdiv;
u64 prediv = 1;
u32 max_fbdiv = 512;
u32 max_prediv, min_prediv;
u64 ddr_clk = priv->phy_clk;
u32 refclk = priv->ref_clk;
u32 remain = refclk;
unsigned char test_data[2] = {0};
int freq_rang[][2] = {
{90, 0x01}, {100, 0x10}, {110, 0x20}, {130, 0x01},
{140, 0x11}, {150, 0x21}, {170, 0x02}, {180, 0x12},
{200, 0x22}, {220, 0x03}, {240, 0x13}, {250, 0x23},
{270, 0x04}, {300, 0x14}, {330, 0x05}, {360, 0x15},
{400, 0x25}, {450, 0x06}, {500, 0x16}, {550, 0x07},
{600, 0x17}, {650, 0x08}, {700, 0x18}, {750, 0x09},
{800, 0x19}, {850, 0x29}, {900, 0x39}, {950, 0x0a},
{1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
{1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
{1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c}
};
/* Shutdown mode */
rk_mipi_dsi_write(regs, PHY_SHUTDOWNZ, 0);
rk_mipi_dsi_write(regs, PHY_RSTZ, 0);
rk_mipi_dsi_write(regs, PHY_TESTCLR, 1);
/* Pll locking */
rk_mipi_dsi_write(regs, PHY_TESTCLR, 0);
/* config cp and lfp */
test_data[0] = 0x80 | (ddr_clk / (200 * MHz)) << 3 | 0x3;
rk_mipi_phy_write(regs, CODE_PLL_VCORANGE_VCOCAP, test_data, 1);
test_data[0] = 0x8;
rk_mipi_phy_write(regs, CODE_PLL_CPCTRL, test_data, 1);
test_data[0] = 0x80 | 0x40;
rk_mipi_phy_write(regs, CODE_PLL_LPF_CP, test_data, 1);
/* select the suitable value for fsfreqrang reg */
for (i = 0; i < ARRAY_SIZE(freq_rang); i++) {
if (ddr_clk / (MHz) >= freq_rang[i][0])
break;
}
if (i == ARRAY_SIZE(freq_rang)) {
debug("%s: Dphy freq out of range!\n", __func__);
return -EINVAL;
}
test_data[0] = freq_rang[i][1] << 1;
rk_mipi_phy_write(regs, CODE_HS_RX_LANE0, test_data, 1);
/*
* Calculate the best ddrclk and it's corresponding div value. If the
* given pixelclock is great than 250M, ddrclk will be fix 1500M.
* Otherwise,
* it's equal to ddr_clk= pixclk * 6. 40MHz >= refclk / prediv >= 5MHz
* according to spec.
*/
max_prediv = (refclk / (5 * MHz));
min_prediv = ((refclk / (40 * MHz)) ? (refclk / (40 * MHz) + 1) : 1);
debug("%s: DEBUG: max_prediv=%u, min_prediv=%u\n", __func__, max_prediv,
min_prediv);
if (max_prediv < min_prediv) {
debug("%s: Invalid refclk value\n", __func__);
return -EINVAL;
}
/* Calculate the best refclk and feedback division value for dphy pll */
for (i = min_prediv; i < max_prediv; i++) {
if ((ddr_clk * i % refclk < remain) &&
(ddr_clk * i / refclk) < max_fbdiv) {
prediv = i;
remain = ddr_clk * i % refclk;
}
}
fbdiv = ddr_clk * prediv / refclk;
ddr_clk = refclk * fbdiv / prediv;
priv->phy_clk = ddr_clk;
debug("%s: DEBUG: refclk=%u, refclk=%llu, fbdiv=%llu, phyclk=%llu\n",
__func__, refclk, prediv, fbdiv, ddr_clk);
/* config prediv and feedback reg */
test_data[0] = prediv - 1;
rk_mipi_phy_write(regs, CODE_PLL_INPUT_DIV_RAT, test_data, 1);
test_data[0] = (fbdiv - 1) & 0x1f;
rk_mipi_phy_write(regs, CODE_PLL_LOOP_DIV_RAT, test_data, 1);
test_data[0] = (fbdiv - 1) >> 5 | 0x80;
rk_mipi_phy_write(regs, CODE_PLL_LOOP_DIV_RAT, test_data, 1);
test_data[0] = 0x30;
rk_mipi_phy_write(regs, CODE_PLL_INPUT_LOOP_DIV_RAT, test_data, 1);
/* rest config */
test_data[0] = 0x4d;
rk_mipi_phy_write(regs, CODE_BANDGAP_BIAS_CTRL, test_data, 1);
test_data[0] = 0x3d;
rk_mipi_phy_write(regs, CODE_TERMINATION_CTRL, test_data, 1);
test_data[0] = 0xdf;
rk_mipi_phy_write(regs, CODE_TERMINATION_CTRL, test_data, 1);
test_data[0] = 0x7;
rk_mipi_phy_write(regs, CODE_AFE_BIAS_BANDGAP_ANOLOG, test_data, 1);
test_data[0] = 0x80 | 0x7;
rk_mipi_phy_write(regs, CODE_AFE_BIAS_BANDGAP_ANOLOG, test_data, 1);
test_data[0] = 0x80 | 15;
rk_mipi_phy_write(regs, CODE_HSTXDATALANEREQUSETSTATETIME,
test_data, 1);
test_data[0] = 0x80 | 85;
rk_mipi_phy_write(regs, CODE_HSTXDATALANEPREPARESTATETIME,
test_data, 1);
test_data[0] = 0x40 | 10;
rk_mipi_phy_write(regs, CODE_HSTXDATALANEHSZEROSTATETIME,
test_data, 1);
/* enter into stop mode */
rk_mipi_dsi_write(regs, N_LANES, 0x03);
rk_mipi_dsi_write(regs, PHY_ENABLECLK, 1);
rk_mipi_dsi_write(regs, PHY_FORCEPLL, 1);
rk_mipi_dsi_write(regs, PHY_SHUTDOWNZ, 1);
rk_mipi_dsi_write(regs, PHY_RSTZ, 1);
return 0;
}
/*
* This function is called by rk_display_init() using rk_mipi_dsi_enable() and
* rk_mipi_phy_enable() to initialize mipi controller and dphy. If success,
* enable backlight.
*/
static int rk_display_enable(struct udevice *dev, int panel_bpp,
const struct display_timing *timing)
{
int ret;
struct rk_mipi_priv *priv = dev_get_priv(dev);
/* Fill the mipi controller parameter */
priv->ref_clk = 24 * MHz;
priv->sys_clk = priv->ref_clk;
priv->pix_clk = timing->pixelclock.typ;
priv->phy_clk = priv->pix_clk * 6;
priv->txbyte_clk = priv->phy_clk / 8;
priv->txesc_clk = 20 * MHz;
/* Config and enable mipi dsi according to timing */
ret = rk_mipi_dsi_enable(dev, timing);
if (ret) {
debug("%s: rk_mipi_dsi_enable() failed (err=%d)\n",
__func__, ret);
return ret;
}
/* Config and enable mipi phy */
ret = rk_mipi_phy_enable(dev);
if (ret) {
debug("%s: rk_mipi_phy_enable() failed (err=%d)\n",
__func__, ret);
return ret;
}
/* Enable backlight */
ret = panel_enable_backlight(priv->panel);
if (ret) {
debug("%s: panel_enable_backlight() failed (err=%d)\n",
__func__, ret);
return ret;
}
return 0;
}
static int rk_mipi_ofdata_to_platdata(struct udevice *dev)
{
struct rk_mipi_priv *priv = dev_get_priv(dev);
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
if (priv->grf <= 0) {
debug("%s: Get syscon grf failed (ret=%llu)\n",
__func__, (u64)priv->grf);
return -ENXIO;
}
priv->regs = (void *)dev_get_addr(dev);
if (priv->regs <= 0) {
debug("%s: Get MIPI dsi address failed (ret=%llu)\n", __func__,
(u64)priv->regs);
return -ENXIO;
}
return 0;
}
/*
* Probe function: check panel existence and readingit's timing. Then config
* mipi dsi controller and enable it according to the timing parameter.
*/
static int rk_mipi_probe(struct udevice *dev)
{
int ret;
struct rk_mipi_priv *priv = dev_get_priv(dev);
ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, "rockchip,panel",
&priv->panel);
if (ret) {
debug("%s: Can not find panel (err=%d)\n", __func__, ret);
return ret;
}
return 0;
}
static const struct dm_display_ops rk_mipi_dsi_ops = {
.read_timing = rk_mipi_read_timing,
.enable = rk_display_enable,
};
static const struct udevice_id rk_mipi_dsi_ids[] = {
{ .compatible = "rockchip,rk3399_mipi_dsi" },
{ }
};
U_BOOT_DRIVER(rk_mipi_dsi) = {
.name = "rk_mipi_dsi",
.id = UCLASS_DISPLAY,
.of_match = rk_mipi_dsi_ids,
.ofdata_to_platdata = rk_mipi_ofdata_to_platdata,
.probe = rk_mipi_probe,
.ops = &rk_mipi_dsi_ops,
.priv_auto_alloc_size = sizeof(struct rk_mipi_priv),
};

View file

@ -117,6 +117,10 @@ void rkvop_mode_set(struct rk3288_vop *regs,
clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN, clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
V_RGB_OUT_EN(1)); V_RGB_OUT_EN(1));
break; break;
case VOP_MODE_MIPI:
clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
V_MIPI_OUT_EN(1));
break;
} }
if (mode == VOP_MODE_HDMI || mode == VOP_MODE_EDP) if (mode == VOP_MODE_HDMI || mode == VOP_MODE_EDP)
@ -177,13 +181,11 @@ void rkvop_mode_set(struct rk3288_vop *regs,
* *
* @dev: VOP device that we want to connect to the display * @dev: VOP device that we want to connect to the display
* @fbbase: Frame buffer address * @fbbase: Frame buffer address
* @l2bpp Log2 of bits-per-pixels for the display
* @ep_node: Device tree node to process - this is the offset of an endpoint * @ep_node: Device tree node to process - this is the offset of an endpoint
* node within the VOP's 'port' list. * node within the VOP's 'port' list.
* @return 0 if OK, -ve if something went wrong * @return 0 if OK, -ve if something went wrong
*/ */
int rk_display_init(struct udevice *dev, ulong fbbase, int rk_display_init(struct udevice *dev, ulong fbbase, int ep_node)
enum video_log2_bpp l2bpp, int ep_node)
{ {
struct video_priv *uc_priv = dev_get_uclass_priv(dev); struct video_priv *uc_priv = dev_get_uclass_priv(dev);
const void *blob = gd->fdt_blob; const void *blob = gd->fdt_blob;
@ -195,6 +197,7 @@ int rk_display_init(struct udevice *dev, ulong fbbase,
int ret, remote, i, offset; int ret, remote, i, offset;
struct display_plat *disp_uc_plat; struct display_plat *disp_uc_plat;
struct clk clk; struct clk clk;
enum video_log2_bpp l2bpp;
vop_id = fdtdec_get_int(blob, ep_node, "reg", -1); vop_id = fdtdec_get_int(blob, ep_node, "reg", -1);
debug("vop_id=%d\n", vop_id); debug("vop_id=%d\n", vop_id);
@ -244,11 +247,24 @@ int rk_display_init(struct udevice *dev, ulong fbbase,
ret = clk_get_by_index(dev, 1, &clk); ret = clk_get_by_index(dev, 1, &clk);
if (!ret) if (!ret)
ret = clk_set_rate(&clk, timing.pixelclock.typ); ret = clk_set_rate(&clk, timing.pixelclock.typ);
if (ret) { if (IS_ERR_VALUE(ret)) {
debug("%s: Failed to set pixel clock: ret=%d\n", __func__, ret); debug("%s: Failed to set pixel clock: ret=%d\n", __func__, ret);
return ret; return ret;
} }
/* Set bitwidth for vop display according to vop mode */
switch (vop_id) {
case VOP_MODE_EDP:
case VOP_MODE_HDMI:
case VOP_MODE_LVDS:
l2bpp = VIDEO_BPP16;
break;
case VOP_MODE_MIPI:
l2bpp = VIDEO_BPP32;
break;
default:
l2bpp = VIDEO_BPP16;
}
rkvop_mode_set(regs, &timing, vop_id); rkvop_mode_set(regs, &timing, vop_id);
rkvop_enable(regs, fbbase, 1 << l2bpp, &timing); rkvop_enable(regs, fbbase, 1 << l2bpp, &timing);
@ -326,7 +342,7 @@ static int rk_vop_probe(struct udevice *dev)
for (node = fdt_first_subnode(blob, port); for (node = fdt_first_subnode(blob, port);
node > 0; node > 0;
node = fdt_next_subnode(blob, node)) { node = fdt_next_subnode(blob, node)) {
ret = rk_display_init(dev, plat->base, VIDEO_BPP16, node); ret = rk_display_init(dev, plat->base, node);
if (ret) if (ret)
debug("Device failed: ret=%d\n", ret); debug("Device failed: ret=%d\n", ret);
if (!ret) if (!ret)
@ -341,7 +357,7 @@ static int rk_vop_bind(struct udevice *dev)
{ {
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
plat->size = 1920 * 1080 * 2; plat->size = 1920 * 1200 * 4;
return 0; return 0;
} }
@ -350,6 +366,8 @@ static const struct video_ops rk_vop_ops = {
}; };
static const struct udevice_id rk_vop_ids[] = { static const struct udevice_id rk_vop_ids[] = {
{ .compatible = "rockchip,rk3399-vop-big" },
{ .compatible = "rockchip,rk3399-vop-lit" },
{ .compatible = "rockchip,rk3288-vop" }, { .compatible = "rockchip,rk3288-vop" },
{ } { }
}; };

View file

@ -18,6 +18,9 @@
#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_FRAMEWORK
#define CONFIG_SPL_DRIVERS_MISC_SUPPORT #define CONFIG_SPL_DRIVERS_MISC_SUPPORT
#define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_SERIAL_SUPPORT
#if defined(CONFIG_SPL_SPI_SUPPORT)
#define CONFIG_SPL_SPI_LOAD
#endif
#define COUNTER_FREQUENCY 24000000 #define COUNTER_FREQUENCY 24000000

View file

@ -4,7 +4,7 @@
* Copyright (c) 2013 MundoReader S.L. * Copyright (c) 2013 MundoReader S.L.
* Author: Heiko Stuebner <heiko@sntech.de> * Author: Heiko Stuebner <heiko@sntech.de>
* *
* SPDX-License-Identifier: GPL-2.0+ * SPDX-License-Identifier: GPL-2.0+
*/ */
#ifndef __DT_BINDINGS_ROCKCHIP_PINCTRL_H__ #ifndef __DT_BINDINGS_ROCKCHIP_PINCTRL_H__
@ -17,6 +17,39 @@
#define RK_GPIO4 4 #define RK_GPIO4 4
#define RK_GPIO6 6 #define RK_GPIO6 6
#define RK_PA0 0
#define RK_PA1 1
#define RK_PA2 2
#define RK_PA3 3
#define RK_PA4 4
#define RK_PA5 5
#define RK_PA6 6
#define RK_PA7 7
#define RK_PB0 8
#define RK_PB1 9
#define RK_PB2 10
#define RK_PB3 11
#define RK_PB4 12
#define RK_PB5 13
#define RK_PB6 14
#define RK_PB7 15
#define RK_PC0 16
#define RK_PC1 17
#define RK_PC2 18
#define RK_PC3 19
#define RK_PC4 20
#define RK_PC5 21
#define RK_PC6 22
#define RK_PC7 23
#define RK_PD0 24
#define RK_PD1 25
#define RK_PD2 26
#define RK_PD3 27
#define RK_PD4 28
#define RK_PD5 29
#define RK_PD6 30
#define RK_PD7 31
#define RK_FUNC_GPIO 0 #define RK_FUNC_GPIO 0
#define RK_FUNC_1 1 #define RK_FUNC_1 1
#define RK_FUNC_2 2 #define RK_FUNC_2 2

View file

@ -0,0 +1,53 @@
#ifndef __DT_BINDINGS_POWER_RK3399_POWER_H__
#define __DT_BINDINGS_POWER_RK3399_POWER_H__
/* VD_CORE_L */
#define RK3399_PD_A53_L0 0
#define RK3399_PD_A53_L1 1
#define RK3399_PD_A53_L2 2
#define RK3399_PD_A53_L3 3
#define RK3399_PD_SCU_L 4
/* VD_CORE_B */
#define RK3399_PD_A72_B0 5
#define RK3399_PD_A72_B1 6
#define RK3399_PD_SCU_B 7
/* VD_LOGIC */
#define RK3399_PD_TCPD0 8
#define RK3399_PD_TCPD1 9
#define RK3399_PD_CCI 10
#define RK3399_PD_CCI0 11
#define RK3399_PD_CCI1 12
#define RK3399_PD_PERILP 13
#define RK3399_PD_PERIHP 14
#define RK3399_PD_VIO 15
#define RK3399_PD_VO 16
#define RK3399_PD_VOPB 17
#define RK3399_PD_VOPL 18
#define RK3399_PD_ISP0 19
#define RK3399_PD_ISP1 20
#define RK3399_PD_HDCP 21
#define RK3399_PD_GMAC 22
#define RK3399_PD_EMMC 23
#define RK3399_PD_USB3 24
#define RK3399_PD_EDP 25
#define RK3399_PD_GIC 26
#define RK3399_PD_SD 27
#define RK3399_PD_SDIOAUDIO 28
#define RK3399_PD_ALIVE 29
/* VD_CENTER */
#define RK3399_PD_CENTER 30
#define RK3399_PD_VCODEC 31
#define RK3399_PD_VDU 32
#define RK3399_PD_RGA 33
#define RK3399_PD_IEP 34
/* VD_GPU */
#define RK3399_PD_GPU 35
/* VD_PMU */
#define RK3399_PD_PMU 36
#endif

View file

@ -20,4 +20,28 @@ struct i2c_eeprom {
unsigned pagewidth; unsigned pagewidth;
}; };
/*
* i2c_eeprom_read() - read bytes from an I2C EEPROM chip
*
* @dev: Chip to read from
* @offset: Offset within chip to start reading
* @buf: Place to put data
* @size: Number of bytes to read
*
* @return 0 on success, -ve on failure
*/
int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size);
/*
* i2c_eeprom_write() - write bytes to an I2C EEPROM chip
*
* @dev: Chip to write to
* @offset: Offset within chip to start writing
* @buf: Buffer containing data to write
* @size: Number of bytes to write
*
* @return 0 on success, -ve on failure
*/
int i2c_eeprom_write(struct udevice *dev, int offset, uint8_t *buf, int size);
#endif #endif

View file

@ -1,77 +0,0 @@
/*
* Copyright (C) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _PMIC_RK808_H_
#define _PMIC_RK808_H_
enum {
REG_DCDC_EN = 0x23,
REG_LDO_EN,
REG_SLEEP_SET_OFF1,
REG_SLEEP_SET_OFF2,
REG_DCDC_UV_STS,
REG_DCDC_UV_ACT,
REG_LDO_UV_STS,
REG_LDO_UV_ACT,
REG_DCDC_PG,
REG_LDO_PG,
REG_VOUT_MON_TDB,
REG_BUCK1_CONFIG,
REG_BUCK1_ON_VSEL,
REG_BUCK1_SLP_VSEL,
REG_BUCK1_DVS_VSEL,
REG_BUCK2_CONFIG,
REG_BUCK2_ON_VSEL,
REG_BUCK2_SLP_VSEL,
REG_BUCK2_DVS_VSEL,
REG_BUCK3_CONFIG,
REG_BUCK4_CONFIG,
REG_BUCK4_ON_VSEL,
REG_BUCK4_SLP_VSEL,
LDO1_ON_VSEL = 0x3b,
LDO1_SLP_VSEL,
LDO2_ON_VSEL,
LDO2_SLP_VSEL,
LDO3_ON_VSEL,
LDO3_SLP_VSEL,
LDO4_ON_VSEL,
LDO4_SLP_VSEL,
LDO5_ON_VSEL,
LDO5_SLP_VSEL,
LDO6_ON_VSEL,
LDO6_SLP_VSEL,
LDO7_ON_VSEL,
LDO7_SLP_VSEL,
LDO8_ON_VSEL,
LDO8_SLP_VSEL,
DEVCTRL,
INT_STS1,
INT_STS_MSK1,
INT_STS2,
INT_STS_MSK2,
IO_POL,
/* Not sure what this does */
DCDC_ILMAX = 0x90,
RK808_NUM_OF_REGS,
};
struct rk808_reg_table {
char *name;
u8 reg_ctl;
u8 reg_vol;
};
int rk808_spl_configure_buck(struct udevice *pmic, int buck, int uvolt);
#endif

193
include/power/rk8xx_pmic.h Normal file
View file

@ -0,0 +1,193 @@
/*
* Copyright (C) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _PMIC_RK8XX_H_
#define _PMIC_RK8XX_H_
enum {
REG_SECONDS = 0x00,
REG_MINUTES,
REG_HOURS,
REG_DAYS,
REG_MONTHS,
REG_YEARS,
REG_WEEKS,
REG_ALARM_SECONDS,
REG_ALARM_MINUTES,
REG_ALARM_HOURS,
REG_ALARM_DAYS,
REG_ALARM_MONTHS,
REG_ALARM_YEARS,
REG_RTC_CTRL = 0x10,
REG_RTC_STATUS,
REG_RTC_INT,
REG_RTC_COMP_LSB,
REG_RTC_COMP_MSB,
ID_MSB = 0x17,
ID_LSB,
REG_CLK32OUT = 0x20,
REG_VB_MON,
REG_THERMAL,
REG_DCDC_EN,
REG_LDO_EN,
REG_SLEEP_SET_OFF1,
REG_SLEEP_SET_OFF2,
REG_DCDC_UV_STS,
REG_DCDC_UV_ACT,
REG_LDO_UV_STS,
REG_LDO_UV_ACT,
REG_DCDC_PG,
REG_LDO_PG,
REG_VOUT_MON_TDB,
REG_BUCK1_CONFIG,
REG_BUCK1_ON_VSEL,
REG_BUCK1_SLP_VSEL,
REG_BUCK1_DVS_VSEL,
REG_BUCK2_CONFIG,
REG_BUCK2_ON_VSEL,
REG_BUCK2_SLP_VSEL,
REG_BUCK2_DVS_VSEL,
REG_BUCK3_CONFIG,
REG_BUCK4_CONFIG,
REG_BUCK4_ON_VSEL,
REG_BUCK4_SLP_VSEL,
REG_BOOST_CONFIG_REG,
REG_LDO1_ON_VSEL,
REG_LDO1_SLP_VSEL,
REG_LDO2_ON_VSEL,
REG_LDO2_SLP_VSEL,
REG_LDO3_ON_VSEL,
REG_LDO3_SLP_VSEL,
REG_LDO4_ON_VSEL,
REG_LDO4_SLP_VSEL,
REG_LDO5_ON_VSEL,
REG_LDO5_SLP_VSEL,
REG_LDO6_ON_VSEL,
REG_LDO6_SLP_VSEL,
REG_LDO7_ON_VSEL,
REG_LDO7_SLP_VSEL,
REG_LDO8_ON_VSEL,
REG_LDO8_SLP_VSEL,
REG_DEVCTRL,
REG_INT_STS1,
REG_INT_STS_MSK1,
REG_INT_STS2,
REG_INT_STS_MSK2,
REG_IO_POL,
REG_OTP_VDD_EN,
REG_H5V_EN,
REG_SLEEP_SET_OFF,
REG_BOOST_LDO9_ON_VSEL,
REG_BOOST_LDO9_SLP_VSEL,
REG_BOOST_CTRL,
/* Not sure what this does */
REG_DCDC_ILMAX = 0x90,
REG_CHRG_COMP = 0x9a,
REG_SUP_STS = 0xa0,
REG_USB_CTRL,
REG1_CHRG_CTRL,
REG2_CHRG_CTRL,
REG3_CHRG_CTRL,
REG_BAT_CTRL,
REG_BAT_HTS_TS1,
REG_BAT_LTS_TS1,
REG_BAT_HTS_TS2,
REG_BAT_LTS_TS2,
REG_TS_CTRL,
REG_ADC_CTRL,
REG_ON_SOURCE,
REG_OFF_SOURCE,
REG_GGCON,
REG_GGSTS,
REG_FRAME_SMP_INTERV,
REG_AUTO_SLP_CUR_THR,
REG3_GASCNT_CAL,
REG2_GASCNT_CAL,
REG1_GASCNT_CAL,
REG0_GASCNT_CAL,
REG3_GASCNT,
REG2_GASCNT,
REG1_GASCNT,
REG0_GASCNT,
REGH_BAT_CUR_AVG,
REGL_BAT_CUR_AVG,
REGH_TS1_ADC,
REGL_TS1_ADC,
REGH_TS2_ADC,
REGL_TS2_ADC,
REGH_BAT_OCV,
REGL_BAT_OCV,
REGH_BAT_VOL,
REGL_BAT_VOL,
REGH_RELAX_ENTRY_THRES,
REGL_RELAX_ENTRY_THRES,
REGH_RELAX_EXIT_THRES,
REGL_RELAX_EXIT_THRES,
REGH_RELAX_VOL1,
REGL_RELAX_VOL1,
REGH_RELAX_VOL2,
REGL_RELAX_VOL2,
REGH_BAT_CUR_R_CALC,
REGL_BAT_CUR_R_CALC,
REGH_BAT_VOL_R_CALC,
REGL_BAT_VOL_R_CALC,
REGH_CAL_OFFSET,
REGL_CAL_OFFSET,
REG_NON_ACT_TIMER_CNT,
REGH_VCALIB0,
REGL_VCALIB0,
REGH_VCALIB1,
REGL_VCALIB1,
REGH_IOFFSET,
REGL_IOFFSET,
REG_SOC,
REG3_REMAIN_CAP,
REG2_REMAIN_CAP,
REG1_REMAIN_CAP,
REG0_REMAIN_CAP,
REG_UPDAT_LEVE,
REG3_NEW_FCC,
REG2_NEW_FCC,
REG1_NEW_FCC,
REG0_NEW_FCC,
REG_NON_ACT_TIMER_CNT_SAVE,
REG_OCV_VOL_VALID,
REG_REBOOT_CNT,
REG_POFFSET,
REG_MISC_MARK,
REG_HALT_CNT,
REGH_CALC_REST,
REGL_CALC_REST,
SAVE_DATA19,
RK808_NUM_OF_REGS,
};
enum {
RK805_ID = 0x8050,
RK808_ID = 0x0000,
RK818_ID = 0x8180,
};
#define RK8XX_ID_MSK 0xfff0
struct rk8xx_reg_table {
char *name;
u8 reg_ctl;
u8 reg_vol;
};
struct rk8xx_priv {
int variant;
};
int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt);
#endif

View file

@ -34,6 +34,15 @@ struct pwm_ops {
* @return 0 if OK, -ve on error * @return 0 if OK, -ve on error
*/ */
int (*set_enable)(struct udevice *dev, uint channel, bool enable); int (*set_enable)(struct udevice *dev, uint channel, bool enable);
/**
* set_invert() - Set the PWM invert
*
* @dev: PWM device to update
* @channel: PWM channel to update
* @polarity: true to invert, false to keep normal polarity
* @return 0 if OK, -ve on error
*/
int (*set_invert)(struct udevice *dev, uint channel, bool polarity);
}; };
#define pwm_get_ops(dev) ((struct pwm_ops *)(dev)->driver->ops) #define pwm_get_ops(dev) ((struct pwm_ops *)(dev)->driver->ops)
@ -60,6 +69,16 @@ int pwm_set_config(struct udevice *dev, uint channel, uint period_ns,
*/ */
int pwm_set_enable(struct udevice *dev, uint channel, bool enable); int pwm_set_enable(struct udevice *dev, uint channel, bool enable);
/**
* pwm_set_invert() - Set pwm default polarity
*
* @dev: PWM device to update
* @channel: PWM channel to update
* @polarity: true to invert, false to keep normal polarity
* @return 0 if OK, -ve on error
*/
int pwm_set_invert(struct udevice *dev, uint channel, bool polarity);
/* Legacy interface */ /* Legacy interface */
#ifndef CONFIG_DM_PWM #ifndef CONFIG_DM_PWM
int pwm_init (int pwm_id, int div, int invert); int pwm_init (int pwm_id, int div, int invert);

View file

@ -23,6 +23,7 @@ static int dm_test_pwm_base(struct unit_test_state *uts)
ut_assertok(pwm_set_enable(dev, 1, true)); ut_assertok(pwm_set_enable(dev, 1, true));
ut_assertok(pwm_set_enable(dev, 2, true)); ut_assertok(pwm_set_enable(dev, 2, true));
ut_asserteq(-ENOSPC, pwm_set_enable(dev, 3, true)); ut_asserteq(-ENOSPC, pwm_set_enable(dev, 3, true));
ut_assertok(pwm_set_invert(dev, 0, true));
ut_assertok(uclass_get_device(UCLASS_PWM, 1, &dev)); ut_assertok(uclass_get_device(UCLASS_PWM, 1, &dev));
ut_asserteq(-ENODEV, uclass_get_device(UCLASS_PWM, 2, &dev)); ut_asserteq(-ENODEV, uclass_get_device(UCLASS_PWM, 2, &dev));

View file

@ -272,6 +272,33 @@ class DtbPlatdata:
upto += 1 upto += 1
return structs return structs
def ScanPhandles(self):
"""Figure out what phandles each node uses
We need to be careful when outputing nodes that use phandles since
they must come after the declaration of the phandles in the C file.
Otherwise we get a compiler error since the phandle struct is not yet
declared.
This function adds to each node a list of phandle nodes that the node
depends on. This allows us to output things in the right order.
"""
for node in self._valid_nodes:
node.phandles = set()
for pname, prop in node.props.items():
if pname in PROP_IGNORE_LIST or pname[0] == '#':
continue
if type(prop.value) == list:
if self.IsPhandle(prop):
# Process the list as pairs of (phandle, id)
it = iter(prop.value)
for phandle_cell, id_cell in zip(it, it):
phandle = fdt_util.fdt32_to_cpu(phandle_cell)
id = fdt_util.fdt32_to_cpu(id_cell)
target_node = self._phandle_node[phandle]
node.phandles.add(target_node)
def GenerateStructs(self, structs): def GenerateStructs(self, structs):
"""Generate struct defintions for the platform data """Generate struct defintions for the platform data
@ -301,6 +328,59 @@ class DtbPlatdata:
self.Out(';\n') self.Out(';\n')
self.Out('};\n') self.Out('};\n')
def OutputNode(self, node):
"""Output the C code for a node
Args:
node: node to output
"""
struct_name = self.GetCompatName(node)
var_name = Conv_name_to_c(node.name)
self.Buf('static struct %s%s %s%s = {\n' %
(STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
for pname, prop in node.props.items():
if pname in PROP_IGNORE_LIST or pname[0] == '#':
continue
ptype = TYPE_NAMES[prop.type]
member_name = Conv_name_to_c(prop.name)
self.Buf('\t%s= ' % TabTo(3, '.' + member_name))
# Special handling for lists
if type(prop.value) == list:
self.Buf('{')
vals = []
# For phandles, output a reference to the platform data
# of the target node.
if self.IsPhandle(prop):
# Process the list as pairs of (phandle, id)
it = iter(prop.value)
for phandle_cell, id_cell in zip(it, it):
phandle = fdt_util.fdt32_to_cpu(phandle_cell)
id = fdt_util.fdt32_to_cpu(id_cell)
target_node = self._phandle_node[phandle]
name = Conv_name_to_c(target_node.name)
vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id))
else:
for val in prop.value:
vals.append(self.GetValue(prop.type, val))
self.Buf(', '.join(vals))
self.Buf('}')
else:
self.Buf(self.GetValue(prop.type, prop.value))
self.Buf(',\n')
self.Buf('};\n')
# Add a device declaration
self.Buf('U_BOOT_DEVICE(%s) = {\n' % var_name)
self.Buf('\t.name\t\t= "%s",\n' % struct_name)
self.Buf('\t.platdata\t= &%s%s,\n' % (VAL_PREFIX, var_name))
self.Buf('\t.platdata_size\t= sizeof(%s%s),\n' %
(VAL_PREFIX, var_name))
self.Buf('};\n')
self.Buf('\n')
self.Out(''.join(self.GetBuf()))
def GenerateTables(self): def GenerateTables(self):
"""Generate device defintions for the platform data """Generate device defintions for the platform data
@ -312,64 +392,18 @@ class DtbPlatdata:
self.Out('#include <dm.h>\n') self.Out('#include <dm.h>\n')
self.Out('#include <dt-structs.h>\n') self.Out('#include <dt-structs.h>\n')
self.Out('\n') self.Out('\n')
node_txt_list = [] nodes_to_output = list(self._valid_nodes)
for node in self._valid_nodes:
struct_name = self.GetCompatName(node)
var_name = Conv_name_to_c(node.name)
self.Buf('static struct %s%s %s%s = {\n' %
(STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
for pname, prop in node.props.items():
if pname in PROP_IGNORE_LIST or pname[0] == '#':
continue
ptype = TYPE_NAMES[prop.type]
member_name = Conv_name_to_c(prop.name)
self.Buf('\t%s= ' % TabTo(3, '.' + member_name))
# Special handling for lists # Keep outputing nodes until there is none left
if type(prop.value) == list: while nodes_to_output:
self.Buf('{') node = nodes_to_output[0]
vals = [] # Output all the node's dependencies first
# For phandles, output a reference to the platform data for req_node in node.phandles:
# of the target node. if req_node in nodes_to_output:
if self.IsPhandle(prop): self.OutputNode(req_node)
# Process the list as pairs of (phandle, id) nodes_to_output.remove(req_node)
it = iter(prop.value) self.OutputNode(node)
for phandle_cell, id_cell in zip(it, it): nodes_to_output.remove(node)
phandle = fdt_util.fdt32_to_cpu(phandle_cell)
id = fdt_util.fdt32_to_cpu(id_cell)
target_node = self._phandle_node[phandle]
name = Conv_name_to_c(target_node.name)
vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id))
else:
for val in prop.value:
vals.append(self.GetValue(prop.type, val))
self.Buf(', '.join(vals))
self.Buf('}')
else:
self.Buf(self.GetValue(prop.type, prop.value))
self.Buf(',\n')
self.Buf('};\n')
# Add a device declaration
self.Buf('U_BOOT_DEVICE(%s) = {\n' % var_name)
self.Buf('\t.name\t\t= "%s",\n' % struct_name)
self.Buf('\t.platdata\t= &%s%s,\n' % (VAL_PREFIX, var_name))
self.Buf('\t.platdata_size\t= sizeof(%s%s),\n' %
(VAL_PREFIX, var_name))
self.Buf('};\n')
self.Buf('\n')
# Output phandle target nodes first, since they may be referenced
# by others
if 'phandle' in node.props:
self.Out(''.join(self.GetBuf()))
else:
node_txt_list.append(self.GetBuf())
# Output all the nodes which are not phandle targets themselves, but
# may reference them. This avoids the need for forward declarations.
for node_txt in node_txt_list:
self.Out(''.join(node_txt))
if __name__ != "__main__": if __name__ != "__main__":
@ -392,6 +426,7 @@ plat.ScanDtb()
plat.ScanTree() plat.ScanTree()
plat.SetupOutput(options.output) plat.SetupOutput(options.output)
structs = plat.ScanStructs() structs = plat.ScanStructs()
plat.ScanPhandles()
for cmd in args[0].split(','): for cmd in args[0].split(','):
if cmd == 'struct': if cmd == 'struct':

View file

@ -13,6 +13,8 @@
#include "mkimage.h" #include "mkimage.h"
#include "rkcommon.h" #include "rkcommon.h"
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
enum { enum {
RK_SIGNATURE = 0x0ff0aa55, RK_SIGNATURE = 0x0ff0aa55,
}; };
@ -71,6 +73,7 @@ static struct spl_info spl_infos[] = {
{ "rk3036", "RK30", 0x1000, false, false }, { "rk3036", "RK30", 0x1000, false, false },
{ "rk3188", "RK31", 0x8000 - 0x800, true, false }, { "rk3188", "RK31", 0x8000 - 0x800, true, false },
{ "rk3288", "RK32", 0x8000, false, false }, { "rk3288", "RK32", 0x8000, false, false },
{ "rk3328", "RK32", 0x8000 - 0x1000, false, false },
{ "rk3399", "RK33", 0x20000, false, true }, { "rk3399", "RK33", 0x20000, false, true },
}; };
@ -83,6 +86,9 @@ static struct spl_info *rkcommon_get_spl_info(char *imagename)
{ {
int i; int i;
if (!imagename)
return NULL;
for (i = 0; i < ARRAY_SIZE(spl_infos); i++) for (i = 0; i < ARRAY_SIZE(spl_infos); i++)
if (!strncmp(imagename, spl_infos[i].imagename, 6)) if (!strncmp(imagename, spl_infos[i].imagename, 6))
return spl_infos + i; return spl_infos + i;
@ -95,17 +101,24 @@ int rkcommon_check_params(struct image_tool_params *params)
int i; int i;
if (rkcommon_get_spl_info(params->imagename) != NULL) if (rkcommon_get_spl_info(params->imagename) != NULL)
return 0; return EXIT_SUCCESS;
/*
* If this is a operation (list or extract), the don't require
* imagename to be set.
*/
if (params->lflag || params->iflag)
return EXIT_SUCCESS;
fprintf(stderr, "ERROR: imagename (%s) is not supported!\n", fprintf(stderr, "ERROR: imagename (%s) is not supported!\n",
strlen(params->imagename) > 0 ? params->imagename : "NULL"); params->imagename ? params->imagename : "NULL");
fprintf(stderr, "Available imagename:"); fprintf(stderr, "Available imagename:");
for (i = 0; i < ARRAY_SIZE(spl_infos); i++) for (i = 0; i < ARRAY_SIZE(spl_infos); i++)
fprintf(stderr, "\t%s", spl_infos[i].imagename); fprintf(stderr, "\t%s", spl_infos[i].imagename);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
return -1; return EXIT_FAILURE;
} }
const char *rkcommon_get_spl_hdr(struct image_tool_params *params) const char *rkcommon_get_spl_hdr(struct image_tool_params *params)
@ -159,9 +172,21 @@ static void rkcommon_set_header0(void *buf, uint file_size,
hdr->disable_rc4 = !rkcommon_need_rc4_spl(params); hdr->disable_rc4 = !rkcommon_need_rc4_spl(params);
hdr->init_offset = RK_INIT_OFFSET; hdr->init_offset = RK_INIT_OFFSET;
hdr->init_size = (file_size + RK_BLK_SIZE - 1) / RK_BLK_SIZE; hdr->init_size = DIV_ROUND_UP(file_size, RK_BLK_SIZE);
hdr->init_size = (hdr->init_size + 3) & ~3; /*
hdr->init_boot_size = hdr->init_size + RK_MAX_BOOT_SIZE / RK_BLK_SIZE; * The init_size has to be a multiple of 4 blocks (i.e. of 2K)
* or the BootROM will not boot the image.
*
* Note: To verify that this is not a legacy constraint, we
* rechecked this against the RK3399 BootROM.
*/
hdr->init_size = ROUND(hdr->init_size, 4);
/*
* The images we create do not contain the stage following the SPL as
* part of the SPL image, so the init_boot_size (which might have been
* read by Rockchip's miniloder) should be the same as the init_size.
*/
hdr->init_boot_size = hdr->init_size;
rc4_encode(buf, RK_BLK_SIZE, rc4_key); rc4_encode(buf, RK_BLK_SIZE, rc4_key);
} }
@ -176,7 +201,7 @@ int rkcommon_set_header(void *buf, uint file_size,
rkcommon_set_header0(buf, file_size, params); rkcommon_set_header0(buf, file_size, params);
/* Set up the SPL name and add the AArch64 'nop' padding, if needed */ /* Set up the SPL name */
memcpy(&hdr->magic, rkcommon_get_spl_hdr(params), RK_SPL_HDR_SIZE); memcpy(&hdr->magic, rkcommon_get_spl_hdr(params), RK_SPL_HDR_SIZE);
if (rkcommon_need_rc4_spl(params)) if (rkcommon_need_rc4_spl(params))
@ -199,25 +224,33 @@ void rkcommon_rc4_encode_spl(void *buf, unsigned int offset, unsigned int size)
} }
} }
void rkcommon_vrec_header(struct image_tool_params *params, int rkcommon_vrec_header(struct image_tool_params *params,
struct image_type_params *tparams) struct image_type_params *tparams,
unsigned int alignment)
{ {
unsigned int unpadded_size;
unsigned int padded_size;
/* /*
* The SPL image looks as follows: * The SPL image looks as follows:
* *
* 0x0 header0 (see rkcommon.c) * 0x0 header0 (see rkcommon.c)
* 0x800 spl_name ('RK30', ..., 'RK33') * 0x800 spl_name ('RK30', ..., 'RK33')
* (start of the payload for AArch64 payloads: we expect the
* first 4 bytes to be available for overwriting with our
* spl_name)
* 0x804 first instruction to be executed * 0x804 first instruction to be executed
* (image start for AArch32, 'nop' for AArch64)) * (start of the image/payload for 32bit payloads)
* 0x808 second instruction to be executed
* (image start for AArch64)
* *
* For AArch64 (ARMv8) payloads, we receive an input file that * For AArch64 (ARMv8) payloads, natural alignment (8-bytes) is
* needs to start on an 8-byte boundary (natural alignment), so * required for its sections (so the image we receive needs to
* we need to put a NOP at 0x804. * have the first 4 bytes reserved for the spl_name). Reserving
* these 4 bytes is done using the BOOT0_HOOK infrastructure.
* *
* Depending on this, the header is either 0x804 or 0x808 bytes * Depending on this, the header is either 0x800 (if this is a
* in length. * 'boot0'-style payload, which has reserved 4 bytes at the
* beginning for the 'spl_name' and expects us to overwrite
* its first 4 bytes) or 0x804 bytes in length.
*/ */
if (rkcommon_spl_is_boot0(params)) if (rkcommon_spl_is_boot0(params))
tparams->header_size = RK_SPL_HDR_START; tparams->header_size = RK_SPL_HDR_START;
@ -227,4 +260,17 @@ void rkcommon_vrec_header(struct image_tool_params *params,
/* Allocate, clear and install the header */ /* Allocate, clear and install the header */
tparams->hdr = malloc(tparams->header_size); tparams->hdr = malloc(tparams->header_size);
memset(tparams->hdr, 0, tparams->header_size); memset(tparams->hdr, 0, tparams->header_size);
tparams->header_size = tparams->header_size;
/*
* If someone passed in 0 for the alignment, we'd better handle
* it correctly...
*/
if (!alignment)
alignment = 1;
unpadded_size = tparams->header_size + params->file_size;
padded_size = ROUND(unpadded_size, alignment);
return padded_size - unpadded_size;
} }

View file

@ -83,8 +83,14 @@ void rkcommon_rc4_encode_spl(void *buf, unsigned int offset, unsigned int size);
* @params: Pointer to the tool params structure * @params: Pointer to the tool params structure
* @tparams: Pointer tot the image type structure (for setting * @tparams: Pointer tot the image type structure (for setting
* the header and header_size) * the header and header_size)
* @alignment: Alignment (a power of two) that the image should be
* padded to (e.g. 512 if we want to align with SD/MMC
* blocksizes or 2048 for the SPI format)
*
* @return bytes of padding required/added (does not include the header_size)
*/ */
void rkcommon_vrec_header(struct image_tool_params *params, int rkcommon_vrec_header(struct image_tool_params *params,
struct image_type_params *tparams); struct image_type_params *tparams,
unsigned int alignment);
#endif #endif

View file

@ -13,16 +13,6 @@
static uint32_t header; static uint32_t header;
static int rkimage_verify_header(unsigned char *buf, int size,
struct image_tool_params *params)
{
return 0;
}
static void rkimage_print_header(const void *buf)
{
}
static void rkimage_set_header(void *buf, struct stat *sbuf, int ifd, static void rkimage_set_header(void *buf, struct stat *sbuf, int ifd,
struct image_tool_params *params) struct image_tool_params *params)
{ {
@ -33,11 +23,6 @@ static void rkimage_set_header(void *buf, struct stat *sbuf, int ifd,
rkcommon_rc4_encode_spl(buf, 4, params->file_size); rkcommon_rc4_encode_spl(buf, 4, params->file_size);
} }
static int rkimage_extract_subimage(void *buf, struct image_tool_params *params)
{
return 0;
}
static int rkimage_check_image_type(uint8_t type) static int rkimage_check_image_type(uint8_t type)
{ {
if (type == IH_TYPE_RKIMAGE) if (type == IH_TYPE_RKIMAGE)
@ -55,10 +40,10 @@ U_BOOT_IMAGE_TYPE(
4, 4,
&header, &header,
rkcommon_check_params, rkcommon_check_params,
rkimage_verify_header, NULL,
rkimage_print_header, NULL,
rkimage_set_header, rkimage_set_header,
rkimage_extract_subimage, NULL,
rkimage_check_image_type, rkimage_check_image_type,
NULL, NULL,
NULL NULL

View file

@ -29,12 +29,20 @@ static void rksd_set_header(void *buf, struct stat *sbuf, int ifd,
unsigned int size; unsigned int size;
int ret; int ret;
printf("params->file_size %d\n", params->file_size);
printf("params->orig_file_size %d\n", params->orig_file_size);
/*
* We need to calculate this using 'RK_SPL_HDR_START' and not using
* 'tparams->header_size', as the additional byte inserted when
* 'is_boot0' is true counts towards the payload.
*/
size = params->file_size - RK_SPL_HDR_START; size = params->file_size - RK_SPL_HDR_START;
ret = rkcommon_set_header(buf, size, params); ret = rkcommon_set_header(buf, size, params);
if (ret) { if (ret) {
/* TODO(sjg@chromium.org): This method should return an error */ /* TODO(sjg@chromium.org): This method should return an error */
printf("Warning: SPL image is too large (size %#x) and will not boot\n", printf("Warning: SPL image is too large (size %#x) and will "
size); "not boot\n", size);
} }
} }
@ -51,18 +59,14 @@ static int rksd_check_image_type(uint8_t type)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* We pad the file out to a fixed size - this method returns that size */
static int rksd_vrec_header(struct image_tool_params *params, static int rksd_vrec_header(struct image_tool_params *params,
struct image_type_params *tparams) struct image_type_params *tparams)
{ {
int pad_size; /*
* Pad to the RK_BLK_SIZE (512 bytes) to be consistent with init_size
rkcommon_vrec_header(params, tparams); * being encoded in RK_BLK_SIZE units in header0 (see rkcommon.c).
*/
pad_size = RK_SPL_HDR_START + rkcommon_get_spl_size(params); return rkcommon_vrec_header(params, tparams, RK_BLK_SIZE);
debug("pad_size %x\n", pad_size);
return pad_size - params->file_size - tparams->header_size;
} }
/* /*

View file

@ -39,8 +39,8 @@ static void rkspi_set_header(void *buf, struct stat *sbuf, int ifd,
debug("size %x\n", size); debug("size %x\n", size);
if (ret) { if (ret) {
/* TODO(sjg@chromium.org): This method should return an error */ /* TODO(sjg@chromium.org): This method should return an error */
printf("Warning: SPL image is too large (size %#x) and will not boot\n", printf("Warning: SPL image is too large (size %#x) and will "
size); "not boot\n", size);
} }
/* /*
@ -71,23 +71,36 @@ static int rkspi_check_image_type(uint8_t type)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* We pad the file out to a fixed size - this method returns that size */ /*
* The SPI payload needs to be padded out to make space for odd half-sector
* layout used in flash (i.e. only the first 2K of each 4K sector is used).
*/
static int rkspi_vrec_header(struct image_tool_params *params, static int rkspi_vrec_header(struct image_tool_params *params,
struct image_type_params *tparams) struct image_type_params *tparams)
{ {
int pad_size; int padding = rkcommon_vrec_header(params, tparams, 2048);
/*
* The file size has not been adjusted at this point (our caller will
* eventually add the header/padding to the file_size), so we need to
* add up the header_size, file_size and padding ourselves.
*/
int padded_size = tparams->header_size + params->file_size + padding;
rkcommon_vrec_header(params, tparams); /*
* We need to store the original file-size (i.e. before padding), as
* imagetool does not set this during its adjustment of file_size.
*/
params->orig_file_size = padded_size;
pad_size = (rkcommon_get_spl_size(params) + 0x7ff) / 0x800 * 0x800; /*
params->orig_file_size = pad_size; * Converting to the SPI format (i.e. splitting each 4K page into two
* 2K subpages and then padding these 2K pages up to take a complete
/* We will double the image size due to the SPI format */ * 4K sector again) will will double the image size.
pad_size *= 2; *
pad_size += RK_SPL_HDR_START; * Thus we return the padded_size as an additional padding requirement
debug("pad_size %x\n", pad_size); * (be sure to add this to the padding returned from the common code).
*/
return pad_size - params->file_size - tparams->header_size; return padded_size + padding;
} }
/* /*